我們常見的同步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...