日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

fifo的rdata_同步FIFO设计

發布時間:2024/9/27 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 fifo的rdata_同步FIFO设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文從微信公眾號--數字IC小站,?轉載,歡迎關注,微信公眾號更新更多更快帶選通信號的同步FIFO(重發)?mp.weixin.qq.com

?我們常見的同步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 使用。

參考代碼如下所示:(本次僅給出SV代碼,下次給可綜合的RTL代碼,代碼僅供參考,不保證沒bug,有問題歡迎交流~)

`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

總結

以上是生活随笔為你收集整理的fifo的rdata_同步FIFO设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。