刚把Verilog uart通信这块代码打出来,想另外加一个接受一帧数据小灯闪一次的功能。
源码如下
module led(
input sys_clk,
input sys_rst_n,
input uart_en,
output reg[3:0] led_en
);
wire flag;
reg uart_en_d0;
reg uart_en_d1;
assign flag=uart_en_d0&(~uart_en_d1);
reg [23:0] counter;
reg start_flag;
always @(posedge sys_clk,negedge sys_rst_n)begin
if (!sys_rst_n) begin
uart_en_d0 <= 1'b0;
uart_en_d1 <= 1'b0;
end
else begin
uart_en_d0 <= uart_en;
uart_en_d1 <= uart_en_d0;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)begin
start_flag<=1'b0;
end
else if (flag)
start_flag<=1'b1;
else if(counter==24'd1000_0000)
start_flag<=1'b0;
else
start_flag<=start_flag;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)begin
led_en<=4'b0;
counter<=24'b0;
end
else if(start_flag==1)
begin
led_en=4'b1111;
counter<=counter+1;
end
else if(counter==24'd1000_0000)begin
led_en<=4'b0;
counter<=24'b0;
end
else begin
led_en<=led_en;
counter<=counter;
end
end
endmodule
结果发送一次数据,小灯一直闪…然后我发现自己的代码 counter led start_flag全部耦合在一个always里,
else if(start_flag==1)
begin
led_en=4'b1111;
counter<=counter+1;
end
else if(counter==24'd1000_0000)begin
led_en<=4'b0;
counter<=24'b0;
end
这块,start_flag可能尚未=>0, else if(counter24’d1000_0000)这条判断压根就不会进行。同时else if(counter24’d1000_0000)这个判断电也不会进行,start_flag也不会清零。
如果把两句else if(counter==24’d1000_0000)改为else if(counter>24’d1000_0000)应该就没问题了,我采用另一种方法,把代码改为如下
module led(
input sys_clk,
input sys_rst_n,
input uart_en,
output reg[3:0] led_en
);
wire flag;
reg uart_en_d0;
reg uart_en_d1;
assign flag=uart_en_d0&(~uart_en_d1);
reg [23:0] counter;
reg start_flag;
always @(posedge sys_clk,negedge sys_rst_n)begin
if (!sys_rst_n) begin
uart_en_d0 <= 1'b0;
uart_en_d1 <= 1'b0;
end
else begin
uart_en_d0 <= uart_en;
uart_en_d1 <= uart_en_d0;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)begin
start_flag<=1'b0;
end
else if (flag)
start_flag<=1'b1;
else if(counter==24'd1000_0000)
start_flag<=1'b0;
else
start_flag<=start_flag;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter <= 24'd0;
else if (start_flag&&(counter < 24'd1000_0000))
counter <= counter + 1'b1;
else
counter <= 24'd0;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led_en <= 4'b0000;
else if((counter == 24'd0)&&start_flag)
led_en<=4'b1111;
else if(counter == 24'd1000_0000)
led_en<=4'b0000;
else
led_en <= led_en;
end
endmodule
success