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

仿真:

忘记截图了

相关推荐
-木槿昔年-13 小时前
【米尔-安路MYD-YM90X创意秀】飞龙派学习和PS串口实践
学习·fpga开发
Aaron158813 小时前
基于RFSOC+VU13P+GPU架构在雷达电子战的技术
人工智能·算法·fpga开发·架构·硬件工程·信号处理·基带工程
jifengzhiling19 小时前
伺服驱动器中DSP与FPGA高效协同架构解析
fpga开发·foc电机控制
太爱学习了1 天前
FPGA图像处理之:图像畸变矫正原理及matlab与fpga实现
图像处理·matlab·fpga开发
技术性摸鱼2 天前
FPGA选型参数
fpga开发
FPGA_小田老师2 天前
ibert 7 Series GT:IBERT远近端(内外)环回测试
fpga开发·ibert·gt测试·近端pcs环回·近端pma环回·远端pcs环回·远端pma环回
尤老师FPGA2 天前
【无标题】
fpga开发
175063319452 天前
VIVADO VLA VIO 硬件调试 降采样
fpga开发
FPGA小迷弟2 天前
基于FPGA开发高速ADC/DAC芯片笔记
图像处理·fpga开发·数据采集·fpga·adc
ZYNQRFSOC3 天前
基于XCKU5P纯逻辑 NVME测试
fpga开发