1module 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
151endmodule
152
153