跳转至

实验要求

第一周 设计数码管扫描

按照下图所示,完成数码管扫描显示,显示的内容为一个定时器的计时数。为了完成这个任务,你需要设计如下内容:

  • 一个数码管动态显示单元,支持8个数码管的动态扫描显示
  • 一个定时器,用于产生定时信号,这个定时器的计数将会显示在数码管中。

image-20231115163933670

上图(来源于PPT)的数据通路中,d3-d0是定时器的输出,对应四组数码管的每组16位数据。数码管刷新的选择信号前设置分频器降频,是因为数码管刷新过快会导致亮度降低

方案1:注意上图中的计数器不是我们先前提到的定时器,也不是我们先前提到的定时器中例化的计数器,而是另一个位数较小的计数器,这个计数器不需要输入start信号,会在分频器输出的新时钟下循环计数,计数结果再被译成独热码作为数码管刷新的选择信号。

方案2:使用上图中的计数器向多路选择和译码器的直接连线只是一种可选的设计,如果你的定时器中的计数器使用的是开关数据和低位多个零的位拼接,然后以高位数据作为显示数据,你可选择较低的两位作为数码管刷新(此时哪组数码管点亮)的选择信号,而不需要再写一个计数器。

方案3:多路选择器和译码器关于此时哪组数码管点亮的选择信号也可以维护在这两个模块内部,直接接受一个输出频率较高的分频器(上图分频器,不是定时器前的分频器,并从上图中删除计数器),等于在多路选择器和译码器内维护新的FSM,每当降频后的时钟上升沿到来时切换数码管。

无论哪种方案,你都要保证肉眼看不清数码管的扫描。

这个实验有两种建议的实现方式:

  • 第一种:使用开关作为定时器的置数,并启动计时,不使用UTU

    你需要自己实现按键开关去抖动数码管动态扫描显示

    你可以自行决定具体的数据通路和模块间关系,只要输入输出正确即可。

    限制文件第二行的period为主时钟周期(ns),waveform中的两个参数为时钟上升沿和下降沿,上升沿默认为0,下降沿默认应设为时钟周期的一半,比如:

    set_property -dict { PACKAGE_PIN E3    IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
    create_clock -add -name sys_clk_pin -period 50.00 -waveform {0 25} [get_ports {clk}];
    

    由于只使用16个开关,最大输入数据为216-1=65535,这会导致计数在肉眼不可分辨的时间完成。为了解决这个问题,我们不推荐大幅度更改限制文件的周期,而推荐使用分频器降频,用脉冲输出作为计数器的时钟;或者令计数器的输入数据为开关数据做高位和内置数据低位补零的位拼接

    你的计数器最终上板显示的计数速度,应近似为一秒一次

    将btnr按钮作为计数开始start按钮。计数完成时IO_L11P_T1_SRCC_14 Sch=led16_r灯亮

    这一步中实验顶层模块接口如下:

    input  logic         clk      // 时钟信号
    input  logic         rstn,      // 复位信号
    input  logic  [15:0] sw,        // 定时器设置的周期数(16位)
    input  logic         st,        // 定时器开始信号
    output logic  [ 7:0] an,        // 数码管位选信号
    output logic  [ 6:0] seg,       // 数码管段选信号
    output logic         td         // 定时器到时信号,接入任何一个led灯即可
    
  • 第二种:将模块接入UTU,实现32位数据的输入,使得定时器可以计数32位的数字

    检查验收时会要求分析UTU的对按键开关去抖动和数码管动态扫描显示的实现。

    使用utu时,要求将btnr(即原本utu的step)按钮改为计数开始start按钮,utu模块step接口接0。

注意

本实验分为两周完成,第一周完成定时器部分(以上内容),在10月31日验收;第二周完成串口部分(以下内容),在11月7日验收。 串口部分尚未发布,实验要求可能有更改。

第二周 设计串行通讯单元

注意

反复提醒,禁止使用分频器的输出作为寄存器的时钟信号,出现此类问题导致仿真通过上板不过,助教有权不解答任何相关由此引发的问题。

提示:仿真正确,上板不过的同学考虑如下

确定是先发最低位?

确定是有起始位和终止位?

确定软件上选择的也是无检验位?

还有疑问的话,使用ILA工具帮助解决问题:

https://blog.csdn.net/unique_ZRF/article/details/127715565 推荐使用文章中的方法一来构建ILA工具

  • (必做)单数据串口数据输出。——基础任务,难度0*
    • 输入:利用16个拨动开关,输入16位的独热码
    • 处理:将独热码理解为16进制的0-F,再译成对应的char的字符(如0对应'0',A对应'A'),经串行通信发送至PC端显示。eg:已知sw选择16'h0400,对应的char为'A'(==8'h41),
    • 串口输出:将'A'发送至PC端显示。
  • (选作)多数据串口数据输出。——完成奖励得3分,难度1*
    • 输入:利用16个拨动开关,每四个一组,按照8421BCD码的方式,每组输入一位16进制数
    • 处理:将4个16进制一位数转化成对应的char的字符后,外加一个回车换行符''rn'',共计6个字符,
    • 输出:依次经串行通信发送至PC端显示。
    • eg:已知sw选择16'hABC1,对应的char为'A','B','C','1','\r','\n'
  • (选做)串行输入。——完成奖励得7分,难度3*
    • 输入:PC端发送8次数据,FPGA接收。共计8*8bits(要求字符在[0-9,A-F])
    • 处理:每1次数据的8bits表示对应的char的字符,转化成对应的16进制数字(如'A'对应A)
    • 显示:将8个16进制数字显示在数码管上。
  • (选做)LookBack——完成奖励得10分,难度5*
    • 任务描述:实现串行通信的LookBack功能,即FPGA接收到的数据会原样返回给PC端。
    • 输入:PC端发送任意数据,FPGA接收。
    • 处理:FPGA接收到的数据原样返回给PC端。
    • 特点:由于PC的输出是连续的,所以导致FPGA的输入rx也是连续的,但是对应的tx模块往往不能够保证及时采集rx模块得到的数据(但是rx模块不能够停下来),所以需要设计一个缓冲区来存储rx模块得到的数据,然后由tx模块逐个取出数据发送。
    • 如果没有缓冲区,往往大家能够看见的现象是:返回给PC端的数据是间隔的。例如:PC发送的数据是“123456789”,FPGA返回的数据是“13579”。
    • 关于缓冲区有疑问,可以提前阅读Lab5的内容,有任何问题欢迎向两位助教提问。

得分详解:最高可得10分的binus(在原始基础上,有超出助教意外的设计还能够得到加分,具体的对应的得分由对应的设计的难度,和两位助教共同商讨决定)。

此分数与GPA没有线性关系。在最终成绩中,每次实验的binus的分数的权重的占比一定不一样,只是为了方便体现设计难度变化和分数凑整而设立的。最终解释权归助教组所有。

在这个过程中,大家需要完成串行通讯单元的设计。这个设计的完整总体设计如下:

image-20231116144815047

其中,TX是串口的发送接口,RX是串口的接收接口,它们使用valid-ready协议与PUTS和GETS模块通讯,并将数据以txd和rxd的形式发送或接收。

对于PUTS而言,它的参考设计如下:(注:这是TX模块的选做,如果不发送多个数据,不需要其中的32位移位器和后面的'\r','\n')

image-20231116144519982

PUTS需要一个32位移位器来存储并发送8bit数据,一个计数器来计数发送的数据位数。当计数器计数到8后,还需要发送一个回车和一个换行符。这些输出都由串行输出接口转化为txd信号

对于GETS而言,它的参考设计如下:

image-20231116144315849

GETS需要一个8位移位器来存储到来的8bit数据,一个计数器来计数接收的数据位数。当计数器计数到8后,完成本次的接收。如果你希望接收32位数据,那么还需要一个32位移位器来存储接收到逐个字节的数据,并将其拼接好。

LookBack的设计不给提示,需要大家自行设计自己认为最合理的架构。(hint:基础至少有uart_rx,uart_tx,FIFO)

实验验收要求

第一周

  • (10月31日验收) 完成32位定时器的设计,能够正确显示定时器的计数值,计数完成时,IO_L11P_T1_SRCC_14 Sch=led16_r灯亮。

第二周

  • (11月7日验收) 完成串行通信模块的设计,具体要求见上,需要保证实现最基础的要求,实验结果以上板能够正常运行为准。