用移位寄存器實現(xiàn)同步FIFO
????????如圖所示,同步FIFO帶有push信號和pop信號,push代表往隊列里面壓入一個數(shù)據(jù),pop代表往隊列外面排出一個數(shù)據(jù)。
?解題思路
? ? ? ? 同步FIFO的空滿判斷用一個計數(shù)器來判斷,收到push信號計數(shù)器加1,收到pop信號時計數(shù)器減1,考慮同時push和pop的情況計數(shù)器不變,當(dāng)計數(shù)器為0時,輸出空,當(dāng)計數(shù)器為DEPTH時,輸出滿。FIFO給出空滿信號,空時不能讀,滿時不能寫。具體代碼如下:
always @(posedge clk)begin
if(!rstn)
counter <= 'd0;
else if(push && pop)
counter <= counter;
else if(push)
counter <= counter + 1'b1;
else if(pop)
counter <= counter - 1'b1;
end
assign empty = (counter == 'd0);
assign full = (counter == DEPTH);
? ? ? ? ?數(shù)據(jù)的寫入和讀出,push數(shù)據(jù)就直接在移位寄存器的一端,用拼接符號把數(shù)據(jù)拼接在一起。pop數(shù)據(jù)輸出DEPTH-counter位置的數(shù)據(jù),因為我們位拼接是從高位開始拼接的,要注意讀出的地址位置。
always @(posedge clk)begin
if(!rstn)
pop_data <= 'd;
else if(push && pop)begin
fifo_mem <= {push_data,fifo_mem[DEPTH-1:1]};
pop_data <= fifo_mem[DEPTH-counter];
end
else if(push)begin
fifo_mem <= {push_data,fifo_mem[DEPTH-1:1]};
end
else if(pop)begin
pop_data <= fifo_mem[DEPTH-counter];
end
end
代碼
module shift_reg_fifo#(
parameter DEPTH = 8 ,
parameter DATA_W = 32
)(
input clk ,
input rstn ,
output empty ,
output full ,
input push ,
input [DATA_W-1:0] push_data ,
input pop ,
output reg [DATA_W-1:0] pop_data
);
reg [DATA_W-1:0] fifo_mem [DEPTH-1:0];
reg [$clog2(DEPTH)+1:0] counter;
always @(posedge clk)begin
if(!rstn)
pop_data <= 'd;
else if(push && pop)begin
fifo_mem <= {push_data,fifo_mem[DEPTH-1:1]};
pop_data <= fifo_mem[DEPTH-counter];
end
else if(push)begin
fifo_mem <= {push_data,fifo_mem[DEPTH-1:1]};
end
else if(pop)begin
pop_data <= fifo_mem[DEPTH-counter];
end
end
always @(posedge clk)begin
if(!rstn)
counter <= 'd0;
else if(push && pop)
counter <= counter;
else if(push)
counter <= counter + 1'b1;
else if(pop)
counter <= counter - 1'b1;
end
assign empty = (counter == 'd0);
assign full = (counter == DEPTH);
endmodule
testbench
`timescale 1ns/1ps
module tb#(
parameter DEPTH = 8 ,
parameter DATA_W = 32
)();
reg clk,rstn;
wire empty,full;
wire [DATA_W-1:0] pop_data;
reg push,pop;
reg [DATA_W-1:0] push_data;
initial begin
forever #5 clk = ~clk;
end
initial begin
clk = 1'b0;
rstn = 1'b0;
pop = 1'b0;
push = 1'b0;
push_data = 32'd0;
#10
rstn = 1'b1;
#16
repeat(8)begin
#10
push = 1'b1;
push_data = $random%32;
end
#10
push = 1'b0;
repeat(8)begin
#10
pop = 1'b1;
end
#10
pop = 1'b0;
repeat(3)begin
#10
pop = 1'b0;
push = 1'b1;
push_data = $random() % 10'd32;
#10
push = 1'b0;
pop = 1'b1;
end
#10
pop = 1'b0;
push = 1'b1;
push_data = $random() % 10'd32;
repeat(4)begin
#10
pop = 1'b1;
push = 1'b1;
push_data = $random() % 10'd32;
end
#10
pop = 1'b0;
push = 1'b0;
#50
$finish();
end
initial begin
$fsdbDumpfile("shift_fifo.fsdb");
$fsdbDumpvars(0);
end
shift_reg_fifo #(
.DEPTH (DEPTH ),
.DATA_W (DATA_W )
)u_shift_reg_fifo(
.clk (clk ),
.rstn (rstn ),
.empty (empty ),
.full (full ),
.push (push ),
.push_data (push_data ),
.pop (pop ),
.pop_data (pop_data )
);
endmodule
? ? ? ? 仿真部分,在深度為8的情況下,我們分別模擬了寫入8個數(shù)據(jù)到寫滿,讀出8個數(shù)據(jù)直到讀空,接著連續(xù)寫讀3次,然后寫入1個數(shù)據(jù)(保證下一步同時讀寫時,F(xiàn)IFO不為空,能讀出數(shù)據(jù))。再同時讀寫4次。
波形圖
文章來源:http://www.zghlxwxcb.cn/news/detail-630049.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-630049.html
到了這里,關(guān)于用移位寄存器實現(xiàn)同步FIFO,帶空滿判斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!