今天在一段代码中看到这样的做法(红色部分是我在此加的注释):
wire [7:0] uart_dout;
wire IsDone;
reg [4:0] uart_count;
reg isDone_ld; //将IsDone延迟一拍 错了,本项目中其实是上个时钟周期的IsDone
wire isDone_pos;
//IsDone在A时钟上升沿之后锁定为1,并且是一个肪冲,下一个时钟上升沿B给其它逻辑判断之后就会==0了
//当A之后B之前,isDone_ld==0(注意) IsDone==1,所以isDone_pos==1
//当B上升沿到来的时候,此时刻isDone==1
//当B上升沿过后,isDone_ld ==1,而且isDone也==0了,所以isDone_pos==0
//总体来看:当A之后虽然isDone==1,isDone_ld==0,但isDone_pos==1;当B过后isDone==0,isDone_ld==1,但isDone_pos==0;
//即isDone==1之后wire类型变量isDone_pos也==1,下一个时钟上升沿给系统逻辑判断之后就会再次==0了
assign isDone_pos = IsDone &(!isDone_ld);
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
isDone_ld <= 0;
end
else begin
isDone_ld <= IsDone;
end
end
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
uart_count <= 5'd0;
uart_rx_data <= 128'd0;
uart_done <= 1'd0;
end
else if(isDone_pos) begin
//此时做的事情将会比isDone晚一个时钟周期
uart_rx_data <= {uart_dout,uart_rx_data[127:8]};//将每次来的数据放在高8位
uart_count <= uart_count + 5'd1;
uart_done <= 1'b0;
end
else if(uart_count == 5'd16) begin //注意上面uart_rx_data<={uart_dout,uart_rx_data[127:8]}赋值之后并不会再次改变赋值形式,只是uart_dout变了之后,uart_rx_data将会随之也改变,所以缓冲16个8bit数据(16*8=128)
uart_count <= 'd0;
uart_done <= 1'b1;//缓冲了16个数据之后就给一个uart_done脉冲
end
else begin
uart_done <= 1'b0;
end
end
来源:oschina
链接:https://my.oschina.net/u/2963604/blog/4339728