ZYNQ_project:key_breath

Synth 8-327\] inferring latch for variable 'led_breath_reg' \["C:/Users/warrior/Desktop/ZYNQ/pl/key_breath/rtl/led_breath.v":66

因为在组合逻辑中,用了非阻塞赋值的方式赋值信号。

组合逻辑自己给自己赋值会产生组合回环,输出不稳定。

模块框图:

代码:

复制代码
/*
    电容按键的上升沿检测,拉高一个时钟周期作为控制标志信号。
*/
module key(
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            key_cup     ,

    output      reg             key_flag    
);
    // reg signal define
    reg             key_cup_r1 ;
    reg             key_cup_r2 ;
    wire            key_flag_r ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            key_cup_r1 <= 1'b0 ;
            key_cup_r2 <= 1'b0 ;
        end
        else begin
            key_cup_r1 <= key_cup    ;
            key_cup_r2 <= key_cup_r1 ;
        end
    end
    assign  key_flag_r = key_cup_r1 && ~key_cup_r2 ;
    // output   key_flag
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            key_flag <= 1'b0 ;
        else
            key_flag <= key_flag_r ;
    end 
endmodule

// 呼吸灯,控制信号来一次,切换灯呼吸。
module led_breath(
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            key_flag    ,

    output      reg     [1:0]   led_out     
);
    parameter   MAX_CNT_MS = 1000 ,
                MAX_CNT_US = 1000 ,
                MAX_CNT_NS = 50   ;

    // reg signal define
    reg     [5:0]       cnt_ns ;
    reg     [9:0]       cnt_us ;
    reg     [9:0]       cnt_ms ;
    reg                 led_mod;
    reg                 led_sel;
    //reg                 led_breath ;
    wire                led_breath ;
    /*************************************************************/
    // reg     [5:0]       cnt_ns ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n)
            cnt_ns <= 6'd0 ;
        else if((cnt_ns == MAX_CNT_NS - 1) || (key_flag))
            cnt_ns <= 6'd0 ;
        else
            cnt_ns <= cnt_ns + 1'b1 ;
    end
    // reg     [9:0]       cnt_us ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_us <= 10'd0 ;
        else if(((cnt_us == MAX_CNT_US - 1)&&(cnt_ns == MAX_CNT_NS - 1))||(key_flag))
            cnt_us <= 10'd0 ;
        else if(cnt_ns == MAX_CNT_NS - 1)
            cnt_us <= cnt_us + 1'b1 ;
        else 
            cnt_us <= cnt_us ; 
    end
    // reg     [9:0]       cnt_ms ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            cnt_ms <= 10'd0 ;
        else if(((cnt_ms == MAX_CNT_MS - 1)&&(cnt_us == MAX_CNT_US - 1)&&(cnt_ns == MAX_CNT_NS - 1))||(key_flag))
            cnt_ms <= 10'd0 ;
        else if((cnt_us == MAX_CNT_US - 1)&&(cnt_ns == MAX_CNT_NS - 1))
            cnt_ms <= cnt_ms + 1'b1 ;
        else 
            cnt_ms <= cnt_ms ;
    end
    // reg                led_mod ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            led_mod <= 1'b1 ;
        else if(key_flag)
            led_mod <= 1'b1 ;
        else if((cnt_ms == MAX_CNT_MS - 1)&&(cnt_us == MAX_CNT_US - 1)&&(cnt_ns == MAX_CNT_NS - 1))
            led_mod <= ~led_mod ;
        else 
            led_mod <= led_mod ;
    end

    // led_breath
    // always @(posedge sys_clk or negedge sys_rst_n) begin
    //     if(~sys_rst_n)
    //         led_breath <= 1'b0 ;
    //     else if((led_mod && (cnt_ms > cnt_us)) || (~led_mod && (cnt_ms < cnt_us)))
    //         led_breath <= 1'b1 ;
    //     else if(((led_mod) && (cnt_ms <= cnt_us)) || (~led_mod && (cnt_ms >= cnt_us)))
    //         led_breath <= 1'b0 ;
    //     else 
    //         led_breath <= led_breath ;
    // end
    // always @(*) begin
    //     if(~sys_rst_n)
    //         led_breath = 1'b0 ;
    //     else if((led_mod && (cnt_ms > cnt_us)) || (~led_mod && (cnt_ms < cnt_us)))
    //         led_breath = 1'b1 ;
    //     else if(((led_mod) && (cnt_ms <= cnt_us)) || (~led_mod && (cnt_ms >= cnt_us)))
    //         led_breath = 1'b0 ;
    //     else 
    //         led_breath = led_breath ;
    // end
    assign  led_breath = ((led_mod && (cnt_ms > cnt_us)) || (~led_mod && (cnt_ms < cnt_us))) ? 1'b1 : 1'b0 ;

    // reg led_sel ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            led_sel <= 1'b0 ;
        else if(key_flag)
            led_sel <= ~led_sel ;
    end
    // output      reg     [1:0]   led_out    
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) 
            led_out <= 2'b00 ;
        else if(led_sel == 0)
            led_out <= {1'b0,led_breath} ;
        else if(led_sel == 1)
            led_out <= {led_breath,1'b0} ;
        else 
            led_out <= 2'b00 ;
    end 

endmodule

module top(
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            key_cup     ,

    output      wire    [1:0]   led_out     
);
    // wire signal define
    wire            key_flag ;

key key_inst(
    .sys_clk            ( sys_clk    ) ,
    .sys_rst_n          ( sys_rst_n  ) ,
    .key_cup            ( key_cup    ) ,

    .key_flag           ( key_flag   )  
);

led_breath led_breath_inst(
    .sys_clk            ( sys_clk    ) ,
    .sys_rst_n          ( sys_rst_n  ) ,
    .key_flag           ( key_flag   ) ,

    .led_out            ( led_out    )  
);

endmodule

`timescale 1ns/1ns
module test_top();
    reg             sys_clk   ;
    reg             sys_rst_n ;
    reg             key_cup   ;
    wire    [1:0]   led_out   ;

top top_inst(
    .sys_clk        ( sys_clk   ) ,
    .sys_rst_n      ( sys_rst_n ) ,
    .key_cup        ( key_cup   ) ,

    .led_out        ( led_out   )  
);
    parameter   CYCLE = 20 ;
    defparam    top_inst.led_breath_inst.MAX_CNT_MS = 100 ;
    defparam    top_inst.led_breath_inst.MAX_CNT_US = 100 ;
    defparam    top_inst.led_breath_inst.MAX_CNT_NS = 50  ;
                
    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        key_cup   <= 1'b0 ;
        #( CYCLE * 2 )    ;
        sys_rst_n <= 1'b1 ;
        #(CYCLE * 10)     ;
        
        #(CYCLE * 1200000);
        key_cup    <= 1'b1;
        #(CYCLE * 10)     ;
        key_cup   <= 1'b0 ;
        #(CYCLE * 1200000);
        $stop             ;
    end
    always #(CYCLE / 2) sys_clk = ~sys_clk;
endmodule

仿真:

忘记截图了

相关推荐
威嵌神州10 小时前
天脉 3 开发环境与 BSP 适配:IDE license、驱动开发、飞腾平台
ide·驱动开发·嵌入式硬件·fpga开发
FPGA小迷弟1 天前
FPGA 应用技术能力的完整闭环(5-8)
fpga开发·dsp开发·fpga·sdr·无线电
狂奔蜗牛(bradley)1 天前
搞定100ns抖动:ARM+FPGA混合EtherCAT主站实战方案
嵌入式硬件·fpga开发
free-elcmacom1 天前
FPGA学习笔记<2>Verilog输入
fpga开发·硬件工程
学习FPGA的电气小兴兴1 天前
基于FPGA的CORDIC向量模式实现arctan运算,Verilog HDL实现
嵌入式硬件·fpga开发·数字信号处理·verilog·fpga·cordic·arctan
FPGA小迷弟2 天前
FPGA 应用技术能力的完整闭环(1-4)
fpga开发·dsp开发·fpga·sdr·无线电
Eloudy2 天前
FPGA 开发与 IC 数字前端设计
fpga开发
tju新生代魔迷2 天前
Verilog HDL 学习笔记(十八)| 附录C:关键字、系统任务和编译指令
fpga开发
free-elcmacom2 天前
FPGA学习笔记<1>FPGA的开发流程
fpga开发·硬件工程·hdl
明德扬2 天前
AD9653单通道波形怎么看?幅度、频率与基础测量入门
学习·fpga开发·fpga