同步FIFO, verilog:
module fifo(clock,reset,read,write,fifo_in,fifo_out,fifo_empty,fifo_half,fifo_full);
input clock,reset,read,write;
input [15:0]fifo_in;
output[15:0]fifo_out;
output fifo_empty,fifo_half,fifo_full;//标志位
reg [15:0]fifo_out;
reg [15:0]ram[15:0];
reg [3:0]read_ptr,write_ptr,counter;//指针与计数
wire fifo_empty,fifo_half,fifo_full;
[email protected](posedge clock)
if(reset)
begin
read_ptr=0;
write_ptr=0;
counter=0;
fifo_out=0; //初始值
end
else
case({read,write})
2‘b00:
counter=counter; //没有读写指令
2‘b01: //写指令,数据输入fifo
begin
ram[write_ptr]=fifo_in;
counter=counter+1;
write_ptr=(write_ptr==15)?0:write_ptr+1;
end
2‘b10: //读指令,数据读出fifo
begin
fifo_out=ram[read_ptr];
counter=counter-1;
read_ptr=(read_ptr==15)?0:read_ptr+1;
end
2‘b11: //读写指令同时,数据可以直接输出
begin
if(counter==0)
fifo_out=fifo_in;
else
begin
ram[write_ptr]=fifo_in;
fifo_out=ram[read_ptr];
write_ptr=(write_ptr==15)?0:write_ptr+1;
read_ptr=(read_ptr==15)?0:write_ptr+1;
end
end
endcase
assign fifo_empty=(counter==0); //标志位赋值 组合电路
assign fifo_half=(counter==8);
assign fifo_full=(counter==15);
endmodule
异步FIFO实现:
module fifo1(rdata, wfull, rempty, wdata, winc, wclk, wrst_n,rinc, rclk, rrst_n);parameter DSIZE = 8; parameter ASIZE = 4;output [DSIZE-1:0] rdata;output wfull;output rempty;input [DSIZE-1:0] wdata;input winc, wclk, wrst_n;input rinc, rclk, rrst_n;reg wfull,rempty;reg [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr, wq1_rptr,rq1_wptr;reg [ASIZE:0] rbin, wbin;reg [DSIZE-1:0] mem[0:(1<<ASIZE)-1];wire [ASIZE-1:0] waddr, raddr;wire [ASIZE:0] rgraynext, rbinnext,wgraynext,wbinnext;wire rempty_val,wfull_val;//-----------------双口RAM存储器--------------------assign rdata=mem[raddr];[email protected](posedge wclk)if (winc && !wfull) mem[waddr] <= wdata;//-------------同步rptr 指针-------------------------always @(posedge wclk or negedge wrst_n)if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};//-------------同步wptr指针---------------------------always @(posedge rclk or negedge rrst_n)if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};//-------------rempty产生与raddr产生-------------------always @(posedge rclk or negedge rrst_n) // GRAYSTYLE2 pointerbeginif (!rrst_n) {rbin, rptr} <= 0;else {rbin, rptr} <= {rbinnext, rgraynext};end// Memory read-address pointer (okay to use binary to address memory)assign raddr = rbin[ASIZE-1:0];assign rbinnext = rbin + (rinc & ~rempty);assign rgraynext = (rbinnext>>1) ^ rbinnext;// FIFO empty when the next rptr == synchronized wptr or on resetassign rempty_val = (rgraynext == rq2_wptr);always @(posedge rclk or negedge rrst_n)beginif (!rrst_n) rempty <= 1‘b1;else rempty <= rempty_val;end//---------------wfull产生与waddr产生------------------------------always @(posedge wclk or negedge wrst_n) // GRAYSTYLE2 pointerif (!wrst_n) {wbin, wptr} <= 0;else {wbin, wptr} <= {wbinnext, wgraynext};// Memory write-address pointer (okay to use binary to address memory)assign waddr = wbin[ASIZE-1:0];assign wbinnext = wbin + (winc & ~wfull);assign wgraynext = (wbinnext>>1) ^ wbinnext;assign wfull_val = (wgraynext=={~wq2_rptr[ASIZE:ASIZE-1], wq2_rptr[ASIZE-2:0]}); //:ASIZE-1]always @(posedge wclk or negedge wrst_n)if (!wrst_n) wfull <= 1‘b0;else wfull <= wfull_val;endmodule
原文地址:https://www.cnblogs.com/liheng369/p/8536816.html
时间: 2024-10-08 09:04:28