第 3 章 数字逻辑电路设计基础

【本章学习目标】

  • 复习设计CPU必须掌握的数字逻辑电路及其对应的Verilog描述形式。
  • 理解同步RAM和异步RAM的区别及其时序行为。
  • 了解数字逻辑电路功能仿真时常见的错误并初步掌握其调试方法。

【本章实践目标】

本章安排三个实践任务(见本章第3.1节)。读者可以在学习本章内容的基础上完成这些任务,两者之间的对应关系如下:

  • ??节的内容对应实践任务2(3.1.1节)和实践任务3(3.1.2节)。
  • ??节的内容对应实践任务4(3.1.3节)。

3.1 任务与实践

完成本章的学习后,读者应完成以下三个实践任务:

  1. 寄存器堆仿真(具体内容见下面第3.1.1小节)。
  2. 同步、异步RAM仿真、综合实现(具体内容见第3.1.2小节)。
  3. 数字逻辑电路的设计与调试(具体内容见下面第3.1.3小节)。

3.1.1 实践任务2:寄存器堆仿真

本实践任务要求:

  1. 对一个寄存器堆设计进行功能仿真,通过观察其仿真波形了解行为特征。

实验环境中提供的寄存器堆源码为“两读一写”的结构,也就是有两个读端口(读端口没有使能位控制,表示永远使能)和一个写端口。接口信号如表3.1所示。

表 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               寄存器堆仿真文件。

建议参考下列步骤完成本实践任务:

  1. 使用Vivado新建一个工程。
  2. 点击“Add Sources”,选择添加设计源码(design sources),加入regfile.v。
  3. 点击“Add Sources”,选择添加仿真源码(simulation sources),加入rf_tb.v。
  4. 对工程进行仿真测试,结合波形观察寄存器堆的读写行为。

3.1.2 实践任务3:同步RAM和异步RAM仿真、综合与实现

本实践任务要求:

  1. 调用Xilinx库IP实例化一个同步RAM,进行仿真以观察行为,进行综合和实现后查看时序结果和资源利用率。
  2. 调用Xilinx库IP实例化一个异步RAM,进行仿真以观察行为,进行综合和实现后查看时序结果和资源利用率。
  3. 对观察到的现象进行对比分析。

请参照第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所示。

表 3.2: RAM包封后顶层接口信号列表

名称

宽度

方向

描述

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工程的参考步骤如下:

  1. 使用Vivado新建一个工程。
  2. 点击“Add Sources”,选择添加设计源码(design sources),加入block_ram_top.v。
  3. 点击“Add Sources”,选择添加约束文件(constraints),加入ram.xdc。
  4. 点击“Add Sources”,选择添加仿真源码(simulation sources),加入ram_tb.v。
  5. 参考第??节,调用Xilinx库IP生成同步RAM(Block RAM,深度为65536,宽度为32,片选使能信号设为一直有效)。

建立异步RAM工程的参考步骤如下:

  1. 使用Vivado新建一个工程。
  2. 点击“Add Sources”,选择添加设计源码(design sources),加入distributed_ram_top.v。
  3. 点击“Add Sources”,选择添加约束文件(constraints),加入ram.xdc。
  4. 点击“Add Sources”,选择添加仿真源码(simulation sources),加入ram_tb.v。
  5. 参考附录DD.1节,调用Xilinx库IP生成异步RAM(Distributed RAM,深度为65536,宽度为32)。

在完成工程的创建后,对它们进行仿真,对比读写行为的异同。在完成工程的仿真后,对它们进行综合和实现,参考附录DD.1节介绍的方法查看时序结果和资源利用率,并结合读写时序进行分析。

在实践过程中,应特别注意以下几点:

  • 生成IP时,请将对应IP命名为block_ram和distributed_ram,如命名错误,IP将会报错。若遇到已生成IP无法改名的情况,可以删除该IP,重新生成。
  • 生成IP时,可以点击窗口左侧的图查看接口信息。当参数正确时,端口名和宽度应与指定的顶层文件中的调用相对应。
  • 有兴趣的读者可以自行调研、参考同步/异步RAM定制的资料,并根据仿真波形对比参数的作用。
  • 对程序进行综合之前请确保已正确加载约束文件(ram.xdc)。
  • 添加testbench时请注意选择add simulation source,否则会导致顶层文件错误,综合结果不正确。
  • 对程序进行综合时,所用的计算机不同,综合时间会有一定的差异,有可能会耗费大量时间,所以应提前计划,安排好时间。
  • 时序报告和资源报告的生成需要查看综合、实现完成后的结果。

3.1.3 实践任务4:数字逻辑电路的设计与调试

本实践任务要求:

  1. 调试并修正一个给定数字逻辑电路设计中的功能错误。
  2. 上板后可以实现正确的功能。

请参照第2.3.1节中介绍的方式获取本次实践任务所需的实验开发环境。具体的实验环境位于 dc_env/exp4/ 目录下,其目录结构如下:

|--show_sw.v             数字电路设计的源码文件。
|--show_sw.xdc           数字电路设计的约束文件,用于综合和实现。
|--tb.v                  数字电路设计的仿真文件,用于仿真。

show_sw.v中的设计共有5个功能错误。该设计的正确功能是:

  1. 获取开发板最右侧4个拨码开关的状态(记为“拨上为1,拨下为0”,实际开发板上拨码开关的电平是“拨上为低电平,拨下为高电平”),共有16个状态(数字编号是0~15)。
  2. 最左侧数码管实时显示4个拨码开关的状态。数码管只支持显示0~9,如果拨码开关状态是10~15,则数码管的显示状态不更改(显示上一次的显示值)。
  3. 最右侧的4个单色LED灯会显示上一次的拨码开关的状态,支持显示0~15(拨码开关拨上,对应LED灯亮)。

比如,初始状态下,4个拨码开关拨下,按复位键,则数码管显示0,LED灯都不亮;拨码开关拨为1,则数码管显示1,LED灯还是都不亮;拨码开关再拨为3,则数码管显示3,LED灯显示1。

提供的设计源码中包含5个bug,其中4个是第??节中提到的波形异常的前4种情况:波形为“Z”、波形为“X”、波形停止和越沿采样,另外的1个bug是功能bug。

本任务提供的示例设计的顶层接口如表3.3所示。

表 3.3: RAM包封后顶层接口信号列表

名称

宽度

方向

描述

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灯

请参考下列步骤完成本实践任务:

  1. 学习本章第??节和附录DD.1节的内容。
  2. 使用Vivado新建一个工程。
  3. 点击“Add Sources”,选择添加设计源码(design sources),加入show_sw.v。
  4. 点击“Add Sources”,选择添加约束文件(constraints),加入show_sw.xdc。
  5. 点击“Add Sources”,选择添加仿真源码(simulation sources),加入tb.v。
  6. 理解示例设计的功能,分析仿真顶层tb.v,并理解仿真的行为。注意,开发板上拨码开关的电平是“拨上为低电平,拨下为高电平”,单色LED灯的电平行为是“高电平不亮,低电平亮”。仿真顶层tb.v也是按此电平设计的。
  7. 进行仿真,并充分利用仿真的辅助小技巧(分割、分组、颜色变化、标志等)进行调试,找出所有的bug。
  8. 仿真完成后,进行综合、实现并生成比特流文件。
  9. 生成比特流文件后,连接开发板,进行上板验证。(如果没有本地或远程FPGA实验平台或者不进行上板实验,可以跳过此步骤。)