题解 | 基础版05#位拆分与运算#

位拆分与运算

http://www.nowcoder.com/practice/1649582a755a4fabb9763d07e62a9752

作者:FPGA探索者
链接:https://www.nowcoder.com/discuss/936631?source_id=profile_create_nctrack&channel=-1
来源:牛客网

1. 题目

输入16位数据d[15:0],按照sel选择输出,并输出valid_out信号(在不输出时候拉低)

sel = 0:不输出且只有此时的输入有效

sel = 1:输出d[3:0]+d[7:4]

sel = 2:输出d[3:0]+d[11:8]

sel = 3:输出d[3:0]+d[15:12]


2. 解析

本题目的sel选择输出比较简单,可以用if...else if...else来完成,也可以用第1题提到的case语句实现。

问题的关键在于还是要像第4题一样做寄存。从波形上没有特别明显看出,但是要注意条件:

只有sel=0时的输入有效!所以在sel=0时用d_reg寄存,而sel不等于0时,相加操作用的是寄存数据d_reg拆分相加,而不是用当前的输入d。


这时候我们再仔细观察下波形,发现确实需要寄存。

组合逻辑通常是关键路径分析的点: 

3. 代码

`timescale 1ns/1ns

module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,

    output [4:0]out, // wire
output validout // wire
);
//*************code***********//

    reg [15:0] d_reg;
    wire [3:0] d0;
    wire [3:0] d1;
    wire [3:0] d2;
    wire [3:0] d3;
    assign d0 = d_reg[3:0];
    assign d1 = d_reg[7:4];
    assign d2 = d_reg[11:8];
    assign d3 = d_reg[15:12];
    reg [4:0] out_reg;
    reg validout_reg;
    always @ (posedge clk&nbs***bsp;negedge rst)
        begin
            if( ~rst ) begin
                out_reg <= 5'b0;
                validout_reg <= 1'b0;
                d_reg <= 16'b0;
            end
            else begin
                case( sel )
                    2'b00 : begin
                        d_reg <= d;
                        out_reg <= 5'b0;
                        validout_reg <= 1'b0;    
                    end
                    2'b01 : begin
                        d_reg <= d_reg;
                        out_reg <= d_reg[3:0] + d_reg[7:4];// d0 + d1;
                        validout_reg <= 1'b1;    
                    end
                     2'b10 : begin
                         d_reg <= d_reg;
                        out_reg <= d0 + d2;
                        validout_reg <= 1'b1;    
                    end
                     2'b11 : begin
                         d_reg <= d_reg;
                        out_reg <= d0 + d3;
                        validout_reg <= 1'b1;    
                    end
                    default : begin
                        out_reg <= 5'b0;
                        validout_reg <= 1'b0;  
                    end
                endcase
            end
        end

    assign out = out_reg;
    assign validout = validout_reg;

//*************code***********//
endmodule


全部评论
这套代码过不了编译
点赞 回复 分享
发布于 2022-05-06 16:19
该牛油正在参与牛客写题解薅羊毛的活动,牛币,周边,京东卡超多奖品放送,活动进入倒计时!快来捡漏啦https://www.nowcoder.com/discuss/888949?source_id=profile_create_nctrack&channel=-1
点赞 回复 分享
发布于 2022-04-27 11:35

相关推荐

运营3年修炼中接简历辅导:你的科研项目经历里,只写了你的动作,没有写你的思考和成果,不要只写使用什么进行了什么,这等于罗列你的任务,简历是为了突出你的优秀,你在什么样的任务背景下,克服了什么样的困难,针对性地做了哪些事情,最后达成了什么成果(用数据体现你的成果和效率)
点赞 评论 收藏
分享
03-16 22:00
武汉大学 C++
幸福的小熊猫想要offer:我阿里投的 c++岗,面试官说自己是做 java 的,c++这辈子才有了
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务