VL31 数据累加输出
描述
实现串并转换电路,输入端输入单bit数据,每当本模块接收到6个输入数据后,输出端输出拼接后的6bit数据。本模块输入端与上游的采用valid-ready双向握手机制,输出端与下游采用valid-only握手机制。数据拼接时先接收到的数据放到data_b的低位。
电路的接口如下图所示。valid_a用来指示数据输入data_a的有效性,valid_b用来指示数据输出data_b的有效性;ready_a用来指示本模块是否准备好接收上游数据,本模块中一直拉高;clk是时钟信号;rst_n是异步复位信号。


理解:
两组握手信号,分别是与上游的valid_a和ready_a、与下游的valid_b和ready_b; 需要说明的是每组的valid和ready之间没有先后关系,谁先谁后都行。
输出信号有三个:
①ready_a:为高表示我现在没啥事,告诉上游我准备好了,你可以发数据了。为低表示我现在data_out正在发送,你先别给我发新数据。
②valid_b:为高表示给下游说我发数据了。
③data_out:给下游发的数据,配合valid_b,只有valid_b为高时,发送的才是有效数据。
那么分别来处理:
①ready_a: 如果下游ready_b拉高,表示下游可以接收模块输出数据,那么此时ready_a应拉高;同时,如果valid_b为低,表示4个数据还没收完,所以也拉高继续接收。
assign ready_a=ready_b|~valid_b;
②valid_b: 当和上游正常通讯时(即valid_a和ready_a均为高),数据正常接收,但注意计数了4个就得加起来输出,num_cnt == 2'd3时拉高valid_b;而等待下游接收,即当ready_a也拉高表示接收完成,则拉低valid_b,保证只有在四个数之和的时候才拉高。
always@(posedge clk or negedge rst_n)beginif(!rst_n)valid_b<=0;else beginif(num_cnt==3&&valid_a&&ready_a)valid_b<=1;else beginif(ready_a)valid_b<=0;endend
end
③data_out: 同理,当和上游正常通讯时(即valid_a和ready_a均为高),数据正常接收,数据累加,当计数器data_cnt == 2'd0表示需要从头再加,清零,但注意需要等到ready_b拉高,表示下游接收完成才能清空重新累加。
always@(posedge clk or negedge rst_n)beginif(!rst_n)data_out<=0;else begin
//输出数据归零与valid_b无关,a准备好且有效,b准备好,即可if(num_cnt==0&&ready_b&&(valid_a&&ready_a)) data_out<=data_in;else beginif(valid_a&&ready_a) //a准备好且有效和上游通讯正常data_out<=data_out+data_in; endendend
代码:
`timescale 1ns / 1nsmodule test(input clk , input rst_n ,input [7:0] data_in ,input valid_a ,input ready_b ,output ready_a ,output reg valid_b ,output reg [9:0] data_out
);assign ready_a=ready_b|~valid_b;reg [1:0] num_cnt;always@(posedge clk or negedge rst_n)beginif(!rst_n)num_cnt<=0;else beginif(ready_a&&valid_a)beginif(num_cnt==3)num_cnt<=0;elsenum_cnt<=num_cnt+1;endelsenum_cnt<=num_cnt;endendalways@(posedge clk or negedge rst_n)beginif(!rst_n)valid_b<=0;else beginif(num_cnt==3&&valid_a&&ready_a)valid_b<=1;elseif(ready_b&&valid_b)valid_b<=0;endendalways@(posedge clk or negedge rst_n)beginif(!rst_n)data_out<=0;else beginif(num_cnt==0&&ready_b&&valid_a&&ready_a) //输出数据归零与valid_b无关,a准备好且有效,b准备好,即可data_out<=data_in;else beginif(valid_a&&ready_a)data_out<=data_out+data_in; endendendendmodule
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
