📄 fifoctlr_ic.v
字号:
/***********************************************************************\* ** Module : fifoctlr_ic.v Last Update: 07/14/00 ** ** Description : FIFO controller top level. ** Implements a 511x8 FIFO with independent read/write ** clocks. ** ** The following Verilog code implements a 511x8 FIFO in a Virtex ** device. The inputs are a Read Clock and Read Enable, a Write Clock * * and Write Enable, Write Data, and a FIFO_gsr signal as an initial ** reset. The outputs are Read Data, Full, Empty, and the FIFOstatus ** outputs, which indicate roughly how full the FIFO is. ** ** Designer : Nick Camilleri ** ** Company : Xilinx, Inc. ** ** Disclaimer : THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY ** WHATSOEVER AND XILINX SPECIFICALLY DISCLAIMS ANY ** IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR ** A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. ** THEY ARE ONLY INTENDED TO BE USED BY XILINX ** CUSTOMERS, AND WITHIN XILINX DEVICES. ** ** Copyright (c) 2000 Xilinx, Inc. ** All rights reserved ** *\***********************************************************************/`timescale 1ns / 10ps`define DATA_WIDTH 7:0`define ADDR_WIDTH 8:0`define CARRY_WIDTH 8:0/************************************************************\* ** The logic modules below are coded explicitly, to ensure ** that the logic is implemented in a minimum of levels. ** *\************************************************************/module xor5_p (data, out);input [4:0] data;output out;wire muxout, mdata1, mdata0;assign mdata1 = ! (data[4] ^ data[3] ^ data[2] ^ data[1]);assign mdata0 = (data[4] ^ data[3] ^ data[2] ^ data[1]);MUXF5 muxf5_1 (.I0(mdata0), .I1(mdata1), .S(data[0]), .O(muxout));assign out = muxout;endmodulemodule xor4_p (data, out);input [3:0] data;output out;assign out = (data[3] ^ data[2] ^ data[1] ^ data[0]);endmodulemodule muxor_p (a, b, c, sel, out);input a, b, c, sel;output out;assign #1 out = (((a == b) && sel) || ((a == c) && ! sel));endmodule /************************************************************\* ** The top level module is listed below. ** *\************************************************************/module fifoctlr_ic (read_clock_in, write_clock_in, read_enable_in, write_enable_in, fifo_gsr_in, write_data_in, read_data_out, fifostatus_out, full_out, empty_out);input read_clock_in, write_clock_in;input read_enable_in, write_enable_in;input fifo_gsr_in;input [`DATA_WIDTH] write_data_in;output [`DATA_WIDTH] read_data_out;output [3:0] fifostatus_out;output full_out, empty_out;wire read_enable = read_enable_in;wire write_enable = write_enable_in;wire fifo_gsr = fifo_gsr_in;wire [`DATA_WIDTH] write_data = write_data_in;wire [`DATA_WIDTH] read_data;assign read_data_out = read_data;reg [8:0] fifostatus;assign fifostatus_out = fifostatus[8:5];reg full, empty;assign full_out = full;assign empty_out = empty;reg [`ADDR_WIDTH] read_addr, write_addr;reg [`ADDR_WIDTH] write_addrgray, write_nextgray;reg [`ADDR_WIDTH] read_addrgray, read_nextgray, read_lastgray;wire read_allow, write_allow, empty_allow, full_allow;wire [`CARRY_WIDTH] ecomp, fcomp;wire [`CARRY_WIDTH] emuxcyo, fmuxcyo;wire emptyg, fullg;wire [`DATA_WIDTH] gnd_bus = 'h0;wire gnd = 0;wire pwr = 1;/**********************************************************************\* ** Global input clock buffers are instantianted for both the read_clock ** and the write_clock, to avoid skew problems. ** *\**********************************************************************/BUFGP gclkread (.I(read_clock_in), .O(read_clock));BUFGP gclkwrite (.I(write_clock_in), .O(write_clock));/**********************************************************************\* ** Block RAM instantiation for FIFO. Module is 512x8, of which one ** address location is sacrificed for the overall speed of the design. ** *\**********************************************************************/RAMB4_S8_S8 bram1 ( .ADDRA(read_addr), .ADDRB(write_addr), .DIA(gnd_bus), .DIB(write_data), .WEA(gnd), .WEB(pwr), .CLKA(read_clock), .CLKB(write_clock), .RSTA(gnd), .RSTB(gnd), .ENA(read_allow), .ENB(write_allow), .DOA(read_data), .DOB() );/************************************************************\* ** Allow flags determine whether FIFO control logic can ** operate. If read_enable is driven high, and the FIFO is ** not Empty, then Reads are allowed. Similarly, if the ** write_enable signal is high, and the FIFO is not Full, ** then Writes are allowed. ** *\************************************************************/assign read_allow = (read_enable && ! empty);assign write_allow = (write_enable && ! full);assign full_allow = (full || write_enable);assign empty_allow = (empty || read_enable);/***********************************************************\* ** Empty flag is set on fifo_gsr (initial), or when gray ** code counters are equal, or when there is one word in ** the FIFO, and a Read operation is about to be performed. ** *\***********************************************************/always @(posedge read_clock or posedge fifo_gsr) if (fifo_gsr) empty <= 'b1; else if (empty_allow) empty <= emptyg;/***********************************************************\* ** Full flag is set on fifo_gsr (initial, but it is cleared ** on the first valid write_clock edge after fifo_gsr is ** de-asserted), or when Gray-code counters are one away ** from being equal (the Write Gray-code address is equal ** to the Last Read Gray-code address), or when the Next ** Write Gray-code address is equal to the Last Read Gray- ** code address, and a Write operation is about to be ** performed. ** *\***********************************************************/always @(posedge write_clock or posedge fifo_gsr) if (fifo_gsr) full <= 'b1; else if (full_allow) full <= fullg;/************************************************************\* ** Generation of Read address pointers. The primary one is ** binary (read_addr), and the Gray-code derivatives are ** generated via pipelining the binary-to-Gray-code result. ** The initial values are important, so they're in sequence. ** ** Grey-code addresses are used so that the registered ** Full and Empty flags are always clean, and never in an ** unknown state due to the asynchonous relationship of the ** Read and Write clocks. In the worst case scenario, Full ** and Empty would simply stay active one cycle longer, but *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -