移位寄存器的设计(VHDL)及testbench的编写

Posted maxwill-peng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了移位寄存器的设计(VHDL)及testbench的编写相关的知识,希望对你有一定的参考价值。

移位寄存器是一种常用的存储元件,此处由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

仿真结果如下:

技术图片

以上是关于移位寄存器的设计(VHDL)及testbench的编写的主要内容,如果未能解决你的问题,请参考以下文章

自定义移位寄存器模块

自定义移位寄存器模块

移位寄存器的 IP核调取及应用

如何编写testbench的总结

vhdl中怎么实现多行注释掉,就是暂时不用那一块

移位寄存器及verilog代码