📄 generic_receive_fifo.v
字号:
begin if(RX_FIFO_SRESET == 1'b1) begin RD_ADDRGRAY[log2_FIFO_SIZE-1] <= 1'b1; RD_ADDRGRAY[log2_FIFO_SIZE-2:1] <= 0; RD_ADDRGRAY[0] <= 1'b1; end else if (RD_ALLOW == 1'b1) RD_ADDRGRAY <= RD_NEXTGRAY; end// purpose: 3rd Pipeline Registered Version of Read Pointer Gray Code. // type : sequential always @(posedge FIFO_CLK) begin if(RX_FIFO_SRESET == 1'b1) begin RD_LASTGRAY[log2_FIFO_SIZE-1] <= 1'b1; RD_LASTGRAY[log2_FIFO_SIZE-2:2] <= 0; RD_LASTGRAY[1] <= 1'b1; RD_LASTGRAY[0] <= 1'b1; end else if (RD_ALLOW == 1'b1) RD_LASTGRAY <= RD_ADDRGRAY; end //-----------------------------------------------------------------------------------// CREATE ACCURATE FIFO_EMPTY SIGNAL USING GRAY CODE READ AND WRITE POINTERS --// Please refer to Xilinx Application Note 131 for an explanation of this logic. --//-----------------------------------------------------------------------------------// The Empty flag generated here is synchronous to // the FIFO_CLK, and is used by the Client Interface.// Empty flag is set on reset, 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.// purpose: Compare individual bits of write and read Gray Code pointers in a LUT. // type : combinatorial // Use the code below when Verilog 2001 generate statements are supported.... /* generate for(i = log2_FIFO_SIZE-1; i >= 0; i = i - 1) begin assign EMPTY_COMPARE[i] = (~(WR_ADDRGRAY[i] ^ RD_ADDRGRAY[i]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[i] ^ RD_NEXTGRAY[i]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 end endgenerate */ // CHANGES REQUIRED // Use the code below when Verilog 2001 generate statements are NOT supported... // Uncomment the code for the correct FIFO_SIZE... // (FIFO_SIZE >= 512) assign EMPTY_COMPARE[0] = (~(WR_ADDRGRAY[0] ^ RD_ADDRGRAY[0]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[0] ^ RD_NEXTGRAY[0]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[1] = (~(WR_ADDRGRAY[1] ^ RD_ADDRGRAY[1]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[1] ^ RD_NEXTGRAY[1]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[2] = (~(WR_ADDRGRAY[2] ^ RD_ADDRGRAY[2]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[2] ^ RD_NEXTGRAY[2]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[3] = (~(WR_ADDRGRAY[3] ^ RD_ADDRGRAY[3]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[3] ^ RD_NEXTGRAY[3]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[4] = (~(WR_ADDRGRAY[4] ^ RD_ADDRGRAY[4]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[4] ^ RD_NEXTGRAY[4]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[5] = (~(WR_ADDRGRAY[5] ^ RD_ADDRGRAY[5]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[5] ^ RD_NEXTGRAY[5]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[6] = (~(WR_ADDRGRAY[6] ^ RD_ADDRGRAY[6]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[6] ^ RD_NEXTGRAY[6]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[7] = (~(WR_ADDRGRAY[7] ^ RD_ADDRGRAY[7]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[7] ^ RD_NEXTGRAY[7]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 assign EMPTY_COMPARE[8] = (~(WR_ADDRGRAY[8] ^ RD_ADDRGRAY[8]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[8] ^ RD_NEXTGRAY[8]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 // (FIFO_SIZE >= 1024) Use this line also assign EMPTY_COMPARE[9] = (~(WR_ADDRGRAY[9] ^ RD_ADDRGRAY[9]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[9] ^ RD_NEXTGRAY[9]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 // (FIFO_SIZE >= 2048) Use this line also /* assign EMPTY_COMPARE[10] = (~(WR_ADDRGRAY[10] ^ RD_ADDRGRAY[10]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[10] ^ RD_NEXTGRAY[10]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 */ // (FIFO_SIZE >= 4096) Use this line also /* assign EMPTY_COMPARE[11] = (~(WR_ADDRGRAY[11] ^ RD_ADDRGRAY[11]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[11] ^ RD_NEXTGRAY[11]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 */ // (FIFO_SIZE >= 8192) Use this line also /* assign EMPTY_COMPARE[12] = (~(WR_ADDRGRAY[12] ^ RD_ADDRGRAY[12]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[12] ^ RD_NEXTGRAY[12]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 */ // (FIFO_SIZE == 16384) Use this line also /* assign EMPTY_COMPARE[13] = (~(WR_ADDRGRAY[13] ^ RD_ADDRGRAY[13]) & REALLY_EMPTY) | // write pointer = read pointer (~(WR_ADDRGRAY[13] ^ RD_NEXTGRAY[13]) & ~REALLY_EMPTY); // write pointer = read pointer - 1 */// purpose: Compare all bits of write and read Gray Code pointers using vertical MUXCY carry chain primitives.// This is very fast and logic efficient!// type : combinatorial MUXCY_L EMUXCY0 ( .DI(LOGIC0), .CI(LOGIC1), .S(EMPTY_COMPARE[0]), .LO(EMPTY_MUXCYO[0]) ); // Use the code below when Verilog 2001 generate statements are supported.... /* generate for(i = log2_FIFO_SIZE-1; i >= 1; i = i - 1) begin MUXCY_L EMUXCY (.DI(LOGIC0), .CI(EMPTY_MUXCYO[i-1]), .S(EMPTY_COMPARE[i]), .LO(EMPTY_MUXCYO[i])); end endgenerate */ // CHANGES REQUIRED // Use the code below when Verilog 2001 generate statements are NOT supported... // Uncomment the code for the correct FIFO_SIZE... // (FIFO_SIZE >= 512) MUXCY_L EMUXCY1 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[1-1]), .S(EMPTY_COMPARE[1]), .LO(EMPTY_MUXCYO[1])); MUXCY_L EMUXCY2 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[2-1]), .S(EMPTY_COMPARE[2]), .LO(EMPTY_MUXCYO[2])); MUXCY_L EMUXCY3 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[3-1]), .S(EMPTY_COMPARE[3]), .LO(EMPTY_MUXCYO[3])); MUXCY_L EMUXCY4 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[4-1]), .S(EMPTY_COMPARE[4]), .LO(EMPTY_MUXCYO[4])); MUXCY_L EMUXCY5 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[5-1]), .S(EMPTY_COMPARE[5]), .LO(EMPTY_MUXCYO[5])); MUXCY_L EMUXCY6 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[6-1]), .S(EMPTY_COMPARE[6]), .LO(EMPTY_MUXCYO[6])); MUXCY_L EMUXCY7 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[7-1]), .S(EMPTY_COMPARE[7]), .LO(EMPTY_MUXCYO[7])); MUXCY_L EMUXCY8 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[8-1]), .S(EMPTY_COMPARE[8]), .LO(EMPTY_MUXCYO[8])); // (FIFO_SIZE >= 1024) Use this line also MUXCY_L EMUXCY9 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[9-1]), .S(EMPTY_COMPARE[9]), .LO(EMPTY_MUXCYO[9])); // (FIFO_SIZE >= 2048) Use this line also /* MUXCY_L EMUXCY10 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[10-1]), .S(EMPTY_COMPARE[10]), .LO(EMPTY_MUXCYO[10])); */ // (FIFO_SIZE >= 4096) Use this line also /* MUXCY_L EMUXCY11 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[11-1]), .S(EMPTY_COMPARE[11]), .LO(EMPTY_MUXCYO[11])); */ // (FIFO_SIZE >= 8192) Use this line also /* MUXCY_L EMUXCY12 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[12-1]), .S(EMPTY_COMPARE[12]), .LO(EMPTY_MUXCYO[12])); */ // (FIFO_SIZE == 16384) Use this line also /* MUXCY_L EMUXCY13 (.DI(LOGIC0), .CI(EMPTY_MUXCYO[13-1]), .S(EMPTY_COMPARE[13]), .LO(EMPTY_MUXCYO[13])); */// purpose: Produce EMPTY signal, having had compared write and read gray code pointers. // type : sequential always @(posedge FIFO_CLK) begin if(RX_FIFO_SRESET == 1'b1) REALLY_EMPTY <= 1'b1; else if ((REALLY_EMPTY | RD_ENABLE) == 1'b1) REALLY_EMPTY <= EMPTY_MUXCYO[log2_FIFO_SIZE-1]; // use final output of carry chain end assign STATUS_EMPTY = REALLY_EMPTY;/*------------------------------------------------------------------------------------- CREATE ACCURATE FIFO_FULL SIGNAL USING GRAY CODE READ AND WRITE POINTERS ---- Please refer to Xilinx Application Note 131 for an explanation of this logic. ----------------------------------------------------------------------------------------- The Full flag generated in this section is synchronous-- to RX_CLK and is used by the FIFO write logic.-- Full flag is set 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. -- Full flag is reset only after the FIFO is no longer full-- and at the end of the first frame to leave the MAC Receiver-- following this condition. Thus the first word to re-enter -- the FIFO will be a Code Word: this will signal that the FIFO -- overflowed and will then begin cleanly with a new MAC frame. */// purpose: Compare individual bits of write and read Gray Code pointers in a LUT. // type : combinatorial// inputs : RD_LASTGRAY, WR_ADDRGRAY, WR_NEXTGRAY, FULL // outputs: FULL_COMPARE // Use the code below when Verilog 2001 generate statements are supported.... /* generate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -