EGo1下板_简单秒表


这是一篇错误示范,记录下来
能下板正常运行的在这: 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}]
  • 8
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值