牛客网——VL4移位运算与乘法

1. 题目

VL4 移位运算与乘法

提示:左移实现×2功能。

d[7:0]out[10:0]
d*1d{3'b0,d}
d*3d*(4-1)(d<<2)-d
d*7d*(8-1)(d<<3)-d
d*8d*8d<<3

2. RTL

module multi_sel
(
    input   wire    [7:0]   d   ,
    input   wire            clk ,
    input   wire            rst ,
    output  reg             input_grant,
    output  reg     [10:0]  out
);

reg [1:0]   cnt;
reg [7:0]   d_buff;

always@(posedge clk)begin 
    if(!rst)begin 
        cnt <= 2'b0;
    end else if(cnt == 3)begin 
        cnt <= 2'b0;
    end else begin 
        cnt <= cnt + 1;
    end 
end 

always@(posedge clk)begin 
    if(!rst)begin 
        d_buff <= 8'd0;
    end else if(cnt == 0)begin 
        d_buff <= d;
    end else begin 
        d_buff <= d_buff;
    end     
end 

always@(posedge clk)begin 
    if(!rst)begin
        out <= 11'b0;
    end else begin 
        case(cnt)
            0 : out <= {3'b0,d};
            1 : out <= (d_buff<<2) - d_buff;
            2 : out <= (d_buff<<3) - d_buff;
            3 : out <= d_buff<<3;
            default : out <= 11'b0;
        endcase
    end 
end 

always@(posedge clk)begin 
    if(!rst)begin 
        input_grant <= 1'b0;
    end else if(cnt == 0)begin
        input_grant <= 1'b1;
    end else begin 
        input_grant <= 1'b0;
    end 
end 

endmodule 

3. Tb 

`timescale 1ps/1ps 

module tb();

reg         clk     ;
reg         rst     ;
reg [7:0]   d       ;

wire[10:0]  out     ;
wire        input_grant;

reg [7:0]   clk_cnt;
reg [1:0]   cnt_buf;
reg         clk_cnt_en;

always begin 
    #2500 clk = ~clk;
end 

initial begin 
    clk =   1;
    rst =   1;
    clk_cnt_en = 0;

    repeat(5)@(posedge clk);
    rst =   0;
    d   =   8'd143;
    repeat(4)@(posedge clk); 
    #1 rst = 1;

            d_case(d,8'd143 );
    #15000  d_case(d,8'd7   );
    #25000  d_case(d,8'd6   );
    #5000   d_case(d,8'd128 );
    #5000   d_case(d,8'd129 );
    #30000  clk_cnt_en = 1;

    repeat(257)begin 
        #20000  d_case(d,clk_cnt);
    end 

    repeat(10000)begin 
        #5000   d_case(d,{$random}%8'hff);
    end 

    repeat(10)@(posedge clk);
    $finish();
end 

always@(multi_sel.d_buff)begin 
    if(clk_cnt == 255)begin 
        clk_cnt <= 1;
    end else if(clk_cnt_en)begin 
        clk_cnt <= clk_cnt + 1'b1;
    end else begin 
        clk_cnt <= 0;
    end 
end 

task d_case;
    output  [7:0]   a;
    input   [7:0]   b;

    a = b;

endtask

always@(posedge clk)begin 
    cnt_buf <= multi_sel.cnt;
end 

always@(cnt_buf)begin 
    if((cnt_buf == 0) && (rst == 1))begin 
        if(out == {3'b0,multi_sel.d_buff});
        else begin 
            $display($realtime,",*1 error:cnt_buf = %d;d_buff*1 = %d;out = %d",cnt_buf,{3'b0,multi_sel.d_buff},out);
        end 
    end else if((cnt_buf == 1) && (rst == 1))begin 
        if(out == ((multi_sel.d_buff << 2)-multi_sel.d_buff));
        else begin  
            $display($realtime,",*3 error:cnt_buf = %d;d_buff*3 = %d;out = %d",cnt_buf,(multi_sel.d_buff << 2)-multi_sel.d_buff,out);
        end 
    end else if((cnt_buf == 2) && (rst == 1))begin 
        if(out == ((multi_sel.d_buff << 3)-multi_sel.d_buff));
        else begin    
            $display($realtime,",*7 error:cnt_buf = %d;d_buff*7 = %d;out = %d",cnt_buf,(multi_sel.d_buff << 3)-multi_sel.d_buff,out);
        end 
    end else if((cnt_buf == 3) && (rst == 1))begin 
        if(out == (multi_sel.d_buff << 3));
        else begin 
            $display($realtime,",*8 error:cnt_buf = %d;d_buff*8 = %d;out = %d",cnt_buf,multi_sel.d_buff << 3,out);
        end 
    end 
end 

initial begin 
    $fsdbDumpfile("tb.fsdb");
    $fsdbDumpvars(0,tb);
end 

multi_sel U0 (
    .clk        (clk    ),
    .rst        (rst    ),
    .d          (d      ),
    .out        (out    ),
    .input_grant(input_grant)
);

endmodule 

4. 仿真结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值