04 4bit移位寄存器设计与功能验证(附源码)
寫在前面,4位右移移位寄存器,顧名思義使用四個觸發器級聯,從一次輸入到輸出,只移動了3位,而不是4位。比如輸入是1101,輸出時為0001,而不是0000。
虛擬機:VMware -14.0.0.24051
環?境:ubuntu 18.04.1
腳?本:makefile(點擊直達)
應用工具:vcs 和 verdi
文章目錄
- 一、Overview
- (1)Theory
- (2)Demand
- 二、Interface
- 三、Timeing
- 四、Design and Functional Verification
- (1)RTL
- (2)Test Bench
- 五、Result
- (1)行為級描述測試結果
- (2)結構級描述測試結果
- (3)bug分析
一、Overview
(1)Theory
-
行為級描述
-
結構級描述
??移位寄存器可以存儲數據,還可以用來實現數據的串并轉換、分頻,構成序列碼發生器、序列碼檢測器等;上圖是4位右移寄存器原理圖,依據移位寄存器的特點,移位寄存器在時鐘的控制下,可將輸入數據依次往后移動,N個寄存器級聯,最后輸出的數據是輸入數據的右移N-1位。其中,左邊的空位會被補0。其中QD是串行輸出端,{QA,QB,QC,QD}可實現并行輸出,如果將輸出端QD接到輸入端QI,則可以實現自循環移位寄存器。
(2)Demand
二、Interface
| clk | 1 | input | System clk signal, xxMhz |
| rst | 1 | input | System reset signal |
| data | 1 | input | Detected data |
| result | 1 | output | Detection result signal |
三、Timeing
四、Design and Functional Verification
(1)RTL
//行為級描述 //-- modified by xlinxdu, 2022/04/27 module shift(input clk_i ,input rst_n_i,input data_i ,output reg [3:0] out_o ); reg [3:0] out_s;always @ (posedge clk_i or negedge rst_n_i)beginif(!rst_n_i)beginout_s <= 4'b0;endelse beginout_s <= {out_s[2:0],data_i};end endalways @ (posedge clk_i or negedge rst_n_i)beginif(!rst_n_i)beginout_o <= 4'b0;endelse beginout_o <= (out_s >> 3);end endendmodule //結構級描述 //-- modified by xlinxdu, 2022/04/27 module shift(input clk_i ,input rst_n_i ,input data_i ,output reg [3:0] result_o,output reg [3:0] out_o ); reg [2:0] cnt; reg QA,QB,QC,QD;always @ (posedge clk_i or negedge rst_n_i)beginif(!rst_n_i) begincnt <= 2'b0;QA <= 1'b0;QB <= 1'b0;QC <= 1'b0;QD <= 1'b0;result_o <= 4'b0;endelse beginQA <= data_i;QB <= QA;QC <= QB;QD <= QC;result_o <= {QD,QC,QB,QA};end endalways @ (posedge clk_i or negedge rst_n_i)beginif(!rst_n_i) beginout_o <= 4'b0;endelse beginout_o <= {out_o[2:0],QD};end end endmodule(2)Test Bench
//行為級描述測試平臺 //-- modified by xlinxdu, 2022/04/27 module tb_shift;reg clk_i;reg rst_n_i;reg data_i; // wire [3:0] result_o;wire [3:0] out_o;initial beginclk_i = 0;rst_n_i = 1;data_i = 0;#10 rst_n_i = 0;#10;rst_n_i = 1; endalways #50 clk_i = ~clk_i; always begin #100 data_i = 1; #100 data_i = 1; #100 data_i = 0; #100 data_i = 1; #100; end shift tb_shift(.clk_i(clk_i),.rst_n_i(rst_n_i),.data_i(data_i), // .result_o(result_o),.out_o(out_o));initial begin$fsdbDumpfile("shift.fsdb");$fsdbDumpvars ;$fsdbDumpMDA ;#1000 $finish ; end endmodule //結構描述測試平臺 //-- modified by xlinxdu, 2022/04/27 module tb_shift;reg clk_i;reg rst_n_i;reg data_i;wire [3:0] result_o;wire [3:0] out_o;initial beginclk_i = 0;rst_n_i = 1;data_i = 0;#10 rst_n_i = 0;#10;rst_n_i = 1; endalways #50 clk_i = ~clk_i; always begin #100 data_i = 1; #100 data_i = 1; #100 data_i = 0; #100 data_i = 1; #100; end shift tb_shift(.clk_i(clk_i),.rst_n_i(rst_n_i),.data_i(data_i),.result_o(result_o),.out_o(out_o));initial begin$fsdbDumpfile("shift.fsdb");$fsdbDumpvars ;$fsdbDumpMDA ;#1000 $finish ; end endmodule五、Result
(1)行為級描述測試結果
(2)結構級描述測試結果
分析:
??在行為級描述過程中,輸出只與輸入有關,每次只會操作就近的四位數據,之外的數據會被丟棄掉,四位內左側補0,因為每次只有四位數據被賦值到中間變量out_s造成下一次的時候,四位以外的數據丟失了,數據不符合實際電路產生的值(bug)。
??在結構級描述過程中,輸出與result_o是4位寄存器的并輸出端,out_o是移位后數據的輸出端,其中輸出的值需要看該時刻前面的完整的輸入值。比如剛開始的時候,串行輸入值為0110時,移位輸出值為0000;串行輸入值為01101時,移位輸出值為0001;串行輸入值為0110111時,移位輸出值為0110,,依次類推,每來一個時鐘,數據右移一位輸出。
(3)bug分析
??針對上述情況,分析產生數據丟失的是因為中間的緩存變量每次只緩存4bit數據,而在四位移位寄存器中,要保證數據不被截取掉,至少保證數據位寬為7(移動的3bit+4bit數據)。見下表:
| a | 000a | 0000 | 000_000a | 0000 | |
| b | 00ab | 0000 | 000_00ab | 0000 | |
| c | 0abc | 0000 | 000_0abc | 0000 | |
| d | abcd | 000a | 000_abcd | 000a | |
| e | bcde | 000b | 00a_bcde | 00ab | |
| f | cdef | 000c | 0ab_cdef | 0abc | |
| g | defg | 000d | abc_defg | abcd | |
| h | efgh | 000h | bcd_efgh | bcde |
- 更正后的測試波形與結構描述的一一致。
作者:xlinxdu
版權:本文是作者原創,版權歸作者所有。
轉載:未經作者允許,禁止轉載,轉載必須保留此段聲明,必須在文章中給出原文連接。
總結
以上是生活随笔為你收集整理的04 4bit移位寄存器设计与功能验证(附源码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Minecraft群组服开服
- 下一篇: 美学心得(第二百四十二集) 罗国正