打拍优化时序不像听起来那么简单

如果你参加过IC校招面试,自然会被问到“setup/hold的概念,以及setup/hold违例怎么办?”

这时候,你肯定会立马在脑海中从打拍或者插buffer两个答案中选一个。但是在实际项目中,往往没有这么简单。举一个实际的场景:

AXI master和AXI slave这一簇信号出现setup时序违例怎么办?

1、从AXI master 到AXI slave 出现setup违例;

2、从AXI slave 到AXI master出现setup违例;

3、两者都出现setup时序违例。

 

所以AXI master和AXI slave之间的打拍会存在4中模式:

 

Forward Registered :对valid和payload路打拍

Backward Registered :对ready路打拍

Fully Registered :同时对valid/payload路和ready路打拍

Pass Through Mode:Bypass,均不打拍

 

这个问题没那么容易或者说不能够直接打拍,是因为这一簇信号遵循valid-ready协议,需要打拍的信号间存在时序的耦合

所以问题就简化成如何在遵循valid -ready协议的master和slave 之间完成“打拍”,或者说在打拍的同时处理valid-ready协议。

 

Forward Registered

 

 

always @(posedge clk or negedge rst_n)begin
   if (rst_n == 1'd0)
       valid_dst <= 1'd0;
   else if (valid_src == 1'd1)
       valid_dst <= #`DLY 1'd1;
   else if (ready_dst == 1'd1)
       valid_dst <= #`DLY 1'd0;
end
 
always @(posedge clk or negedge rst_n)begin
   if (rst_n == 1'd0)
       payload_dst <= 'd0;
   else if (valid_src == 1'd1 && ready_src == 1'd1)
       payload_dst <= #`DLY payload_src;
end
 
ready_src = (~valid_dst) | ready_dst

现在来分析下上述Forward Registered 打拍代码的几个输出端口:

 

valid_dst:在master发请求(拉高valid_src)时拉高valid_dst,直到当前master没有valid请求并且slave可以接收请求(拉高ready_dst)时拉低valid_dst,表示一次传输完成。

 

payload_dst:在master发请求(拉高valid_src),并且前面没有请求、请求已经被接收或者正在被接收时将payload_src打拍赋给payload_dst。

 

其实master本身也会遵循valid-ready协议,payload_src和valid_src做同样处理就行,即也可以在(valid_src == 1'd1 && ready_src == 1'd0)时进行赋值,因为此时payload_src输入应该约束保持原始数据。

 

ready_src:register slice或者slave可以接收数据时拉高ready_src.

 

Backward Registered

 

 

always @(posedge clk or negedge rst_n)begin
   if (rst_n == 1'd0)
       valid_tmp0 <= 1'd0;
   else if (valid_src == 1'd1 && ready_dst == 1'd0 &&valid_tmp0 == 1'd0)
       valid_tmp0 <= #`DLY 1'd1;
   else if (ready_dst == 1'd1)
       valid_tmp0 <= #`DLY 1'd0;
end
 
always @(posedge clk or negedge rst_n)begin
    if (rst_n == 1'd0)
       payload_tmp0 <= 'd0;
   else if (valid_src == 1'd1 && ready_dst == 1'd0 &&valid_tmp0 == 1'd0)
       payload_tmp0 <= #`DLY payload_src;
end
 
assign payload_dst = (valid_tmp0 == 1'd1) ?payload_tmp0 : payload_src;
 
always @(posedge clk or negedge rst_n)begin
   if (rst_n == 1'd0)
       ready_src <= 1'd0;
   else
       ready_src <= #`DLY ready_dst;
end

Backward Registered 打拍相比较Forward Registered 会复杂点,因为存在slave没有ready时master发来请求,需要暂存payload的场景。

现在来分析下上述Backward Registered打拍代码的几个输出端口:

 

ready_src:对ready通路直接进行打拍。

 

valid_dst:当slave没有ready,master发来请求时拉高标志位valid_tmp0,表示下一次slave准备好之后应该从register slice内暂存的payload拿数据

 

payload_dst:当slave没有ready,master发来请求时暂存payload到payload_tmp。最终的payload_dst根据标志位valid_tmp0从payload_tmp和payload_src之间选择

 

Fully Registered

 

类似于,简单理解就是个乒乓BUFFER,使用非空信号做valid_dst;payload的非满信号做ready_src

 

Pass Through Mode

 

直接相连

 

通过上述分析,可以使用register slice mode参数化的库,在后端要求AXI BUS打拍时直接调用,而无需重复造轮子。

 

Reference:

https://blog.csdn.net/cy413026/article/details/88698824

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值