写在前面

  1. 这个专栏的内容记录的是牛客的Verilog题库刷题。
  2. 牛客算是一个Verilog宝藏刷题网站了,网站提供在线仿真环境,不用自己找题(点击直达),<刷题记录>专栏,持续打卡中…


一、题目

1. 题目描述

制作一个四选一的多路选择器,要求输出定义上为线网类型


2. 状态转换

信号 二进制码
d0 11
d1 10
d2 01
d3 00

3. 信号示意图

在这里插入图片描述


4. 波形示意图

在这里插入图片描述


5. 输入描述

输入信号 d0 d1 d2 d3 sel
类型 wire wire wire wire wire

6. 输出描述

输出信号 mux_out
类型 wire

二、分析

由波形图可以得到下面的表格

信号 片选值 mux_out
sel 2’b00 d3(2‘b10)
sel 2’b01 d2(2’b01)
sel 2’b10 d1 (2’b00)
sel 2’b11 d0 (2‘b11)

在这里插入图片描述

软件思想上,有两种实现方法,一是使用if-else,二是使用case语句。实际对应的电路实际上都是数选器。

  实现的方式有三种,一是使用四输入查找表case方式;二是使用if-else if-else;三是使用两个二输入的查找表方式,此方法使用的资源一样,但是速度提升一倍(如果if-else if-…过长,也可以使用类似的方法进行分割,利用并行执行的特点进行优化。)


三、RTL

`timescale 1ns/1ns
module mux4_1(
  input [1:0] d0  ,
  input [1:0] d1  ,
  input [1:0] d2  ,
  input [1:0] d3  ,
  input [1:0] sel ,

  output [1:0] mux_out
);

reg [1:0] mux_out_tmp;

always @ (*)begin
	case(sel)
     2'b00: mux_out_tmp = d3;
     2'b01: mux_out_tmp = d2; 
     2'b10: mux_out_tmp = d1; 
     2'b11: mux_out_tmp = d0;  
     default: mux_out_tmp = d0;
   endcase
end

/*
always @ (*)begin
  if(sel == 2'b00) mux_out_tmp = d3;
  else if(sel == 2'b01) mux_out_tmp = d2;
  else if(sel == 2'b10) mux_out_tmp = d1;
  else mux_out_tmp = d0;
end
*/

assign mux_out = mux_out_tmp;

endmodule

四、Testbench

module tb_mux4_1;

  reg [1:0] mux_out;

  reg [1:0] d3     ;
  reg [1:0] d2     ;
  reg [1:0] d1     ;
  reg [1:0] d0     ;
  reg [1:0] sel    ;

initial begin
  d0  = 2'b11;
  d1  = 2'b00;
  d2  = 2'b01;
  d3  = 2'b10;
  case_4(sel,2'b00);
  case_4(sel,2'b01);
  case_4(sel,2'b10);
  case_4(sel,2'b11);

  repeat(100)begin
    case_random(sel); 
  end
end

/*-----------------------------------------------\
 --    --
\-----------------------------------------------*/
task case_4;
  output [1:0] a;
  input  [1:0] b;

  case(b)
    2'b00:    a = 2'b00;
    2'b01: #1 a = 2'b01;
    2'b10: #1 a = 2'b10;
    2'b11: #1 a = 2'b11;
  endcase
endtask


/*-----------------------------------------------\
 --    --
\-----------------------------------------------*/
task case_random;
  output [1:0] a;
  #1 a = {$random}%4;
endtask

always@(mux_out) begin              
  if(mux_out == sel  )begin
    //$display("Expected decryption result: %d", sel);
    //$display("Actual   decryption result: %d", mux_out);
    //$display("Correct! The same as the expected!\n");
  end
  else if({!mux_out[1],mux_out[0]} == sel)begin
    //$display("Expected decryption result: %d", sel);
    //$display("Actual   decryption result: %d", mux_out);
    //$display("Correct! The same as the expected!\n");
  end
  else begin
    $display("Expected decryption result: %d", sel);
    $display("Actual   decryption result: %d", mux_out);
    $display("Error!,sel= %d,out= %d\n",sel,mux_out);
  end
end

mux4_1 tb_mux4_1(
                 .d0(d0),
                 .d1(d1),
                 .d2(d2),
                 .d3(d3),
                 .sel(sel),
                 .mux_out(mux_out)
);


initial #100 $finish;
initial begin
  $fsdbDumpfile("mux4_1.fsdb");
  $fsdbDumpvars            ;
  $fsdbDumpMDA             ;
end
endmodule


五、结果分析

(1) TB结果

在这里插入图片描述

结果正常。在Testbench中写到,当预期值和结果不一致时,会出现"Error"并打印当前预期值和实际值。


(2)波形图

在这里插入图片描述


(3)覆盖率

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

可以看到,总覆盖率是80.95%,并不到100%。原因在于受信号翻转覆盖率的影响,由图三可以看到,因为输入信号d0~d3始终不变,但是行覆盖率达到100%。


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


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

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐