From 39fafc65b8354a0fca06d1bedc54060c55941a9c Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Sat, 19 Oct 2019 16:58:30 +0200 Subject: [PATCH] Archie: replace vidc fifo with DCFIFO component to fix clock domain crossing issues --- .../archie/fpga/mist/archimedes_mist_top.qsf | 10 +- cores/archie/rtl/vidc.v | 20 +- cores/archie/rtl/vidc_dcfifo.qip | 3 + cores/archie/rtl/vidc_dcfifo.v | 179 ++++++++++++++++++ cores/archie/rtl/vidc_dmachannel.v | 127 +++++-------- cores/archie/rtl/vidc_fifo.v | 143 -------------- 6 files changed, 248 insertions(+), 234 deletions(-) create mode 100644 cores/archie/rtl/vidc_dcfifo.qip create mode 100644 cores/archie/rtl/vidc_dcfifo.v delete mode 100644 cores/archie/rtl/vidc_fifo.v diff --git a/cores/archie/fpga/mist/archimedes_mist_top.qsf b/cores/archie/fpga/mist/archimedes_mist_top.qsf index 62862db..ba3f454 100644 --- a/cores/archie/fpga/mist/archimedes_mist_top.qsf +++ b/cores/archie/fpga/mist/archimedes_mist_top.qsf @@ -136,7 +136,7 @@ set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_* set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to DRAM_* set_global_assignment -name ENABLE_SIGNALTAP OFF -set_global_assignment -name USE_SIGNALTAP_FILE output_files/fdc.stp +set_global_assignment -name USE_SIGNALTAP_FILE output_files/vidc.stp set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF set_global_assignment -name ENABLE_NCE_PIN OFF @@ -177,7 +177,7 @@ set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to DRAM_DQ[*] set_global_assignment -name SEED 1 set_global_assignment -name ENABLE_DRC_SETTINGS OFF set_location_assignment PLL_1 -to CLOCKS|altpll_component|auto_generated|pll1 -set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL set_global_assignment -name VERILOG_FILE archimedes_mist_top.v set_global_assignment -name SYSTEMVERILOG_FILE rgb2ypbpr.sv set_global_assignment -name VERILOG_FILE sigma_delta_dac.v @@ -192,8 +192,6 @@ set_global_assignment -name VERILOG_FILE ../../rtl/fdc1772.v set_global_assignment -name VERILOG_FILE ../../rtl/latches.v set_global_assignment -name VERILOG_FILE ../../rtl/floppy.v set_global_assignment -name VERILOG_FILE ../../rtl/podules.v -set_global_assignment -name VERILOG_FILE ../../rtl/vidc_audio.v -set_global_assignment -name VERILOG_FILE ../../rtl/vidc_dmachannel.v set_global_assignment -name VERILOG_FILE ../../rtl/i2cslave/serialInterface.v set_global_assignment -name VERILOG_FILE ../../rtl/i2cslave/registerInterface.v set_global_assignment -name VERILOG_FILE ../../rtl/i2cslave/i2cSlaveTop.v @@ -202,7 +200,9 @@ set_global_assignment -name VERILOG_FILE ../../rtl/ioc_irq.v set_global_assignment -name VERILOG_FILE ../../rtl/ioc.v set_global_assignment -name VERILOG_FILE ../../rtl/amber/a23_barrel_shift.v set_global_assignment -name VERILOG_FILE ../../rtl/memc_translator.v -set_global_assignment -name VERILOG_FILE ../../rtl/vidc_fifo.v +set_global_assignment -name VERILOG_FILE ../../rtl/vidc_audio.v +set_global_assignment -name VERILOG_FILE ../../rtl/vidc_dmachannel.v +set_global_assignment -name QIP_FILE ../../rtl/vidc_dcfifo.qip set_global_assignment -name VERILOG_FILE ../../rtl/vidc_timing.v set_global_assignment -name VERILOG_FILE ../../rtl/vidc.v set_global_assignment -name VERILOG_FILE ../../rtl/por.v diff --git a/cores/archie/rtl/vidc.v b/cores/archie/rtl/vidc.v index 03f6e1c..e513185 100644 --- a/cores/archie/rtl/vidc.v +++ b/cores/archie/rtl/vidc.v @@ -40,8 +40,8 @@ module vidc( // dma control. input [31:0] viddat, input vidak, - output vidrq, - + output vidrq, + input sndak, output sndrq, @@ -102,6 +102,7 @@ wire snd_load; // internal data request lines wire currq_int; wire vidrq_int; +reg hsync_cpu; reg cepix; @@ -157,15 +158,15 @@ vidc_dmachannel VIDEODMA ( .rq ( vidrq_int ), .busy ( vid_load ), - .stall ( ~hsync ), - + .stall ( ~hsync_cpu ), + .dev_data ( pix_data ), .dev_ak ( pix_ack ) ); // this module does the math for a DMA channel -vidc_dmachannel #(.FIFO_SIZE(2)) CURSORDMA ( +vidc_dmachannel #(.FIFO4WORDS(1'b1)) CURSORDMA ( .rst ( flybk | rst_i ), .clkcpu ( clkcpu ), @@ -178,7 +179,7 @@ vidc_dmachannel #(.FIFO_SIZE(2)) CURSORDMA ( .rq ( currq_int ), .busy ( cur_load ), - .stall ( hsync | vid_load ), + .stall ( hsync_cpu | vid_load ), .dev_data ( csr_data ), .dev_ak ( csr_ack ) @@ -186,7 +187,7 @@ vidc_dmachannel #(.FIFO_SIZE(2)) CURSORDMA ( ); // this module does the math for a DMA channel -vidc_dmachannel SOUNDDMA ( +vidc_dmachannel #(.FIFO4WORDS(1'b1)) SOUNDDMA ( .rst ( rst_i ), .clkcpu ( clkcpu ), @@ -386,7 +387,8 @@ assign video_b[2:0] = vidc_colour[10:8]; assign video_en = enabled; -// this demux's the two dma channels that share the vidrq. -assign vidrq = hsync ? vidrq_int : ~vid_load & currq_int; +// this demux's the two dma channels that share the vidrq. +always @(posedge clkcpu) hsync_cpu <= hsync; // transfer hsync to cpu clock domain +assign vidrq = hsync_cpu ? vidrq_int : ~vid_load & currq_int; endmodule diff --git a/cores/archie/rtl/vidc_dcfifo.qip b/cores/archie/rtl/vidc_dcfifo.qip new file mode 100644 index 0000000..025b8df --- /dev/null +++ b/cores/archie/rtl/vidc_dcfifo.qip @@ -0,0 +1,3 @@ +set_global_assignment -name IP_TOOL_NAME "FIFO" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "vidc_dcfifo.v"] diff --git a/cores/archie/rtl/vidc_dcfifo.v b/cores/archie/rtl/vidc_dcfifo.v new file mode 100644 index 0000000..d1d7658 --- /dev/null +++ b/cores/archie/rtl/vidc_dcfifo.v @@ -0,0 +1,179 @@ +// megafunction wizard: %FIFO% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: dcfifo_mixed_widths + +// ============================================================ +// File Name: vidc_dcfifo.v +// Megafunction Name(s): +// dcfifo_mixed_widths +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 Patches 4.26 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2014 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module vidc_dcfifo ( + aclr, + data, + rdclk, + rdreq, + wrclk, + wrreq, + q, + wrusedw); + + input aclr; + input [31:0] data; + input rdclk; + input rdreq; + input wrclk; + input wrreq; + output [7:0] q; + output [3:0] wrusedw; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri0 aclr; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [7:0] sub_wire0; + wire [3:0] sub_wire1; + wire [7:0] q = sub_wire0[7:0]; + wire [3:0] wrusedw = sub_wire1[3:0]; + + dcfifo_mixed_widths dcfifo_mixed_widths_component ( + .aclr (aclr), + .data (data), + .rdclk (rdclk), + .rdreq (rdreq), + .wrclk (wrclk), + .wrreq (wrreq), + .q (sub_wire0), + .wrusedw (sub_wire1), + .rdempty (), + .rdfull (), + .rdusedw (), + .wrempty (), + .wrfull ()); + defparam + dcfifo_mixed_widths_component.add_usedw_msb_bit = "ON", + dcfifo_mixed_widths_component.intended_device_family = "Cyclone III", + dcfifo_mixed_widths_component.lpm_numwords = 8, + dcfifo_mixed_widths_component.lpm_showahead = "OFF", + dcfifo_mixed_widths_component.lpm_type = "dcfifo_mixed_widths", + dcfifo_mixed_widths_component.lpm_width = 32, + dcfifo_mixed_widths_component.lpm_widthu = 4, + dcfifo_mixed_widths_component.lpm_widthu_r = 6, + dcfifo_mixed_widths_component.lpm_width_r = 8, + dcfifo_mixed_widths_component.overflow_checking = "ON", + dcfifo_mixed_widths_component.rdsync_delaypipe = 4, + dcfifo_mixed_widths_component.read_aclr_synch = "ON", + dcfifo_mixed_widths_component.underflow_checking = "ON", + dcfifo_mixed_widths_component.use_eab = "ON", + dcfifo_mixed_widths_component.write_aclr_synch = "ON", + dcfifo_mixed_widths_component.wrsync_delaypipe = 4; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0" +// Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1" +// Retrieval info: PRIVATE: AlmostFull NUMERIC "0" +// Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1" +// Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "4" +// Retrieval info: PRIVATE: Depth NUMERIC "8" +// Retrieval info: PRIVATE: Empty NUMERIC "1" +// Retrieval info: PRIVATE: Full NUMERIC "1" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0" +// Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1" +// Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0" +// Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0" +// Retrieval info: PRIVATE: Optimize NUMERIC "0" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0" +// Retrieval info: PRIVATE: UsedW NUMERIC "1" +// Retrieval info: PRIVATE: Width NUMERIC "32" +// Retrieval info: PRIVATE: dc_aclr NUMERIC "1" +// Retrieval info: PRIVATE: diff_widths NUMERIC "1" +// Retrieval info: PRIVATE: msb_usedw NUMERIC "1" +// Retrieval info: PRIVATE: output_width NUMERIC "8" +// Retrieval info: PRIVATE: rsEmpty NUMERIC "0" +// Retrieval info: PRIVATE: rsFull NUMERIC "0" +// Retrieval info: PRIVATE: rsUsedW NUMERIC "0" +// Retrieval info: PRIVATE: sc_aclr NUMERIC "0" +// Retrieval info: PRIVATE: sc_sclr NUMERIC "0" +// Retrieval info: PRIVATE: wsEmpty NUMERIC "0" +// Retrieval info: PRIVATE: wsFull NUMERIC "0" +// Retrieval info: PRIVATE: wsUsedW NUMERIC "1" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADD_USEDW_MSB_BIT STRING "ON" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "8" +// Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF" +// Retrieval info: CONSTANT: LPM_TYPE STRING "dcfifo_mixed_widths" +// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "32" +// Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "4" +// Retrieval info: CONSTANT: LPM_WIDTHU_R NUMERIC "6" +// Retrieval info: CONSTANT: LPM_WIDTH_R NUMERIC "8" +// Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON" +// Retrieval info: CONSTANT: RDSYNC_DELAYPIPE NUMERIC "4" +// Retrieval info: CONSTANT: READ_ACLR_SYNCH STRING "ON" +// Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON" +// Retrieval info: CONSTANT: USE_EAB STRING "ON" +// Retrieval info: CONSTANT: WRITE_ACLR_SYNCH STRING "ON" +// Retrieval info: CONSTANT: WRSYNC_DELAYPIPE NUMERIC "4" +// Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT GND "aclr" +// Retrieval info: USED_PORT: data 0 0 32 0 INPUT NODEFVAL "data[31..0]" +// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +// Retrieval info: USED_PORT: rdclk 0 0 0 0 INPUT NODEFVAL "rdclk" +// Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq" +// Retrieval info: USED_PORT: wrclk 0 0 0 0 INPUT NODEFVAL "wrclk" +// Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq" +// Retrieval info: USED_PORT: wrusedw 0 0 4 0 OUTPUT NODEFVAL "wrusedw[3..0]" +// Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0 +// Retrieval info: CONNECT: @data 0 0 32 0 data 0 0 32 0 +// Retrieval info: CONNECT: @rdclk 0 0 0 0 rdclk 0 0 0 0 +// Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0 +// Retrieval info: CONNECT: @wrclk 0 0 0 0 wrclk 0 0 0 0 +// Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0 +// Retrieval info: CONNECT: wrusedw 0 0 4 0 @wrusedw 0 0 4 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL vidc_dcfifo_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/cores/archie/rtl/vidc_dmachannel.v b/cores/archie/rtl/vidc_dmachannel.v index b684351..0773e71 100644 --- a/cores/archie/rtl/vidc_dmachannel.v +++ b/cores/archie/rtl/vidc_dmachannel.v @@ -26,124 +26,97 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + module vidc_dmachannel ( - input clkcpu, - input clkdev, - input cedev, + input rst, + + // dma bus + input clkcpu, + input ak, + output reg rq, + input [31:0] cpu_data, - input rst, - - // dma bus - input ak, - output reg rq, - input [31:0] cpu_data, - output busy, input stall, // dont start another request with this high. - - // device bus + + // device bus + input clkdev, + input cedev, input dev_ak, output [7:0] dev_data ); + +// 8 or 4 words fifo +parameter FIFO4WORDS = 1'b0; -parameter FIFO_SIZE = 3; -localparam MEM_DEPTH = 2**FIFO_SIZE; -localparam WORD_WIDTH = FIFO_SIZE; -localparam BYTE_WIDTH = FIFO_SIZE + 2; -localparam HALF_FULL = 1<<(WORD_WIDTH-1); +reg [1:0] dma_count = 2'd0; +reg load = 1'b0; +wire fifo_can_load; +wire [3:0] wrusedw; -reg [1:0] dma_count = 2'd0; -reg load = 1'b0; -reg ak_r = 1'b0; - -// each channel has a fifo of a different size. -wire [WORD_WIDTH-1:0] wr_ptr; -wire [WORD_WIDTH-1:0] space; - -wire full; - -wire fifo_can_load; - initial begin rq = 1'b0; end - -vidc_fifo #(.FIFO_SIZE(FIFO_SIZE)) VIDEO_FIFO( - - .rst ( rst ), - .wr_clk ( clkcpu ), - .rd_clk ( clkdev ), - .rd_ce ( cedev ), - .wr_en ( ak & load ), - .rd_en ( dev_ak ), - - .din ( cpu_data ), - .dout ( dev_data ), - - .wr_ptr ( wr_ptr ), - - .space ( space ), - .full ( full ) -); + +vidc_dcfifo VIDEO_FIFO( + + .aclr ( rst ), + .data ( cpu_data ), + .rdclk ( clkdev ), + .rdreq ( cedev & dev_ak ), + .wrclk ( clkcpu ), + .wrreq ( ak & load ), + .q ( dev_data ), + .wrusedw( wrusedw ) +); // DMA interface control // this is in the cpu clock domain. always @(posedge clkcpu) begin reg rstD, rstD2; - ak_r <= ak; rstD <= rst; rstD2 <= rstD; if (rstD2 == 1'b1) begin - + // do reset logic dma_count <= 2'd0; load <= 1'b0; rq <= 1'b0; - + end else begin - + // if the load is in progress - if ((load == 1'b1) & (ak == 1'b1)) begin - + if (ak & load) begin + // are we done? - if (dma_count == 2'd3) begin - - load <= 1'b0; - - end - + if (dma_count == 2'd3) load <= 1'b0; // clear the request on the first ack. // the dma action will continue until 4 words are read. rq <= 1'b0; - + // count the ack pulses dma_count <= dma_count + 2'd1; - end else if (load == 1'b0) begin - + end else if (~load) begin + // possibly unnecessary? dma_count <= 2'd0; - + // if the fifo can load and its our slot then go. + if (fifo_can_load === 1'b1) begin + load <= 1'b1; + rq <= 1'b1; + end end - - // if the fifo can load and its our slot then go. - if (fifo_can_load === 1'b1) begin - - load <= 1'b1; - rq <= 1'b1; - - end - end - + end -// TODO: replace 2'b00 with bits 4 and 5 of fifo control register for video fifo. -assign fifo_can_load = ~stall & ((space > 3'd4) | ((space == 'd0) & (full == 1'b0))) & (wr_ptr[1:0] == 2'b00); -assign busy = load; +// TODO: use bits 4 and 5 of fifo control register for requesting new data to the video fifo. +// But the RAM timing is so different from the original machine that it won't be useful +assign fifo_can_load = ~stall && ((!FIFO4WORDS && wrusedw <= 4) || (FIFO4WORDS && wrusedw == 0)); +assign busy = load; endmodule diff --git a/cores/archie/rtl/vidc_fifo.v b/cores/archie/rtl/vidc_fifo.v deleted file mode 100644 index 1c0e92f..0000000 --- a/cores/archie/rtl/vidc_fifo.v +++ /dev/null @@ -1,143 +0,0 @@ -`timescale 1ns / 1ps -/* vidc_fifo.v - - Copyright (c) 2012-2014, Stephen J. Leary - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -module vidc_fifo #( - parameter FIFO_SIZE = 3 -) -( - input rst, - input wr_clk, - input wr_en, - input[31:0] din, - - input rd_clk, - input rd_ce, - input rd_en, - output reg [7:0] dout, - - output reg [WORD_WIDTH-1:0] wr_ptr, - output reg [WORD_WIDTH-1:0] space, - output reg full, - output empty -); - -localparam MEM_DEPTH = 2**FIFO_SIZE; -localparam WORD_WIDTH = FIFO_SIZE; -localparam BYTE_WIDTH = FIFO_SIZE + 2; - -reg [31:0] data[0:MEM_DEPTH-1]; -reg [BYTE_WIDTH-1:0] rd_ptr; - -integer k; - -initial begin - - wr_ptr = 'd0; - rd_ptr = 'd0; - full = 1'b0; - dout = 8'd0; - - for (k = 0; k < MEM_DEPTH; k = k + 1) - begin - data[k] = 32'd0; - end - - $display("FIFO has %x", MEM_DEPTH); - -end - -reg [BYTE_WIDTH-1:0] rd_ptr_r; - -always @(posedge wr_clk) begin - reg rstD, rstD2; - - rd_ptr_r <= rd_ptr; - space <= {rd_ptr_r[BYTE_WIDTH-1:2]} - wr_ptr; - rstD <= rst; - rstD2 <= rstD; - - if (rstD2) begin - - wr_ptr <= 'd0; - full <= 1'b0; - - end else begin - - if (wr_ptr != {rd_ptr_r[BYTE_WIDTH-1:2]}) begin - - full <= 1'b0; - - end - - if (wr_en == 1'b1) begin - - data[wr_ptr] <= din; - wr_ptr <= wr_ptr + 2'd1; - full <= (wr_ptr + 2'd1) == {rd_ptr_r[BYTE_WIDTH-1:2]}; - - end - - end - -end - -wire [7:0] q; - -always @(posedge rd_clk) begin - - reg rstD, rstD2; - - rstD <= rst; - rstD2 <= rstD; - if(rd_ce) begin - if (rstD2) begin - - rd_ptr <= 'd0; - dout <= 8'd0; - - end else if (rd_en) begin - - if (~empty) begin - rd_ptr <= rd_ptr + 1'd1; - dout <= q; - end else begin - dout <= 'd0; - end - end - end -end - -assign empty = !full & space == 'd0; - -// cross the clock domain. -assign q = (rd_ptr[1:0] == 2'b00) ? data[{rd_ptr[BYTE_WIDTH-1:2]}][7:0] : - (rd_ptr[1:0] == 2'b01) ? data[{rd_ptr[BYTE_WIDTH-1:2]}][15:8] : - (rd_ptr[1:0] == 2'b10) ? data[{rd_ptr[BYTE_WIDTH-1:2]}][23:16] : data[{rd_ptr[BYTE_WIDTH-1:2]}][31:24]; - -endmodule