【芯片前端】保持代码手感——握手协议ready打拍时序优化

在valid-ready双向握手机制下,对下游反馈的ready进行打拍,实现对上游接口的ready信号时序优化。当拍若ready有效则数据可以直接向下游握手,若ready无效则数据寄存一拍。要求数据输出不能丢弃或乱序,且上游的ready为寄存器输出

接口如下:

module backward_pipe #(
	parameter WIDTH = 8)
(
	input clk,
	input rst_n,
	
	input [WIDTH -1:0]data_in,
	input 			  data_in_valid,
	output			  data_in_ready,
	
	output[WIDTH -1:0]data_out,
	output			  data_out_valid,
	input			  data_out_ready
);

endmodule

题目解析

给ready打拍一直都是我没想明白的操作,所以这次一定要把他想清楚。这个题目的核心就是给前级传的ready必须是寄存器输出,所以我想了三个小时,终于把这个寄存器给做出来了:

wire out_ready_en = data_in_valid || data_out_ready;
wire out_ready_d  = data_out_ready;
wire out_ready_q;
dffse #(.WIDTH(1), .VALUE(1'b1))
u_out_ready_dffse(
	.clk(clk),
	.rst_n(rst_n),
	.d(out_ready_d),
	.en(out_ready_en),
	.q(out_ready_q)
);
assign data_in_ready  = out_ready_q;

这个寄存器必须是复位值为1,因为不管上来有没有ready这个打拍也能存一拍。那么这个寄存器的含义是啥呢?他表示着此时data的寄存器里的值是不是一个有效的值,如果为1表示data寄存器没有用或者没值,为0表示data的寄存器里有有效值。所以上来复位值为1表示此时data寄存器里没有有效值。而后每次en时把data_out_ready更新进去,如果更新进去的是1那么就意味着数据直接被下游拿走了(“当拍若ready有效则数据可以直接向下游握手”),如果更新进去的值是0则意味着数据下游没接,存在data寄存器里了。

那么out_ready_en的逻辑实际是比较难做的。当data_out_ready为1时肯定是可以更新寄存器的,那么另外一种情况就是data_in_valid为1时,看下面的场景分析:

data_in_validdata_out_readydata_in_readydata_out_ready_en

下一拍data_in_ready

即data_out_ready_q

10010

data寄存器中存放着有效数据,无法接上游数据;

data_in_validdata_out_readydata_in_readydata_out_ready_en

下一拍data_in_ready

即data_out_ready_q

11011

data寄存器中存放着有效数据,当拍被取走,因此刷新 data_out_ready_q表示从下一拍的data寄存器里没有有效值,如果下一拍的out_ready还是为1那么数据就透传了,如果下一拍out_ready又变成0那么数据存入data寄存器(因为下一拍data_in_ready一定是1)。如果还是没说清楚,那一会看下波形吧。

data寄存器的逻辑还是非常简单:

wire 			 data_en = data_in_valid && data_in_ready;
wire [WIDTH -1:0]data_d  = data_in;
wire [WIDTH -1:0]data_q;
dffe #(.WIDTH(WIDTH))
u_in_data_dffe(
	.clk(clk),
	.d(data_d),
	.en(data_en),
	.q(data_q)
);

接下来是产生对外输出的逻辑:

assign data_out_valid = data_in_valid || (~out_ready_q);
assign data_out       = out_ready_q ? data_in : data_q;
assign data_in_ready  = out_ready_q;

out_ready_q的含义很清楚,为0时表示data寄存器里有值需要往外取。可以看到这样给上游传出去的data_in_ready是寄存器输出,逻辑非常干净。

波形分析

感觉给ready打拍这个事啊,拿话说根本说不清以后我就拿这个题去考别人好了,看谁能说清。

看这个波形,时刻1上游有valid下游没有ready,那么把数据存入了寄存器,上游ready跳变位0表示data寄存器里有有效值,不能再接上游的数据了;

时刻2,下游ready起了,把data寄存器里的数据0取走;时刻3下游ready持续有效,直接把值1透传给下游(注意此时数据还是同时写入了data寄存器,但是data_out_ready_q即data_in_ready标记为1即data寄存器里的值是无效值);

时刻4,下游ready起了,把data寄存器里的数据2取走;而后下一拍data_out_ready回归为0,则值3被写到了寄存器中且被标记有效;

时刻5,数值3被取走,且后面从时刻6开始又可以透传了。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

尼德兰的喵

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值