题解 | #数据累加输出#

数据累加输出

http://www.nowcoder.com/practice/956fa4fa03e4441d85262dc1ec46a3bd

简析

输入:data_in[7:0] , valid_a, ready_b
输出:data_out[9:0], ready_a, valid_b

  • 数据端口:输入数据data_in,输出数据data_out
  • 上游握手信号:上游输入的数据是否有效valid_a,向上游发送本模块是否准备好接受ready_a
  • 下游握手信号:本模块输出的数据是否有效valid_b,下游是否准备好接受ready_b

首先设置一个计数器cnt用来指示有效数据的数量。cnt应只在输入有效且模块当前可以接收数据的状态工作。

reg [1:0] cnt;
always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
    	cnt <= 0;
    else
        cnt <= valid_a&&ready_a? cnt+1: cnt;
end

当输入的有效数据达到4个时,输出数据有效,valid_b==1,模块暂停数据输入和更新;当下游将数据取走后,也就是ready_b==1时,valid==0,模块继续工作。

always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
     	 valid_b <= 0;
    else if(~valid_b)
    	 valid_b <= cnt==3;
    else
     	 valid_b <= ready_b==0;
end

当输出数据有效并且尚未被下游读取时,模块尚未准备好接受新数据,此时ready_a==0。同时,通过多次仿真发现ready_a可以在非时钟边沿变化,所以是组合逻辑。

assign ready_a = ~(valid_b&&~ready_b);

最后,输出的数据data_out,当输入数据无效或者模块还未准备好接收数据时,data_out保持;当计数器清零时,输入新的数据;当正常工作时,data_out与输入数据累加。

always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
      	data_out <= 0;
    else if(~valid_a||~ready_a)
      	data_out <= data_out;
    else if(cnt==0)
      	data_out <= data_in;
    else
      	data_out <= data_out+data_in;
end

代码

`timescale 1ns/1ns

module valid_ready(
	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
);
    reg [1:0] cnt;
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            cnt <= 0;
        else
            cnt <= valid_a&&ready_a? cnt+1: cnt;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            data_out <= 0;
        else if(~valid_a||~ready_a)
            data_out <= data_out;
        else if(cnt==0)
            data_out <= data_in;
        else
            data_out <= data_out+data_in;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            valid_b <= 0;
        else if(~valid_b)
            valid_b <= cnt==3;
        else 
            valid_b <= ready_b==0;
    end
    
    assign ready_a = ~(valid_b&&~ready_b);
endmodule
Verilog篇题解 文章被收录于专栏

本人对牛客网verilog篇题目一些理解

全部评论
计数器到3的时候要置零,你这没有体现
点赞 回复 分享
发布于 2023-08-11 15:00 湖北

相关推荐

头像
10-22 20:13
中南大学 Java
序言大家好呀。我是希晨er,一个初入职场的程序猿小登最近上班摸鱼刷到了一篇文章:10年深漂,放弃高薪,回长沙一年有感,还有聊聊30岁大龄程序员过往的心路历程,突然就有点感慨。我如今也做出了和大明哥一样的抉择,只是更早。此外我22年的人生,好像从来没好好记录过。正好现在工作不太忙,就想把这些经历写下来,也希望能得到社区里各位前辈的指点个人背景我是03年出生的西安娃,父母都是普通打工人。刚从中南大学软件工程专业毕业半年,现在在老家的央企过着躺平摆烂的日子成长轨迹从农村到城市的童年我家并不是西安的,只是爸妈在西安上班,从小学之后就把我接到了西安。后来老家房子拆了,爷爷奶奶也搬了过来。农村的生活,我觉...
Yki_:看哭了,恋爱那一段你女朋友说你不够关心她,可你毕竟也愿意遇到矛盾写几千字来和她慢慢分析;说不愿意给她花钱,我感觉可能只是消费观不一样;如果她想留在长沙,也应该提前跟你说开。不过她也许会心疼你放弃大厂offer转向数字马力?我也因为同样的原因有过一段幸福而充满遗憾的感情,不过跟爱情相比确实前途更重要一点。至于offer的选择,换我我也会这么选。把这些旧事记录下来以后,接下来就好好向前看吧,加油兄弟
🍊晨光随笔
点赞 评论 收藏
分享
熊大不大:微信也是华为旗下吧,我看我朋友也是华为工牌写wx
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务