fpga 电梯项目
累死我了。昨天下午到今天中午。
累不累不要紧,主要是这是期末复习周。分秒寸金的复习周。
吐槽两句
调试:
vivado,verilog的开发方式和其他语言不太一样。调试的话,要么仿真,要么建立一个debug core调试核,要么下板。一开始,觉得很快就能做完;觉得编写仿真文件,或者现学调试不合算,我选择直接下板。然后被这个反复下板浪费的时间折磨到了。
而且三阶段,一个是分析,一个是硬件,一个是比特流,每一项都花时间,每一项都走不开,不能像是“让程序慢慢跑,吃个饭先”之类的。
下次一定仿真。
暂时不要相信gpt的复杂代码水平
基于python或c或go之类的几十行一两百行还好,这种复杂的程序真的是难为gpt这种泛用模型了。尤其是verilog还是个非主流语言。
而且,我这个项目,是网络上已经有不少现成的,gpt是将它们按照我的要求缝在了一起。有的地方缝错位了,有的地方不该缝的缝上了。还有有的地方我以为缝错了其实缝对了。导致修改花了绝大多数时间。
不过,要我自己从零写,不知道要花多少时间。我没这个时间也没这个精力再写一次。
遗憾:
fpga开发板贵的一批。学校给了我使用的机会,但我没有珍惜。
下次一定。
基本架构
有以下几个部分:
- top:顶层文件
- key_debounce:按键消抖
- matrix_key:矩阵键盘。实际使用四个键,属于是卵用没有,只能添乱。
- switch_control:拨码开关控制(并输出floor查看运行状态)
- clk_div:理论有用但实际没用,全他妈用的是自己分频…………这个模块对我的唯一贡献,是给led_control模块塞了一个花了我好长时间的bug……
- seg_control:控制数码管显示。大改过。
- led_control:控制led和电梯上下楼,名副其实的灵魂模块。
- beep_control:一个意义不明的模块,我不知道gpt本来是想做什么,反正它在我这里就是一个运行指示器。
top里面重要的reg:
- row行信号,设置为1110
- 一开始设的是0001,纳闷了好久。
- 几个led灯
- key_in和key_out
- floor和floor_out
- floor是寄存器,作为模块输入,不能作为输出。
- 要改变floor的值,需要通过一个wire,floor_out来转接。
- 我在top里面加了一句always @(posedge clk) floor<=floor_out; endmodule,用来将这两个直接相连。
模块介绍
top:顶层文件
模块例化,将floor_out和floor链接。
`timescale 1ns / 1ps不知道有没有用,总之加上就是了。之前因为这一句翻过车。
总之就是要把各个变量对应好,不要出现什么时钟频率错误,in和out变量错误什么的。
key_debounce:按键消抖
基本原理是检测到按键按下,然后等20个时钟周期再看看,如果还是按下,那就真的按下了,输出按键信息。
switch_control:拨码开关控制(并输出floor查看运行状态)
其实也是个没卵用的模块,把二位的led_status分割成一个rst一个start。我是不知道为什么我不在xdc里面直接定义rst和start……可能是闲得蛋疼。
但是我还是保留了,毕竟能正常工作,还能加点其他功能,不在其他模块碍眼。例如打印floor状态。
clk_div:理论有用但实际没用,全他妈用的是自己分频…………这个模块对我的唯一贡献,是给led_control模块塞了一个花了我好长时间的bug……
字面意思,理论上应该用这个控制所有时钟分频,但是我的模块用分频的少,所以都自己分了。
seg_control:控制数码管显示。大改过。
大改指的是把本来的全部注释掉然后重写。
主要是因为我改了matrix_key,没用,导致编码从8421变成了独热码。而且我的floor只有两位,按键四个,不需要那么复杂的东西。
两个数码管,交替选择,选择时显示内容。
如果不使用分频,会导致残影。理论上需要专门的方法去除,但是我懒狗,我是把频率降一下就当没看到残影。我是用的是1000hz。
led_control:控制led和电梯上下楼,名副其实的灵魂模块。
首先是判断key_in,如果非零,那就说明按键按下。在这个情况下,需要根据floor和key的内容选择新的floor。
松开按键,则key就会归零,于是针对key我使用了一个key_reg保存上一次的输入。所有判断都是在计时器计满之后执行的;都是基于上一次key的输入来选择判断。
好吧,实际用到key_reg的只有一处,控制led灯那里。要求是:
1 |
|
本来有很多用了key_reg的,砍掉了。
还有就是运行时灯的流动,
1 |
|
代码:
1 |
|
注意不是流水灯,但大差不差。
beep_control:一个意义不明的模块,我不知道gpt本来是想做什么,反正它在我这里就是一个运行指示器。
改了,改成了到站叫一声。
使用了一个timer_start一个beep_enable来分别控制counter和timer,timer控制时长,counter控制频率。