1 /************************************** * 2. 3 *************************************** * *************/4 module FIFO (dataIn, RD, wR, RST, CLK, dataout, full, empty); 5 input [7:0] dataIn; 6 Input Rd, wR, RST, CLK; 7 output [7:0] dataout; 8 output full, empty; 9 wire [] dataout; 10 Reg full_in, empty_in; 11 Reg [] mem []; 12 Reg [] RP, WP; // It is actually a cyclic read/write process. The 4-bit binary number is exactly 16 States, indicating 16 depths: 13 assign full = full_in; 14 assign empty = empty_in; 15 // memory read out16 assign dataout = mem [RP]; 17 // memory write in18 always @ (posedge CLK) begin19 if (WR &&~ Full_in) MEm [WP] <= dataIn; 20 end21 // memory write pointer increment22 always @ (posedge CLK or negedge RST) begin23 if (! RST) WP <= 0; 24 else begin25 if (WR &&~ Full_in) WP <= WP + 1 'b1; 26 end27 end28 // memory read pointer increment29 always @ (posedge CLK or negedge RST) begin30 if (! RST) rp <= 0; 31 else begin32 if (RD &&~ Empty_in) rp <= RP + 1 'b1; 33 end34 end35 // full signal generate36 always @ (posedge CLK or negedge RST) begin37 if (! RST) full_in <= 1 'b0; 38 else begin39 if ((~ RD & wr) & (Wp = RP-1) | (Rp = 4'h0 & Wp = 4'hf ))) 40 full_in <= 1 'b1; 41 else if (full_in & rd) full_in <= 1' B0; 42 end43 end44 // empty signal generate45 always @ (posedge CLK or negedge RST) begin46 if (! RST) empty_in <= 1 'b1; 47 else begin48 if (RD &&~ WR) & (Rp = wp-1 | (Rp = 4 'hf & Wp = 4 'h0) 49 empty_in <= 1 'b1; 50 else if (empty_in & wr) empty_in <= 1 'b0; 51 end52 end53 endmodule
Synchronize FIFO
Synchronization of FIFO is relatively simple, but it is a little more complicated that the full and empty signals are generated. There are two ways to use the above Code, but it is not easy to understand, FIFO first-in-first-out, it can be seen that the Read and Write addresses are increasing from scratch, so that the first write will be read first. For synchronous FIFO, the clock is the same. If both read and write operations are performed, the FIFO will never be full. Because when writing the pointer to the end of the FIFO, it will continue to write from the zero address (assuming that the zero address data has been read, of course it can be overwritten), so the cycle repeats. How to generate an empty full sign:
This is the most intuitive case. For full, if the write operation has not been read, the full mark should be generated when wrp = FIFO depth. If the write operation continues, data that has not been read will be overwritten to invalidate the data.
For empty, if wrp = 0 and RDP = FIFO depth, an empty flag should be generated if read continues. The read will start from the zero address, and the zero address will either be the previous data or be empty, so...
The second case: the difference between wrp and RDP is 1. If RDP-wrp = 1 is not read, data overwrites will occur if the write continues; if wrp-RDP = 1 is not written, the system reads the error data.
This is the reason for the flag expression in the program.
There is also a simple way to generate a full sign:
The read/write address is not used to determine whether the FIFO is full. Design a counter (pt_cnt) to indicate the number of data in the FIFO in the current cycle. Because the FIFO contains a maximum of 16 data records, a 5-bit counter is used to indicate the number of data records in the FIFO. The calculation is as follows:
L When resetting, pt_cnt = 0;
L if wr_en and rd_en are both valid, pt_cnt is not added or subtracted; this means that the number of data in the FIFO remains unchanged during read/write operations on the FIFO at the same time.
L if wr_en is valid and full = 0, pt_cont + 1; indicates that when the write operation is performed and the FIFO is not full, the number of data in the FIFO is increased by 1;
L if rd_en is valid and empty = 0, the pt_cont-1; indicates that when the read operation and the FIFO is not full, the number of data in the FIFO is reduced by 1;
L if pt_cnt = 0, it indicates that the FIFO is empty, you need to set empty = 1; if pt_cnt = 16, it indicates that the FIFO is full now, you need to set full = 1.
Program of this module:
1 module flag_gen(clk,rst,full,emptyp,wr_en,rd_en); 2 input clk,rst; 3 input rd_en; 4 input wr_en; 5 output full,emptyp; 6 reg full,emptyp; 7 reg[4:0]count; 8 parameter max_count=5‘b01111; 9 always @ (posedge clk or negedge rst)10 begin11 if(!rst)12 count<=0;13 else14 begin15 case({wr_en,rd_en})16 2‘b00:count<=count;17 2‘b01:18 if(count!==5‘b00000)19 count<=count-1;20 2‘b10:21 if(count!== max_count) 22 count<=count+1;23 2‘b11:count<=count;24 endcase25 end26 end27 always @(count)28 begin29 if(count==5‘b00000)30 emptyp<=1;31 else32 emptyp<=0;33 end34 always @(count)35 begin36 if(count== max_count)37 full<=1;38 else39 full<=0; 40 end41 endmoduleGeneration of full and empty flags
We once again witnessed the power of bit Concatenation Operators.
Describe how to synchronize FIFO data using