aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp1/inband_lib/packet_builder.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp1/inband_lib/packet_builder.v')
-rwxr-xr-xfpga/usrp1/inband_lib/packet_builder.v152
1 files changed, 152 insertions, 0 deletions
diff --git a/fpga/usrp1/inband_lib/packet_builder.v b/fpga/usrp1/inband_lib/packet_builder.v
new file mode 100755
index 000000000..2c9122394
--- /dev/null
+++ b/fpga/usrp1/inband_lib/packet_builder.v
@@ -0,0 +1,152 @@
+module packet_builder #(parameter NUM_CHAN = 2)(
+ // System
+ input rxclk,
+ input reset,
+ input [31:0] timestamp_clock,
+ input [3:0] channels,
+ // ADC side
+ input [15:0]chan_fifodata,
+ input [NUM_CHAN:0]chan_empty,
+ input [9:0]chan_usedw,
+ output reg [3:0]rd_select,
+ output reg chan_rdreq,
+ // FX2 side
+ output reg WR,
+ output reg [15:0]fifodata,
+ input have_space,
+ input wire [31:0]rssi_0, input wire [31:0]rssi_1, input wire [31:0]rssi_2,
+ input wire [31:0]rssi_3, output wire [7:0] debugbus,
+ input [NUM_CHAN:0] underrun);
+
+
+ // States
+ `define IDLE 3'd0
+ `define HEADER1 3'd1
+ `define HEADER2 3'd2
+ `define TIMESTAMP 3'd3
+ `define FORWARD 3'd4
+
+ `define MAXPAYLOAD 504
+
+ `define PAYLOAD_LEN 8:0
+ `define TAG 12:9
+ `define MBZ 15:13
+
+ `define CHAN 4:0
+ `define RSSI 10:5
+ `define BURST 12:11
+ `define DROPPED 13
+ `define UNDERRUN 14
+ `define OVERRUN 15
+
+ reg [NUM_CHAN:0] overrun;
+ reg [2:0] state;
+ reg [8:0] read_length;
+ reg [8:0] payload_len;
+ reg timestamp_complete;
+ reg [3:0] check_next;
+
+ wire [31:0] true_rssi;
+ wire [4:0] true_channel;
+ wire ready_to_send;
+
+ assign debugbus = {chan_empty[0], rd_select[0], have_space,
+ (chan_usedw >= 10'd504), (chan_usedw ==0),
+ ready_to_send, state[1:0]};
+
+ assign true_rssi = (rd_select[1]) ? ((rd_select[0]) ? rssi_3:rssi_2) :
+ ((rd_select[0]) ? rssi_1:rssi_0);
+ assign true_channel = (check_next == 4'd0 ? 5'h1f : {1'd0, check_next - 4'd1});
+ assign ready_to_send = (chan_usedw >= 10'd504) || (chan_usedw == 0) ||
+ ((rd_select == NUM_CHAN)&&(chan_usedw > 0));
+
+ always @(posedge rxclk)
+ begin
+ if (reset)
+ begin
+ overrun <= 0;
+ WR <= 0;
+ rd_select <= 0;
+ chan_rdreq <= 0;
+ timestamp_complete <= 0;
+ check_next <= 0;
+ state <= `IDLE;
+ end
+ else case (state)
+ `IDLE: begin
+ chan_rdreq <= #1 0;
+ //check if the channel is full
+ if(~chan_empty[check_next])
+ begin
+ if (have_space)
+ begin
+ //transmit if the usb buffer have space
+ //check if we should send
+ if (ready_to_send)
+ state <= #1 `HEADER1;
+
+ overrun[check_next] <= 0;
+ end
+ else
+ begin
+ state <= #1 `IDLE;
+ overrun[check_next] <= 1;
+ end
+ rd_select <= #1 check_next;
+ end
+ check_next <= #1 (check_next == channels ? 4'd0 : check_next + 4'd1);
+ end
+
+ `HEADER1: begin
+ fifodata[`PAYLOAD_LEN] <= #1 9'd504;
+ payload_len <= #1 9'd504;
+ fifodata[`TAG] <= #1 0;
+ fifodata[`MBZ] <= #1 0;
+ WR <= #1 1;
+
+ state <= #1 `HEADER2;
+ read_length <= #1 0;
+ end
+
+ `HEADER2: begin
+ fifodata[`CHAN] <= #1 true_channel;
+ fifodata[`RSSI] <= #1 true_rssi[5:0];
+ fifodata[`BURST] <= #1 0;
+ fifodata[`DROPPED] <= #1 0;
+ fifodata[`UNDERRUN] <= #1 (check_next == 0) ? 1'b0 : underrun[true_channel];
+ fifodata[`OVERRUN] <= #1 (check_next == 0) ? 1'b0 : overrun[true_channel];
+ state <= #1 `TIMESTAMP;
+ end
+
+ `TIMESTAMP: begin
+ fifodata <= #1 (timestamp_complete ? timestamp_clock[31:16] : timestamp_clock[15:0]);
+ timestamp_complete <= #1 ~timestamp_complete;
+
+ if (~timestamp_complete)
+ chan_rdreq <= #1 1;
+
+ state <= #1 (timestamp_complete ? `FORWARD : `TIMESTAMP);
+ end
+
+ `FORWARD: begin
+ read_length <= #1 read_length + 9'd2;
+ fifodata <= #1 (read_length >= payload_len ? 16'hDEAD : chan_fifodata);
+
+ if (read_length >= `MAXPAYLOAD)
+ begin
+ WR <= #1 0;
+ state <= #1 `IDLE;
+ chan_rdreq <= #1 0;
+ end
+ else if (read_length == payload_len - 4)
+ chan_rdreq <= #1 0;
+ end
+
+ default: begin
+ //handling error state
+ state <= `IDLE;
+ end
+ endcase
+ end
+endmodule
+