这是一篇错误示范,记录下来
能下板正常运行的在这: Ego1下板_计数秒表
1. 秒表功能介绍
秒表显示的时间分为3个十进制数字,从00.0到99.9秒循环计数。包含一个同步清零信号clr,使秒表返回00.0,还包含一个启动信号go,开始或停止计数。在本设计中,一个十进制数用4位的BCD码表示。例如139表示为“0001 0011 1001”和140表示为“0001 0100 0000”。
2. 秒表电路设计
计数脉冲由EGo1板的系统时钟产生。
系统时钟频率为100MHz,所以需要设置一个最大值为10_000_000的计数器,让她每0.1秒产生一个时钟周期的脉冲,用于三位BCD计数器的计数时钟。
2.1 错误结果分析
module stop_watch(
output wire [3:0] d2,
output wire [3:0] d1,
output wire [3:0] d0,
input wire clk, // system clk
input wire go, // start or not
input wire clr // reset
);
parameter count_value = 10_000_000;
reg [23:0] ms_reg;
wire ms_tick;
reg [3:0] d2_reg, d2_next;
reg [3:0] d1_reg, d1_next;
reg [3:0] d0_reg, d0_next;
always @ (posedge clk) begin
if (clr == 1'b0) begin
ms_reg <= 24'b0;
d2_reg <= 4'b0;
d1_reg <= 4'b0;
d0_reg <= 4'b0;
end else if (go == 1) begin
d2_reg <= d2_next;
d1_reg <= d1_next;
d0_reg <= d0_next;
if (ms_reg < count_value) begin
ms_reg <= ms_reg + 1;
end else begin
ms_reg <= 24'b0;
end
end
end
assign ms_tick = (ms_reg == count_value) ? 1'b1 : 1'b0;
always @ (*) begin
if (ms_tick) begin
if (d0_reg != 9)
d0_next <= d0_reg + 1;
else begin
d0_next <= 4'b0;
if (d1_reg != 9)
d1_next <= d1_reg + 1;
else begin
d1_next <= 4'b0;
if (d2_reg != 9)
d2_next <= d2_reg + 1;
else
d2_next <= 4'b0;
end
end
end
end
assign d2 = d2_reg;
assign d1 = d1_reg;
assign d0 = d0_reg;
endmodule
生成二进制流文件后下板
- 问题1:go信号使能,开始计时,但是计时速度太快,没到实际的0.1秒就自动加1。手机录像后慢速播放发现d1和d2都是0~9变化,d0漏节拍,只显示了0, 2, 4, 6, 8。
解决:第二个修改d2, d1, d0的always块的敏感事件列表改成posedge ms_tick。如果是星号的话,ms_tick和d_reg寄存器发生变化都会引起always块的重复执行,实际需要执行一次结果执行两次,但是仿真是正常加1。 - 问题2:clr复位信号使能,数码管显示00.0,期待复位信号无效后可以从00.0重新开始计时,但是实际又从复位之前被打断的时间继续计时。d_next寄存器没有受到复位影响还保存这之前的置,等到复位信号无效,会直接进入第一个always的else分支,重新给d_reg赋了旧值。而不是按期待中的先执行第二个always块,之后再执行第一个always块,有歧义
解决:在复位的时候将d_next也全部清零,但是下板后数码管一直显示0.00,不能计数。
建议:寄存器的层数不要太多,多了仿真能过,下板看不明白
2.2 最终版本
换个方法,只用一层寄存器存储计数结果
3. 数码管显示
数码管显示调用之前的七段数码管动态显示模块,除了没有显示中间的小数点,其他一切ok
- 下面的代码新增加了功能,下板出错了。如果要显示小圆点,需要多添加带有小数点的八段数码管case模块,关于数码管的动态显示,是所有数码管各有各的位选信号,但是段选信号是并联的,所以分成两个case对seg赋值是有问题的。我真是造作
module led_dynamic(
output reg [7:0] seg,
output reg [3:0] an,
input wire clk,
input wire rst,
input wire [3:0] in3, in2, in1, in0
);
parameter _0 = ~8'hc0, seg8_0 = ~8'h40;
parameter _1 = ~8'hf9, seg8_1 = ~8'h79;
parameter _2 = ~8'ha4, seg8_2 = ~8'h24;
parameter _3 = ~8'hb0, seg8_3 = ~8'h30;
parameter _4 = ~8'h99, seg8_4 = ~8'h19;
parameter _5 = ~8'h92, seg8_5 = ~8'h12;
parameter _6 = ~8'h82, seg8_6 = ~8'h02;
parameter _7 = ~8'hf8, seg8_7 = ~8'h78;
parameter _8 = ~8'h80, seg8_8 = ~8'h00;
parameter _9 = ~8'h90, seg8_9 = ~8'h10;
parameter _err = ~8'hcf;
parameter N = 18;
reg [N-1 : 0] regN;
reg [3:0] hex_in_7;
reg [3:0] hex_in_8;
always @ (posedge clk or posedge rst) begin
if (rst == 1'b0) begin
regN <= 0;
end else begin
regN <= regN + 1;
end
end
always @ (*) begin
case (regN[N-1: N-2])
2'b00: begin
an <= 4'b0001;
hex_in_7 <= in0;
end
2'b01: begin
an <= 4'b0010;
hex_in_7 <= in1;
end
2'b10: begin
an <= 4'b0100;
hex_in_8 <= in2;
end
2'b11: begin
an <= 4'b1000;
hex_in_7 <= in3;
end
default: begin
an <= 4'b1111;
hex_in_7 <= in3;
end
endcase
end
always @ (*) begin
if (an != 4'b0100)
case (hex_in_7)
4'h0: seg <= _0;
4'h1: seg <= _1;
4'h2: seg <= _2;
4'h3: seg <= _3;
4'h4: seg <= _4;
4'h5: seg <= _5;
4'h6: seg <= _6;
4'h7: seg <= _7;
4'h8: seg <= _8;
4'h9: seg <= _9;
default:seg <= _err;
endcase
else
case (hex_in_8)
4'h0: seg <= seg8_0;
4'h1: seg <= seg8_1;
4'h2: seg <= seg8_2;
4'h3: seg <= seg8_3;
4'h4: seg <= seg8_4;
4'h5: seg <= seg8_5;
4'h6: seg <= seg8_6;
4'h7: seg <= seg8_7;
4'h8: seg <= seg8_8;
4'h9: seg <= seg8_9;
default:seg <= _err;
endcase
end
endmodule
4. 顶层文件和约束文件
module top_stop_watch(
output wire [7:0] seg,
output wire [3:0] an,
input wire clk,
input wire go,
input wire clr
);
wire [3:0] data3;
wire [3:0] data2;
wire [3:0] data1;
stop_watch stop_watch0 (
.d2(data3), .d1(data2), .d0(data1),
.clk(clk), .go(go), .clr(clr)
);
led_dynamic led_dynamic0 (
.seg(seg), .an(an),
.clk(clk), .rst(1'b1), .in3(data3), .in2(data2), .in1(data1), .in0(4'b0000)
);
endmodule
约束文件
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33} [get_ports {an[3]}]
set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports {an[2]}]
set_property -dict {PACKAGE_PIN C1 IOSTANDARD LVCMOS33} [get_ports {an[1]}]
set_property -dict {PACKAGE_PIN H1 IOSTANDARD LVCMOS33} [get_ports {an[0]}]
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {seg[0]}]
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {seg[1]}]
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {seg[2]}]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {seg[3]}]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {seg[4]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {seg[5]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {seg[6]}]
set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports {seg[7]}]
set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports clk ]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports {clr}]
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {go}]