Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / inband_lib / packet_builder.v
1 module packet_builder #(parameter NUM_CHAN = 2)(
2     // System
3     input rxclk,
4     input reset,
5          input [31:0] timestamp_clock,
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     input [NUM_CHAN:0] underrun);
20     
21     
22     // States
23     `define IDLE                     3'd0
24     `define HEADER1                  3'd1
25     `define HEADER2                  3'd2
26     `define TIMESTAMP                3'd3
27     `define FORWARD                  3'd4
28         
29     `define MAXPAYLOAD 504
30     
31     `define PAYLOAD_LEN 8:0
32     `define TAG 12:9
33     `define MBZ 15:13
34     
35     `define CHAN 4:0
36     `define RSSI 10:5
37     `define BURST 12:11
38     `define DROPPED 13
39     `define UNDERRUN 14
40     `define OVERRUN 15
41     
42     reg [NUM_CHAN:0] overrun;
43     reg [2:0] state;
44     reg [8:0] read_length;
45     reg [8:0] payload_len;
46     reg timestamp_complete;
47     reg [3:0] check_next;
48         
49     wire [31:0] true_rssi;
50     wire [4:0] true_channel;
51     wire ready_to_send;
52
53     assign debugbus = {chan_empty[0], rd_select[0], have_space, 
54                        (chan_usedw >= 10'd504), (chan_usedw ==0),  
55                        ready_to_send, state[1:0]};
56
57     assign true_rssi = (rd_select[1]) ? ((rd_select[0]) ? rssi_3:rssi_2) :
58                                                         ((rd_select[0]) ? rssi_1:rssi_0);
59     assign true_channel = (check_next == 4'd0 ? 5'h1f : {1'd0, check_next - 4'd1});
60     assign ready_to_send = (chan_usedw >= 10'd504) || (chan_usedw == 0) || 
61                            ((rd_select == NUM_CHAN)&&(chan_usedw > 0));
62                 
63     always @(posedge rxclk)
64     begin
65         if (reset)
66           begin
67             overrun <= 0;
68             WR <= 0;
69             rd_select <= 0;
70             chan_rdreq <= 0;
71             timestamp_complete <= 0;
72             check_next <= 0;
73             state <= `IDLE;
74           end
75         else case (state)
76             `IDLE: begin
77                 chan_rdreq <= #1 0;
78                 //check if the channel is full
79                 if(~chan_empty[check_next])
80                   begin
81                     if (have_space)
82                       begin
83                         //transmit if the usb buffer have space
84                        //check if we should send
85                        if (ready_to_send)
86                            state <= #1 `HEADER1;
87                                                     
88                        overrun[check_next] <= 0;
89                       end
90                   else
91                     begin
92                       state <= #1 `IDLE;
93                       overrun[check_next] <= 1;
94                     end
95                   rd_select <= #1 check_next;
96                 end
97                 check_next <= #1 (check_next == channels ? 4'd0 : check_next + 4'd1);
98             end
99             
100             `HEADER1: begin
101                 fifodata[`PAYLOAD_LEN] <= #1 9'd504;
102                 payload_len <= #1 9'd504;
103                 fifodata[`TAG] <= #1 0;
104                 fifodata[`MBZ] <= #1 0;
105                 WR <= #1 1;
106                 
107                 state <= #1 `HEADER2;
108                 read_length <= #1 0;
109             end
110             
111             `HEADER2: begin
112                 fifodata[`CHAN] <= #1 true_channel;
113                 fifodata[`RSSI] <= #1 true_rssi[5:0];
114                 fifodata[`BURST] <= #1 0;
115                 fifodata[`DROPPED] <= #1 0;
116                 fifodata[`UNDERRUN] <= #1 (check_next == 0) ? 1'b0 : underrun[true_channel];
117                 fifodata[`OVERRUN] <= #1 (check_next == 0) ? 1'b0 : overrun[true_channel];
118                 state <= #1 `TIMESTAMP;
119             end
120             
121             `TIMESTAMP: begin
122                 fifodata <= #1 (timestamp_complete ? timestamp_clock[31:16] : timestamp_clock[15:0]);
123                 timestamp_complete <= #1 ~timestamp_complete;
124                 
125                 if (~timestamp_complete)
126                     chan_rdreq <= #1 1;
127                 
128                 state <= #1 (timestamp_complete ? `FORWARD : `TIMESTAMP);
129             end
130             
131             `FORWARD: begin
132                 read_length <= #1 read_length + 9'd2;
133                 fifodata <= #1 (read_length >= payload_len ? 16'hDEAD : chan_fifodata);
134                 
135                 if (read_length >= `MAXPAYLOAD)
136                   begin
137                     WR <= #1 0;
138                     state <= #1 `IDLE;
139                                         chan_rdreq <= #1 0;
140                   end
141                 else if (read_length == payload_len - 4)
142                     chan_rdreq <= #1 0;
143             end
144             
145             default: begin
146                                 //handling error state
147                 state <= `IDLE;
148             end
149             endcase
150     end
151 endmodule
152