牛客:VL31 数据累加输出

提交代码:

考虑情况全面

(1)valid-ready双向握手机制:上游正常通讯时(即valid_a和ready_a均为高)

(2)data_out: 同理,当和上游正常通讯时(即valid_a和ready_a均为高),数据正常接收,数据累加,当计数器data_cnt == 2'd0表示需要从头再加,清零,但注意需要等到ready_b拉高,表示下游接收完成才能清空重新累加

`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@(negedge rst_n, posedge clk)begin
	if(~rst_n)
	cnt <= 0;
	else if(valid_a && ready_a)
	//valid_a和ready_a同时拉高,valid_a数据有效,ready_a数据准备好,说明上游数据正常,计数器计数
	cnt <= cnt == 3 ? 0	: cnt + 1;
end

//在data_out准备好,valid_b拉高时,如果下游的ready_b为低,表示下游此时不能接收本模块的数据,那么,将会拉低ready_a,以反压上游数据输入;
assign ready_a = ~valid_b || ready_b;

always@(negedge rst_n, posedge clk) begin
	if (~rst_n)
	valid_b <= 0;
	else if (cnt == 3 && valid_a && ready_a)
	//完成4个数累加同时上游数据正常
	valid_b <= 1;
	else if(valid_b && ready_b) 
	//当下游ready_b拉高,且valid_b为高,表示模块与下游握手成功,valid_b在下一个时钟周期拉低;
	valid_b <= 0;
end

always@(negedge rst_n, posedge clk) begin
	if(~rst_n)
	data_out <= 0;
	else if (ready_b && cnt == 0 && ready_a && valid_a)
	data_out <= {2'b00, data_in};
	else if (ready_a && valid_a)
	data_out <= data_out + data_in;
end



endmodule

tb文件

`timescale 1ns/1ns
module testbench();
initial begin
        #50 $finish;
    end

    //波形图必须输出到out.vcd
    initial begin
        $dumpfile("out.vcd");  // 波形图必须输出到out.vcd
        $dumpvars(0, testbench);   
    end

    reg clk, rst_n, valid_a, ready_b;
    reg [7:0]data_in;
    wire ready_a, valid_b;
    wire [9:0] data_out;

    initial begin
        rst_n = 0;
        clk = 0;
        valid_a = 1;
        #2 rst_n = 1;
    end  

    always #1 clk = ~clk;

    initial begin
        ready_b = 0;
        #17 ready_b = 1;
    end

    always@(negedge rst_n, posedge clk) begin
        if (~rst_n)
        data_in <= 1;
        else
        data_in <= data_in + 1;
    end

    valid_ready dut(
        .clk(clk), 
        .rst_n(rst_n), 
        .data_in(data_in), 
        .valid_a(valid_a), 
        .ready_b(ready_b),
        .ready_a(ready_a), 
        .valid_b(valid_b), 
        .data_out(data_out)
    );
endmodule

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值