設計要求:上游模塊產生的數據是8位寬, FIFO輸入輸出而是16位寬的,那么就需要將上游產生的兩個8bit數據進行拼接,湊成一個完整的16bit數據,然后再一次寫入fifo
上游模塊產生兩個信號 datat_in[7:0] 和 data_in_vld 給FIFO,在控制FIFO模塊中,將利用這兩個信號通過一定方式轉換成寫入FIFO,思路步驟如下:
(1)、將兩個8bit數據拼接一個16bit的,那么就需要一個計數器 (cnt0),對數據進行數數,數兩個,所以位寬1bit就夠 ,定義
reg [0:0] cnt0;
(2)、計數器啟動條件 (add_cnt0), 啟動條件無非就是利用data_in_vld ,當data_in_vld 有效時,立刻啟動計數器,可以畫出data_in_vld 和 add_cnt0的波形對應關系了
add_cnt0 = data_in_vld == 1;
(3)、計數器結束條件(end_cnt0),當計數器cnt0 == 2-1 時(也就是數到了2個數),就停止計數。 根據cnt0 數數情況,可以畫出end_cnt0的波形了
end_cnt0 = add_cnt0 && cnt0 == 2-1;
(4)、該考慮處理怎么處理data_in的數據了,肯定要結合 cnt0 將 數據 進行 拼接,在cnt0 == 1-1 時,就得將第一個data_in[7:0]的數據保存到data_temp[15:8]中的高八位,
在cnt0 == 2-1 時,就得將 data_in[7:0]的數據保存到data_temp[7:0]中的低八位。如下寫法
1 always @(posedge clk_in or negedge rst_n)begin 2 if(!rst_n)begin 3 data_temp <= 0; 4 end 5 else if(add_cnt0 && cnt0 == 1)begin 6 data_temp[7:0] <= data_in; 7 end 8 else if(add_cnt0 && cnt0 == 0)begin 9 data_temp[15:8] <= data_in; 10 end 11 end
可以將上面的形式轉換另外一種高級方式:
always @(posedge clk_in or negedge rst_n)begin if(!rst_n)begin data_temp <= 0; end else if(add_cnt0 && cnt0 >= 0 && cnt0 < 2)begin data_temp[DOUT_W-1 - cnt0*DIN_W -:DIN_W] = data_in; end end
data_temp[DOUT_W-1 - cnt0*DIN_W -:DIN_W] = data_temp[16-1 - cnt0*8 -:8]:
當cnt0 = 0 時,data_temp[16-1 - 0*8 -:8] = data_temp[15 -:8] 表示data_temp第15位開始,往下數8個,相當於就是datat_temp[15:8]
當cnt0 = 1 時,data_temp[16-1 - 1*8 -:8] = data_temp[7 -:8] 表示data_temp第7位開始,往下數8個,相當於就是datat_temp[7:0]
是不是立馬覺得很高級了,一行表示完,看起來代碼少了,但理解起來有點費勁,就讓人產生高級感了!!!!
根據cnt0,就可以畫出data_temp 和cnt0的對應關系了。
(4)、拼接完了,那就得考慮如何產生wrreq信號了,首先記住一個關鍵點,wrreq 和待寫入fifo的數據(data_temp[15:0])要保持在同一拍,既然要保持在同一拍,說明數據拼接好了,
就可以畫出 wrreq 和 data_temp[15:0] 的波形,如下圖,
wrreq 和 data_temp = 16'h1011 保持在同一拍,且wrreq只能保持一個時鍾周期,畫出這兩個相對應的波形。
現在波形畫的差不多了,可以看出在哪個節點 將 wrreq 拉高,也就是end_cnt0 == 1 時,將wrreq拉高,因為還要考慮一個usedw條件,所以將兩個條件一同寫上,如下代碼:
always @(posedge clk_in or negedge rst_n)begin if(!rst_n)begin wrreq <= 0; end else if(end_cnt0 && wrusedw < 61 )begin wrreq <= 1; //只保留一個時鍾周期 end else begin wrreq <= 0; end end
大概輪廓波形:
modelsim仿真波形: 在wrreq = 1 期間, data_temp = 16'h1011, 保持在同一拍,且只保留一個時鍾周期,當第一個寫完之后,可以看到q 上面已經顯示 16'h1011,說明已成功寫入fifo中