跳转至

实验 5:内存串口实验

串口是实现计算机与外接设备通信最为简单的接口,在实际的计算机系统中,它经常作为一个总线上的外设设备出现。本实验由同学实现 Wishbone 总线 Master 模块,通过本实验中给出的 UART 控制器,实现对 ThinPAD 教学计算机上串口的访问;同时,结合实验 4 中设计的 SRAM 控制器,实现 SRAM 与 UART 之间数据的双向传输,为后续的 CPU 设计实验做好准备。

模板文件

本实验的顶层模块模板:thinpad_top.srcs/sources_1/new/lab5/lab5_top.sv

Wishbone 非对齐访问

关于在 Wishbone 总线上进行非对齐访问的情况,请 严格 按照 Wisbone Master 实现#非对齐访问中说明的方式处理。即在访问 0x10000005 这个地址时, wb_sel 应使用 4'b0010 。在群内的相关讨论以及实验前小测题有误。如已经完成实验 5, 不需要 修改自己通过测试的实现。

实验目的

  1. 熟悉 ThinPAD-Cloud 教学计算机串行接口的配置及与总线的连接方式;
  2. 掌握 Wishbone Master 的时序及模块设计方法;
  3. 理解总线数据传输的基本原理;
  4. 熟悉通过总线访问 UART 等外设的方法。

实验环境

  1. 硬件环境:PC 计算机,Windows 10 或者 Linux 操作系统;ThinPAD-Cloud 远程实验平台;
  2. 软件环境:FPGA 开发工具软件 Vivado;ThinPAD-Cloud 远程实验平台提供的串口调试工具;
  3. 基础模块:
    1. 实验 4 中编写的 Wishbone SRAM 控制器;
    2. wb_mux_3 1M3S 总线仲裁模块;
    3. Wishbone UART 控制器 uart_controller(教学团队给出,已经包含在工程模板内)。

实验内容

使用教学计算机上的 FPGA 芯片,编写代码,通过 Wishbone 协议及给出的 Wishbone UART 控制器、之前编写的 Wishbone SRAM 控制器,同时完成对教学机 UART 和 SRAM 的访问。实现和外部设备(实验中为 ThinPAD-Cloud 平台)的通信。要求分别实现如下功能:

  1. 将拨码开关设置为起始地址 Addr,该地址是 Wishbone 总线的地址,如 0x8000_1000 表示 BaseRAM 这一内存区域的第 0x1000 字节
  2. 单击复位按钮。
  3. 使用云平台向 FPGA 的串口发送 10 个字节的随机数,FPGA 将随机数存储到从 Addr 开始的连续 10 个 word 上(存储进最低 8 位,高 24 位不使用),即每次读写操作地址应当 +4。
  4. FPGA 将上述 10 个随机数发送回串口,云平台从 FPGA 的串口接收 10 个字节。
  5. 程序读取 BaseRAM 中对应位置的数据,并将 SRAM 中数据、串口接收到的数据与初始随机数进行对比,对比时只考虑 SRAM 数据的最低 8 位。

同学需要在顶层模块中实现 Wishbone Master 状态机,根据拨码开关的输入,生成总线上的请求,从而实现实验的要求。

原理图

实验步骤

本实验的操作比较复杂,首先需要在 ThinPAD-Cloud 云平台上正确选择直连串口,并正确配置串口的参数(波特率默认为 115200)。然后,在编写 Verilog 代码时,要正确理解 UART 的工作原理,了解 UART 控制器内部各个寄存器之间的关系,设计好状态机的各个状态。在此基础上,设计好实现的代码,再将代码下载到 FPGA 中,进行调试。

  1. 从复位中恢复的时候,把拨码开关指示的地址记录下来,记作 addr,保证 addr 对齐到四字节的边界。
  2. 读串口:用 Verilog 语言编写从串口读取数据的代码。

    • 读串口需要循环读取串口控制器的状态寄存器(地址是 0x1000_0005),当它的状态显示可以读入新的数据的时候,再读取串口控制器的数据寄存器(地址是 0x1000_0000)。实际上就是用硬件状态机实现了实验一中的 READ_SERIAL 函数。
    • 建议设计状态:READ_WAIT_ACTION(正在读取状态寄存器)、READ_WAIT_CHECK(读取了状态寄存器当前的取值,判断是否可以读取新的值)、READ_DATA_ACTION(正在读取数据寄存器)、READ_DATA_DONE(完成读取数据寄存器,进入下面的操作)

    循环读取状态寄存器,直到可以读取新数据的一种可能的波形:

    clockCYC_OSTB_OADR_O0x100000050x100000050x10000000SEL_O0b00100b00100b0001WE_OACK_IDAT_I0x00000x01000x0012STATEIDLEREAD_WAIT_ACTIONR_W_CREAD_WAIT_ACTIONR_W_CREAD_DATA_ACTION

    其中 R_W_C 表示 READ_WAIT_CHECK,波形中不断读取 0x10000005,直到可以读取数据,才去读取 0x100000000。注意 ADR_O SEL_O DAT_I 在非对齐访问时的写法。之后写串口也是类似的。

  3. 写内存:把从串口读取的数据写入到内存中。

  4. 每次从串口读取一个字节的数据,就要向内存写入一个字节的数据(仅存储最低 8 位),第 i 次写入的 Wishbone 操作地址是 addr+4*i,也就是每次写入的时候地址增加 4

  5. 建议设计状态:WRITE_SRAM_ACTION(正在写入 SRAM)、WRITE_SRAM_DONE(写入 SRAM 完成,进入下面的操作)

  6. 写串口:再把从串口读取的数据写回到串口。

  7. 写串口需要循环读取串口控制器的状态寄存器(地址是 0x1000_0005),当它的状态显示可以写入新的数据的时候,再写入串口控制器的数据寄存器(地址是 0x1000_0000)。实际上就是用硬件状态机实现了实验一中 WRITE_SERIAL 函数。

  8. 建议设计状态:WRITE_WAIT_ACTION(正在读取状态寄存器)、WRITE_WAIT_CHECK(读取了状态寄存器当前的取值,判断是否可以写入新的值)、WRITE_DATA_ACTION(正在写入数据寄存器)、WRITE_DATA_DONE(完成写入数据寄存器,进入下面的操作)

  9. 循环以上过程,直到完成了十次。

实验提示

  1. 本实验中使用的是 ThinPAD 教学计算机的 直连串口,即 uart_txduart_rxd 两个信号,连接到 Wishbone 串口控制器上。注意不要与共享总线(CPLD 串口)相混淆。实验时,请将 uart_rdnuart_wrn 两个 CPLD 串口的控制线置为 1,避免与 SRAM 产生冲突。
  2. Wishbone 串口控制器模块需要正确指定时钟的频率和串口波特率,实验模板中默认置为了 10MHz,波特率为 115200。如果需要修改系统时钟的频率,需要修改对应参数的数值。

思考题

  1. 阅读 Wishbone UART 控制器的代码,体会 MMIO 寄存器的概念。映射到地址空间上的“内存”的内容一定是只受 Master 端控制的吗?如何将数码管和拨码开关也映射到地址空间上?

实验报告要求

  1. 给出你的状态机设计,并简要解释每个状态的功能。

  2. 进行仿真,给出仿真波形,初步验证设计的正确性。

  3. 上板进行实验,给出实验过程截图,验证设计的正确性。注意不是 OJ 通过截图。

  4. 回答思考题。


最后更新: 2023年11月6日
作者:Jiajie Chen (36.54%), Youyou Lu (15.38%), gaoyichuan (31.73%), cuibst (16.35%)