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

仿真:

忘记截图了

相关推荐
数字芯片实验室1 小时前
当FPGA开始支持“自然语言编程“,芯片定制的门槛要变了
fpga开发
Kong_19943 小时前
芯片开发学习笔记·二十四——PCIe(PCI Express)
fpga开发·芯片开发
化屾为海4 小时前
FPGA CP测试
fpga开发
何如呢4 小时前
ROM查表法实现UW
fpga开发
碎碎思5 小时前
FPGA图像处理平台搭建:MIPI + VDMA + Ethernet全流程
图像处理·人工智能·fpga开发
希言自然也19 小时前
赛灵思KU系列FPGA的EFUSE/BBRAM加密操作
fpga开发
Terasic友晶科技21 小时前
答疑解惑 | DE25-Nano开发板Uboot阶段与FPGA外设交互失败
fpga开发·led·uboot·de25-nano·terasic
雨霁初曦1 天前
VHDL设计-基于四状态Moore型状态机
fpga开发
liuluyang5301 天前
clk_mux_seq sv改进
fpga开发·uvm
cmc10281 天前
222.ila窗口不出来----如果ad9361相连的rx_data_clk_in_p没有接匹配电阻,出来的时钟会不会很差,导致ila不正常工作呀
fpga开发