赞
踩
相信网上已经有很多文章对valid/ready的原理与应用等进行了很详细的描述,这里就不再赘述,直接上代码:
module frs #(parameter DW='d256)( input [DW-1:0] m_data , input m_valid , output m_ready , output reg [DW-1:0] s_data , output reg s_valid , input s_ready , input clk , input rst_n ); //============== Forward Registered ======== always @(posedge clk or negedge rst_n) begin if (rst_n == 1'd0) s_valid <= 1'd0; else if (m_valid == 1'd1) s_valid <= 1'd1; else if (s_ready == 1'd1) s_valid <= 1'd0; end always @(posedge clk or negedge rst_n) begin if (rst_n == 1'd0) s_data <= 'd0; else if (m_valid == 1'd1 && m_ready == 1'd1) s_data <= m_data; end assign m_ready = (~s_valid) | s_ready; endmodule
当设计中数据流处理的流水线级数比较多时,ready的时序将会变得很差,这可以通过对ready信号寄存一拍来改善其时序。
module brs #(parameter DW='d256)( input [DW-1:0] m_data , input m_valid , output m_ready , output [DW-1:0] s_data , output s_valid , input s_ready , input clk, input rst_n ); reg valid_tmp0; reg [DW-1:0] payload_tmp0; reg ready_d1; always @(posedge clk or negedge rst_n) begin if (rst_n == 1'd0) valid_tmp0 <= 1'd0; else if (m_valid == 1'd1 && s_ready == 1'd0 && valid_tmp0 == 1'd0) valid_tmp0 <= 1'd1; else if (s_ready == 1'd1) valid_tmp0 <= 1'd0; end always @(posedge clk or negedge rst_n) begin if (rst_n == 1'd0) payload_tmp0 <= 'd0; else if (m_valid == 1'd1 && s_ready == 1'd0 && valid_tmp0 == 1'd0) payload_tmp0 <= m_data; end assign s_data = (valid_tmp0 == 1'd1) ? payload_tmp0 : m_data; always @(posedge clk or negedge rst_n) begin if (rst_n == 1'd0) ready_d1 <= 1'd0; else ready_d1 <= s_ready; end assign m_ready = ~valid_tmp0 | ready_d1; assign s_valid = valid_tmp0 | m_valid; endmodule
仿真图如下,可以看到仿真结果正确。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。