移位寄存器是一種常用的存儲元件,此處由D觸發器構成,如下圖所示。
當時鍾邊沿到來時,存儲在移位寄存器的數據朝一個方向移動一個BIT位。
移位寄存器的功能主要為:串並轉換,並串轉換和同步延遲。

vhdl代碼如下:
1 library ieee; 2 use ieee.std_logic_1164.all; 3 4 entity shiftreg_rb is --實體說明及端口說明 5 port( 6 si,clr_bar,clk:in std_logic; 7 qout:buffer std_logic_vector(3 downto 0)--由於qout端口既是當前D觸發器的輸入也是上一個D觸發器的輸出。 8 ); --即qout信號是被驅動源驅動的同時還要驅動下一個端口。 9 end entity shiftreg_rb; --此情況下要使用buffer模式的端口。 10 11 architecture behavior of shiftreg_rb is 12 begin 13 process (clk) ---當時鍾發生變化(上升沿或下降沿發生),執行進程 14 begin 15 if clk='1' then --時鍾上升沿觸發 16 if clr_bar = '0' then --時鍾使能 17 qout <= "0000"; 18 else 19 qout(0) <=qout(1);--數據左移 20 qout(1) <=qout(2); 21 qout(2) <=qout(3); 22 qout(3) <=si; 23 end if; 24 end if; 25 end process; 26 end behavior;
Testbench編寫:
1 LIBRARY IEEE; 2 USE IEEE.std_logic_1164.all; 3 USE IEEE.NUMERIC_STD.ALL; 4 USE IEEE.MATH_REAL.ALL; 5 USE IEEE.STD_LOGIC_UNSIGNED.ALL; 6 USE IEEE.STD_LOGIC_ARITH.ALL;--因為將INTEGER型數據轉換成STD_LOGIC_VECTOR需要使用CONV_STD_LOGIC_VECTOR命令。 7 --而此命令在IEEE.STD_LOGIC_ARITH.ALL中。 8 9 ENTITY shiftreg_tb IS --testbench實體聲明,由於testbench位最高層模塊,因此無輸入輸出端口。 10 END shiftreg_tb; 11 12 ARCHITECTURE testbench OF shiftreg_tb IS 13 COMPONENT shiftreg_rb IS --例化子模塊(元件)前,需進行子模塊(元件)聲明 14 port( 15 si,clr_bar,clk:in std_logic; 16 qout:buffer std_logic_vector(3 downto 0) 17 ); 18 END COMPONENT; 19 SIGNAL si,clk:STD_LOGIC; --信號聲明,為元件例化時所用 20 SIGNAL clr_bar:STD_LOGIC:='1'; --信號聲明,為元件例化時所用 21 SIGNAL qout:STD_LOGIC_VECTOR(3 downto 0); 22 SIGNAL temp1:INTEGER range 0 to 15; --將產生的偽隨機數轉化為整數型數值temp1 23 SIGNAL temp2:STD_LOGIC_VECTOR(3 DOWNTO 0); --將temp1轉化邏輯位矢量temp2 24 SIGNAL count1:STD_LOGIC_VECTOR (0 to 3):="0100";--計數信號 25 CONSTANT clk_period :time:=50 ns; --時鍾信號 26 27 28 BEGIN 29 U_shiftreg_rb:shiftreg_rb PORT MAP( --UUT(被測元件shiftreg_rb)的例化 30 si=>si, 31 clr_bar=>clr_bar, 32 clk=>clk, 33 qout=>qout 34 ); 35 36 PROCESS 37 VARIABLE seed1,seed2:POSITIVE; --偽隨機數生成格式 種子seed1,seed2位positive型的,默認位1,改變種子的值會生成不同的隨機數 38 VARIABLE rand:REAL; --偽隨機數生成格式 rand必須為real型數值 39 BEGIN 40 IF count1="0100" THEN --每個200ns產生一次隨機數 41 UNIFORM(seed1,seed2,rand); 42 temp1 <= INTEGER(TRUNC(rand*15.0)); --生成的隨機數范圍在0~15,且把生成的實數型隨機數轉化為整型。 43 temp2 <=CONV_STD_LOGIC_VECTOR(temp1,4);--由於沒找到直接將整數型轉化為標准邏輯型(STD_LOGIC)的命令,所以先將整型隨機數轉化為標准邏輯矢量型 44 --** 此處要注意,要實現移位寄存器的並轉串模式,不能將隨機數信號直接加再qout上,因為buffer型端口的驅動源只來自其內部。 45 --** 不過可以將qout改成inout類型試試,不過目前沒成功。還一種方法是將多位信號分別加在D觸發器的輸入端口,這種方法肯定可行。 46 47 si <= temp2(0); --再將temp2的最低位賦值給移位寄存器的輸入si,這樣也可以產生一個隨機的輸入信號si。 48 count1 <= "0000"; 49 END IF; 50 WAIT FOR(clk_period/2); --使clk時鍾信號周期為25ns 51 clk <= '1'; 52 count1<= count1 +'1'; 53 WAIT FOR(clk_period/2); 54 clk <= '0'; 55 56 END PROCESS; 57 END testbench;
自動仿真.do文件的編寫
quit -sim #退出仿真 .main clear #清空命令框 vlib ./lib #在.do文件所在目錄創建名為lib的文件夾 vlib ./lib/work #在lib文件夾里創建名為work的文件夾 vmap work ./lib/work #將物理文件地址./lib/work映射到邏輯工作庫work vcom -work work ./shiftreg_tb.vhd #編譯vhdl文件,且將編譯結果放在邏輯庫work中 vcom -work work ./../design/*.vhd #編譯vhdl文件,且將編譯結果放在邏輯庫work中 vsim -voptargs=+acc work.shiftreg_tb #不帶優化的啟動modelsim仿真 add wave -divider {shiftreg_tb} #添加測試列表名 add wave shiftreg_tb/clk #添加待測信號 add wave shiftreg_tb/si add wave shiftreg_tb/clr_bar add wave shiftreg_tb/count1 add wave shiftreg_tb/temp1 add wave shiftreg_tb/temp2 add wave shiftreg_tb/qout add wave -divider {U_shiftreg_tb} add wave shiftreg_tb/U_shiftreg_rb/* run 1us #仿真運行1us
編寫好自動測試文件后,將其與測試平台shiftreg_tb.vhd文件放在一個文件名sim下。
打開modelsim,輸入命令 do run.do
仿真結果如下:

