文章

Fpag学习记录-lab-00!

Fpga lab-01 记录我的fpga学习以及踩坑之路

这个学期报名了fpga的课程,特此记录一下我的学习心路历程

在计数的时候conter要在另一个always而不能和led在同一个always里面

出现问题的原因是你在同一个 always 块中的条件语句内同时使用了 led 和 counter 的赋值操作, 但是 Verilog 中的 always 块应该是边沿敏感的,只有一个赋值操作会在每个时钟上升沿(或下降沿,取决于你的条件)触发。 在这种情况下,同时赋值两个不同的寄存器可能导致不确定的结果,因为它们在同一时钟周期内可能会有冲突。

为了解决这个问题,你可以将 led 和 counter 的赋值操作放在不同的 always 块中,以确保它们在不同的时钟周期内触发。 这将使你的代码更可读和可维护。

对于led的操作,必须只能在led的always里面而不能在counter的always里面,不然会报错

1
2
3
4
5
6
7
8
9
10
11
12
具体的实现细节
    1. 定义一个4位的寄存器counter,用来计数从0000到1111
    2. 修改流水灯的时间间隔为0.25ms
    3. 当到达一秒的时候,直接将流水灯的直接改成counter
    4. 要注意的是,当我们的我们的counter和led是相反的,所以我们要将counter左右对称反转之后,再将里面的值赋值给led
    例如像一下的就是将led反转后再赋值,n位寄存器的用法和c语言里面的数组比较相似
        > led[0] <= counter[3]; // 将 counter 的最高位赋值给 led 的最低位
        > led[1] <= counter[2]; // 将 counter 的次高位赋值给 led 的次低位
        > led[2] <= counter[1]; // 将 counter 的次低位赋值给 led 的次高位
        > led[3] <= counter[0]; // 将 counter 的最低位赋值给 led 的最高位

**当将16进制计数器和LED流水灯合并的时候,除了在pin planner那里将灯的接口配置好,还有电压一定要手动重新选择为3.3VTTL。不要LED灯不会亮**

关于数码管模块的说明,以下由gpt解说

这段 Verilog 代码实现了一个基于时钟的计数器和7段LED显示器的控制逻辑。让我逐步解释它:

  1. 模块输入和输出:

    • clk:系统时钟输入。
    • rst_n:复位信号,低电平有效。
    • seg_sel:7段LED显示器的段选信号,用于选择要显示的7段LED。
    • seg_data:7段LED显示器的数据信号,用于指定每个7段LED的段状态。
  2. 时间计数器和1Hz 信号生成:

    这部分代码实现了一个时间计数器,它在 clk 的上升沿或复位信号 rst_n 的下降沿时工作。计数器 timer_cnt 递增,同时生成一个 en_1hz 信号,当 timer_cnt 达到 49,999,999 时,en_1hz 信号为高电平。这意味着 en_1hz 信号每秒会变为高电平一次。

  3. 多个 10 进制计数器:

    这部分代码使用多个名为 count10_mX 的模块实例来实现 10 进制计数器。每个计数器模块在 clk 上升沿时工作,根据 en 信号递增计数器的值。计数器之间的连接是级联的,这意味着一个计数器的输出 tX 信号将作为下一个计数器的 en 信号,从而实现了级联的计数逻辑。

  4. 7段LED数码管解码器:

    使用多个 seg_decoder_mX 模块实例将十进制计数器的输出 countX 解码为对应的7段LED显示器的段数据,存储在 seg_data_X 中。

  5. 7段LED扫描:

    seg_scan 模块实例通过选择 seg_sel 信号来控制哪个7段LED显示器处于活动状态,以及将 seg_data_X 的数据传送到相应的7段LED显示器以显示数字。

总体来说,这段代码是一个计时器和多个7段LED显示器之间的接口,用于在7段LED上显示从0到9的数字,并且它们的显示状态会随时间变化。同时,计时器每秒产生一个脉冲信号,可以用于同步其他操作。

当大概看gpt解释的数码管模块之后,我们就可以动手制作我们的十六进制计数器

  • 知道count10是一个十进制的计数函数(这个函数需要成16进制的函数,并且是每3秒进行一次加法)
  • seg_decoder是一个解码模块,里面对应的是fpga的数码管的数字和01的数值(这个函数不需要修改)
  • seg_scan,数码管的扫描模块。这个模块我们也完全不需要取修改 *因此我们只需要将10进制计数器修改成16进制的计数器即可 具体做法

十六进计数器具体实现

  • 16进制计数器和10进制的计数器一样,同时采用clk,reset_n作为输入
  • .区别:16进制计数器需要分别将个位的计数的数字以及十位上的数字作为输入
  • .如果使能信号(每隔3秒来一次,要和LED灯的3秒钟对齐)来的话,就判断是否达到进位条件

首先if判断个位数是否到达9(因为我们最大的计数值只是去到15,这里似乎有点偷懒,但是可以实现功能) 接着判断是否同时满足个位数为5且十位数为1,如果满足的话,就让输入的两个data均为0

本文由作者按照 CC BY 4.0 进行授权