rtl中握手流水前向/后向插流水

 首先前向会引入至少一个cyc的延迟,前向 m_valid和m_dout是寄存器输出

而后向是s_ready寄存器输出,如果m_ready没有反压,数据不会有delay。

根据实际情况选择使用,也可以两个级联使用。

1.前向插流水

assign s_ready = (~m_valid) | m_ready;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        m_valid <= 1'd0;
    else if (start == 1'd1)
        m_valid <= 1'd0;
    else if (s_valid == 1'd1)
        m_valid <= 1'd1;
    else if (m_ready == 1'd1)
        m_valid <= 1'd0;
end

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        m_dout <= {DW{1'd0}};
    else if (s_valid == 1'd1 && s_ready == 1'd1)
        m_dout <= s_din;
end

1.2 非完整写法

assign s_ready = m_ready;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        m_valid <= 1'd0;
    else if (start == 1'd1)
        m_valid <= 1'd0;
    else if (s_valid == 1'd1 && s_ready == 1'd1)
        m_valid <= 1'd1;
    else if (m_ready == 1'd1)
        m_valid <= 1'd0;
end

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        m_dout <= {DW{1'd0}};
    else if (s_valid == 1'd1 && s_ready == 1'd1)
        m_dout <= s_din;
end

这种不完整写法在s_ready和m_valid的产生都和标准写法不一致。这两种写法不能混写。非完整写法和标准写法的时序区别在于,如果最后一级有反压,不完整写法的各级流水都同时停掉了,此时没有充分利用各级流水上的寄存器缓存,各级寄存器可能是空的;而标准写法最后一级反压逐级上传,各级寄存器上都会有数据。

2.后向插流水

2.1 标准写法

assign m_valid = full | (s_valid & s_ready);
assign s_ready = ~full;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        full <= 1'd0;
    else if (start == 1'd1)
        full <= 1'd0;
    else
        full <= m_valid & (~m_ready);
end

assign m_dout = (full == 1'd1) ? s_din_ff : s_din;

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        s_din_ff <= {DW{1'd0}};
    else if (s_valid == 1'd1 && s_ready == 1'd1 && m_ready == 1'd0)
        s_din_ff <= s_din;
end

2.2 非标准写法

assign m_dout = (s_valid == 1'd1 && s_ready == 1'd1) ? s_din : s_din_ff;
assign m_valid = (s_valid & s_ready) | m_valid_tmp; 

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        m_valid_tmp <= 1'd0;
    else if (start == 1'd1)
        m_valid_tmp <= 1'd0;
    else if (s_valid == 1'd1 && s_ready == 1'd1 && m_ready == 1'd0)
        m_valid_tmp <= 1'd1;
    else if (m_ready == 1'd1)
        m_valid_tmp <= 1'd0;
end

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        s_din_ff <= {DW{1'd0}};
    else if (s_valid == 1'd1 && s_ready == 1'd1 && m_ready == 1'd0)
        s_din_ff <= s_din;
end

always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'd0)
        s_ready <= 1'd0;
    else if (start == 1'd1)
        s_ready <= 1'd0;
    else
        s_ready <= m_ready;
end

非标准写法的s_ready和m_valid都和和标准写法不一致。这两种写法不能混写。标准写法只在后级不能接收s_din时才将数据锁存到s_din_ff上面,这两种写法结果应该是一样的。

可以用在后级rdy信号做FIFO/mem的读信号,虽然fifo/mem的读数据比rden晚一拍,用上述后向插流水就没有问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值