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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
//`include "../common/fpga_regs_common.v"
//`include "../common/fpga_regs_standard.v"
module rx_buffer_inband
( input usbclk,
input bus_reset,
input reset, // DSP side reset (used here), do not reset registers
input reset_regs, //Only reset registers
output [15:0] usbdata,
input RD,
output wire have_pkt_rdy,
output reg rx_overrun,
input wire [3:0] channels,
input wire [15:0] ch_0,
input wire [15:0] ch_1,
input wire [15:0] ch_2,
input wire [15:0] ch_3,
input wire [15:0] ch_4,
input wire [15:0] ch_5,
input wire [15:0] ch_6,
input wire [15:0] ch_7,
input rxclk,
input rxstrobe,
input clear_status,
input [6:0] serial_addr,
input [31:0] serial_data,
input serial_strobe,
output wire [15:0] debugbus,
//Connection with tx_inband
input rx_WR,
input [15:0] rx_databus,
input rx_WR_done,
output reg rx_WR_enabled,
//signal strength
input wire [31:0] rssi_0, input wire [31:0] rssi_1,
input wire [31:0] rssi_2, input wire [31:0] rssi_3,
input wire [1:0] tx_underrun
);
parameter NUM_CHAN = 1;
genvar i ;
// FX2 Bug Fix
reg [8:0] read_count;
always @(negedge usbclk)
if(bus_reset)
read_count <= #1 9'd0;
else if(RD & ~read_count[8])
read_count <= #1 read_count + 9'd1;
else
read_count <= #1 RD ? read_count : 9'b0;
// Time counter
reg [31:0] timestamp_clock;
always @(posedge rxclk)
if (reset)
timestamp_clock <= 0;
else
timestamp_clock <= timestamp_clock + 1;
// USB side fifo
wire [11:0] rdusedw;
wire [11:0] wrusedw;
wire [15:0] fifodata;
wire [15:0] fifodata_il[0:NUM_CHAN];
wire WR;
wire have_space;
reg sel;
reg wr;
always@(posedge rxclk)
begin
if(reset)
begin
sel<=1;
wr<=0;
end
else if(rxstrobe)
begin
sel<=0;
wr<=1;
end
else if(wr&~sel)
sel<=1;
else if(wr&sel)
wr<=0;
else
wr<=0;
end
assign fifodata_il[0] = (sel)?ch_1:ch_0;
assign fifodata_il[1] = (sel)?ch_3:ch_2;
fifo_4kx16_dc rx_usb_fifo (
.aclr ( reset ),
.data ( fifodata ),
.rdclk ( ~usbclk ),
.rdreq ( RD & ~read_count[8] ),
.wrclk ( rxclk ),
.wrreq ( WR ),
.q ( usbdata ),
.rdempty ( ),
.rdusedw ( rdusedw ),
.wrfull ( ),
.wrusedw ( wrusedw ) );
assign have_pkt_rdy = (rdusedw >= 12'd256);
assign have_space = (wrusedw < 12'd760);
// Rx side fifos
// These are of size [NUM_CHAN:0] because the extra channel is used for the
// RX command channel. If there were no command channel, they would be
// NUM_CHAN-1.
wire chan_rdreq;
wire [15:0] chan_fifodata;
wire [9:0] chan_usedw;
wire [NUM_CHAN:0] chan_empty;
wire [3:0] rd_select;
wire [NUM_CHAN:0] rx_full;
packet_builder #(NUM_CHAN) rx_pkt_builer (
.rxclk ( rxclk ),
.reset ( reset ),
.timestamp_clock ( timestamp_clock ),
.channels ( NUM_CHAN ),
.chan_rdreq ( chan_rdreq ),
.chan_fifodata ( chan_fifodata ),
.chan_empty ( chan_empty ),
.rd_select ( rd_select ),
.chan_usedw ( chan_usedw ),
.WR ( WR ),
.fifodata ( fifodata ),
.have_space ( have_space ),
.rssi_0(rssi_0), .rssi_1(rssi_1),
.rssi_2(rssi_2),.rssi_3(rssi_3), .debugbus(debug),
.underrun(tx_underrun));
// Detect overrun
always @(posedge rxclk)
if(reset)
rx_overrun <= 1'b0;
else if(rx_full[0])
rx_overrun <= 1'b1;
else if(clear_status)
rx_overrun <= 1'b0;
// FIXME: what is the purpose of these two lines?
wire [15:0]ch[NUM_CHAN:0];
assign ch[0] = ch_0;
wire cmd_empty;
always @(posedge rxclk)
if(reset)
rx_WR_enabled <= 1;
else if(cmd_empty)
rx_WR_enabled <= 1;
else if(rx_WR_done)
rx_WR_enabled <= 0;
// Of Size 0:NUM_CHAN due to extra command channel.
wire [15:0] dataout [0:NUM_CHAN];
wire [9:0] usedw [0:NUM_CHAN];
wire empty[0:NUM_CHAN];
generate for (i = 0 ; i < NUM_CHAN; i = i + 1)
begin : generate_channel_fifos
wire rdreq;
assign rdreq = (rd_select == i) & chan_rdreq;
fifo_1kx16 rx_chan_fifo (
.aclr ( reset ),
.clock ( rxclk ),
.data ( fifodata_il[i] ),
.rdreq ( rdreq ),
.wrreq ( ~rx_full[i] & wr),
.empty (empty[i]),
.full (rx_full[i]),
.q ( dataout[i]),
.usedw ( usedw[i]),
.almost_empty(chan_empty[i])
);
end
endgenerate
wire [7:0] debug;
fifo_1kx16 rx_cmd_fifo (
.aclr ( reset ),
.clock ( rxclk ),
.data ( rx_databus ),
.rdreq ( (rd_select == NUM_CHAN) & chan_rdreq ),
.wrreq ( rx_WR & rx_WR_enabled),
.empty ( cmd_empty),
.full ( rx_full[NUM_CHAN] ),
.q ( dataout[NUM_CHAN]),
.usedw ( usedw[NUM_CHAN] )
);
assign chan_empty[NUM_CHAN] = cmd_empty | rx_WR_enabled;
assign chan_fifodata = dataout[rd_select];
assign chan_usedw = usedw[rd_select];
assign debugbus = {4'd0, rxclk, rxstrobe, rx_full[0], rx_full[1], sel, wr};
endmodule
|