verilog数据缓存16个字节的处理方式

自作多情 提交于 2020-08-10 18:17:58

今天在一段代码中看到这样的做法(红色部分是我在此加的注释):

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!