首先前向会引入至少一个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;endalways @(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;endalways @(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);endassign 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 s_ready = m_ready;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_valid_tmp <= 1'd1; else if (s_ready == 1'd1) m_valid_tmp <= 1'd0;endalways @(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) s_din_ff <= s_din;end非标准写法的s_ready和m_valid都和和标准写法不一致。这两种写法不能混写。非完整写法和标准写法的时序区别在于,标准写法只在后级不能接收s_din时才将数据锁存到s_din_ff上面,而且s_ready的时序比非标准写法好。非标的写法在任何时候数据都会锁存在s_din_ff上面。