前言
最近还是在写spec文档,一天不写代码保持手感的大业就不能停止。
这篇是握手拆分的模块,一般来说握手拆分有两种情况,一种是所有下游ready同时拉起了才向上握手,另外一种是下游可以分先后接收数据,每一路都接收完成后向上握手。本篇文章实现的是第二种形式。
欢迎下载测试:verilog_cbb: 个人常用cbb for verilog
接口
接口的形式是比较简单的,上游是一路握手,下游是多路握手。
实现
整体代码的实现思路其实也不难,就是使用一个history寄存器记录对下游握手的情况。当对下游只剩一路没有握手且当拍对应的out_ready置起,那么就可以对上游握手了。
module hand_split #(
parameter CHANNEL = 2
)(
input clk,
input rst_n,
input in_valid,
output in_ready,
output [CHANNEL -1:0]out_valid,
input [CHANNEL -1:0]out_ready
);
//in out hand_en
wire in_hand_en = in_valid & in_ready;
wire [CHANNEL -1:0]out_hand_en = out_valid & out_ready;
//history hand record
reg [CHANNEL -1:0]history_q;
wire [CHANNEL -1:0]history_d;
wire history_en;
assign history_en = (|out_hand_en) || in_hand_en;
assign history_d = in_hand_en ? {CHANNEL{1'b0}} : history_q | (out_valid & out_ready);
always @(posedge clk or negedge rst_n)begin
if(~rst_n) history_q <= {CHANNEL{1'b0}};
else if(history_en) history_q <= history_d;
end
//out valid
assign out_valid = {CHANNEL{in_valid}} & (~history_q);
//in_ready
assign in_ready = ((history_q | out_ready) == {CHANNEL{1'b1}});
endmodule
波形
通过auto_verification打出波形验证功能: