• 牛客刷题<31>数据累加输出


    题目:数据累加输出_牛客题霸_牛客网

    思路:需要注意的是 只有当valid_a 与 ready_a同时为1才能累加数据,ready_b为高时清空计数器,在下一个时钟上升沿valid_b拉低。ready_a与ready_b之间是组合逻辑的关系,累加4个之后,valid_b拉高 然后若是ready_b为低则立刻将ready_a拉低,表示没准备好接收上游数据,数据被锁存住。核心:只有valid_a ready_a同时为高才能累加数据,只有valid_b ready_b同时为高 才能将累加结果输出,并在下一时钟上升沿重新开始累加。

    题意梳理

    两组握手信号,分别是与上游的valid_a和ready_a、与下游的valid_b和ready_b; 需要说明的是每组的valid和ready之间没有先后关系,谁先谁后都行;

    输出信号有三个:

    ①ready_a:为高表示我现在没啥事,告诉上游我准备好了,你可以发数据了;

    ②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个就得加起来输出一次,所以data_cnt == 2'd3时拉高valid_b;而等待下游接收,即当ready_a也拉高表示接收完成,则拉低valid_b,保证只有在四个数之和的时候才拉高。

        always@(posedge clk or negedge rst_n) begin
            if(!rst_n)
                valid_b <= 1'b0;
            else if(valid_a && ready_a && data_cnt == 2'd3)
                valid_b <= 1'd1;
            else if(valid_b && ready_b)
                valid_b <= 1'd0;
        end

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

        always@(posedge clk or negedge rst_n) begin
            if(!rst_n)
                data_out <= 10'b0;
            else if(valid_a && ready_a && data_cnt == 2'd0 && ready_b)
                data_out <= data_in;
            else if(valid_a && ready_a)
                data_out <= data_out + data_in;
        end 

    代码

    1. `timescale 1ns/1ns
    2. module valid_ready(
    3. input clk ,
    4. input rst_n ,
    5. input [7:0] data_in ,
    6. input valid_a ,
    7. input ready_b ,
    8. output ready_a ,
    9. output reg valid_b ,
    10. output reg [9:0] data_out
    11. );
    12. reg [1:0] data_cnt;
    13. assign ready_a = !valid_b | ready_b;
    14. always@(posedge clk or negedge rst_n)begin
    15. if(!rst_n)
    16. data_cnt <= 2'd0;
    17. else if(valid_a && ready_a)
    18. data_cnt <= (data_cnt == 2'd3) ? 2'd0 : (data_cnt + 1'd1);
    19. end
    20. always@(posedge clk or negedge rst_n)begin
    21. if(!rst_n)
    22. valid_b <= 1'd0;
    23. else if(data_cnt == 2'd3 && valid_a && ready_a)
    24. valid_b <= 1'd1;
    25. else if(valid_b && ready_b)
    26. valid_b <= 1'd0;
    27. end
    28. always@(posedge clk or negedge rst_n)begin
    29. if(!rst_n)
    30. data_out <= 1'd0;
    31. else if(ready_b && valid_a && ready_a && (data_cnt == 2'd0))
    32. data_out <= data_in;
    33. else if(valid_a && ready_a)
    34. data_out <= data_out + data_in;
    35. end
    36. endmodule

     解法二:分段写

    1. module valid_ready(
    2. input clk ,
    3. input rst_n ,
    4. input [7:0] data_in ,
    5. input valid_a ,
    6. input ready_b ,
    7. output ready_a ,
    8. output reg valid_b ,
    9. output reg [9:0] data_out
    10. );
    11. reg [1:0] count;
    12. always @ (posedge clk or negedge rst_n)
    13. begin
    14. if( ~rst_n ) begin
    15. count <= 2'b0;
    16. end
    17. else begin
    18. if(valid_a & ready_a) begin
    19. if( count == 2'd3)
    20. count <= 2'd0;
    21. else
    22. count <= count + 2'd1;
    23. end
    24. end
    25. end
    26. always @ (posedge clk or negedge rst_n)
    27. begin
    28. if( ~rst_n ) begin
    29. data_out <= 10'b0;
    30. end
    31. else begin
    32. if(valid_a && ready_a) begin
    33. if(count == 2'd0) begin
    34. data_out <= data_in;
    35. end
    36. else begin
    37. data_out <= data_out + data_in;
    38. end
    39. end
    40. end
    41. end
    42. always @ (posedge clk or negedge rst_n)
    43. begin
    44. if( ~rst_n ) begin
    45. valid_b <= 1'b0;
    46. end
    47. else begin
    48. if(count == 2'd3 && valid_a && ready_a) begin
    49. valid_b <= 1'b1;
    50. end
    51. else if(valid_b && ready_b)begin
    52. valid_b <= 1'b0;
    53. end
    54. else begin
    55. valid_b <= valid_b;
    56. end
    57. end
    58. end
    59. assign ready_a = ~valid_b | ready_b;
    60. endmodule

  • 相关阅读:
    vue考试系统后台管理项目-登录、记住密码功能
    Python中记住过去(模型状态)的五种方法
    linux mysql数据库备份
    83、SpringBoot --- 下载和安装 MSYS2、 Redis
    Nodejs安装及npm配置(超详细)
    python实现层次分析法(AHP)
    《代码大全2》第10章 使用变量的一般事项
    SaaSBase:什么是CDP集团?
    深度分页,我都是这么玩的
    鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统
  • 原文地址:https://blog.csdn.net/mxh3600/article/details/126855566