1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 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
|