Merged features/inband-usb r5224:6306 into trunk.
[debian/gnuradio] / usrp / fpga / inband_lib / packet_builder.v
1 module packet_builder #(parameter NUM_CHAN = 1)(
2     // System
3     input rxclk,
4     input reset,
5          input [31:0] adctime,
6          input [3:0] channels,
7     // ADC side
8     input [15:0]chan_fifodata,
9     input [NUM_CHAN:0]chan_empty,
10     input [9:0]chan_usedw,
11     output reg [3:0]rd_select,
12     output reg chan_rdreq,
13     // FX2 side
14     output reg WR,
15     output reg [15:0]fifodata,
16     input have_space, 
17         input wire [31:0]rssi_0, input wire [31:0]rssi_1, input wire [31:0]rssi_2,
18         input wire [31:0]rssi_3, output wire [7:0] debugbus);
19     
20     
21     // States
22     `define IDLE                     3'd0
23     `define HEADER1                  3'd1
24         `define HEADER2                                  3'd2
25     `define TIMESTAMP                3'd3
26         `define FORWARD                                  3'd4
27         
28     `define MAXPAYLOAD 504
29     
30     `define PAYLOAD_LEN 8:0
31     `define TAG 12:9
32     `define MBZ 15:13
33     
34     `define CHAN 4:0
35     `define RSSI 10:5
36     `define BURST 12:11
37     `define DROPPED 13
38     `define UNDERRUN 14
39     `define OVERRUN 15
40     
41     reg [2:0] state;
42     reg [8:0] read_length;
43     reg [8:0] payload_len;
44     reg tstamp_complete;
45     reg [3:0] check_next;
46         wire [8:0] chan_used;
47     wire [31:0] true_rssi;
48
49         assign debugbus = {state, chan_empty[0], chan_empty[1], check_next[0],
50                                                 have_space, rd_select[0]};
51         assign chan_used = chan_usedw[8:0];
52         assign true_rssi = (rd_select[1]) ? ((rd_select[0]) ? rssi_3:rssi_2) :
53                                                         ((rd_select[0]) ? rssi_1:rssi_0);       
54     always @(posedge rxclk)
55     begin
56         if (reset)
57           begin
58             WR <= 0;
59             rd_select <= 0;
60             chan_rdreq <= 0;
61             tstamp_complete <= 0;
62             check_next <= 0;
63             state <= `IDLE;
64           end
65         else case (state)
66             `IDLE: begin
67                                 if (have_space)
68                                   begin
69                                         if(~chan_empty[check_next])
70                                       begin
71                                 state <= #1 `HEADER1;
72                                                 rd_select <= #1 check_next;
73                                           end
74                                         check_next <= #1 (check_next == channels ? 4'd0 : check_next + 4'd1);
75                                   end   
76             end
77             
78             `HEADER1: begin
79                 fifodata[`PAYLOAD_LEN] <= #1 (chan_used > 9'd252
80                                            ? 9'd252 : chan_used << 1);
81                 payload_len <= #1 (chan_used > 9'd252
82                                 ? 9'd252 : chan_used << 1);
83                 fifodata[`TAG] <= #1 0;
84                 fifodata[`MBZ] <= #1 0;
85                 WR <= #1 1;
86                 
87                 state <= #1 `HEADER2;
88                 read_length <= #1 0;
89             end
90             
91             `HEADER2: begin
92                 fifodata[`CHAN] <= #1 (check_next == 4'd0 ? 5'h1f : {1'd0, check_next - 4'd1});
93                 fifodata[`RSSI] <= #1 true_rssi[5:0];
94                 fifodata[`BURST] <= #1 0;
95                 fifodata[`DROPPED] <= #1 0;
96                 fifodata[`UNDERRUN] <= #1 0;
97                 fifodata[`OVERRUN] <= #1 0;
98                 
99                 state <= #1 `TIMESTAMP;
100             end
101             
102             `TIMESTAMP: begin
103                 fifodata <= #1 (tstamp_complete ? adctime[31:16] : adctime[15:0]);
104                 tstamp_complete <= #1 ~tstamp_complete;
105                 
106                 if (~tstamp_complete)
107                     chan_rdreq <= #1 1;
108                 
109                 state <= #1 (tstamp_complete ? `FORWARD : `TIMESTAMP);
110             end
111             
112             `FORWARD: begin
113                 read_length <= #1 read_length + 9'd2;
114                 fifodata <= #1 (read_length >= payload_len ? 16'hDEAD : chan_fifodata);
115                 
116                 if (read_length >= `MAXPAYLOAD)
117                   begin
118                     WR <= #1 0;
119                     state <= #1 `IDLE;
120                   end
121                 else if (read_length == payload_len - 4)
122                     chan_rdreq <= #1 0;
123             end
124             
125             default: begin
126                                 //handling error state
127                 state <= `IDLE;
128             end
129             endcase
130     end
131 endmodule
132