]> git.gag.com Git - debian/gnuradio/blobdiff - usrp/fpga/inband_lib/packet_builder.v
Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / inband_lib / packet_builder.v
diff --git a/usrp/fpga/inband_lib/packet_builder.v b/usrp/fpga/inband_lib/packet_builder.v
new file mode 100755 (executable)
index 0000000..2c91223
--- /dev/null
@@ -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
+