diff options
Diffstat (limited to 'sdr_lib/rx_buffer.v')
-rw-r--r-- | sdr_lib/rx_buffer.v | 243 |
1 files changed, 149 insertions, 94 deletions
diff --git a/sdr_lib/rx_buffer.v b/sdr_lib/rx_buffer.v index ec5b8eefe..7c52925c9 100644 --- a/sdr_lib/rx_buffer.v +++ b/sdr_lib/rx_buffer.v @@ -20,21 +20,24 @@ // // Interface to Cypress FX2 bus -// A packet is 512 Bytes. Each fifo line is 2 bytes -// Fifo has 1024 or 2048 lines +// A packet is 512 Bytes, the fifo has 4096 lines of 18 bits each `include "../../firmware/include/fpga_regs_common.v" `include "../../firmware/include/fpga_regs_standard.v" module rx_buffer - ( input usbclk, - input bus_reset, // Not used in RX - input reset, // DSP side reset (used here), do not reset registers - input reset_regs, //Only reset registers + ( // Read/USB side + input usbclk, + input bus_reset, output [15:0] usbdata, input RD, - output wire have_pkt_rdy, + output reg have_pkt_rdy, output reg rx_overrun, + input clear_status, + // Write/DSP side + input rxclk, + input reset, // DSP side reset (used here), do not reset registers + input rxstrobe, input wire [3:0] channels, input wire [15:0] ch_0, input wire [15:0] ch_1, @@ -44,139 +47,191 @@ module rx_buffer 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, + // Settings, on rxclk also input [6:0] serial_addr, input [31:0] serial_data, input serial_strobe, - output [15:0] debugbus + input reset_regs, //Only reset registers + output [31:0] debugbus ); - - wire [15:0] fifodata, fifodata_8; - reg [15:0] fifodata_16; - wire [11:0] rxfifolevel; - wire rx_empty, rx_full; - - wire bypass_hb, want_q; - wire [4:0] bitwidth; - wire [3:0] bitshift; + wire [15:0] fifodata, fifodata_8; + reg [15:0] fifodata_16; + + wire [11:0] rxfifolevel; + wire rx_full; + + wire bypass_hb, want_q; + wire [4:0] bitwidth; + wire [3:0] bitshift; setting_reg #(`FR_RX_FORMAT) sr_rxformat(.clock(rxclk),.reset(reset_regs), .strobe(serial_strobe),.addr(serial_addr),.in(serial_data), .out({bypass_hb,want_q,bitwidth,bitshift})); - // Receive FIFO (ADC --> USB) + // USB Read Side of FIFO + always @(negedge usbclk) + have_pkt_rdy <= (rxfifolevel >= 256); // 257 Bug Fix - reg [8:0] read_count; + 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; + read_count <= 0; + else if(RD) + read_count <= read_count + 1; else - read_count <= #1 RD ? read_count : 9'b0; + read_count <= 0; - // Detect overrun + // FIFO + wire ch0_in, ch0_out, iq_out; + assign ch0_in = (phase == 1); + + fifo_4k_18 rxfifo + ( // DSP Write Side + .data ( {ch0_in, phase[0], fifodata} ), + .wrreq (~rx_full & (phase != 0)), + .wrclk ( rxclk ), + .wrfull ( rx_full ), + .wrempty ( ), + .wrusedw ( ), + // USB Read Side + .q ( {ch0_out,iq_out,usbdata} ), + .rdreq ( RD & ~read_count[8] ), + .rdclk ( ~usbclk ), + .rdfull ( ), + .rdempty ( ), + .rdusedw ( rxfifolevel ), + // Async, shared + .aclr ( reset ) ); + + // DSP Write Side of FIFO + reg [15:0] ch_0_reg; + reg [15:0] ch_1_reg; + reg [15:0] ch_2_reg; + reg [15:0] ch_3_reg; + reg [15:0] ch_4_reg; + reg [15:0] ch_5_reg; + reg [15:0] ch_6_reg; + reg [15:0] ch_7_reg; + always @(posedge rxclk) - if(reset) - rx_overrun <= 1'b0; - else if(rxstrobe & (store_next != 0)) - rx_overrun <= 1'b1; - else if(clear_status) - rx_overrun <= 1'b0; + if (rxstrobe) + begin + ch_0_reg <= ch_0; + ch_1_reg <= ch_1; + ch_2_reg <= ch_2; + ch_3_reg <= ch_3; + ch_4_reg <= ch_4; + ch_5_reg <= ch_5; + ch_6_reg <= ch_6; + ch_7_reg <= ch_7; + end - reg [3:0] store_next; + reg [3:0] phase; always @(posedge rxclk) if(reset) - store_next <= #1 4'd0; - else if(rxstrobe & (store_next == 0)) - store_next <= #1 4'd1; - else if(~rx_full & (store_next == channels)) - store_next <= #1 4'd0; - else if(~rx_full & (bitwidth == 5'd8) & (store_next == (channels>>1))) - store_next <= #1 4'd0; - else if(~rx_full & (store_next != 0)) - store_next <= #1 store_next + 4'd1; - + phase <= 4'd0; + else if(phase == 0) + begin + if(rxstrobe) + phase <= 4'd1; + end + else if(~rx_full) + if(phase == channels) + phase <= 4'd0; + else + phase <= phase + 4'd1; + assign fifodata = (bitwidth == 5'd8) ? fifodata_8 : fifodata_16; - + assign fifodata_8 = {round_8(top),round_8(bottom)}; reg [15:0] top,bottom; - + function [7:0] round_8; input [15:0] in_val; - + round_8 = in_val[15:8] + (in_val[15] & |in_val[7:0]); endfunction // round_8 always @* - case(store_next) + case(phase) 4'd1 : begin - bottom = ch_0; - top = ch_1; + bottom = ch_0_reg; + top = ch_1_reg; end 4'd2 : begin - bottom = ch_2; - top = ch_3; + bottom = ch_2_reg; + top = ch_3_reg; end 4'd3 : begin - bottom = ch_4; - top = ch_5; + bottom = ch_4_reg; + top = ch_5_reg; end 4'd4 : begin - bottom = ch_6; - top = ch_7; + bottom = ch_6_reg; + top = ch_7_reg; end default : begin top = 16'hFFFF; bottom = 16'hFFFF; end - endcase // case(store_next) + endcase // case(phase) always @* - case(store_next) - 4'd1 : fifodata_16 = ch_0; - 4'd2 : fifodata_16 = ch_1; - 4'd3 : fifodata_16 = ch_2; - 4'd4 : fifodata_16 = ch_3; - 4'd5 : fifodata_16 = ch_4; - 4'd6 : fifodata_16 = ch_5; - 4'd7 : fifodata_16 = ch_6; - 4'd8 : fifodata_16 = ch_7; + case(phase) + 4'd1 : fifodata_16 = ch_0_reg; + 4'd2 : fifodata_16 = ch_1_reg; + 4'd3 : fifodata_16 = ch_2_reg; + 4'd4 : fifodata_16 = ch_3_reg; + 4'd5 : fifodata_16 = ch_4_reg; + 4'd6 : fifodata_16 = ch_5_reg; + 4'd7 : fifodata_16 = ch_6_reg; + 4'd8 : fifodata_16 = ch_7_reg; default : fifodata_16 = 16'hFFFF; - endcase // case(store_next) + endcase // case(phase) - fifo_4k rxfifo - ( .data ( fifodata ), - .wrreq (~rx_full & (store_next != 0)), - .wrclk ( rxclk ), + // Detect overrun + reg clear_status_dsp, rx_overrun_dsp; + always @(posedge rxclk) + clear_status_dsp <= clear_status; - .q ( usbdata ), - .rdreq ( RD & ~read_count[8] ), - .rdclk ( ~usbclk ), - - .aclr ( reset ), // This one is asynchronous, so we can use either reset - - .rdempty ( rx_empty ), - .rdusedw ( rxfifolevel ), - .wrfull ( rx_full ), - .wrusedw ( ) - ); + always @(negedge usbclk) + rx_overrun <= rx_overrun_dsp; + + always @(posedge rxclk) + if(reset) + rx_overrun_dsp <= 1'b0; + else if(rxstrobe & (phase != 0)) + rx_overrun_dsp <= 1'b1; + else if(clear_status_dsp) + rx_overrun_dsp <= 1'b0; + + // Debug bus + // + // 15:0 rxclk domain => TXA 15:0 + // 31:16 usbclk domain => RXA 15:0 - assign have_pkt_rdy = (rxfifolevel >= 256); + assign debugbus[0] = reset; + assign debugbus[1] = reset_regs; + assign debugbus[2] = rxstrobe; + assign debugbus[6:3] = channels; + assign debugbus[7] = rx_full; + assign debugbus[11:8] = phase; + assign debugbus[12] = ch0_in; + assign debugbus[13] = clear_status_dsp; + assign debugbus[14] = rx_overrun_dsp; + assign debugbus[15] = rxclk; - // Debugging Aids - assign debugbus[0] = RD; - assign debugbus[1] = rx_overrun; - assign debugbus[2] = read_count[8]; - assign debugbus[3] = rx_full; - assign debugbus[4] = rxstrobe; - assign debugbus[5] = usbclk; - assign debugbus[6] = have_pkt_rdy; - assign debugbus[10:7] = store_next; - //assign debugbus[15:11] = rxfifolevel[4:0]; - assign debugbus[15:11] = bitwidth; + assign debugbus[16] = bus_reset; + assign debugbus[17] = RD; + assign debugbus[18] = have_pkt_rdy; + assign debugbus[19] = rx_overrun; + assign debugbus[20] = read_count[0]; + assign debugbus[21] = read_count[8]; + assign debugbus[22] = ch0_out; + assign debugbus[23] = iq_out; + assign debugbus[24] = clear_status; + assign debugbus[30:25] = 0; + assign debugbus[31] = usbclk; endmodule // rx_buffer |