时间:2025-02-07 来源:FPGA_UCY 关于我们 0
基础语法
bc2acf7810125261c2631e9b95de6e976bb02f724d8502b516921d10aa0ac870727d7f589006af2a1e523d0ce74a10e90838551e4ca7b1881b5344f22e063
1.1 可综合模块
以为单元,具体实现如下:
1.1.1 时序逻辑
以异步触发的D触发器为例,时序逻辑在块里实现。
主要注意点:
1. 声明模块时,输入变量一定是wire类型。
2. 声明模块时,输出变量可以是wire,也可以是reg, reg变量只能在块中赋值。
3. 敏感列表既可以是边沿触发,也可以是电平触发。
4. 沿触发的逻辑里,一定采用的是非阻塞触发《=。
1.1.2 组合逻辑
以数据选择器为例,组合逻辑通常使用语句赋值。
主要注意点:
1. sel = 0时,c = a;sel = 1时,c =b,即二选一数据选择器。四选一则有两个选择端,四个输入端,八选一则是三个选择端,八个输入端。
2. wire 变量一定要用连续赋值语句赋值,而且必须用阻塞赋值。
1.2 仿真模块
仿真模块和可综合模块的区别:
可综合模块最终生成的bit文件会烧录进芯片运行,而仿真模块编译过后是在仿真软件(例如)上运行的。仿真模块是基于可综合模块进行例化,并通过仿真软件的模拟,可以初步验证我们写的可综合模块的实现现象。
以计数器为例,可综合模块如下:
基于以上可综合模块的仿真模块如下:
1. 仿真的模块声明不需要输入列表。
2. 块只能对【寄存器】量进行赋值。
3. 例化模块时,如果原始模块是输出变量,则括号内必须【wire变量】。
HDL常见例子
2.1 译码器
2.1.1 可综合模块(case语句)
此模块用case实现了一个数据选择的功能,先产生了一个8位计数器,通过判断计数器的值来输出不同的取值,当计数器计数到1时,和o_dv分别输出5和1,当计数器为2时,输出7和1,其余均输出0。(Note:Case语句常常运用于状态机中状态的判断)
Case语句注意点:
必须有语句,否则会形成锁存器。
2.1.2 仿真模块
2.2 状态机
由于FPGA内部语句块都是并行运行的,当我们希望FPGA按照顺序执行我们的语句时,就会用到状态机。
下面例子是使用状态机模拟的一个简单的自动售货机,该售货机中的商品 2.5 元一件,每次投币既能投入 1 元,也能投入 0.5 元,当投入 3 元时,需要设定找零。
2.2.1 状态图
2.2.2 可综合模块(2段式状态机)
2.2.3 仿真模块
2.2.4 仿真脚本
仿真脚本可以省去人工操作软件图形页面的步骤,运行脚本,可以根据脚本命令自动运行包括创建工作目录,编译文件,启动仿真等步骤,以下是本例中的仿真脚本。
仿真脚本编写好后,只需要进入仿真软件(本例使用的是),改变当前路径到脚本保存的路径,然后在命令行输入 do [脚本文件名] 即可。
仿真结果:
2.2.5 上板测试
上板测试对原来的条件做了一定改动更方便观测结果,输入和输出分别使用的按键和LED灯,测试版使用的是的,实现的功能如下:
① 在开发板上完成自动售货机的实验,投币的动作通过按键实现, 当按一次按键(按下到抬起算一次),算作投币一次。
③ 当投入总金额为 5 毛时, led 灯亮一个,投入总金额为 1 元时, led 灯亮两个, 投入总金额为 1.5 元时, led 灯亮三个, 投入总金额为 2 元时, led 亮四个, 用单向流水灯效果充当出可乐并且不找零的情况,用双向流水灯效果充当既出可乐又找零的情况。流水灯持续十秒后熄灭,状态回到初始状态。
重新设计状态图如下:
代码详见工程,笔记不再赘述,此次笔记主要记录关于顶层模块和例化的相关知识点:
工程目录如下所示:
各模块之间的关系是:
顶层文件是fsm.v,在fsm.v中调用了模块,和,这三个模块的功能分别是单向流水灯,双向流水灯和按键消抖。想在顶层文件中调用对应的模块需要在顶层文件中对相应的模块进行例化,以单向流水灯为例。