引言
前面两篇文章分别给出了RS前向/后向打拍器的设计,分别可以优化valid和ready信号的时序。那么如果想要同时优化valid/ready时序则可以同时例化前向/后向打拍器。那么例化时谁在前谁在后呢?xilinx官网给出RS双向打拍器的结构框图,也该是后向打拍器在前,前向打拍器级联在后向打拍器之后。
本文在前两篇文章的基础上,对RS打拍器做整体的封装集成。包括如下几种工作模式:
"BYPASS":直通模式。
"FORWARD":前向模式,仅优化valid时序。
"BACKWARD":后向模式,仅优化ready时序。
"FULL":全向模式。同时优化valid ready时序。
CBB设计源码
// ==================-------------------------------------------------------=====================
// 在路上-正出发
// Common Building Block
// ==================-------------------------------------------------------=====================
// ________ ________ ________
// |\ ____\ |\ __ \ |\ __ \
// \ \ \___| \ \ \|\ /_ \ \ \|\ /_
// \ \ \ \ \ __ \ \ \ __ \
// \ \ \____ \ \ \|\ \ \ \ \|\ \
// \ \_______\ \ \_______\ \ \_______\
// \|_______| \|_______| \|_______|
// ==================-------------------------------------------------------=====================
// 在路上-正出发
// Common Building Block
// ==================-------------------------------------------------------=====================
// CBB Module Name :CBB_RS
// CBB Created Date :2024-08-17
// CBB Module Function:Register Slice mode:WRAP
// Usage Limitation :
// Author :在路上-正出发
// -----------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------
`timescale 1ns/1ps
module CBB_RS#(
// ---- parameter define
parameter P_RS_TYPE = "FULL",//"BYPASS" "FORWARD" "BACKWARD" "FULL"(by default)
parameter P_DATA_WIDTH = 64
)(
// ---- port define
input i_clk,
input i_rstn,
input slv_i_valid,
input [P_DATA_WIDTH-1:0] slv_i_data,
output slv_o_ready,
output mst_o_valid,
output [P_DATA_WIDTH-1:0] mst_o_data,
input mst_i_ready
);
wire w_valid;
wire [P_DATA_WIDTH-1:0] w_data;
wire w_ready;
generate
if(P_RS_TYPE == "BYPASS")
begin
assign mst_o_valid = slv_i_valid;
assign mst_o_data = slv_i_data;
assign slv_o_ready = mst_i_ready;
end
else if(P_RS_TYPE == "FORWARD")
begin
CBB_RS_FORWARD #(
.P_DATA_WIDTH(P_DATA_WIDTH)
) U_CBB_RS_FORWARD (
.i_clk (i_clk),
.i_rstn (i_rstn),
.slv_i_valid (slv_i_valid),
.slv_i_data (slv_i_data),
.slv_o_ready (slv_o_ready),
.mst_o_valid (mst_o_valid),
.mst_o_data (mst_o_data),
.mst_i_ready (mst_i_ready)
);
end
else if(P_RS_TYPE == "BACKWARD")
begin
CBB_RS_BACKWARD #(
.P_DATA_WIDTH(P_DATA_WIDTH)
) U_CBB_RS_BACKWARD (
.i_clk (i_clk),
.i_rstn (i_rstn),
.slv_i_valid (slv_i_valid),
.slv_i_data (slv_i_data),
.slv_o_ready (slv_o_ready),
.mst_o_valid (mst_o_valid),
.mst_o_data (mst_o_data),
.mst_i_ready (mst_i_ready)
);
end
else
begin
CBB_RS_BACKWARD #(
.P_DATA_WIDTH(P_DATA_WIDTH)
) U_CBB_RS_BACKWARD (
.i_clk (i_clk),
.i_rstn (i_rstn),
.slv_i_valid (slv_i_valid),
.slv_i_data (slv_i_data),
.slv_o_ready (slv_o_ready),
.mst_o_valid (w_valid),
.mst_o_data (w_data),
.mst_i_ready (w_ready)
);
CBB_RS_FORWARD #(
.P_DATA_WIDTH(P_DATA_WIDTH)
) U_CBB_RS_FORWARD (
.i_clk (i_clk),
.i_rstn (i_rstn),
.slv_i_valid (w_valid),
.slv_i_data (w_data),
.slv_o_ready (w_ready),
.mst_o_valid (mst_o_valid),
.mst_o_data (mst_o_data),
.mst_i_ready (mst_i_ready)
);
end
endgenerate
endmodule
CBB验证
验证源码
参考前两篇。
波形
略。
数据比对
perl脚本
参考上一篇。