fifo的rdata_同步FIFO设计
本文從微信公眾號(hào)--數(shù)字IC小站,?轉(zhuǎn)載,歡迎關(guān)注,微信公眾號(hào)更新更多更快帶選通信號(hào)的同步FIFO(重發(fā))?mp.weixin.qq.com
?我們常見(jiàn)的同步FIFO一般都是固定位寬輸入,固定位寬輸出的,因此他們之間的關(guān)系一般來(lái)說(shuō)都是固定的,比較容易理解,網(wǎng)上也有很多類似的代碼去指導(dǎo)怎么編寫,在此不再贅述。如果突發(fā)奇想,添加一個(gè)選通信號(hào)wstrb呢?那么這個(gè)世界是不是就不太一樣了呀~~
假設(shè)題目如下:
編寫代碼,實(shí)現(xiàn)如下的同步FIFO功能,示意圖如下:
其中,clock為輸入時(shí)鐘;reset_n為復(fù)位信號(hào),低有效;valid_in為輸入有效信號(hào),當(dāng)輸入信號(hào)為無(wú)效信號(hào)時(shí),數(shù)據(jù)不寫進(jìn)FIFO;wstrb為選通信號(hào),當(dāng)其為0時(shí),輸入數(shù)據(jù)的低8位有效,當(dāng)其為1時(shí),輸入數(shù)據(jù)的低16位有效,當(dāng)其為2時(shí),輸入數(shù)據(jù)的低32位有效,當(dāng)其為3時(shí),輸入數(shù)據(jù)全部有效;data_in為輸入數(shù)據(jù),每次數(shù)據(jù)為64位;valid_out為輸出有效信號(hào);ready_in為FIFO狀態(tài)信號(hào),當(dāng)為高時(shí),證明FIFO內(nèi)部有足夠的空間存儲(chǔ)數(shù)據(jù);data_out為輸出數(shù)據(jù),32位寬。
上次把類似的題目給同學(xué)們作為實(shí)驗(yàn)題,交上來(lái)的作業(yè)發(fā)現(xiàn)有很多bug,下次講講bug~
解題思路如下:
因?yàn)檩斎肟赡苁?位,也可能是16位,32位,64位有效,而輸出永遠(yuǎn)都是32位的,那么我們把fifo寬度定義為8位,深度定義為32位。從實(shí)際情況出發(fā),假設(shè)每當(dāng)數(shù)據(jù)存儲(chǔ)大于24byte時(shí),發(fā)送ready_in為0信號(hào);每當(dāng)fifo中數(shù)據(jù)大于4byte時(shí),就立即取出;每個(gè)時(shí)鐘存儲(chǔ)的數(shù)據(jù),至少等待一個(gè)時(shí)鐘周期才能取出,不能同時(shí)刻取出...
最簡(jiǎn)單的方法是使用sv編寫,因?yàn)閟v中有quene,完美解決了Verilog需要讀寫指針或者計(jì)數(shù)器等問(wèn)題,請(qǐng)注意,這種寫法是不可綜合的,可作為Testbench中的reference model 使用。
參考代碼如下所示:(本次僅給出SV代碼,下次給可綜合的RTL代碼,代碼僅供參考,不保證沒(méi)bug,有問(wèn)題歡迎交流~)
`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();
end
else if (valid_in&&ready_in) begin
casex (wstrb)
2'b00:
begin
stack.push_back(data_in[7:0]);
end
?
2'b01:
begin
stack.push_back(data_in[7:0]);
stack.push_back(data_in[15:8]);
end
?
2'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]);
end
?
2'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]);
end
endcase
end
end
?
always@(posedge clock or negedge reset_n)
begin
if(!reset_n)
begin
data_out <=32'b0;
valid_out <='0;
end
else 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;
end
join
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;
end
join
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;
end
join
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;
end
join
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;
end
join
else
begin
valid_out <='0;
end
end
?
assign ready_in=(stack.size<=24);
endmodule
總結(jié)
以上是生活随笔為你收集整理的fifo的rdata_同步FIFO设计的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 工行无介质白金信用卡是什么意思
- 下一篇: jenkins shell 权限_jen