• VL4 移位运算与乘法


    写在前面

    1. 这个专栏的内容记录的是牛客的Verilog题库刷题,附带RTL\TestBench,并进行覆盖率收集
    2. 牛客算是一个Verilog宝藏刷题网站了,网站提供在线仿真环境,不用自己找题(点击直达),<刷题记录>专栏,持续打卡中…


    一、题目

    (1)题目描述

    已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)


    (2)信号示意图

    在这里插入图片描述


    (3)波形示意图

    在这里插入图片描述


    (4)端口描述

    信号方向类型位宽描述
    clkinputwire1bit时钟,周期为5ns
    rstinputwire1bit同步复位,低电平复位
    dinputwire8bit输入的8bit数据
    outoutputreg11bit输出,依次将输入*1、*3、*7、*8输出
    input_grantoutputreg1bit输出,指示当前输入是有效的,时序控制

    二、分析

    由时序可以知道,模块采用低电平有效的同步复位;在输入有效的情况下,依次输出4次乘法的结果后,再重新对输入采样并再一次输出一个输入有效的输出信号(input_grant);在两次有效的输入之间,输入数据发生了变化,因此需要在锁存每次有效的数据再进行运算。

    cntout
    0out = {3’b0,d[7:0]}
    1out = (d << 2) - d
    2out = (d <<< 3) - d
    3out = d <<< 3

    三、RTL

    module multi_sel
    (
      input              clk        , 
      input              rst        ,
      input      [7 :0]  d          ,
      output reg [10:0]  out        ,
      output reg         input_grant
    );
    
    reg [7:0] d_buff;
    reg [1:0] cnt   ;
    
    
    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'b1;
      end
    end
    
    
    always @ (posedge clk) begin
      if (!rst) begin
        d_buff <= 8'b0;
      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: begin out <= {3'b0,d}    ;end
          1: begin out <= (d_buff << 2) - d_buff;end
          2: begin out <= (d_buff << 3) - d_buff;end
          3: begin out <=  d_buff << 3          ;end
          default: out <= 11'b0;
        endcase
      end
    end
    
    
    always @ (posedge clk) begin
      if (!rst) begin
        input_grant <= 1'b0;
      end
      else if (cnt == 2'b00) begin
        input_grant <= 1'b1;
      end
      else begin
        input_grant <= 1'b0;
      end
    end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    四、Testbench

    `timescale 1ps/1ps
    module tb_multi_sel;
    
      reg         clk         ;
      reg         rst         ;
      reg  [7:0]  d           ;
      
      wire [10:0] out         ;
      
      wire        input_grant ;
    
    
    /*-----------------------------------------------\
     --    --
    \-----------------------------------------------*/
    //-- debug signal
    reg  [7:0] clk_cnt   ;
    reg  [1:0] cnt_buff  ;
    reg        clk_cnt_en;
    
    
    initial begin
      clk   = 1;
      rst   = 1;
      clk_cnt_en = 0;
      #1000 rst = 0;
      d = 8'd143; 
      #4001 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
    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
    
    /*-----------------------------------------------\
     --  clock period is 5ns  --
    \-----------------------------------------------*/
    always begin
      #2500 clk = ~clk;
    end
    
    /*-----------------------------------------------\
     --  display  --
    \-----------------------------------------------*/
    always @ (posedge clk) begin               
      cnt_buff <= multi_sel.cnt;
    end
    
    always @ (cnt_buff)begin
      if((cnt_buff == 0) && (rst == 1))begin
        if(out == {3'b0,multi_sel.d_buff});
        else begin
          $display($realtime,",*1 error:cnt_buff = %d;d_buff*1 = %d;out = %d",cnt_buff,{3'b0,multi_sel.d_buff},out);
        end
      end
      else if((cnt_buff == 1) && (rst == 1))begin
        if(out == ((multi_sel.d_buff << 2) - multi_sel.d_buff));
        else begin
          $display($realtime,",*3 error:cnt_buff = %d;d_buff*3 = %d;out = %d",cnt_buff,(multi_sel.d_buff << 2) - multi_sel.d_buff,out);
        end
      end
      else if((cnt_buff == 2) && (rst == 1))begin
        if(out == ((multi_sel.d_buff << 3) - multi_sel.d_buff));
        else begin
          $display($realtime,",*7 error:cnt_buff = %d;d_buff*7 = %d;out = %d",cnt_buff,(multi_sel.d_buff << 3) - multi_sel.d_buff,out);
        end
      end
      else if((cnt_buff == 3) && (rst == 1))begin
        if(out == (multi_sel.d_buff << 3));
        else begin
          $display($realtime,",*8 error:cnt_buff = %d;d_buff*8 = %d;out = %d",cnt_buff,(multi_sel.d_buff << 3),out);
        end
      end
    end
    
    multi_sel u_multi_sel(
                     .clk          (clk  ),
                     .rst          (rst  ),
                     .d            (d    ),
                     .out          (out  ),
                     .input_grant  (input_grant)
                  );
    
    initial #60000000 $finish;
    initial begin
      $fsdbDumpfile("multi_sel.fsdb");
      $fsdbDumpvars            ;
      $fsdbDumpMDA             ;
    end
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121

    五、结果分析

    (1)TB结果

    在这里插入图片描述在这里插入图片描述


    (2)波形图

    在这里插入图片描述

    测试波形与预期时序一致


    (3)覆盖率

    在这里插入图片描述

    例化的模块相关覆盖率达到100%


    ✍✍☛ 题库入口
      经过一段时间的沉淀,发现入行IC行业,自己的底子还是很差,写的文章质量参差不齐,也没能解答大家的疑问。决定还是要实打实从基础学起,由浅入深。因此决定通过补充/完善基础知识的同时,通过题库刷题不断提高自己的设计水平,题库推荐给大家(点击直达),<题库记录>栏目不定期更新,欢迎前来讨论。


    作者:xlinxdu
    版权:本文版权归作者所有
    转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。

  • 相关阅读:
    rabbitmq默认交换机锁绑定的routingkey-待研究
    什么原因让Redis气急败坏的回击挑战者?总有奸人想害朕
    【PyTorch][chapter 20][李宏毅深度学习]【无监督学习][ GAN]【实战】
    Android修行手册之Kotlin - 自定义View的几种写法
    PT_大数定律LLN
    物联网智能垃圾管理技术中传感器与数传电台的作用
    pytorch之nn.Conv1d详解
    SpringBoot测试及web环境模拟测试
    微信小程序 | 动手实现双十一红包雨
    Linux与Shell学习--shell系列4--常用的数据类型(数字、字符串和数组)
  • 原文地址:https://blog.csdn.net/qq_43244515/article/details/126850199