summaryrefslogtreecommitdiffstats
path: root/usrp2
diff options
context:
space:
mode:
authorIan Buckley <ianb@server2.(none)>2010-07-29 21:25:26 -0700
committerIan Buckley <ianb@server2.(none)>2010-07-29 21:25:26 -0700
commit8cd762bdbcbd6a43a2fcc1c0b523cc14bfd7ab69 (patch)
treeae72deb4fb98b50438fc660a081dbf89fffbebd5 /usrp2
parent886606f55da066b66d214e512a2226b19a1073df (diff)
downloaduhd-8cd762bdbcbd6a43a2fcc1c0b523cc14bfd7ab69.tar.gz
uhd-8cd762bdbcbd6a43a2fcc1c0b523cc14bfd7ab69.tar.bz2
uhd-8cd762bdbcbd6a43a2fcc1c0b523cc14bfd7ab69.zip
Checkpoint checkin.
Loopback is running via the external ZBT SRAM...HOWEVER, its not running well, its stable but the data is corrupted sometimes. Not clear if its a logic or AC timing/SI issue yet.
Diffstat (limited to 'usrp2')
-rw-r--r--usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v165
-rw-r--r--usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco82
-rw-r--r--usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v165
-rw-r--r--usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco82
-rw-r--r--usrp2/extramfifo/Makefile.srcs16
-rw-r--r--usrp2/extramfifo/ext_fifo.v120
-rw-r--r--usrp2/extramfifo/ext_fifo_tb.cmd11
-rw-r--r--usrp2/extramfifo/ext_fifo_tb.prj9
-rw-r--r--usrp2/extramfifo/ext_fifo_tb.sh1
-rw-r--r--usrp2/extramfifo/ext_fifo_tb.v285
-rw-r--r--usrp2/extramfifo/nobl_fifo.v264
-rw-r--r--usrp2/extramfifo/nobl_if.v136
-rw-r--r--usrp2/extramfifo/test_sram_if.v171
13 files changed, 1507 insertions, 0 deletions
diff --git a/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v b/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v
new file mode 100644
index 000000000..1d7a5ca2a
--- /dev/null
+++ b/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v
@@ -0,0 +1,165 @@
+/*******************************************************************************
+* This file is owned and controlled by Xilinx and must be used *
+* solely for design, simulation, implementation and creation of *
+* design files limited to Xilinx devices or technologies. Use *
+* with non-Xilinx devices or technologies is expressly prohibited *
+* and immediately terminates your license. *
+* *
+* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" *
+* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR *
+* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION *
+* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION *
+* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS *
+* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, *
+* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE *
+* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY *
+* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
+* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
+* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
+* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
+* FOR A PARTICULAR PURPOSE. *
+* *
+* Xilinx products are not intended for use in life support *
+* appliances, devices, or systems. Use in such applications are *
+* expressly prohibited. *
+* *
+* (c) Copyright 1995-2007 Xilinx, Inc. *
+* All rights reserved. *
+*******************************************************************************/
+// The synthesis directives "translate_off/translate_on" specified below are
+// supported by Xilinx, Mentor Graphics and Synplicity synthesis
+// tools. Ensure they are correct for your synthesis tool(s).
+
+// You must compile the wrapper file fifo_xlnx_512x36_2clk_18to36.v when simulating
+// the core, fifo_xlnx_512x36_2clk_18to36. When compiling the wrapper file, be sure to
+// reference the XilinxCoreLib Verilog simulation library. For detailed
+// instructions, please refer to the "CORE Generator Help".
+
+`timescale 1ns/1ps
+
+module fifo_xlnx_512x36_2clk_18to36(
+ din,
+ rd_clk,
+ rd_en,
+ rst,
+ wr_clk,
+ wr_en,
+ dout,
+ empty,
+ full);
+
+
+input [17 : 0] din;
+input rd_clk;
+input rd_en;
+input rst;
+input wr_clk;
+input wr_en;
+output [35 : 0] dout;
+output empty;
+output full;
+
+// synthesis translate_off
+
+ FIFO_GENERATOR_V4_4 #(
+ .C_COMMON_CLOCK(0),
+ .C_COUNT_TYPE(0),
+ .C_DATA_COUNT_WIDTH(10),
+ .C_DEFAULT_VALUE("BlankString"),
+ .C_DIN_WIDTH(18),
+ .C_DOUT_RST_VAL("0"),
+ .C_DOUT_WIDTH(36),
+ .C_ENABLE_RLOCS(0),
+ .C_FAMILY("spartan3"),
+ .C_FULL_FLAGS_RST_VAL(0),
+ .C_HAS_ALMOST_EMPTY(0),
+ .C_HAS_ALMOST_FULL(0),
+ .C_HAS_BACKUP(0),
+ .C_HAS_DATA_COUNT(0),
+ .C_HAS_INT_CLK(0),
+ .C_HAS_MEMINIT_FILE(0),
+ .C_HAS_OVERFLOW(0),
+ .C_HAS_RD_DATA_COUNT(0),
+ .C_HAS_RD_RST(0),
+ .C_HAS_RST(1),
+ .C_HAS_SRST(0),
+ .C_HAS_UNDERFLOW(0),
+ .C_HAS_VALID(0),
+ .C_HAS_WR_ACK(0),
+ .C_HAS_WR_DATA_COUNT(0),
+ .C_HAS_WR_RST(0),
+ .C_IMPLEMENTATION_TYPE(2),
+ .C_INIT_WR_PNTR_VAL(0),
+ .C_MEMORY_TYPE(1),
+ .C_MIF_FILE_NAME("BlankString"),
+ .C_MSGON_VAL(1),
+ .C_OPTIMIZATION_MODE(0),
+ .C_OVERFLOW_LOW(0),
+ .C_PRELOAD_LATENCY(0),
+ .C_PRELOAD_REGS(1),
+ .C_PRIM_FIFO_TYPE("1kx18"),
+ .C_PROG_EMPTY_THRESH_ASSERT_VAL(4),
+ .C_PROG_EMPTY_THRESH_NEGATE_VAL(5),
+ .C_PROG_EMPTY_TYPE(0),
+ .C_PROG_FULL_THRESH_ASSERT_VAL(1023),
+ .C_PROG_FULL_THRESH_NEGATE_VAL(1022),
+ .C_PROG_FULL_TYPE(0),
+ .C_RD_DATA_COUNT_WIDTH(9),
+ .C_RD_DEPTH(512),
+ .C_RD_FREQ(1),
+ .C_RD_PNTR_WIDTH(9),
+ .C_UNDERFLOW_LOW(0),
+ .C_USE_DOUT_RST(1),
+ .C_USE_ECC(0),
+ .C_USE_EMBEDDED_REG(0),
+ .C_USE_FIFO16_FLAGS(0),
+ .C_USE_FWFT_DATA_COUNT(0),
+ .C_VALID_LOW(0),
+ .C_WR_ACK_LOW(0),
+ .C_WR_DATA_COUNT_WIDTH(10),
+ .C_WR_DEPTH(1024),
+ .C_WR_FREQ(1),
+ .C_WR_PNTR_WIDTH(10),
+ .C_WR_RESPONSE_LATENCY(1))
+ inst (
+ .DIN(din),
+ .RD_CLK(rd_clk),
+ .RD_EN(rd_en),
+ .RST(rst),
+ .WR_CLK(wr_clk),
+ .WR_EN(wr_en),
+ .DOUT(dout),
+ .EMPTY(empty),
+ .FULL(full),
+ .CLK(),
+ .INT_CLK(),
+ .BACKUP(),
+ .BACKUP_MARKER(),
+ .PROG_EMPTY_THRESH(),
+ .PROG_EMPTY_THRESH_ASSERT(),
+ .PROG_EMPTY_THRESH_NEGATE(),
+ .PROG_FULL_THRESH(),
+ .PROG_FULL_THRESH_ASSERT(),
+ .PROG_FULL_THRESH_NEGATE(),
+ .RD_RST(),
+ .SRST(),
+ .WR_RST(),
+ .ALMOST_EMPTY(),
+ .ALMOST_FULL(),
+ .DATA_COUNT(),
+ .OVERFLOW(),
+ .PROG_EMPTY(),
+ .PROG_FULL(),
+ .VALID(),
+ .RD_DATA_COUNT(),
+ .UNDERFLOW(),
+ .WR_ACK(),
+ .WR_DATA_COUNT(),
+ .SBITERR(),
+ .DBITERR());
+
+
+// synthesis translate_on
+
+endmodule
+
diff --git a/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco b/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco
new file mode 100644
index 000000000..df97fd0e0
--- /dev/null
+++ b/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco
@@ -0,0 +1,82 @@
+##############################################################
+#
+# Xilinx Core Generator version K.39
+# Date: Thu Jul 29 23:02:41 2010
+#
+##############################################################
+#
+# This file contains the customisation parameters for a
+# Xilinx CORE Generator IP GUI. It is strongly recommended
+# that you do not manually alter this file as it may cause
+# unexpected and unsupported behavior.
+#
+##############################################################
+#
+# BEGIN Project Options
+SET addpads = false
+SET asysymbol = false
+SET busformat = BusFormatAngleBracketNotRipped
+SET createndf = false
+SET designentry = Verilog
+SET device = xc3s2000
+SET devicefamily = spartan3
+SET flowvendor = Other
+SET formalverification = false
+SET foundationsym = false
+SET implementationfiletype = Ngc
+SET package = fg456
+SET removerpms = false
+SET simulationfiles = Behavioral
+SET speedgrade = -5
+SET verilogsim = true
+SET vhdlsim = false
+# END Project Options
+# BEGIN Select
+SELECT Fifo_Generator family Xilinx,_Inc. 4.4
+# END Select
+# BEGIN Parameters
+CSET almost_empty_flag=false
+CSET almost_full_flag=false
+CSET component_name=fifo_xlnx_512x36_2clk_18to36
+CSET data_count=false
+CSET data_count_width=10
+CSET disable_timing_violations=false
+CSET dout_reset_value=0
+CSET empty_threshold_assert_value=4
+CSET empty_threshold_negate_value=5
+CSET enable_ecc=false
+CSET enable_int_clk=false
+CSET fifo_implementation=Independent_Clocks_Block_RAM
+CSET full_flags_reset_value=0
+CSET full_threshold_assert_value=1023
+CSET full_threshold_negate_value=1022
+CSET input_data_width=18
+CSET input_depth=1024
+CSET output_data_width=36
+CSET output_depth=512
+CSET overflow_flag=false
+CSET overflow_sense=Active_High
+CSET performance_options=First_Word_Fall_Through
+CSET programmable_empty_type=No_Programmable_Empty_Threshold
+CSET programmable_full_type=No_Programmable_Full_Threshold
+CSET read_clock_frequency=1
+CSET read_data_count=false
+CSET read_data_count_width=9
+CSET reset_pin=true
+CSET reset_type=Asynchronous_Reset
+CSET underflow_flag=false
+CSET underflow_sense=Active_High
+CSET use_dout_reset=true
+CSET use_embedded_registers=false
+CSET use_extra_logic=false
+CSET valid_flag=false
+CSET valid_sense=Active_High
+CSET write_acknowledge_flag=false
+CSET write_acknowledge_sense=Active_High
+CSET write_clock_frequency=1
+CSET write_data_count=false
+CSET write_data_count_width=10
+# END Parameters
+GENERATE
+# CRC: 117ae77f
+
diff --git a/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v b/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v
new file mode 100644
index 000000000..f7f6e7e9f
--- /dev/null
+++ b/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v
@@ -0,0 +1,165 @@
+/*******************************************************************************
+* This file is owned and controlled by Xilinx and must be used *
+* solely for design, simulation, implementation and creation of *
+* design files limited to Xilinx devices or technologies. Use *
+* with non-Xilinx devices or technologies is expressly prohibited *
+* and immediately terminates your license. *
+* *
+* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" *
+* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR *
+* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION *
+* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION *
+* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS *
+* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, *
+* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE *
+* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY *
+* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
+* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
+* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
+* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
+* FOR A PARTICULAR PURPOSE. *
+* *
+* Xilinx products are not intended for use in life support *
+* appliances, devices, or systems. Use in such applications are *
+* expressly prohibited. *
+* *
+* (c) Copyright 1995-2007 Xilinx, Inc. *
+* All rights reserved. *
+*******************************************************************************/
+// The synthesis directives "translate_off/translate_on" specified below are
+// supported by Xilinx, Mentor Graphics and Synplicity synthesis
+// tools. Ensure they are correct for your synthesis tool(s).
+
+// You must compile the wrapper file fifo_xlnx_512x36_2clk_36to18.v when simulating
+// the core, fifo_xlnx_512x36_2clk_36to18. When compiling the wrapper file, be sure to
+// reference the XilinxCoreLib Verilog simulation library. For detailed
+// instructions, please refer to the "CORE Generator Help".
+
+`timescale 1ns/1ps
+
+module fifo_xlnx_512x36_2clk_36to18(
+ din,
+ rd_clk,
+ rd_en,
+ rst,
+ wr_clk,
+ wr_en,
+ dout,
+ empty,
+ full);
+
+
+input [35 : 0] din;
+input rd_clk;
+input rd_en;
+input rst;
+input wr_clk;
+input wr_en;
+output [17 : 0] dout;
+output empty;
+output full;
+
+// synthesis translate_off
+
+ FIFO_GENERATOR_V4_4 #(
+ .C_COMMON_CLOCK(0),
+ .C_COUNT_TYPE(0),
+ .C_DATA_COUNT_WIDTH(9),
+ .C_DEFAULT_VALUE("BlankString"),
+ .C_DIN_WIDTH(36),
+ .C_DOUT_RST_VAL("0"),
+ .C_DOUT_WIDTH(18),
+ .C_ENABLE_RLOCS(0),
+ .C_FAMILY("spartan3"),
+ .C_FULL_FLAGS_RST_VAL(0),
+ .C_HAS_ALMOST_EMPTY(0),
+ .C_HAS_ALMOST_FULL(0),
+ .C_HAS_BACKUP(0),
+ .C_HAS_DATA_COUNT(0),
+ .C_HAS_INT_CLK(0),
+ .C_HAS_MEMINIT_FILE(0),
+ .C_HAS_OVERFLOW(0),
+ .C_HAS_RD_DATA_COUNT(0),
+ .C_HAS_RD_RST(0),
+ .C_HAS_RST(1),
+ .C_HAS_SRST(0),
+ .C_HAS_UNDERFLOW(0),
+ .C_HAS_VALID(0),
+ .C_HAS_WR_ACK(0),
+ .C_HAS_WR_DATA_COUNT(0),
+ .C_HAS_WR_RST(0),
+ .C_IMPLEMENTATION_TYPE(2),
+ .C_INIT_WR_PNTR_VAL(0),
+ .C_MEMORY_TYPE(1),
+ .C_MIF_FILE_NAME("BlankString"),
+ .C_MSGON_VAL(1),
+ .C_OPTIMIZATION_MODE(0),
+ .C_OVERFLOW_LOW(0),
+ .C_PRELOAD_LATENCY(0),
+ .C_PRELOAD_REGS(1),
+ .C_PRIM_FIFO_TYPE("512x36"),
+ .C_PROG_EMPTY_THRESH_ASSERT_VAL(4),
+ .C_PROG_EMPTY_THRESH_NEGATE_VAL(5),
+ .C_PROG_EMPTY_TYPE(0),
+ .C_PROG_FULL_THRESH_ASSERT_VAL(509),
+ .C_PROG_FULL_THRESH_NEGATE_VAL(508),
+ .C_PROG_FULL_TYPE(0),
+ .C_RD_DATA_COUNT_WIDTH(10),
+ .C_RD_DEPTH(1024),
+ .C_RD_FREQ(1),
+ .C_RD_PNTR_WIDTH(10),
+ .C_UNDERFLOW_LOW(0),
+ .C_USE_DOUT_RST(1),
+ .C_USE_ECC(0),
+ .C_USE_EMBEDDED_REG(0),
+ .C_USE_FIFO16_FLAGS(0),
+ .C_USE_FWFT_DATA_COUNT(0),
+ .C_VALID_LOW(0),
+ .C_WR_ACK_LOW(0),
+ .C_WR_DATA_COUNT_WIDTH(9),
+ .C_WR_DEPTH(512),
+ .C_WR_FREQ(1),
+ .C_WR_PNTR_WIDTH(9),
+ .C_WR_RESPONSE_LATENCY(1))
+ inst (
+ .DIN(din),
+ .RD_CLK(rd_clk),
+ .RD_EN(rd_en),
+ .RST(rst),
+ .WR_CLK(wr_clk),
+ .WR_EN(wr_en),
+ .DOUT(dout),
+ .EMPTY(empty),
+ .FULL(full),
+ .CLK(),
+ .INT_CLK(),
+ .BACKUP(),
+ .BACKUP_MARKER(),
+ .PROG_EMPTY_THRESH(),
+ .PROG_EMPTY_THRESH_ASSERT(),
+ .PROG_EMPTY_THRESH_NEGATE(),
+ .PROG_FULL_THRESH(),
+ .PROG_FULL_THRESH_ASSERT(),
+ .PROG_FULL_THRESH_NEGATE(),
+ .RD_RST(),
+ .SRST(),
+ .WR_RST(),
+ .ALMOST_EMPTY(),
+ .ALMOST_FULL(),
+ .DATA_COUNT(),
+ .OVERFLOW(),
+ .PROG_EMPTY(),
+ .PROG_FULL(),
+ .VALID(),
+ .RD_DATA_COUNT(),
+ .UNDERFLOW(),
+ .WR_ACK(),
+ .WR_DATA_COUNT(),
+ .SBITERR(),
+ .DBITERR());
+
+
+// synthesis translate_on
+
+endmodule
+
diff --git a/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco b/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco
new file mode 100644
index 000000000..a1c75dc39
--- /dev/null
+++ b/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco
@@ -0,0 +1,82 @@
+##############################################################
+#
+# Xilinx Core Generator version K.39
+# Date: Thu Jul 29 18:10:59 2010
+#
+##############################################################
+#
+# This file contains the customisation parameters for a
+# Xilinx CORE Generator IP GUI. It is strongly recommended
+# that you do not manually alter this file as it may cause
+# unexpected and unsupported behavior.
+#
+##############################################################
+#
+# BEGIN Project Options
+SET addpads = false
+SET asysymbol = false
+SET busformat = BusFormatAngleBracketNotRipped
+SET createndf = false
+SET designentry = Verilog
+SET device = xc3s2000
+SET devicefamily = spartan3
+SET flowvendor = Other
+SET formalverification = false
+SET foundationsym = false
+SET implementationfiletype = Ngc
+SET package = fg456
+SET removerpms = false
+SET simulationfiles = Behavioral
+SET speedgrade = -5
+SET verilogsim = true
+SET vhdlsim = false
+# END Project Options
+# BEGIN Select
+SELECT Fifo_Generator family Xilinx,_Inc. 4.4
+# END Select
+# BEGIN Parameters
+CSET almost_empty_flag=false
+CSET almost_full_flag=false
+CSET component_name=fifo_xlnx_512x36_2clk_36to18
+CSET data_count=false
+CSET data_count_width=9
+CSET disable_timing_violations=false
+CSET dout_reset_value=0
+CSET empty_threshold_assert_value=4
+CSET empty_threshold_negate_value=5
+CSET enable_ecc=false
+CSET enable_int_clk=false
+CSET fifo_implementation=Independent_Clocks_Block_RAM
+CSET full_flags_reset_value=0
+CSET full_threshold_assert_value=509
+CSET full_threshold_negate_value=508
+CSET input_data_width=36
+CSET input_depth=512
+CSET output_data_width=18
+CSET output_depth=1024
+CSET overflow_flag=false
+CSET overflow_sense=Active_High
+CSET performance_options=First_Word_Fall_Through
+CSET programmable_empty_type=No_Programmable_Empty_Threshold
+CSET programmable_full_type=No_Programmable_Full_Threshold
+CSET read_clock_frequency=1
+CSET read_data_count=false
+CSET read_data_count_width=10
+CSET reset_pin=true
+CSET reset_type=Asynchronous_Reset
+CSET underflow_flag=false
+CSET underflow_sense=Active_High
+CSET use_dout_reset=true
+CSET use_embedded_registers=false
+CSET use_extra_logic=false
+CSET valid_flag=false
+CSET valid_sense=Active_High
+CSET write_acknowledge_flag=false
+CSET write_acknowledge_sense=Active_High
+CSET write_clock_frequency=1
+CSET write_data_count=false
+CSET write_data_count_width=9
+# END Parameters
+GENERATE
+# CRC: 392ad537
+
diff --git a/usrp2/extramfifo/Makefile.srcs b/usrp2/extramfifo/Makefile.srcs
new file mode 100644
index 000000000..7cd49f4f6
--- /dev/null
+++ b/usrp2/extramfifo/Makefile.srcs
@@ -0,0 +1,16 @@
+#
+# Copyright 2010 Ettus Research LLC
+#
+
+##################################################
+# Extram Sources
+##################################################
+EXTRAM_SRCS = $(abspath $(addprefix $(BASE_DIR)/../extramfifo/, \
+ext_fifo.v \
+nobl_if.v \
+nobl_fifo.v \
+icon.v \
+icon.xco \
+ila.v \
+ila.xco \
+))
diff --git a/usrp2/extramfifo/ext_fifo.v b/usrp2/extramfifo/ext_fifo.v
new file mode 100644
index 000000000..55935146a
--- /dev/null
+++ b/usrp2/extramfifo/ext_fifo.v
@@ -0,0 +1,120 @@
+module ext_fifo
+ #(parameter INT_WIDTH=36,EXT_WIDTH=18,DEPTH=19)
+ (
+ input int_clk,
+ input ext_clk,
+ input rst,
+ input [EXT_WIDTH-1:0] RAM_D_pi,
+ output [EXT_WIDTH-1:0] RAM_D_po,
+ output RAM_D_poe,
+ output [DEPTH-1:0] RAM_A,
+ output RAM_WEn,
+ output RAM_CENn,
+ output RAM_LDn,
+ output RAM_OEn,
+ output RAM_CE1n,
+ input [INT_WIDTH-1:0] datain,
+ input src_rdy_i, // WRITE
+ output dst_rdy_o, // not FULL
+ output [INT_WIDTH-1:0] dataout,
+ output src_rdy_o, // not EMPTY
+ input dst_rdy_i // READ
+ );
+
+ wire [EXT_WIDTH-1:0] write_data;
+ wire [EXT_WIDTH-1:0] read_data;
+ wire full1, empty1;
+ wire full2, empty2;
+
+
+ // FIFO buffers data from UDP engine into external FIFO clock domain.
+ fifo_xlnx_512x36_2clk_36to18 fifo_xlnx_512x36_2clk_36to18_i1 (
+ .rst(rst),
+ .wr_clk(int_clk),
+ .rd_clk(ext_clk),
+ .din(datain), // Bus [35 : 0]
+ .wr_en(src_rdy_i),
+ .rd_en(space_avail&~empty1),
+ // .rd_en(~full2&~empty1),
+ .dout(write_data), // Bus [17 : 0]
+ .full(full1),
+ .empty(empty1));
+ assign dst_rdy_o = ~full1;
+
+
+
+ // External FIFO running at ext clock rate and 18 bit width.
+ nobl_fifo #(.WIDTH(EXT_WIDTH),.DEPTH(DEPTH))
+ nobl_fifo_i1
+ (
+ .clk(ext_clk),
+ .rst(rst),
+ .RAM_D_pi(RAM_D_pi),
+ .RAM_D_po(RAM_D_po),
+ .RAM_D_poe(RAM_D_poe),
+ .RAM_A(RAM_A),
+ .RAM_WEn(RAM_WEn),
+ .RAM_CENn(RAM_CENn),
+ .RAM_LDn(RAM_LDn),
+ .RAM_OEn(RAM_OEn),
+ .RAM_CE1n(RAM_CE1n),
+ .write_data(write_data),
+ .write_strobe(space_avail & ~empty1 ),
+ .space_avail(space_avail),
+ .read_data(read_data),
+ .read_strobe(data_avail & ~full2),
+ .data_avail(data_avail)
+ );
+
+
+
+ // FIFO buffers data read from external FIFO into DSP clk domain and to TX DSP.
+ fifo_xlnx_512x36_2clk_18to36 fifo_xlnx_512x36_2clk_18to36_i1 (
+ .rst(rst),
+ .wr_clk(ext_clk),
+ .rd_clk(int_clk),
+ .din(read_data), // Bus [17 : 0]
+ // .din(write_data), // Bus [17 : 0]
+ .wr_en(data_avail & ~full2 ),
+ // .wr_en(~full2&~empty1),
+ .rd_en(dst_rdy_i),
+ .dout(dataout), // Bus [35 : 0]
+ .full(full2),
+ .empty(empty2));
+ assign src_rdy_o = ~empty2;
+
+
+
+ wire [35:0] CONTROL0;
+ reg [7:0] datain_reg,write_data_reg,read_data_reg ;
+ reg space_avail_reg,data_avail_reg,empty1_reg,full2_reg ;
+
+ always @(posedge ext_clk)
+ begin
+ //datain_reg <= datain[7:0];
+ write_data_reg <= write_data[7:0];
+ read_data_reg <= read_data[7:0];
+ space_avail_reg <= space_avail;
+ data_avail_reg <= data_avail;
+ empty1_reg <= empty1;
+ full2_reg <= full2;
+ end
+
+
+ icon icon_i1
+ (
+ .CONTROL0(CONTROL0)
+ );
+
+ ila ila_i1
+ (
+ .CLK(ext_clk),
+ .CONTROL(CONTROL0),
+ // .TRIG0(address_reg),
+ .TRIG0(write_data_reg[7:0]),
+ .TRIG1(read_data_reg[7:0]),
+ .TRIG2(0),
+ .TRIG3({space_avail_reg,data_avail_reg,empty1_reg,full2_reg})
+ );
+
+endmodule // ext_fifo
diff --git a/usrp2/extramfifo/ext_fifo_tb.cmd b/usrp2/extramfifo/ext_fifo_tb.cmd
new file mode 100644
index 000000000..b0ab830dc
--- /dev/null
+++ b/usrp2/extramfifo/ext_fifo_tb.cmd
@@ -0,0 +1,11 @@
+/opt/Xilinx/12.1/ISE_DS/ISE/verilog/src/glbl.v
+-y .
+-y ../coregen/
+-y ../models
+-y /home/ianb/usrp-fpga/usrp2/sdr_lib
+-y /home/ianb/usrp-fpga/usrp2/control_lib
+-y /home/ianb/usrp-fpga/usrp2/models
+-y /opt/Xilinx/12.1/ISE_DS/ISE/verilog/src/unisims
+-y /opt/Xilinx/12.1/ISE_DS/ISE/verilog/src
+-y /opt/Xilinx/12.1/ISE_DS/ISE/verilog/src/XilinxCoreLib
+
diff --git a/usrp2/extramfifo/ext_fifo_tb.prj b/usrp2/extramfifo/ext_fifo_tb.prj
new file mode 100644
index 000000000..a11a15b2f
--- /dev/null
+++ b/usrp2/extramfifo/ext_fifo_tb.prj
@@ -0,0 +1,9 @@
+verilog work "./ext_fifo_tb.v"
+verilog work "./ext_fifo.v"
+verilog work "./nobl_fifo.v"
+verilog work "./nobl_if.v"
+verilog work "../coregen/fifo_xlnx_512x36_2clk_36to18.v"
+verilog work "../coregen/fifo_xlnx_512x36_2clk_18to36.v"
+verilog work "../models/CY7C1356C/cy1356.v"
+verilog work "../models/idt71v65603s150.v"
+verilog work "$XILINX/verilog/src/glbl.v"
diff --git a/usrp2/extramfifo/ext_fifo_tb.sh b/usrp2/extramfifo/ext_fifo_tb.sh
new file mode 100644
index 000000000..a56574102
--- /dev/null
+++ b/usrp2/extramfifo/ext_fifo_tb.sh
@@ -0,0 +1 @@
+fuse -prj ext_fifo_tb.prj -t work.glbl -t work.ext_fifo_tb -L unisims_ver -L xilinxcorelib_ver -o ext_fifo_tb
diff --git a/usrp2/extramfifo/ext_fifo_tb.v b/usrp2/extramfifo/ext_fifo_tb.v
new file mode 100644
index 000000000..aa1fd6e3c
--- /dev/null
+++ b/usrp2/extramfifo/ext_fifo_tb.v
@@ -0,0 +1,285 @@
+`timescale 1ns / 1ps
+`define INT_WIDTH 36
+`define EXT_WIDTH 18
+`define DEPTH 19
+`define DUMP_VCD_FULL
+
+module ext_fifo_tb();
+
+
+ reg int_clk;
+ reg ext_clk;
+ reg rst;
+
+
+
+ wire [`EXT_WIDTH-1:0] RAM_D_pi;
+ wire [`EXT_WIDTH-1:0] RAM_D_po;
+ wire [`EXT_WIDTH-1:0] RAM_D;
+ wire RAM_D_poe;
+ wire [`DEPTH-1:0] RAM_A;
+ wire RAM_WEn;
+ wire RAM_CENn;
+ wire RAM_LDn;
+ wire RAM_OEn;
+ wire RAM_CE1n;
+ reg [`INT_WIDTH-1:0] datain;
+ reg src_rdy_i; // WRITE
+ wire dst_rdy_o; // not FULL
+ wire [`INT_WIDTH-1:0] dataout;
+ reg [`INT_WIDTH-1:0] ref_dataout;
+ wire src_rdy_o; // not EMPTY
+ reg dst_rdy_i;
+
+
+ // Clocks
+ // Int clock is 100MHz
+ // Ext clock is 125MHz
+ initial
+ begin
+ int_clk <= 0;
+ ext_clk <= 0;
+ datain <= 0;
+ ref_dataout <= 1;
+ src_rdy_i <= 0;
+ dst_rdy_i <= 0;
+ end
+
+ always
+ #5 int_clk <= ~int_clk;
+
+ always
+ #4 ext_clk <= ~ext_clk;
+
+
+ initial
+ begin
+ rst <= 1;
+ repeat (5) @(negedge int_clk);
+ rst <= 0;
+ @(negedge int_clk);
+ repeat (1000)
+ begin
+ @(negedge int_clk);
+ datain <= datain + 1;
+ src_rdy_i <= 1;
+ @(negedge int_clk);
+ src_rdy_i <= 0;
+// @(negedge int_clk);
+// dst_rdy_i <= src_rdy_o;
+// @(negedge int_clk);
+// dst_rdy_i <= 0;
+ repeat (2) @(negedge int_clk);
+ end // repeat (1000)
+ // Fall through fifo, first output already valid
+ if (dataout !== ref_dataout)
+ $display("Error: Expected %x, got %x",ref_dataout, dataout);
+ repeat (1000)
+ begin
+ @(negedge int_clk);
+ datain <= datain + 1;
+ src_rdy_i <= 1;
+ @(negedge int_clk);
+ src_rdy_i <= 0;
+ @(negedge int_clk);
+ ref_dataout <= ref_dataout + 1;
+ dst_rdy_i <= src_rdy_o;
+ @(negedge int_clk);
+ if (dataout !== ref_dataout)
+ $display("Error: Expected %x, got %x",ref_dataout, dataout);
+ dst_rdy_i <= 0;
+// repeat (2) @(negedge int_clk);
+ end // repeat (1000)
+ repeat (1000)
+ begin
+// @(negedge int_clk);
+// datain <= datain + 1;
+// src_rdy_i <= 1;
+// @(negedge int_clk);
+// src_rdy_i <= 0;
+ @(negedge int_clk);
+ ref_dataout <= ref_dataout + 1;
+ dst_rdy_i <= src_rdy_o;
+ @(negedge int_clk);
+ if (dataout !== ref_dataout)
+ $display("Error: Expected %x, got %x",ref_dataout, dataout);
+ dst_rdy_i <= 0;
+// repeat (2) @(negedge int_clk);
+ end // repeat (1000)
+
+ $finish;
+
+ end // initial begin
+
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // Simulation control //
+ ///////////////////////////////////////////////////////////////////////////////////
+ `ifdef DUMP_LX2_TOP
+ // Set up output files
+ initial begin
+ $dumpfile("ext_fifo_tb.lx2");
+ $dumpvars(1,ext_fifo_tb);
+ end
+ `endif
+
+ `ifdef DUMP_LX2_FULL
+ // Set up output files
+ initial begin
+ $dumpfile("ext_fifo_tb.lx2");
+ $dumpvars(0,ext_fifo_tb);
+ end
+ `endif
+
+ `ifdef DUMP_VCD_TOP
+ // Set up output files
+ initial begin
+ $dumpfile("ext_fifo_tb.vcd");
+ $dumpvars(1,ext_fifo_tb);
+ end
+ `endif
+
+ `ifdef DUMP_VCD_TOP_PLUS_NEXT
+ // Set up output files
+ initial begin
+ $dumpfile("ext_fifo_tb.vcd");
+ $dumpvars(2,ext_fifo_tb);
+ end
+ `endif
+
+
+ `ifdef DUMP_VCD_FULL
+ // Set up output files
+ initial begin
+ $dumpfile("ext_fifo_tb.vcd");
+ $dumpvars(0,ext_fifo_tb);
+ end
+ `endif
+
+ // Update display every 10 us
+ always #10000 $monitor("Time in uS ",$time/1000);
+
+ wire [`EXT_WIDTH-1:0] RAM_D_pi_ext;
+ wire [`EXT_WIDTH-1:0] RAM_D_po_ext;
+ wire [`EXT_WIDTH-1:0] RAM_D_ext;
+ wire RAM_D_poe_ext;
+
+ genvar i;
+
+ //
+ // Instantiate IO for Bidirectional bus to SRAM
+ //
+
+ generate
+ for (i=0;i<18;i=i+1)
+ begin : gen_RAM_D_IO
+
+ IOBUF #(
+ .DRIVE(12),
+ .IOSTANDARD("LVCMOS25"),
+ .SLEW("FAST")
+ )
+ RAM_D_i (
+ .O(RAM_D_pi_ext[i]),
+ .I(RAM_D_po_ext[i]),
+ .IO(RAM_D[i]),
+ .T(RAM_D_poe_ext)
+ );
+ end // block: gen_RAM_D_IO
+
+ endgenerate
+
+ wire [`DEPTH-1:0] RAM_A_ext;
+ wire RAM_WEn_ext,RAM_LDn_ext,RAM_CE1n_ext,RAM_OEn_ext,RAM_CENn_ext;
+
+ assign #1 RAM_D_pi = RAM_D_pi_ext;
+
+ assign #1 RAM_D_po_ext = RAM_D_po;
+
+ assign #1 RAM_D_poe_ext = RAM_D_poe;
+
+ assign #2 RAM_WEn_ext = RAM_WEn;
+
+ assign #2 RAM_LDn_ext = RAM_LDn;
+
+ assign #2 RAM_CE1n_ext = RAM_CE1n;
+
+ assign #2 RAM_OEn_ext = RAM_OEn;
+
+ assign #2 RAM_CENn_ext = RAM_CENn;
+
+ assign #2 RAM_A_ext = RAM_A;
+
+/* -----\/----- EXCLUDED -----\/-----
+ wire [13:0] temp1;
+ assign temp1 = 14'h0;
+ wire [3:0] temp2;
+ assign temp2 = 4'h0;
+ -----/\----- EXCLUDED -----/\----- */
+
+
+ idt71v65603s150 idt71v65603s150_i1
+ (
+ .A(RAM_A_ext[17:0]),
+ .adv_ld_(RAM_LDn_ext), // advance (high) / load (low)
+ .bw1_(1'b0),
+ .bw2_(1'b0),
+ .bw3_(1'b1),
+ .bw4_(1'b1), // byte write enables (low)
+ .ce1_(RAM_CE1n_ext),
+ .ce2(1'b1),
+ .ce2_(1'b0), // chip enables
+ .cen_(RAM_CENn_ext), // clock enable (low)
+ .clk(ext_clk), // clock
+ .IO({RAM_D[16:9],RAM_D[7:0]}),
+ .IOP({RAM_D[17],RAM_D[8]}), // data bus
+ .lbo_(1'b0), // linear burst order (low)
+ .oe_(RAM_OEn_ext), // output enable (low)
+ .r_w_(RAM_WEn_ext)
+ ); // read (high) / write (low)
+
+/* -----\/----- EXCLUDED -----\/-----
+
+
+ cy1356 cy1356_i1
+ ( .d(RAM_D),
+ .clk(ext_clk),
+ .a(RAM_A_ext),
+ .bws(2'b00),
+ .we_b(RAM_WEn_ext),
+ .adv_lb(RAM_LDn_ext),
+ .ce1b(RAM_CE1n_ext),
+ .ce2(1'b1),
+ .ce3b(1'b0),
+ .oeb(RAM_OEn_ext),
+ .cenb(RAM_CENn_ext),
+ .mode(1'b0)
+ );
+ -----/\----- EXCLUDED -----/\----- */
+
+
+ ext_fifo
+ #(.INT_WIDTH(`INT_WIDTH),.EXT_WIDTH(`EXT_WIDTH),.DEPTH(`DEPTH))
+ ext_fifo_i1
+ (
+ .int_clk(int_clk),
+ .ext_clk(ext_clk),
+ .rst(rst),
+ .RAM_D_pi(RAM_D_pi),
+ .RAM_D_po(RAM_D_po),
+ .RAM_D_poe(RAM_D_poe),
+ .RAM_A(RAM_A),
+ .RAM_WEn(RAM_WEn),
+ .RAM_CENn(RAM_CENn),
+ .RAM_LDn(RAM_LDn),
+ .RAM_OEn(RAM_OEn),
+ .RAM_CE1n(RAM_CE1n),
+ .datain(datain),
+ .src_rdy_i(src_rdy_i), // WRITE
+ .dst_rdy_o(dst_rdy_o), // not FULL
+ .dataout(dataout),
+ .src_rdy_o(src_rdy_o), // not EMPTY
+ .dst_rdy_i(dst_rdy_i)
+ );
+
+endmodule // ext_fifo_tb
diff --git a/usrp2/extramfifo/nobl_fifo.v b/usrp2/extramfifo/nobl_fifo.v
new file mode 100644
index 000000000..1bd7439ad
--- /dev/null
+++ b/usrp2/extramfifo/nobl_fifo.v
@@ -0,0 +1,264 @@
+module nobl_fifo
+ #(parameter WIDTH=18,DEPTH=19)
+ (
+ input clk,
+ input rst,
+ input [WIDTH-1:0] RAM_D_pi,
+ output [WIDTH-1:0] RAM_D_po,
+ output RAM_D_poe,
+ output [DEPTH-1:0] RAM_A,
+ output RAM_WEn,
+ output RAM_CENn,
+ output RAM_LDn,
+ output RAM_OEn,
+ output RAM_CE1n,
+ input [WIDTH-1:0] write_data,
+ input write_strobe,
+ output reg space_avail,
+ output reg [WIDTH-1:0] read_data,
+ input read_strobe,
+ output reg data_avail
+ );
+
+ reg [DEPTH-1:0] capacity;
+ reg [DEPTH-1:0] wr_pointer;
+ reg [DEPTH-1:0] rd_pointer;
+ wire [DEPTH-1:0] address;
+
+ reg supress;
+ reg data_avail_int; // Data available with high latency from ext FIFO flag
+ wire [WIDTH-1:0] data_in;
+ wire data_in_valid;
+ reg [WIDTH-1:0] read_data_pending;
+ reg pending_avail;
+ wire read_strobe_int;
+
+
+
+ assign read = read_strobe_int && data_avail_int;
+ assign write = write_strobe && space_avail;
+
+ // When a read and write collision occur, supress availability flags next cycle
+ // and complete write followed by read over 2 cycles. This forces balanced arbitration
+ // and makes for a simple logic design.
+
+ always @(posedge clk)
+ if (rst)
+ begin
+ capacity <= 1 << (DEPTH-1);
+ wr_pointer <= 0;
+ rd_pointer <= 0;
+ space_avail <= 0;
+ data_avail_int <= 0;
+ supress <= 0;
+ end
+ else
+ begin
+ space_avail <= ~((capacity == 0) || (read&&write) || (capacity == 1 && write) );
+ // Capacity has 1 cycle delay so look ahead here for corner case of read of last item in FIFO.
+ data_avail_int <= ~((capacity == (1 << (DEPTH-1))) || (read&&write) || (capacity == ((1 << (DEPTH-1))-1) && read) );
+ supress <= read && write;
+ wr_pointer <= wr_pointer + write;
+ rd_pointer <= rd_pointer + ((~write && read) || supress);
+ capacity <= capacity - write + ((~write && read) || supress); // REVISIT
+ end // else: !if(rst)
+
+ assign address = write ? wr_pointer : rd_pointer;
+ assign enable = write || read || supress;
+
+ //
+ // Need to have first item in external FIFO moved into local registers for single cycle latency and throughput on read.
+ // 2 local registers are provided so that a read every other clock cycle can be sustained.
+ // No fowarding logic is provided to bypass the external FIFO as latency is of no concern.
+ //
+ always @(posedge clk)
+ if (rst)
+ begin
+ read_data <= 0;
+ data_avail <= 0;
+ read_data_pending <= 0;
+ pending_avail <= 0;
+ end
+ else
+ begin
+ case({read_strobe,data_in_valid})
+ // No read externally, no new data arriving from external FIFO
+ 2'b00: begin
+ case({data_avail,pending_avail})
+ // Start Data empty, Pending empty.
+ //
+ // End Data full, Pending empty
+ 2'b00: begin
+ read_data <= read_data;
+ data_avail <= data_avail;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= pending_avail;
+ end
+ // Start Data empty, Pending full.
+ // Data <= Pending,
+ // End Data full, Penidng empty.
+ 2'b01: begin
+ read_data <= read_data_pending;
+ data_avail <= 1'b1;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= 1'b0;
+ end
+ // Start Data full, Pending empty.
+ //
+ // End Data full, Pending empty
+ 2'b10: begin
+ read_data <= read_data;
+ data_avail <= data_avail;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= pending_avail;
+ end
+ // Start Data full, Pending full.
+ //
+ // End Data full, Pending full.
+ 2'b11: begin
+ read_data <= read_data;
+ data_avail <= data_avail;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= pending_avail;
+ end
+ endcase
+ end
+ // No read externally, new data arriving from external FIFO
+ 2'b01: begin
+ case({data_avail,pending_avail})
+ // Start Data empty, Pending empty.
+ // Data <= FIFO
+ // End Data full, Pending empty
+ 2'b00: begin
+ read_data <= data_in;
+ data_avail <= 1'b1;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= 1'b0;
+ end
+ // Start Data empty, Pending full.
+ // Data <= Pending, Pending <= FIFO
+ // End Data full, Penidng full.
+ 2'b01: begin
+ read_data <= read_data_pending;
+ data_avail <= 1'b1;
+ read_data_pending <= data_in ;
+ pending_avail <= 1'b1;
+ end
+ // Start Data full, Pending empty.
+ // Pending <= FIFO
+ // End Data full, Pending full
+ 2'b10: begin
+ read_data <= read_data;
+ data_avail <= 1'b1;
+ read_data_pending <= data_in ;
+ pending_avail <= 1'b1;
+ end
+ // Data full, Pending full.
+ // *ILLEGAL STATE*
+ 2'b11: begin
+
+ end
+ endcase
+ end
+ // Read externally, no new data arriving from external FIFO
+ 2'b10: begin
+ case({data_avail,pending_avail})
+ // Start Data empty, Pending empty.
+ // *ILLEGAL STATE*
+ 2'b00: begin
+
+ end
+ // Start Data empty, Pending full.
+ // *ILLEGAL STATE*
+ 2'b01: begin
+
+ end
+ // Start Data full, Pending empty.
+ // Out <= Data
+ // End Data empty, Pending empty.
+ 2'b10: begin
+ read_data <= read_data;
+ data_avail <= 1'b0;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= 1'b0;
+ end
+ // Start Data full, Pending full.
+ // Out <= Data,
+ // End Data full, Pending empty
+ 2'b11: begin
+ read_data <= read_data_pending;
+ data_avail <= 1'b1;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= 1'b0;
+ end
+ endcase
+ end
+ // Read externally, new data arriving from external FIFO
+ 2'b11: begin
+ case({data_avail,pending_avail})
+ // Start Data empty, Pending empty.
+ // *ILLEGAL STATE*
+ 2'b00: begin
+
+ end
+ // Start Data empty, Pending full.
+ // *ILLEGAL STATE*
+ 2'b01: begin
+
+ end
+ // Start Data full, Pending empty.
+ // Out <= Data, Data <= FIFO
+ // End Data full, Pending empty.
+ 2'b10: begin
+ read_data <= data_in;
+ data_avail <= 1'b1;
+ read_data_pending <= read_data_pending ;
+ pending_avail <= 1'b0;
+ end
+ // Start Data full, Pending full.
+ // Out <= Data, Data <= Pending, Pending <= FIFO
+ // End Data full, Pending full
+ 2'b11: begin
+ read_data <= read_data_pending;
+ data_avail <= 1'b1;
+ read_data_pending <= data_in ;
+ pending_avail <= 1'b1;
+ end
+ endcase
+ end
+ endcase
+ end
+
+ // Start an external FIFO read as soon as a read of the buffer reg is strobed to minimise refill latency.
+ // If the buffer reg or the pending buffer reg is already empty also pre-emptively start a read.
+ // However there must be something in ext FIFO to read.
+ // This means that there can be 2 outstanding reads to the ext FIFO active at any time helping to hide latency.
+ assign read_strobe_int = (read_strobe & data_avail & ~pending_avail) || (~data_avail && ~pending_avail);
+
+
+ //
+ // Simple NoBL SRAM interface, 4 cycle read latency.
+ // Read/Write arbitration via temprary application of empty/full flags.
+ //
+ nobl_if nobl_if_i1
+ (
+ .clk(clk),
+ .rst(rst),
+ .RAM_D_pi(RAM_D_pi),
+ .RAM_D_po(RAM_D_po),
+ .RAM_D_poe(RAM_D_poe),
+ .RAM_A(RAM_A),
+ .RAM_WEn(RAM_WEn),
+ .RAM_CENn(RAM_CENn),
+ .RAM_LDn(RAM_LDn),
+ .RAM_OEn(RAM_OEn),
+ .RAM_CE1n(RAM_CE1n),
+ .address(address),
+ .data_out(write_data),
+ .data_in(data_in),
+ .data_in_valid(data_in_valid),
+ .write(write),
+ .enable(enable)
+ );
+
+endmodule // nobl_fifo
diff --git a/usrp2/extramfifo/nobl_if.v b/usrp2/extramfifo/nobl_if.v
new file mode 100644
index 000000000..3143ce5ba
--- /dev/null
+++ b/usrp2/extramfifo/nobl_if.v
@@ -0,0 +1,136 @@
+module nobl_if
+ #(parameter WIDTH=18,DEPTH=19)
+ (
+ input clk,
+ input rst,
+ input [WIDTH-1:0] RAM_D_pi,
+ output [WIDTH-1:0] RAM_D_po,
+ output reg RAM_D_poe,
+ output [DEPTH-1:0] RAM_A,
+ output RAM_WEn,
+ output RAM_CENn,
+ output RAM_LDn,
+ output RAM_OEn,
+ output RAM_CE1n,
+ input [DEPTH-1:0] address,
+ input [WIDTH-1:0] data_out,
+ output reg [WIDTH-1:0] data_in,
+ output reg data_in_valid,
+ input write,
+ input enable
+ );
+
+
+ reg enable_pipe1;
+ reg [DEPTH-1:0] address_pipe1;
+ reg write_pipe1;
+ reg [WIDTH-1:0] data_out_pipe1;
+
+ reg enable_pipe2;
+ reg write_pipe2;
+ reg [WIDTH-1:0] data_out_pipe2;
+
+ reg enable_pipe3;
+ reg write_pipe3;
+ reg [WIDTH-1:0] data_out_pipe3;
+
+ assign RAM_LDn = 0;
+ assign RAM_OEn = 0;
+
+
+ //
+ // Pipeline stage 1
+ //
+ always @(posedge clk)
+ if (rst)
+ begin
+ enable_pipe1 <= 0;
+ address_pipe1 <= 0;
+ write_pipe1 <= 0;
+ data_out_pipe1 <= 0;
+ end
+ else
+ begin
+ enable_pipe1 <= enable;
+
+ if (enable)
+ begin
+ address_pipe1 <= address;
+ write_pipe1 <= write;
+
+ if (write)
+ data_out_pipe1 <= data_out;
+ end
+ end // always @ (posedge clk)
+
+ // Pipeline 1 drives address, write_enable, chip_select on NoBL SRAM
+ assign RAM_A = address_pipe1;
+ assign RAM_CENn = 1'b0;
+ assign RAM_WEn = ~write_pipe1;
+ assign RAM_CE1n = ~enable_pipe1;
+
+ //
+ // Pipeline stage2
+ //
+ always @(posedge clk)
+ if (rst)
+ begin
+ enable_pipe2 <= 0;
+ data_out_pipe2 <= 0;
+ write_pipe2 <= 0;
+ end
+ else
+ begin
+ data_out_pipe2 <= data_out_pipe1;
+ write_pipe2 <= write_pipe1;
+ enable_pipe2 <= enable_pipe1;
+ end
+
+ //
+ // Pipeline stage3
+ //
+ always @(posedge clk)
+ if (rst)
+ begin
+ enable_pipe3 <= 0;
+ data_out_pipe3 <= 0;
+ write_pipe3 <= 0;
+ RAM_D_poe <= 0;
+ end
+ else
+ begin
+ data_out_pipe3 <= data_out_pipe2;
+ write_pipe3 <= write_pipe2;
+ enable_pipe3 <= enable_pipe2;
+ RAM_D_poe <= ~(write_pipe2 & enable_pipe2); // Active low driver enable in Xilinx.
+ end
+
+ // Pipeline 3 drives write data on NoBL SRAM
+ assign RAM_D_po = data_out_pipe3;
+
+
+ //
+ // Pipeline stage4
+ //
+ always @(posedge clk)
+ if (rst)
+ begin
+ data_in_valid <= 0;
+ data_in <= 0;
+ end
+ else
+ begin
+ data_in <= RAM_D_pi;
+ if (enable_pipe3 & ~write_pipe3)
+ begin
+ // Read data now available to be registered.
+ data_in_valid <= 1'b1;
+ end
+ else
+ data_in_valid <= 1'b0;
+ end // always @ (posedge clk)
+
+
+
+
+endmodule // nobl_if
diff --git a/usrp2/extramfifo/test_sram_if.v b/usrp2/extramfifo/test_sram_if.v
new file mode 100644
index 000000000..9f36b409c
--- /dev/null
+++ b/usrp2/extramfifo/test_sram_if.v
@@ -0,0 +1,171 @@
+`define WIDTH 18
+`define DEPTH 19
+
+module test_sram_if
+ (
+ input clk,
+ input rst,
+ input [`WIDTH-1:0] RAM_D_pi,
+ output [`WIDTH-1:0] RAM_D_po,
+ output RAM_D_poe,
+ output [`DEPTH-1:0] RAM_A,
+ output RAM_WEn,
+ output RAM_CENn,
+ output RAM_LDn,
+ output RAM_OEn,
+ output RAM_CE1n,
+ output reg correct
+ );
+
+ reg [`DEPTH-1:0] write_count;
+ reg [`DEPTH-1:0] read_count;
+ reg enable;
+ reg write;
+ reg write_cycle;
+ reg read_cycle;
+ reg enable_reads;
+ reg [18:0] address;
+ reg [17:0] data_out;
+ wire [17:0] data_in;
+ wire data_in_valid;
+
+ reg [17:0] check_data;
+ reg [17:0] check_data_old;
+ reg [17:0] check_data_old2;
+
+ //
+ // Create counter that generates both external modulo 2^19 address and modulo 2^18 data to test RAM.
+ //
+
+ always @(posedge clk)
+ if (rst)
+ begin
+ write_count <= 19'h0;
+ read_count <= 19'h0;
+ end
+ else if (write_cycle) // Write cycle
+ if (write_count == 19'h7FFFF)
+ begin
+ write_count <= 19'h0;
+ end
+ else
+ begin
+ write_count <= write_count + 1'b1;
+ end
+ else if (read_cycle) // Read cycle
+ if (read_count == 19'h7FFFF)
+ begin
+ read_count <= 19'h0;
+ end
+ else
+ begin
+ read_count <= read_count + 1'b1;
+ end
+
+ always @(posedge clk)
+ if (rst)
+ begin
+ enable_reads <= 0;
+ read_cycle <= 0;
+ write_cycle <= 0;
+ end
+ else
+ begin
+ write_cycle <= ~write_cycle;
+ if (enable_reads)
+ read_cycle <= write_cycle;
+ if (write_count == 15) // Enable reads 15 writes after reset terminates.
+ enable_reads <= 1;
+ end // else: !if(rst)
+
+ always @(posedge clk)
+ if (rst)
+ begin
+ enable <= 0;
+ end
+ else if (write_cycle)
+ begin
+ address <= write_count;
+ data_out <= write_count[17:0];
+ enable <= 1;
+ write <= 1;
+ end
+ else if (read_cycle)
+ begin
+ address <= read_count;
+ check_data <= read_count[17:0];
+ check_data_old <= check_data;
+ check_data_old2 <= check_data_old;
+ enable <= 1;
+ write <= 0;
+ end
+ else
+ enable <= 0;
+
+ always @(posedge clk)
+ if (data_in_valid)
+ begin
+ correct <= (data_in == check_data_old2);
+ end
+
+
+ nobl_if nobl_if_i1
+ (
+ .clk(clk),
+ .rst(rst),
+ .RAM_D_pi(RAM_D_pi),
+ .RAM_D_po(RAM_D_po),
+ .RAM_D_poe(RAM_D_poe),
+ .RAM_A(RAM_A),
+ .RAM_WEn(RAM_WEn),
+ .RAM_CENn(RAM_CENn),
+ .RAM_LDn(RAM_LDn),
+ .RAM_OEn(RAM_OEn),
+ .RAM_CE1n(RAM_CE1n),
+ .address(address),
+ .data_out(data_out),
+ .data_in(data_in),
+ .data_in_valid(data_in_valid),
+ .write(write),
+ .enable(enable)
+ );
+
+
+ wire [35:0] CONTROL0;
+ reg [7:0] data_in_reg, data_out_reg, address_reg;
+ reg data_in_valid_reg,write_reg,enable_reg,correct_reg;
+
+ always @(posedge clk)
+ begin
+ data_in_reg <= data_in[7:0];
+ data_out_reg <= data_out[7:0];
+ data_in_valid_reg <= data_in_valid;
+ write_reg <= write;
+ enable_reg <= enable;
+ correct_reg <= correct;
+ address_reg <= address;
+
+ end
+
+
+ icon icon_i1
+ (
+ .CONTROL0(CONTROL0)
+ );
+
+ ila ila_i1
+ (
+ .CLK(clk),
+ .CONTROL(CONTROL0),
+ // .TRIG0(address_reg),
+ .TRIG0(data_in_reg[7:0]),
+ .TRIG1(data_out_reg[7:0]),
+ .TRIG2(address_reg[7:0]),
+ .TRIG3({data_in_valid_reg,write_reg,enable_reg,correct_reg})
+ );
+
+
+
+endmodule // test_sram_if
+
+ \ No newline at end of file