第二周第一天:
错题记录:
1.不属于并行语句的是case语句
2.repeat不是分支语句
3.非阻塞赋值运算赋值不是立刻改变
4.三目运算符:?:
5.无锁存器指列举了所有的的情况
6.移位补零
8×8led灯驱动:实现流水灯的话行和列有不同的模值来控制计数,三倍关系,时钟分频,然后状态机,最后组合逻辑电路实现。实现n×nled灯一圈一圈变化的话由于行和列变化频率相同,所以用相同的模值控制。
always语句里面要么全用阻塞赋值,要么全用非阻塞赋值。
遇到的问题:文件名中×(乘号)好像也不能够识别,改了之后综合就成功了。
组合电路中 always块的使用原则
(1)只在一个 always模块中对变量赋值
(2)组合电路采用阻塞赋值
(3)在敏感列表中使用@自动包含所有输入信号
(4)确保包含 if-else和case语句的所有分支
(5)确保所有分支的输出都被赋值;
(6)一种同时满足(4)和(5)原则的方法是在 always块开始时给输出赋默认值;
第二周第二天:
实现基于FPGA蜂鸣器音乐演奏
蜂鸣器分为无源和有源,有源蜂鸣器频率固定,只有单一音调。FPGA板子和单片机开发板上的蜂鸣器大部分都是无源蜂鸣器,可以由编程实现频率变化,由此发出不同音调的声音。
编程思路:
1.不同的唱名对因不同的分频系数,由此产生不同的音调。要设计分频计数器来记录发出音调的分频系数。
分频系数计算公式:系统时钟频/音频频率/2,除以2代表半个周期,如中音do就是125M/523.3/2.
2.除了音调,还需要节拍,设计一个计时器计数节拍。
3.利用case语句写入节拍和要发出的音调。
实现程序:1.发出中音do 2.依次按下四个button,发出do、ri、mi、fa(这里casex语句比case语句好) 3.谱曲 谱曲就是在第二个程序下增加乐曲中需要的节拍,每秒四个节拍频率要除以4 在每次更新数据时tune_cnt要强制清零,否则tune_cnt与tune_delay可能会越差越大,导致乐曲播放停止。
模块:最后64个状态可以理解为64选1选择器,受beat控制。beat_cnt的模值是系统频率sys_freq的四分之一。Beat在beat_cnt的控制下产生64个beat。每beat产生一次,tune_delay就更新。Tune_delay通过第一个模块产生beep。
第二周第三天
上午:连接数码管引脚并测试数码管是否工作正常
下午目标:1.两数码管分别同时显示不同的1和0
2.实现模值可调的加法计数器
3.按键调解计数器可调模值
计数器:计数模块(0-59)→扫描模块(state)→显示译码模块→数码管显像
产生低位:counter%10 产生高位:(counter/10)%10
注意写代码时段选高位到低位依次是:dp-g-f-e-d-c-b-a
显示译码模块(共阳):
reg [7:0]seg;
always@(*)
if(!rst_n)seg=8’hff;
else
case(data_disp)
4’d0:seg=~8’h3f;
4’d1:seg=~8’h06;
4’d2:seg=~8’h5b;
4’d3:seg=~8’h4f;
4’d4:seg=~8’h66;
4’d5:seg=~8’h6d;
4’d6:seg=~8’h7d;
4’d7:seg=~8’h07;
4’d8:seg=~8’h7f;
4’d9:seg=~8’h6f;
4’d10:seg=~8’h77;
4’d11:seg=~8’h7c;
4’d12:seg=~8’h39;
4’d13:seg=~8’h5e;
4’d14:seg=~8’h79;
4’d15:seg=~8’h71;
default:seg=~8’h00;
endcase
第二周第四天上午:
改进数码管可变模值计数。注意实例化名字是引用IP核里面的。key_out是模块里面自己定义的btn_out,key_in是btn。
下午:继续改进及呼吸灯的预习
呼吸灯设计原理:呼吸灯设计原理归结为对于分频和占空比的应用,就是先分频,然后再设置占空比的设计。占空比也就是控制LED暗亮的时间达到具有呼吸灯的效果。
脉冲宽度调制(PWM) 的概念:LED的点亮和熄灭,是电平高低变换的结果,可以将一高一低看作一个周期,每个周期一亮一灭,会显示为LED的闪烁,当周期很短,也就是频率很高时,这种闪烁将不被肉眼识别,会让人产生LED连续发光的感觉。在一个周期内,高电平时长与一个周期时长的比叫做占空比,占空比越高,相当于通过LED的电流就越大,视觉上的感觉就越亮。说到这里,应该就有了做呼吸灯的思路,就是改变占空比!让占空比小幅度有级提升,就会有LED无级变亮的感觉。反之就会变暗。占空比越高,亮度越亮。
首先将1s 分为1000份(1ms),然后在1ms内在继续分为1000份(1us),每一个1ms内,依次增加亮灯时间
即:
第1个1ms内亮灯1us
第2个1ms内亮灯2us
第3个1ms内亮灯2us
…… 第1000个1ms内亮灯1000us
第二周第五天上午:
计数器的优化 关于消抖的说明:1.IP核调用 2.做一个消抖module再调用(层次化设计) 3.添加一个always块用于消抖
最后讲了一下pwm波
第二周第六天:
流水呼吸灯:遇到的问题:给led赋值的时候没有注意到位宽,在写状态机的时候在条件中把state==2’d3写成了state<=2’d3导致一直只有一个状态。
学习方法总结:
在编写代码之前,最好像老师一样先把思路理清楚,先打个草稿,清楚自己大概需要哪些模块,没注意到的细节后面来补,先把理论知识了解清楚,这样会比直接想到什么写什么更有效一些。而这些思路是由需求产生的,一般需求就是老师上课所说的要实现的项目目标。设计源代码烧到板子上有错误时,从仿真程序上找错误。然后就是学习能力的逐渐提升,在每犯一个错误的时候就要对这个错误有足够的印象。最后到一定程度了花费在这些错误上的时间就会更少,也提升了熟练度和解决问题的能力。
遇到的问题与解决方案
- 工程文件名有中文路径和特殊符号都会报错。
- 蜂鸣器在谱曲的时候播了一会儿就停止了,在老师讲解下明白是没有强制清零的话tune_cnt与tune_delay会越差越远。
- 数码管引脚接错
- 按键消抖IP调用实例化明白key_in和key_out表示的意思。
- 呼吸灯不呼吸,状态机那里条件语句的条件写错了个。