牛客刷题<五>位拆分与运算

 题目:位拆分与运算_牛客题霸_牛客网

思路:1、寄存器的位是可以分开单独运算的,并不是一个输入就是一个数据,在很多情况下,一个输入既包括数据又包括地址等其他有效信息。

2、需要考虑数据锁存的问题,一定要在sel为0的时候进行锁存,只有此时的写入才是有效的,同时存在多种情况且没有优先级问题。因此使用case语句。

可以得到状态转换

seloutvalid_out
00锁存输入0
1[3:0]+[7:4]1
2[3:0]+[11:8]1
3[3:0]+[15:12]1

 解法一

`timescale 1ns/1ns
module data_cal
(
    input clk,
    input rst,
    input [15:0] d,
    input [1:0] sel,
    output reg [4:0] out,
    output reg valid_out
);
    reg [15:0] data_lock;
    always@(posedge clk or negedge rst)
        begin
            if(!rst)
                data_lock <= 1'b0;
            else
                data_lock <= d;
        end
    always@(posedge clk or negedge rst)
        begin
            if(!rst)begin
                out <= 5'd0;
                valid_out <= 1'b0;
            end
            else 
                case(sel)
                    2'd0:begin
                        valid_out <= 1'b0;
                        out <= 0;
                    end
                    2'd1:begin
                        valid_out <= 1'b1;
                        out <= data_lock[3:0] + data_lock[7:4];
                    end
                    2'd2:begin
                        valid_out <= 1'b1;
                        out <= data_lock[3:0] + data_lock[11:8];
                    end
                    2'd3:begin
                        valid_out <= 1'b1;
                        out <= data_lock[3:0] + data_lock[15:12];
                    end
                    default:begin
                        valid_out <= 1'b0;
                        out <= 5'd0;
                    end
                endcase
        end
endmodule

解法二:三目运算符

`timescale 1ns/1ns

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

output [4:0]out,
output validout
);
//*************code***********//
reg [15:0] d_reg;
always@(posedge clk or negedge rst)
    if(rst == 1'b0)
        d_reg <= 16'b0;
    else if(sel == 2'b0)
       d_reg <= d;
   else
       d_reg <= d_reg;
    
assign validout = (sel == 2'b0)? 1'b0 : 1'b1;
assign out = (sel == 2'd0)? 5'b0:
             (sel == 2'd1)? d_reg[3:0] + d_reg[7:4] :
             (sel == 2'd2)? d_reg[3:0] + d_reg[11:8] :
             (sel == 2'd3)? d_reg[3:0] + d_reg[15:12] : 5'b0;

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

Testbench

`timescale 1ns/1ns



module testbench();
	reg clk=1;
	//always #5 clk = ~clk;  // Create clock with period=10
    initial begin
        repeat(100)
        #5 clk = ~clk;
    end
    reg rst;
    wire [4:0] out;
    wire valid_out;
    reg [15:0] d;
    reg [1:0] sel;
// A testbench
   initial
       begin
           rst =1'b0;
           d = 16'd0;
           sel = 2'd0;
           #2
           rst = 1'b1;
           d =16'b0000_0000_0000_0000;
           sel =2'd0;
           #10
           rst = 1'b1;
           d =16'b1000_0100_0010_0001;
           sel =2'd2;
           #10
           rst = 1'b1;
           d =16'b1000_0100_0010_0011;
           sel =2'd1;
           #10
           rst = 1'b1;
           d =16'b1000_0100_0010_0011;
           sel =2'd0;
           #5
           rst = 1'b1;
           d =16'b1000_0100_0010_0011;
           sel =2'd3;
           #10
           rst = 1'b1;
           d =16'b1000_0100_0010_0111;
           sel =2'd3;
       end
    
 data_cal data_cal_inst
(
    .clk(clk),
    .rst(rst),
    .d(d),
    .sel(sel),
    .out(out),
    .valid_out(valid_out)
);
    
    
//end    
  initial begin
    $dumpfile("out.vcd");
    // This will dump all signal, which may not be useful
    //$dumpvars;
    // dumping only this module
    //$dumpvars(1, testbench);
    // dumping only these variable
    // the first number (level) is actually useless
    $dumpvars(0, testbench);
end  
    
endmodule

注意:initial模块中只能是reg型变量,含有clk的要单独写一个always块中,通过

repeat(100)

#5 clk = ~clk;

这样波形会更加好看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值