题解 | #数据累加输出#

数据累加输出

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

我最后提交的RTL呢,data_out是reg输出的,valid_b不是reg输出,后面也提交了一版valid_b reg输出的代码。

既然在累加四次的下一拍valid_b就必须要输出有效,那么可见这个题的核心就在于记录累加次数的计数器,所以我们就先做这个计数器好了:

wire hand_a = (valid_a && ready_a);
wire hand_b = (valid_b && ready_b);

//add num cnt
wire         cnt_en;
wire [3 -1:0]cnt_d;
wire [3 -1:0]cnt_q;
assign cnt_en = hand_a || hand_b;
assign cnt_d  = (hand_a && hand_b) ? 3'd1 :
                hand_b ? 3'd0 :
                cnt_q + 3'd1;
dffre #(.WIDTH(3)) u_cnt_dffre(
    .clk(clk),
    .rst_n(rst_n),
    .d(cnt_d),
    .en(cnt_en),
    .q(cnt_q)
);

这个cnt的寄存器位3bit,更新的条件必定是输入握手成功或输出握手成功,逻辑也很清晰:1.当只有输入握手时,cnt + 1;2.当只有输出握手时,cnt归零;3.当同一拍输入握手&&输出握手时,cnt置1,显然,在这种条件下是没有性能瓶颈的。

ok,cnt的条件已经做完,其他的就变得简单了。

累加寄存器的逻辑很类似,就不赘述了:

wire         value_en;
wire [10 -1:0]value_d;
wire [10 -1:0]value_q;
assign value_en = cnt_en;
assign value_d  = (hand_a && hand_b) ? {2'b0, data_in} :
                  hand_b ? 10'd0 :
                  value_q + {2'b0, data_in};
dffre #(.WIDTH(10)) u_value_dffre(
    .clk(clk),
    .rst_n(rst_n),
    .d(value_d),
    .en(value_en),
    .q(value_q)
);

assign valid_b  = (cnt_q == 3'd4);

wire valid_b_en = cnt_en;
wire valid_b_d  = (cnt_d == 3'd4);
dffre #(.WIDTH(10)) u_valid_b_dffre(
    .clk(clk),
    .rst_n(rst_n),
    .d(valid_b_d),
    .en(valid_b_en),
    .q(valid_b)
);

assign ready_a  = (cnt_q != 3'd4);

因为不能有空泡,所以输入的ready要看输出的握手,这样虽然性能更好,但是时序更差:

assign ready_a  = (cnt_q != 3'd4) || hand_b;

 完整代码

`timescale 1ns/1ns

module dffre#(
    parameter WIDTH = 1
)(
    input                 clk,
    input                 rst_n,
    input  [WIDTH -1:0]    d,
    input                en,
    output [WIDTH -1:0]    q
);
reg [WIDTH -1:0]q;
always @(posedge clk or negedge rst_n)begin
    if(~rst_n)  q <= {WIDTH{1'b0}};
    else if(en) q <= d;
end
endmodule

module valid_ready(
    input                 clk         ,   
    input                 rst_n        ,
    input        [7:0]    data_in        ,
    input                valid_a        ,
    input                 ready_b        ,
 
     output                 ready_a        ,
     output                valid_b        ,
    output      [9:0]     data_out
);

parameter MAX = 4;

wire hand_a = (valid_a && ready_a);
wire hand_b = (valid_b && ready_b);

//add num cnt
wire         cnt_en;
wire [3 -1:0]cnt_d;
wire [3 -1:0]cnt_q;
assign cnt_en = hand_a || hand_b;
assign cnt_d  = (hand_a && hand_b) ? 3'd1 :
                hand_b ? 3'd0 :
                cnt_q + 3'd1;
dffre #(.WIDTH(3)) u_cnt_dffre(
    .clk(clk),
    .rst_n(rst_n),
    .d(cnt_d),
    .en(cnt_en),
    .q(cnt_q)
);

//add num value
wire         value_en;
wire [10 -1:0]value_d;
wire [10 -1:0]value_q;
assign value_en = cnt_en;
assign value_d  = (hand_a && hand_b) ? {2'b0, data_in} :
                  hand_b ? 10'd0 :
                  value_q + {2'b0, data_in};
dffre #(.WIDTH(10)) u_value_dffre(
    .clk(clk),
    .rst_n(rst_n),
    .d(value_d),
    .en(value_en),
    .q(value_q)
);

//gen hand
wire valid_b_en = cnt_en;
wire valid_b_d  = (cnt_d == 3'd4);
dffre #(.WIDTH(10)) u_valid_b_dffre(
    .clk(clk),
    .rst_n(rst_n),
    .d(valid_b_d),
    .en(valid_b_en),
    .q(valid_b)
);
    
//assign valid_b  = (cnt_q == 3'd4);
assign ready_a  = (cnt_q != 3'd4) || hand_b;
assign data_out = value_q;

endmodule
没有mismatch但是就是报比对不过,改用
assign valid_b  = (cnt_q == 3'd4);
就过了,而我在verdi里比了一下,两个结果是完全对的上的啊


全部评论

相关推荐

2025-12-08 16:04
门头沟学院 Java
本人本科末9,今年大三。大一大二一直玩,什么都没学到,在大学混日子混了两年,每天不是在打农就是在steam。大三开学时一个和自己玩的好的同学去实习了,才发现自己白白浪费了两年的时间,如果真不冲一下就真去京东,阿里,美团送外卖了今年9月份开始学Java,一开始一直跟着黑马视频看,后面发现看视频效率太低了,时间根本不够,就开始主要看文档和看书了。这几个月一直在学,真的尽力了,希望暑期前能找一份好点的实习。我简历上面的项目大多没有指标,但是实际上我是真没多少时间去做项目,我基本主要是动手只做了外卖和天机,黑马点评和12306我都是只是看了项目。主要是自己的时间真的不多,但是这样子自己的代码能力确实比较差。而且自己也没有做过实际的工程,我顶多用jmeter测试一下接口tps啥的,比如使用Redis管道提升了一点性能,减少Redis交互,这种值得写上去吗?需不需要具体到某些数字求求各位佬给一些建议,看看简历怎么优化?项目介绍是不是不够详细?没有具体到业务方面。项目会不会提到大致实现原理导致面试官一看简历就知道怎么实现就没有问的欲望?专业技能一些字段是不是要加粗,是不是写太啰嗦了?有没有必要压缩内容变成一页?两页的话是不是都要把两页填地满满的。
给秋招一个交代:一页简历最好,网上做的项目放面试官眼里都是玩具,简历上不需要强调有什么难点,记住就行防止真的问。然后背八股,多投多面试就行
点赞 评论 收藏
分享
01-17 11:57
已编辑
门头沟学院 前端工程师
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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