第 3 章 数字逻辑电路设计基础
【本章学习目标】
- 复习设计CPU必须掌握的数字逻辑电路和Verilog描述的知识。
- 理解同步RAM和异步RAM的区别及其时序行为。
- 初步掌握进行数字逻辑电路功能仿真时常见的错误及其调试方法。
3.1 任务与实践
完成本章的学习后,读者应完成以下三个实践任务:
3.1.1 实践任务2:寄存器堆仿真
本实践任务要求:
- 对一个寄存器堆设计进行功能仿真,通过观察其仿真波形了解行为特征。
实验环境中提供的寄存器堆源码为“两读一写”的结构,也就是有两个读端口(读端口没有使能位控制,表示永远使能)和一个写端口。接口信号如表3.1所示。
名称 | 宽度 | 方向 | 描述 |
clk | 1 | input | 时钟信号 |
raddr1 | 5 | input | 寄存器堆读地址1 |
rdata1 | 32 | output | 寄存器堆读返回数据1 |
raddr2 | 5 | input | 寄存器堆读地址2 |
rdata2 | 32 | output | 寄存器堆读返回数据2 |
we | 1 | input | 寄存器堆写使能 |
waddr | 5 | input | 寄存器堆写使能 |
wdata | 32 | input | 寄存器堆写数据 |
请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境位于 dc_env/exp2/ 目录下,其目录结构如下:
|--regfile.v 寄存器堆源码文件。
|--rf_tb.v 寄存器堆仿真文件。
建议参考下列步骤完成本实践任务:
- 使用Vivado新建一个工程。
- 点击“Add Sources”,选择添加设计源码(design sources),加入regfile.v。
- 点击“Add Sources”,选择添加仿真源码(simulation sources),加入rf_tb.v。
- 对工程进行仿真测试,结合波形观察寄存器堆的读写行为。
3.1.2 实践任务3:同步RAM和异步RAM仿真、综合与实现
本实践任务要求:
- 调用Xilinx库IP实例化一个同步RAM,进行仿真以观察行为,进行综合和实现后查看时序结果和资源利用率。
- 调用Xilinx库IP实例化一个异步RAM,进行仿真以观察行为,进行综合和实现后查看时序结果和资源利用率。
- 对观察到的现象进行对比分析。
请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境位于 dc_env/exp3/ 目录下,其目录结构如下:
|--block_ram_top.v 同步RAM(Block RAM)的源码顶层文件。
|--distributed_ram_top.v 异步RAM(Distributed RAM)的源码顶层文件。
|--ram.xdc 两种RAM的仿真约束文件,用于综合和实现。
|--ram_tb.v 两种RAM的仿真文件,用于仿真。
实验环境提供的设计顶层文件用于将两种类型的RAM封装成相同的模块名和接口。封装后的RAM顶层接口信号如表3.2所示。
名称 | 宽度 | 方向 | 描述 |
clk | 1 | Input | 时钟信号 |
ram_wen | 1 | Input | RAM的写使能信号:为1表示写入操作,为0表示读取操作 |
ram_addr | 16 | Input | RAM的地址信号,读和写的地址都由该信号指示 |
ram_wdata | 32 | Input | RAM写入的数据 |
ram_rdata | 32 | Output | RAM读出的数据 |
注意:包封后的RAM接口没有片选信号,即片选使能始终有效(其内部实例化的具体RAM的片选使能信号恒为1)。
建立同步RAM工程的参考步骤如下:
- 使用Vivado新建一个工程。
- 点击“Add Sources”,选择添加设计源码(design sources),加入block_ram_top.v。
- 点击“Add Sources”,选择添加约束文件(constraints),加入ram.xdc。
- 点击“Add Sources”,选择添加仿真源码(simulation sources),加入ram_tb.v。
- 参考附录D第D.1节,调用Xilinx库IP生成同步RAM(Block RAM,深度为65536,宽度为32,片选使能信号设为一直有效)。
建立异步RAM工程的参考步骤如下:
- 使用Vivado新建一个工程。
- 点击“Add Sources”,选择添加设计源码(design sources),加入distributed_ram_top.v。
- 点击“Add Sources”,选择添加约束文件(constraints),加入ram.xdc。
- 点击“Add Sources”,选择添加仿真源码(simulation sources),加入ram_tb.v。
- 参考附录D第D.1节,调用Xilinx库IP生成异步RAM(Distributed RAM,深度为65536,宽度为32)。
在完成工程的创建后,对它们进行仿真,对比读写行为的异同。在完成工程的仿真后,对它们进行综合和实现,参考附录D第D.1节介绍的方法查看时序结果和资源利用率,并结合读写时序进行分析。
在实践过程中,应特别注意以下几点:
- 生成IP时,请将对应IP命名为block_ram和distributed_ram,如命名错误,IP将会报错。若遇到已生成IP无法改名的情况,可以删除该IP,重新生成。
- 生成IP时,可以点击窗口左侧的图查看接口信息。当参数正确时,端口名和宽度应与指定的顶层文件中的调用相对应。
- 有兴趣的读者可以自行调研、参考同步/异步RAM定制的资料,并根据仿真波形对比参数的作用。
- 对程序进行综合之前请确保已正确加载约束文件(ram.xdc)。
- 添加testbench时请注意选择add simulation source,否则会导致顶层文件错误,综合结果不正确。
- 对程序进行综合时,所用的计算机不同,综合时间会有一定的差异,有可能会耗费大量时间,所以应提前计划,安排好时间。
- 时序报告和资源报告的生成需要查看综合、实现完成后的结果。
3.1.3 实践任务4:数字逻辑电路的设计与调试
本实践任务要求:
- 调试并修正一个给定数字逻辑电路设计中的功能错误。
- 上板后可以实现正确的功能。
请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境位于 dc_env/exp4/ 目录下,其目录结构如下:
|--show_sw.v 数字电路设计的源码文件。
|--show_sw.xdc 数字电路设计的约束文件,用于综合和实现。
|--tb.v 数字电路设计的仿真文件,用于仿真。
show_sw.v中的设计共有5个功能错误。该设计的正确功能是:
- 获取开发板最右侧4个拨码开关的状态(记为“拨上为1,拨下为0”,实际开发板上拨码开关的电平是“拨上为低电平,拨下为高电平”),共有16个状态(数字编号是0~15)。
- 最左侧数码管实时显示4个拨码开关的状态。数码管只支持显示0~9,如果拨码开关状态是10~15,则数码管的显示状态不更改(显示上一次的显示值)。
- 最右侧的4个单色LED灯会显示上一次的拨码开关的状态,支持显示0~15(拨码开关拨上,对应LED灯亮)。
比如,初始状态下,4个拨码开关拨下,按复位键,则数码管显示0,LED灯都不亮;拨码开关拨为1,则数码管显示1,LED灯还是都不亮;拨码开关再拨为3,则数码管显示3,LED灯显示1。
提供的设计源码中包含5个bug,其中4个情况:波形为“Z”、波形为“X”、波形停止和越沿采样,另外的1个bug是功能bug。
本任务提供的示例设计的顶层接口如表3.3所示。
名称 | 宽度 | 方向 | 描述 |
clk | 1 | input | 时钟信号 |
resetn | 1 | input | 复位信号 |
switch | 4 | input | 对应开发板上最右侧4个拨码开关 |
num_csn | 8 | output | 数码管的片选信号 |
num_a_g | 7 | output | 数码管的7段信号 |
led | 4 | output | 对应开发板上最右侧4个单色LED灯 |
请参考下列步骤完成本实践任务:
- 学习本章和附录D第D.1节的内容。
- 使用Vivado新建一个工程。
- 点击“Add Sources”,选择添加设计源码(design sources),加入show_sw.v。
- 点击“Add Sources”,选择添加约束文件(constraints),加入show_sw.xdc。
- 点击“Add Sources”,选择添加仿真源码(simulation sources),加入tb.v。
- 理解示例设计的功能,分析仿真顶层tb.v,并理解仿真的行为。注意,开发板上拨码开关的电平是“拨上为低电平,拨下为高电平”,单色LED灯的电平行为是“高电平不亮,低电平亮”。仿真顶层tb.v也是按此电平设计的。
- 进行仿真,并充分利用仿真的辅助小技巧(分割、分组、颜色变化、标志等)进行调试,找出所有的bug。
- 仿真完成后,进行综合、实现并生成比特流文件。
- 生成比特流文件后,连接开发板,进行上板验证。(如果没有本地或远程FPGA实验平台或者不进行上板实验,可以跳过此步骤。)