fifo的rdata 同步FIFO設計

2021-10-12 15:49:35 字數 3934 閱讀 5683

​我們常見的同步fifo一般都是固定位寬輸入,固定位寬輸出的,因此他們之間的關係一般來說都是固定的,比較容易理解,網上也有很多類似的**去指導怎麼編寫,在此不再贅述。如果突發奇想,新增乙個選通訊號wstrb呢?那麼這個世界是不是就不太一樣了呀~~

假設題目如下:

編寫**,實現如下的同步fifo功能,示意圖如下:

其中,clock為輸入時鐘;reset_n為復位訊號,低有效;valid_in為輸入有效訊號,當輸入訊號為無效訊號時,資料不寫進fifo;wstrb為選通訊號,當其為0時,輸入資料的低8位有效,當其為1時,輸入資料的低16位有效,當其為2時,輸入資料的低32位有效,當其為3時,輸入資料全部有效;data_in為輸入資料,每次資料為64位;valid_out為輸出有效訊號;ready_in為fifo狀態訊號,當為高時,證明fifo內部有足夠的空間儲存資料;data_out為輸出資料,32位寬。

上次把類似的題目給同學們作為實驗題,交上來的作業發現有很多bug,下次講講bug~

解題思路如下:

因為輸入可能是8位,也可能是16位,32位,64位有效,而輸出永遠都是32位的,那麼我們把fifo寬度定義為8位,深度定義為32位。從實際情況出發,假設每當資料儲存大於24byte時,傳送ready_in為0訊號;每當fifo中資料大於4byte時,就立即取出;每個時鐘儲存的資料,至少等待乙個時鐘週期才能取出,不能同時刻取出...

最簡單的方法是使用sv編寫,因為sv中有quene,完美解決了verilog需要讀寫指標或者計數器等問題,請注意,這種寫法是不可綜合的,可作為testbench中的reference model 使用。

`timescale 1ns / 100ps

// author:sjtu_chen

// date: 2019/10/26

// version: v1.0

// module name: fifo-systemverilog

// project name: systemverilog lab1

module fifo_ref(

clock, reset_n, valid_in,wstrb,data_in,valid_out,ready_in,data_out

input clock;

input reset_n;

input valid_in;

input [1:0] wstrb;

input [63:0] data_in;

output [31:0] data_out;

output valid_out;

output ready_in;

logic [31:0] data_out;

logic valid_out;

logic ready_in;

logic [7:0] stack [$];

always@(posedge clock or negedge reset_n)

begin

if(!reset_n)

begin

stack.delete();

endelse if (valid_in&&ready_in) begin

ca*** (wstrb)

2'b00:

begin

stack.push_back(data_in[7:0]);

end2'b01:

begin

stack.push_back(data_in[7:0]);

stack.push_back(data_in[15:8]);

end2'b10:

begin

stack.push_back(data_in[7:0]);

stack.push_back(data_in[15:8]);

stack.push_back(data_in[23:16]);

stack.push_back(data_in[31:24]);

end2'b11:

begin

stack.push_back(data_in[7:0]);

stack.push_back(data_in[15:8]);

stack.push_back(data_in[23:16]);

stack.push_back(data_in[31:24]);

stack.push_back(data_in[39:32]);

stack.push_back(data_in[47:40]);

stack.push_back(data_in[55:48]);

stack.push_back(data_in[63:56]);

endendcase

endend

always@(posedge clock or negedge reset_n)

begin

if(!reset_n)

begin

data_out <=32'b0;

valid_out <='0;

endelse if(wstrb==3&&valid_in==1&&stack.size>11)

fork

valid_out <= '1;

begin

data_out[7:0] =stack.pop_front;

data_out[15:8] =stack.pop_front;

data_out[23:16]=stack.pop_front;

data_out[31:24]=stack.pop_front;

endjoin

else if(wstrb==2&&valid_in==1&&stack.size>7)

fork

valid_out <= '1;

begin

data_out[7:0] =stack.pop_front;

data_out[15:8] =stack.pop_front;

data_out[23:16]=stack.pop_front;

data_out[31:24]=stack.pop_front;

endjoin

else if(wstrb==1&&valid_in==1&&stack.size>5)

fork

valid_out <= '1;

begin

data_out[7:0] =stack.pop_front;

data_out[15:8] =stack.pop_front;

data_out[23:16]=stack.pop_front;

data_out[31:24]=stack.pop_front;

endjoin

else if(wstrb==0&&valid_in==1&&stack.size>4)

fork

valid_out <= '1;

begin

data_out[7:0] =stack.pop_front;

data_out[15:8] =stack.pop_front;

data_out[23:16]=stack.pop_front;

data_out[31:24]=stack.pop_front;

endjoin

else if(valid_in==0&&stack.size>=4)

fork

valid_out <= '1;

begin

data_out[7:0] =stack.pop_front;

data_out[15:8] =stack.pop_front;

data_out[23:16]=stack.pop_front;

data_out[31:24]=stack.pop_front;

endjoin

else

begin

valid_out <='0;

endend

assign ready_in=(stack.size<=24);

endmodule

同步fifo的串並 同步fifo設計

1.同步fifo的功能點 當fifo寫滿的時候,輸出滿標誌.當fifo讀空的時候,輸出空標誌.寫滿之後不能繼續寫,即有滿標誌,禁止向ram寫入資料,防止資料混亂.讀空之後不能繼續讀,讀完所有資料,禁止重複讀.對於空滿標誌的判斷,設計的思想是,當讀指標等於寫指標加1,且同時有乙個寫使能,這樣,就認為f...

mysql批量控制項fifo檔案 檔案 FIFO佇列

filefifo.php 檔案型fifo佇列 classfilefifo file data,資料檔案的路徑 private file data file idx,索引檔案的路徑 private file idx file idx bak,索引備份檔案的路徑,防止意外斷電等導致索引檔案破壞 priv...

非同步fifo 同步FIFO設計實現

在學習跨時鐘域處理的時候,有一種方法是用非同步fifo來處理跨時鐘域處理的。那麼在這之前先看看同步fifo實現。所謂同步fifo,就是讀寫時鐘是同乙個時鐘頻率。本次實現是通過計數器的形式來實現滿空標誌。具體實現如下 module fifo sync input clk input rst n inp...