summaryrefslogtreecommitdiffstats
path: root/sdr_lib/rx_buffer.v
diff options
context:
space:
mode:
Diffstat (limited to 'sdr_lib/rx_buffer.v')
-rw-r--r--sdr_lib/rx_buffer.v182
1 files changed, 182 insertions, 0 deletions
diff --git a/sdr_lib/rx_buffer.v b/sdr_lib/rx_buffer.v
new file mode 100644
index 000000000..70c800e3d
--- /dev/null
+++ b/sdr_lib/rx_buffer.v
@@ -0,0 +1,182 @@
+// -*- verilog -*-
+//
+// USRP - Universal Software Radio Peripheral
+//
+// Copyright (C) 2003 Matt Ettus
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+// Interface to Cypress FX2 bus
+// A packet is 512 Bytes. Each fifo line is 2 bytes
+// Fifo has 1024 or 2048 lines
+
+`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
+ 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 [15: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;
+
+ 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)
+
+ // 257 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;
+
+ // Detect overrun
+ 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;
+
+ reg [3:0] store_next;
+ 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;
+
+ 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)
+ 4'd1 : begin
+ bottom = ch_0;
+ top = ch_1;
+ end
+ 4'd2 : begin
+ bottom = ch_2;
+ top = ch_3;
+ end
+ 4'd3 : begin
+ bottom = ch_4;
+ top = ch_5;
+ end
+ 4'd4 : begin
+ bottom = ch_6;
+ top = ch_7;
+ end
+ default : begin
+ top = 16'hFFFF;
+ bottom = 16'hFFFF;
+ end
+ endcase // case(store_next)
+
+ 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;
+ default : fifodata_16 = 16'hFFFF;
+ endcase // case(store_next)
+
+ fifo_4k rxfifo
+ ( .data ( fifodata ),
+ .wrreq (~rx_full & (store_next != 0)),
+ .wrclk ( rxclk ),
+
+ .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 ( )
+ );
+
+ assign have_pkt_rdy = (rxfifolevel >= 256);
+
+ // 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;
+
+endmodule // rx_buffer
+