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

仿真:

忘记截图了

相关推荐
nanxl15 小时前
FPGA-DDS信号发生器
fpga开发·verilog·vivado
黄埔数据分析7 小时前
RecoNIC 入门:SmartNIC 上支持 RDMA 的计算卸载-FPGA-智能网卡-AMD-Xilinx
fpga开发
nanxl19 小时前
FPGA-数字时钟
fpga开发·verilog·vivado
尤老师FPGA1 天前
LVDS系列9:Xilinx 7系可编程输入延迟(二)
单片机·嵌入式硬件·fpga开发
内有小猪卖1 天前
时序约束 记录
fpga开发
Cao1234567893211 天前
FPGA时钟设计
fpga开发
JNTeresa1 天前
锁存器知识点详解
fpga开发
Cao1234567893211 天前
FPGA基础之基础语法
fpga开发
一大Cpp1 天前
通过Quartus II实现Nios II编程
fpga开发
7yewh2 天前
Verilog 语法 (二)
fpga开发