diff options
author | Ian Buckley <ianb@server2.(none)> | 2010-07-29 21:25:26 -0700 |
---|---|---|
committer | Matt Ettus <matt@ettus.com> | 2010-11-11 11:36:09 -0800 |
commit | fb73ea172526319803756b985dd3c104881304b1 (patch) | |
tree | 5f5a6d4da4f24a317395c86586e49ec6b9bb414a | |
parent | d0742cf2a5285ed08d49e16948d8227414247f6a (diff) | |
download | uhd-fb73ea172526319803756b985dd3c104881304b1.tar.gz uhd-fb73ea172526319803756b985dd3c104881304b1.tar.bz2 uhd-fb73ea172526319803756b985dd3c104881304b1.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.
-rw-r--r-- | usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v | 165 | ||||
-rw-r--r-- | usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco | 82 | ||||
-rw-r--r-- | usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v | 165 | ||||
-rw-r--r-- | usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco | 82 | ||||
-rw-r--r-- | usrp2/extramfifo/Makefile.srcs | 16 | ||||
-rw-r--r-- | usrp2/extramfifo/ext_fifo.v | 120 | ||||
-rw-r--r-- | usrp2/extramfifo/ext_fifo_tb.cmd | 11 | ||||
-rw-r--r-- | usrp2/extramfifo/ext_fifo_tb.prj | 9 | ||||
-rw-r--r-- | usrp2/extramfifo/ext_fifo_tb.sh | 1 | ||||
-rw-r--r-- | usrp2/extramfifo/ext_fifo_tb.v | 285 | ||||
-rw-r--r-- | usrp2/extramfifo/nobl_fifo.v | 264 | ||||
-rw-r--r-- | usrp2/extramfifo/nobl_if.v | 136 | ||||
-rw-r--r-- | usrp2/extramfifo/test_sram_if.v | 171 |
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 |