【Verilog-CBB】开发与验证(5)——RS后向打拍器



引言

接上篇,完成了RS前向打拍器的CBB设计。RS后向打拍器的设计则主要是为了缓解ready信号的时序问题。后向打拍器是对ready以及数据信号进行寄存。

RS后向打拍器的设计逻辑是这样的,复位时,ready缓存器(深度为1)对上游拉高ready,如果上游发来valid以及对应的数据,那么valid信号以及数据信号直接传给下游,data不需要缓存。如果后续的传输下游ready信号一直不反压上游,那么数据和有效信号不需要缓存直接传给下游。如果下游ready信号反压上游,阻塞传输,那么数据信号缓存一拍送至输出端口,等待握手,如果下游继续反压,则RS前向打拍器则会继续反压上游。其实可以理解为深度为1的握手缓存器。

CBB设计源码

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================

//                 ________          ________          ________                                                               
//                |\   ____\        |\   __  \        |\   __  \                                                              
//                \ \  \___|        \ \  \|\ /_       \ \  \|\ /_                                                             
//                 \ \  \            \ \   __  \       \ \   __  \                                                            
//                  \ \  \____        \ \  \|\  \       \ \  \|\  \                                                           
//                   \ \_______\       \ \_______\       \ \_______\                                                          
//                    \|_______|        \|_______|        \|_______|  

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================                                                                                                              
                                                                                                                                                                                                                                                                                                         
// CBB Module Name    :CBB_RS_BACKWARD
// CBB Created Date   :2024-08-16
// CBB Module Function:Register Slice mode:backward
// Usage Limitation   :
// Author             :在路上-正出发
// -----------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------

`timescale 1ns/1ps

module  CBB_RS_BACKWARD#(
// ---- parameter define
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

);

reg 						r_mst_i_ready;
always @(posedge i_clk or negedge i_rstn) begin : proc_ready
	if(~i_rstn) begin
		 r_mst_i_ready <= 1'b1;
	end else if (mst_o_valid)begin
		 r_mst_i_ready <= mst_i_ready;
	end
end

reg 	[P_DATA_WIDTH-1:0] 	r_mst_o_data;
always @(posedge i_clk) begin : proc_data
	if (slv_i_valid & slv_o_ready)begin
		 r_mst_o_data <= slv_i_data;
	end
end
assign mst_o_data = slv_o_ready ? slv_i_data  : r_mst_o_data;
assign slv_o_ready= r_mst_i_ready;
assign mst_o_valid= slv_i_valid | (~slv_o_ready);

endmodule




CBB验证

从侧 valid信号拉高的时间间隔随机,且拉高的时机与ready无关,主侧ready信号拉高的持续时间随机,相邻两个高电平之间的间隔随机。包括各种反压case。

验证源码

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================

//                 ________          ________          ________                                                               
//                |\   ____\        |\   __  \        |\   __  \                                                              
//                \ \  \___|        \ \  \|\ /_       \ \  \|\ /_                                                             
//                 \ \  \            \ \   __  \       \ \   __  \                                                            
//                  \ \  \____        \ \  \|\  \       \ \  \|\  \                                                           
//                   \ \_______\       \ \_______\       \ \_______\                                                          
//                    \|_______|        \|_______|        \|_______|  

// ==================-------------------------------------------------------=====================
//                                        在路上-正出发
//                                    Common Building Block
// ==================-------------------------------------------------------=====================                                                                                                              
                                                                                                                                                                                                                                                                                                         
// CBB Module Name    :TB_RS_BACKWARD
// CBB Created Date   :2024-08-17
// CBB Module Function:
// Usage Limitation   :
// Author             :在路上-正出发
// -----------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------

`timescale 1ns/1ps

module  TB_RS_BACKWARD();
// ---- parameter define
parameter P_DATA_WIDTH 		= 32;

// ---- port define 
reg 						i_clk;
reg 						i_rstn;

reg 						slv_i_valid;
reg [P_DATA_WIDTH-1:0] 		slv_i_data;
wire 						slv_o_ready;

wire 						mst_o_valid;
wire [P_DATA_WIDTH-1:0] 	mst_o_data;
reg 						mst_i_ready;

initial i_clk = 1'b0;
always #5 i_clk = ~i_clk;

integer time_dly1,time_dly2;

integer sim_ctrl;

initial
begin
	i_rstn = 1'b0;
	mst_i_ready = 1'b0;
	#20;
	i_rstn = 1'b1;
	#20;
	repeat(20)
	begin
		time_dly1 = $urandom_range(1,10);
		repeat(time_dly1)
		begin
			@(posedge i_clk);
		end
		@(posedge i_clk)
		mst_i_ready <= 1'b1;

		time_dly1 = $urandom_range(1,10);
		repeat(time_dly1)
		begin
			@(posedge i_clk);
		end
		@(posedge i_clk)
		mst_i_ready <= 1'b0;
	end
end

initial
begin
	sim_ctrl = 1;
	slv_i_valid = 1'b0;
	slv_i_data  = 0;
	@(posedge i_rstn);
	#20;
	repeat(20)
	begin
		@(posedge i_clk)
		slv_i_valid <= 1'b1;
		slv_i_data  <= $random();
		while(~slv_o_ready) @(posedge i_clk);
		@(posedge i_clk)
		slv_i_valid <= 1'b0;
		slv_i_data  <= 0;

		time_dly2 = $urandom_range(1,10);
		repeat(time_dly2) @(posedge i_clk);
	end
	#200;
	sim_ctrl = 0;
	#100;
	$finish;
end

integer file_handle_slv,file_handle_mst;
initial
begin
	file_handle_slv = $fopen("D:/VIVADO_WORK_SPACE/CBB_DESIGN/SIM_TXT/CBB_RS_BACKWARD_SLV_DATA.txt","w+");
 
	while(sim_ctrl)
	begin
		if(slv_i_valid&slv_o_ready)
		begin
			$fdisplayh(file_handle_slv,slv_i_data);
			$display("slv_i_data = %h",slv_i_data);
			@(posedge i_clk);
	 	end
	 	else
	 	begin
	 		@(posedge i_clk);
	 	end
	end
	$fclose(file_handle_slv);
end

initial
begin
	file_handle_mst = $fopen("D:/VIVADO_WORK_SPACE/CBB_DESIGN/SIM_TXT/CBB_RS_BACKWARD_MST_DATA.txt","w+");
 
	while(sim_ctrl)
	begin
		if(mst_o_valid&mst_i_ready)
		begin
			$fdisplayh(file_handle_mst,mst_o_data);
			@(posedge i_clk);
		end
		else
	 	begin
	 		@(posedge i_clk);
	 	end
	end
	$fclose(file_handle_mst);
end

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)
	);

endmodule

波形

数据比对

验证时将主侧和从侧的握手数据记录下来并存放于文件中,利用perl脚本完成对数据的逐行比对。对比数据的完整性、准确性、顺序性。

perl脚本源码

=pod
=================================
时间:2024-08-17
作者:在路上-正出发
摘要:实现文本的逐行对比
=================================
=cut

use warnings;

my $txt_a_path = "D:\\VIVADO_WORK_SPACE\\CBB_DESIGN/SIM_TXT\\CBB_RS_BACKWARD_SLV_DATA.txt";
my $txt_b_path = "D:\\VIVADO_WORK_SPACE\\CBB_DESIGN/SIM_TXT\\CBB_RS_BACKWARD_MST_DATA.txt";

if((-e $txt_a_path) and (-e $txt_b_path))
{
    if((-s $txt_a_path) != (-s $txt_b_path))
    {
        die "文件大小不一致!\n";
    }
}
else
{
    die "文件不存在!\n";
}
open txt_a_handle , "<$txt_a_path\n" || die "can't open $txt_a_path\n";
open txt_b_handle , "<$txt_b_path\n" || die "can't open $txt_b_path\n";

my $line_txt_a;
my $line_txt_b;
my $error_flag=0;
my $line_cnt = 0;
while($line_txt_a = <txt_a_handle>)
{   
    $line_cnt = $line_cnt + 1;
    $line_txt_b = <txt_b_handle>;
    if($line_txt_a ne $line_txt_b)
    {
        $error_flag = 1;
        print "[ERROR]this line is not same!,line num = ".$line_cnt."\n";
    }
}
close(txt_a_handle);
close(txt_b_handle);

if($error_flag)
{                               
    print "  _____      _                       _     " . "\n"; 
    print " |\" ___| U  /\"\\  u       ___        |\"|    " . "\n"; 
    print "U| |_  u  \\/ _ \\/       |_\"_|     U | | u  " . "\n"; 
    print "\\|  _|/   / ___ \\        | |       \\| |/__ " . "\n"; 
    print " |_|     /_/   \\_\\     U/| |\\u      |_____|" . "\n"; 
    print " )(\\\\,-   \\\\    >>  .-,_|___|_,-.   //  \\\\ " . "\n"; 
    print "(__)(_/  (__)  (__)  \\_)-' '-(_/   (_\")(\"_)" . "\n"; 
}
else
{
    print "  ____        _        ____       ____    " ."\n"; 
    print "U|  _\"\\ u U  /\"\\  u   / __\"| u   / __\"| u " ."\n"; 
    print "\\| |_) |/  \\/ _ \\/   <\\___ \\/   <\\___ \\/  " ."\n"; 
    print " |  __/    / ___ \\    u___) |    u___) |  " ."\n"; 
    print " |_|      /_/   \\_\\   |____/>>   |____/>> " ."\n"; 
    print " ||>>_     \\\\    >>    )(  (__)   )(  (__)" ."\n"; 
    print "(__)__)   (__)  (__)  (__)       (__)     " ."\n"; 
}

比对结果

CBB综合

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在路上-正出发

哈哈,多少是个心意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值