移位寄存器与串并转换
实验目的:
(1)用位拼接操作符实现移位寄存器(注意区分左移与右移);
(2)利用移位寄存器实现串—并转换,从当前工程的根目录下的data.txt文本中读取数据,作为串—并转换器的输入比特流,然后将这些串行输入的比特流转换为每组有8bit的数据;
(3)学会使用文件控制任务$readmemb,完成存储器变量(寄存器组)的初始化;
(4)学会写Modelsim脚本测试文件,并掌握测试脚本常用的命令及仿真方法。
实验内容及过程:
(1)用位拼接符实现移位寄存器(data_in是输入的位宽为1bit的信号,shift_reg是位宽为8bit的输出变量)
【右移操作】
思想:将每次输入的data_in放到shift_reg的最高位,同时去掉shift_reg的最低位,然后达到向右移位的效果。
shift_reg <= {data_in, shift_reg[7:1]};
//过程枚举:
//第1个时钟周期:(data_in_1,0000000)
//第2个时钟周期:(data_in_2,data_in_1,000000)
//......
//第8个时钟周期:(data_in_8,data_in_7,data_in_6,data_in_5,data_in_4,data_in_3,data_in_2,data_in_1)
【左移操作】
思想:将每次输入的data_in放到shift_reg的最低位,同时去掉shift_reg的最高位,然后达到向左移位的效果。
shift_reg <= {shift_reg[6:0], data_in};
//过程枚举:
//第1个时钟周期:(0000000,data_in_1)
//第2个时钟周期:(000000,data_in_1,data_in_2)
//......
//第8个时钟周期:(data_in_1,data_in_2,data_in_3,data_in_4,data_in_5,data_in_6,data_in_7,data_in_8)
(2)串—并转换
串—并转换是在移位寄存器的基础上实现的,将输入的串行数据data_in按照每8bit为一组的形式“组装”成新的并行数据。具体而言,就是将data_in输入的比特流一位一位地(逐位)送入移位寄存器,然后,串—并转换器每8个时钟周期读取一次移位寄存器输出端的数据(在这里也就是读shift_reg的值,8个时钟周期的控制由计数器完成),并将数据按照并行8bit的形式输出。
本实验应采用哪种移位操作方式呢?根据串行输入“先传低位,后传高位”的一般规则,故本实验需采用右移操作的方式,将最先送进来的比特放在shift_reg的最低位,然后依次按照“由低位至高位”的方式依次存放各比特。实验代码截图如下所示:
Testbench代码如下:
【文件控制任务$readmemb】
$readmemb是专门用作读取文本文件中的二进制数据,并用这些数据初始化存储器变量(寄存器组),如:testbench代码中的$readmemb("./data.txt", mem1x16)语句,它将是用来读取当前modelsim工程根目录下的data.txt中的数据(数据内容见图1所示),然后将这些值赋给mem1x16(它是一个有16个1位位宽的寄存器组)。
说明:上面的./data.txt是相对路径,$readmemb还可以使用绝对路径。
图1 data.txt中的数据
(3)测试脚本的书写
对比传统的鼠标点击方式和使用测试脚本运行仿真,后者较前者更加快速和便捷,在提高调试代码的效率的同时,提高了仿真的准确性,避免了鼠标点击时易点错或者漏添加文件的现象。总之,使用测试脚本的方式更方便、快捷、高效。
注意:用测试脚本仿真也要先建工程,建完工程就不用管了(不用手动添加文件、编译文件等)。
① #号是注释符;
② quit –sim命令是退出当前仿真(终止仿真过程,关闭仿真窗口,但不关闭当前工程),.main clear命令是清除命令行显示窗口中的内容;
③ 本实验的测试脚本内容如下:
#退出当前仿真
quit -sim
#清除命令行显示窗口的内容
.main clear
#创建库lib(就是在当前工程根目录下创建文件夹)
vlib lib
vlib ./lib/work
#将work逻辑库映射到实际的文件路径上来
vmap work ./lib/work
#也可以采用以下的简单用法
# vmap work work
# 因为新建仿真工程的时候就自动生成了work库和work文件夹,所以只需要做简单的映射即可
#编译(第2个work是逻辑库的名字,./是当前目录,../是上一目录)
vlog -work work ./tb_ex_shift_reg.v
vlog -work work ./../design/ex_shift_reg.v
#方法二--用通配符,编译design文件夹中的所有.v文件(避免反复添加)
vlog -work work ./../design/*.v
#启动仿真(-voptargs=+acc是编译参数,决定是否优化)
vsim -voptargs=+acc work.tb_ex_shift_reg
#不带优化的仿真
# vsim -novopt work.tb_ex_shift_reg
#添加波形(tb_ex_shift_reg是模块名,data_in是该模块的信号)
add wave tb_ex_shift_reg/data_in
add wave tb_ex_shift_reg/data_out
add wave tb_ex_shift_reg/sclk
add wave tb_ex_shift_reg/rst_n
add wave tb_ex_shift_reg/mem1x16
#添加例化模块的信号(ex_shift_reg_inst是例化的模块名)
add wave tb_ex_shift_reg/ex_shift_reg_inst/*
run 1us
仿真波形图如图2所示:
图2 仿真波形图
由图2可知,串—并转换后的数据通过data_out输出,先输出的是01010101(0x55),后输出的是00010001(0x11),这与data.txt中的数据是一致的——data.txt中的存放顺序是1010101010001000,经过串—并转换后,变为了0101010100010001,因“低位先传,高位后传”的原因发生了逆序,但仿真结果与我们的设计初衷是一致的,故仿真验证通过。
文章评论(0条评论)
登录后参与讨论