赞
踩
在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_valid | data_out_ready | data_in_ready | data_out_ready_en | 下一拍data_in_ready 即data_out_ready_q |
1 | 0 | 0 | 1 | 0 |
data寄存器中存放着有效数据,无法接上游数据;
data_in_valid | data_out_ready | data_in_ready | data_out_ready_en | 下一拍data_in_ready 即data_out_ready_q |
1 | 1 | 0 | 1 | 1 |
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开始又可以透传了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。