电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

第4讲 移位寄存器与串并转换

移位寄存器与串并转换

实验目的

(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,因“低位先传,高位后传”的原因发生了逆序,但仿真结果与我们的设计初衷是一致的,故仿真验证通过。

博主
271030191@qq.com
三爷重修FPGA之路
两年前开始接触FPGA,后来零零散散、断断续续学了一部分内容,总感觉缺乏系统和专业的训练。从现在开始,我愿意与诸位博友一道共同学习FPGA,相互学习、共同进步。加油~
点击跳转