前言
最近还是在写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打出波形验证功能: