4月4清明假期修改了一天的project依旧实现不了,RTL视图只能出来一个模块,另外两个设计的模块出不来,管脚更是没有办法配置。是代码问题吗?我改了改,改了改,依旧不行。而另一个project里我用同样的代码文件(.v),同样的BDF,就成功做出来了。我不禁怀疑,真是玄学?于是又经过4月6号的一天摸索,开始另一个实验,依旧是改bug改到再也不想看见那块板子和那个屏幕。晚饭后回到实验室,我把实验室电脑上做出来的project打开,对比笔记本上没有做出来的project,突然想起好像是要把哪个设为顶层文件来着,这一对比,恍然大悟!BDF应该设为顶层文件的!
在做出来的project里,我误打误撞把BDF设置成顶层文件(然而我自己并没有意识到),就比较幸运地成功了。而后面的几个project里我都是把(.v)文件设置成了顶层文件。
经过此番折腾,我终于深刻记住了把BDF设置成顶层文件这句话,果然是实践出真知。在紧接着的实验中,同样的代码文件造成一个出结果一个不出结果的灵异现象果真没有再发生,OK,搞定!
正如师哥所说:硬件开发中,设计和敲代码的工作量和开发时间仅占三成,剩下七成都是debug。此次所犯的低级错误也让我收获了一些debug的技能,锻炼了一番强大的心理耐受力。
昨儿朋友说:*我们可能是bug的制造机!*哈哈哈,这实在是太形象了!
写一个今早完成的小实验:
实验题目:让四个数码管稳定显示“E”“E”“1”“1”
所用设备:terasic DE0
所用软件:quartus II 9.1
实验过程:
1、( .v)文件程序
module testthree(
OUT1,
OUT2,
OUT3,
OUT4);
output [7-1:0] OUT1;
output [7-1:0] OUT2;
output [7-1:0] OUT3;
output [7-1:0] OUT4;
reg [7-1:0] OUT1;
reg [7-1:0] OUT2;
reg [7-1:0] OUT3;
reg [7-1:0] OUT4;
always @(*) begin
OUT1 = 7'b 1111001;
OUT2 = 7'b 1111001;
OUT3 = 7'b 0000110;
OUT4 = 7'b 0000110;
end
endmodule
2、BDF
3、RTL视图
4、管脚配置
5、下载到板子上
很快就做好了(๑´0`๑)
根据这个程序,只需要修改数码管对应的代码,就可以显示任何你想显示的数字,如下图显示的“1234”。
注意“0”为“亮”,“1”为“灭”,代码顺序为OUT = 7’b 6543210(数字代表对应的管子,每个管子有0、 1两个逻辑值),是倒着写的。下图是position and index of each segment in a 7-segment display。因为我的程序中没有用到DP,所以我只定义了7个输出。
如果要用DP,可以设置output [8-1:0] OUT; 对应的代码顺序就是OUT = 8’b DP6543210。
实验二(1):让七段LED发光管以1HZ的频率闪烁起来,从全1到全E来回切换
实验软件:quartus II 9.1
实验板子:terasic DE0
实验过程:
1、(.v)verilog HDL代码
module clk(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 50_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule
///
module cnt_en_0to1(
CLK , // clock
CNTVAL, // counter value
EN ,);
input CLK;
input EN;
output CNTVAL;
reg CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 1)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
endmodule
///
module dec_1to7(
IN ,
OUT1,
OUT2,
OUT3,
OUT4);
input IN;
output [7-1:0] OUT1 ;
output [7-1:0] OUT2 ;
output [7-1:0] OUT3 ;
output [7-1:0] OUT4 ;
reg [7-1:0] OUT1 ;
reg [7-1:0] OUT2 ;
reg [7-1:0] OUT3 ;
reg [7-1:0] OUT4 ;
always @ (IN) begin
case(IN)
1'b0: OUT1 = 7'b 1111001;
1'b1: OUT1 = 7'b 0000110;
endcase
case(IN)
1'b0: OUT2 = 7'b 1111001;
1'b1: OUT2 = 7'b 0000110;
endcase
case(IN)
1'b0: OUT3 = 7'b 1111001;
1'b1: OUT3 = 7'b 0000110;
endcase
case(IN)
1'b0: OUT4 = 7'b 1111001;
1'b1: OUT4 = 7'b 0000110;
endcase
end
endmodule
程序中posedge clk意思是clk上升沿触发(与此对应negedge clk意思是clk下降沿触发),两者都是边沿触发
2、BDF
3、RTL视图
4、管脚配置
5、实验结果
可以看到板子上“1”和“E”以1HZ频率,即1秒的周期不断跳跃。
6、实验总结
本实验最关键的地方就是parameter MAX_VAL值的设置。因为时钟模块(labtwo)的代码逻辑就是:当计数到parameter MAX_VAL时,输出OV为1,否则OV为0。在这里我们把parameter MAX_VAL的值设置为50M,这样一来经过变换,时钟频率就由输入的50MHZ变慢为输出的1HZ。
我最开始设置的parameter MAX_VAL = 25M,因为我觉得在第二个模块0-1转换时速度会继续下降一倍,那样才会最终呈现1HZ的频率,实验证明并不是这样。所以cnt_en_0to1模块并不具备延时功能。
实验二(2):增加闪烁频率,使用实验来测定,到什么频率时,你分不清1和E,此时你看到的是什么图样?
答:当参数MAX_VAL = 500_000时,频率为100HZ时,即周期为100ms,分不清1和E,此时看到的是8888。