[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 definereg key_cup_r1 ;reg key_cup_r2 ;wire key_flag_r ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) beginkey_cup_r1 <= 1'b0 ;key_cup_r2 <= 1'b0 ;endelse beginkey_cup_r1 <= key_cup ;key_cup_r2 <= key_cup_r1 ;endendassign key_flag_r = key_cup_r1 && ~key_cup_r2 ;// output key_flagalways @(posedge sys_clk or negedge sys_rst_n) beginif(~sys_rst_n) key_flag <= 1'b0 ;elsekey_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 definereg [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) beginif(~sys_rst_n)cnt_ns <= 6'd0 ;else if((cnt_ns == MAX_CNT_NS - 1) || (key_flag))cnt_ns <= 6'd0 ;elsecnt_ns <= cnt_ns + 1'b1 ;end// reg [9:0] cnt_us ;always @(posedge sys_clk or negedge sys_rst_n) beginif(~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) beginif(~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) beginif(~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 ;// endassign 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) beginif(~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) beginif(~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 definewire 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 beginsys_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 ;endalways #(CYCLE / 2) sys_clk = ~sys_clk;
endmodule
仿真:
忘记截图了