移位寄存器是一种常用的存储元件,此处由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
仿真结果如下:
来源:https://www.cnblogs.com/Maxwill-Peng/p/12227696.html