📄 fifoctlr_ic.v
字号:
* it would not generate an error or give false values. ** *\************************************************************/always @(posedge read_clock or posedge fifo_gsr) if (fifo_gsr) read_addr <= 'h0; else if (read_allow) read_addr <= read_addr + 1;always @(posedge read_clock or posedge fifo_gsr) if (fifo_gsr) read_nextgray <= 9'b100000000; else if (read_allow) read_nextgray <= { read_addr[8], (read_addr[8] ^ read_addr[7]), (read_addr[7] ^ read_addr[6]), (read_addr[6] ^ read_addr[5]), (read_addr[5] ^ read_addr[4]), (read_addr[4] ^ read_addr[3]), (read_addr[3] ^ read_addr[2]), (read_addr[2] ^ read_addr[1]), (read_addr[1] ^ read_addr[0]) };always @(posedge read_clock or posedge fifo_gsr) if (fifo_gsr) read_addrgray <= 9'b100000001; else if (read_allow) read_addrgray <= read_nextgray;always @(posedge read_clock or posedge fifo_gsr) if (fifo_gsr) read_lastgray <= 9'b100000011; else if (read_allow) read_lastgray <= read_addrgray;/************************************************************\* ** Generation of Write address pointers. Identical copy of ** read pointer generation above, except for names. ** *\************************************************************/always @(posedge write_clock or posedge fifo_gsr) if (fifo_gsr) write_addr <= 'h0; else if (write_allow) write_addr <= write_addr + 1;always @(posedge write_clock or posedge fifo_gsr) if (fifo_gsr) write_nextgray <= 9'b100000000; else if (write_allow) write_nextgray <= { write_addr[8], (write_addr[8] ^ write_addr[7]), (write_addr[7] ^ write_addr[6]), (write_addr[6] ^ write_addr[5]), (write_addr[5] ^ write_addr[4]), (write_addr[4] ^ write_addr[3]), (write_addr[3] ^ write_addr[2]), (write_addr[2] ^ write_addr[1]), (write_addr[1] ^ write_addr[0]) };always @(posedge write_clock or posedge fifo_gsr) if (fifo_gsr) write_addrgray <= 9'b100000001; else if (write_allow) write_addrgray <= write_nextgray;/************************************************************\* ** Alternative generation of FIFOstatus outputs. Used to ** determine how full FIFO is, based on how far the Write ** pointer is ahead of the Read pointer. read_truegray * * is synchronized to write_clock (rag_writesync), converted ** to binary (ra_writesync), and then subtracted from the ** pipelined write_addr (write_addrr) to find out how many ** words are in the FIFO (fifostatus). The top bits are * * then 1/2 full, 1/4 full, etc. (not mutually exclusive). ** fifostatus has a one-cycle latency on write_clock; or, ** one cycle after the write address is incremented on a * * write operation, fifostatus is updated with the new * * capacity information. There is a two-cycle latency on ** read operations. ** ** If read_clock is much faster than write_clock, it is * * possible that the fifostatus counter could drop several ** positions in one write_clock cycle, so the low-order bits ** of fifostatus are not as reliable. ** ** NOTE: If the fifostatus flags are not needed, then this ** section of logic can be trimmed, saving 20+ slices and ** improving the circuit performance. ** *\************************************************************/reg [`ADDR_WIDTH] read_truegray, rag_writesync, write_addrr;wire [`ADDR_WIDTH] ra_writesync;wire [2:0] xorout;always @(posedge read_clock or posedge fifo_gsr) if (fifo_gsr) read_truegray <= 'h0; else read_truegray <= { read_addr[8], (read_addr[8] ^ read_addr[7]), (read_addr[7] ^ read_addr[6]), (read_addr[6] ^ read_addr[5]), (read_addr[5] ^ read_addr[4]), (read_addr[4] ^ read_addr[3]), (read_addr[3] ^ read_addr[2]), (read_addr[2] ^ read_addr[1]), (read_addr[1] ^ read_addr[0]) };always @(posedge write_clock or posedge fifo_gsr) if (fifo_gsr) rag_writesync <= 'h0; else rag_writesync <= read_truegray;xor4_p xor8_5 (.data(rag_writesync[8:5]), .out(xorout[0]));xor5_p xor8_4 (.data(rag_writesync[8:4]), .out(xorout[1]));xor4_p xor4_1 (.data(rag_writesync[4:1]), .out(xorout[2]));assign ra_writesync = { rag_writesync[8], (rag_writesync[8] ^ rag_writesync[7]), (rag_writesync[8] ^ rag_writesync[7] ^ rag_writesync[6]), xorout[0], xorout[1], (xorout[1] ^ rag_writesync[3]), (xorout[1] ^ rag_writesync[3] ^ rag_writesync[2]), (xorout[0] ^ xorout[2]), (xorout[0] ^ xorout[2] ^ rag_writesync[0]) };always @(posedge write_clock or posedge fifo_gsr) if (fifo_gsr) write_addrr <= 'h0; else write_addrr <= write_addr;always @(posedge write_clock or posedge fifo_gsr) if (fifo_gsr) fifostatus <= 'h0; else if (! full) fifostatus <= write_addrr - ra_writesync;/************************************************************\* ** The two conditions decoded with special carry logic are ** Empty and Full (gated versions). These are used to ** determine the next state of the Full/Empty flags. Carry ** logic is used for optimal speed. (The previous ** implementation of AlmostEmpty and AlmostFull have been ** wrapped into the corresponding carry chains for faster ** performance). ** ** When write_addrgray is equal to read_addrgray, the FIFO ** is Empty, and emptyg (combinatorial) is asserted. Or, ** when write_addrgray is equal to read_nextgray (1 word in ** the FIFO) then the FIFO potentially could be going Empty, ** so emptyg is asserted, and the Empty flip-flop enable is ** gated with empty_allow, which is conditioned with a valid ** read. ** ** Similarly, when read_lastgray is equal to write_addrgray, ** the FIFO is full (511 addresses). Or, when read_lastgray ** is equal to write_nextgray, then the FIFO potentially * * could be going Full, so fullg is asserted, and the Full ** flip-flop enable is gated with full_allow, which is * * conditioned with a valid write. ** ** Note: To have utilized the full address space (512) * * would have required extra logic to determine Full/Empty ** on equal addresses, and this would have slowed down the ** overall performance, which was the top priority. * * *\************************************************************/muxor_p emuxor0 (.a(write_addrgray[0]), .b(read_addrgray[0]), .c(read_nextgray[0]), .sel(empty), .out(ecomp[0]));muxor_p emuxor1 (.a(write_addrgray[1]), .b(read_addrgray[1]), .c(read_nextgray[1]), .sel(empty), .out(ecomp[1]));muxor_p emuxor2 (.a(write_addrgray[2]), .b(read_addrgray[2]), .c(read_nextgray[2]), .sel(empty), .out(ecomp[2]));muxor_p emuxor3 (.a(write_addrgray[3]), .b(read_addrgray[3]), .c(read_nextgray[3]), .sel(empty), .out(ecomp[3]));muxor_p emuxor4 (.a(write_addrgray[4]), .b(read_addrgray[4]), .c(read_nextgray[4]), .sel(empty), .out(ecomp[4]));muxor_p emuxor5 (.a(write_addrgray[5]), .b(read_addrgray[5]), .c(read_nextgray[5]), .sel(empty), .out(ecomp[5]));muxor_p emuxor6 (.a(write_addrgray[6]), .b(read_addrgray[6]), .c(read_nextgray[6]), .sel(empty), .out(ecomp[6]));muxor_p emuxor7 (.a(write_addrgray[7]), .b(read_addrgray[7]), .c(read_nextgray[7]), .sel(empty), .out(ecomp[7]));muxor_p emuxor8 (.a(write_addrgray[8]), .b(read_addrgray[8]), .c(read_nextgray[8]), .sel(empty), .out(ecomp[8]));MUXCY_L emuxcy0 (.DI(gnd), .CI(pwr), .S(ecomp[0]), .LO(emuxcyo[0]));MUXCY_L emuxcy1 (.DI(gnd), .CI(emuxcyo[0]), .S(ecomp[1]), .LO(emuxcyo[1]));MUXCY_L emuxcy2 (.DI(gnd), .CI(emuxcyo[1]), .S(ecomp[2]), .LO(emuxcyo[2]));MUXCY_L emuxcy3 (.DI(gnd), .CI(emuxcyo[2]), .S(ecomp[3]), .LO(emuxcyo[3]));MUXCY_L emuxcy4 (.DI(gnd), .CI(emuxcyo[3]), .S(ecomp[4]), .LO(emuxcyo[4]));MUXCY_L emuxcy5 (.DI(gnd), .CI(emuxcyo[4]), .S(ecomp[5]), .LO(emuxcyo[5]));MUXCY_L emuxcy6 (.DI(gnd), .CI(emuxcyo[5]), .S(ecomp[6]), .LO(emuxcyo[6]));MUXCY_L emuxcy7 (.DI(gnd), .CI(emuxcyo[6]), .S(ecomp[7]), .LO(emuxcyo[7]));MUXCY_L emuxcy8 (.DI(gnd), .CI(emuxcyo[7]), .S(ecomp[8]), .LO(emptyg));muxor_p fmuxor0 (.a(read_lastgray[0]), .b(write_addrgray[0]), .c(write_nextgray[0]), .sel(full), .out(fcomp[0]));muxor_p fmuxor1 (.a(read_lastgray[1]), .b(write_addrgray[1]), .c(write_nextgray[1]), .sel(full), .out(fcomp[1]));muxor_p fmuxor2 (.a(read_lastgray[2]), .b(write_addrgray[2]), .c(write_nextgray[2]), .sel(full), .out(fcomp[2]));muxor_p fmuxor3 (.a(read_lastgray[3]), .b(write_addrgray[3]), .c(write_nextgray[3]), .sel(full), .out(fcomp[3]));muxor_p fmuxor4 (.a(read_lastgray[4]), .b(write_addrgray[4]), .c(write_nextgray[4]), .sel(full), .out(fcomp[4]));muxor_p fmuxor5 (.a(read_lastgray[5]), .b(write_addrgray[5]), .c(write_nextgray[5]), .sel(full), .out(fcomp[5]));muxor_p fmuxor6 (.a(read_lastgray[6]), .b(write_addrgray[6]), .c(write_nextgray[6]), .sel(full), .out(fcomp[6]));muxor_p fmuxor7 (.a(read_lastgray[7]), .b(write_addrgray[7]), .c(write_nextgray[7]), .sel(full), .out(fcomp[7]));muxor_p fmuxor8 (.a(read_lastgray[8]), .b(write_addrgray[8]), .c(write_nextgray[8]), .sel(full), .out(fcomp[8])); MUXCY_L fmuxcy0 (.DI(gnd), .CI(pwr), .S(fcomp[0]), .LO(fmuxcyo[0]));MUXCY_L fmuxcy1 (.DI(gnd), .CI(fmuxcyo[0]), .S(fcomp[1]), .LO(fmuxcyo[1]));MUXCY_L fmuxcy2 (.DI(gnd), .CI(fmuxcyo[1]), .S(fcomp[2]), .LO(fmuxcyo[2]));MUXCY_L fmuxcy3 (.DI(gnd), .CI(fmuxcyo[2]), .S(fcomp[3]), .LO(fmuxcyo[3]));MUXCY_L fmuxcy4 (.DI(gnd), .CI(fmuxcyo[3]), .S(fcomp[4]), .LO(fmuxcyo[4]));MUXCY_L fmuxcy5 (.DI(gnd), .CI(fmuxcyo[4]), .S(fcomp[5]), .LO(fmuxcyo[5]));MUXCY_L fmuxcy6 (.DI(gnd), .CI(fmuxcyo[5]), .S(fcomp[6]), .LO(fmuxcyo[6]));MUXCY_L fmuxcy7 (.DI(gnd), .CI(fmuxcyo[6]), .S(fcomp[7]), .LO(fmuxcyo[7]));MUXCY_L fmuxcy8 (.DI(gnd), .CI(fmuxcyo[7]), .S(fcomp[8]), .LO(fullg)); endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -