写在前面
- 这个专栏的内容记录的是牛客的Verilog题库刷题。
- 牛客算是一个
Verilog宝藏刷题网站
了,网站提供在线仿真环境,不用自己找题(点击直达),<刷题记录>专栏,持续打卡中…
制作一个四选一的多路选择器,要求输出定义上为线网类型
信号 | 二进制码 |
---|---|
d0 | 11 |
d1 | 10 |
d2 | 01 |
d3 | 00 |
输入信号 | d0 | d1 | d2 | d3 | sel |
---|---|---|---|---|---|
类型 | wire | wire | wire | wire | wire |
输出信号 | 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-…过长,也可以使用类似的方法进行分割,利用并行执行的特点进行优化
。)
`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
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
结果正常。在Testbench中写到,当预期值和结果不一致时,会出现"Error"并打印当前预期值和实际值。
可以看到,总覆盖率是80.95%,并不到100%。原因在于受信号翻转覆盖率的影响,由图三可以看到,因为
输入信号d0~d3始终不变
,但是行覆盖率达到100%。
✍✍☛ 题库入口
经过一段时间的沉淀,发现入行IC行业,自己的底子还是很差,写的文章质量参差不齐,也没能解答大家的疑问。决定还是要实打实从基础学起,由浅入深。因此决定通过补充/完善基础知识的同时,通过题库刷题不断提高自己的设计水平,题库推荐给大家(点击直达),<题库记录>栏目不定期更新,欢迎前来讨论。2022.09.05 记
作者:xlinxdu
版权:本文版权归作者所有
转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。