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

仿真:

忘记截图了

相关推荐
tju新生代魔迷1 天前
Verilog HDL 学习笔记(十)| 第10章 时序和延迟
笔记·学习·fpga开发
aprilaaaaa2 天前
(TC397 学习笔记)二、ICU和TIM的时钟计算
笔记·学习·fpga开发
X_xcccc2 天前
2026高端FPGA开发平台权威评测与选型指南
fpga开发
威嵌神州2 天前
军工加固计算机七大核心特性解析|国产化、宽温、强加固工程实现
嵌入式硬件·计算机网络·fpga开发
FPGA小迷弟2 天前
高云半导体深度解读:国产FPGA车规赛道的领跑者
fpga开发
努力搬砖的小H2 天前
FPGA应用技巧之Block Design基本使用方法
功能测试·fpga开发·zynq·block design
ALINX技术博客2 天前
【黑金云课堂】FPGA技术教程FPGA 基础:HDMI视频输入与环路输出实验
fpga开发·音视频
hahaha60162 天前
HLS高层次综合设计--axi之burst纠偏
开发语言·算法·fpga开发·c#
珞光电子USRP SDR软件无线电平台3 天前
国产嵌入式SDR平台LW-E320-G详解:射频、FPGA、ARM架构与应用选型
arm开发·fpga开发·架构
FPGA小迷弟3 天前
【硬核通俗】FPGA实现SDR软件无线电完整技术解析(原理+架构+实战)
fpga开发·dsp开发·sdr·无线电