写在前面
- 这个专栏的内容记录的是Verilog题库刷题过程,附带RTL\TestBench,并进行
代码覆盖率收集
。- 该题库算是一个
Verilog宝藏刷题网站
了,提供在线仿真环境(题库),<刷题记录>专栏,持续打卡中…
一、题目
(1)题目描述
在数字芯片设计中,通常把完成特定功能且相对独立的代码编写成子模块,在需要的时候再在主模块中例化使用,以提高代码的可复用性和设计的层次性,方便后续的修改。
请编写一个子模块,将输入两个8bit位宽的变量data_a,data_b,并输出data_a,data_b之中较小的数。并在主模块中例化,实现输出三个8bit输入信号的最小值的功能。
(2) 状态转换
对于子模块
条件 | 子模块输出 |
---|---|
a > b | b |
a = b | a,b都行 |
a < b | a |
其他(如出现X或者Z) | z |
(3)信号示意图
(4)端口描述
信号 | 方向 | 类型 | 位宽 | 描述 |
---|---|---|---|---|
clk | input | wire | 1bit | 时钟,时钟周期为5ns |
rst_n | input | wire | 1bit | 复位信号,异步下降沿有效 |
a | input | wire | 8bit | 输入的数据data_a |
b | input | wire | 8bit | 输入的数据data_b |
c | input | wire | 8bit | 输入的数据data_c |
d | output | reg | 8bit | 输出a,b,c三者中的最小值 |
二、分析
设计一个二输入比较器子模块,主模块通过调用一个子模块,子模块输出值直接和第三个值比较大小,最后输出最小值。如果调用两个子模块进行比较,会多消耗一个比较器资源。
三、RTL
1、top module
module main_mod
(
//-- system signal
input clk ,
input rst_n,
//-- input signal
input [7:0] a,
input [7:0] b,
input [7:0] c,
//--
output reg [7:0] d
);
wire [7:0] data0;
reg [7:0] c_buff;
a_b2min u0_a_b2min(
.clk (clk ),
.rst_n(rst_n),
.a (a ),
.b (b ),
.c (data0)
);
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
c_buff <= 8'b0;
end
else begin
c_buff <= c;
end
end
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
d <= 8'b0;
end
else if (data0>c_buff) begin
d <= c_buff;
end
else if (data0 <= c_buff) begin
d <= data0;
end
else begin
d <= 8'bz;
end
end
endmodule
2、子模块
module a_b2min
(
//-- system signal
input clk ,
input rst_n,
//-- input signal
input [7:0] a,
input [7:0] b,
//--
output reg [7:0] c
);
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
c <= 8'b0;
end
else if (a>b) begin
c <= b;
end
else if (a <= b) begin
c <= a;
end
else begin
c <= 8'bz;
end
end
endmodule
四、Testbench
`timescale 1ps/1ps
module tb_main_mod;
reg clk;
reg rst_n;
reg [7:0] a ;
reg [7:0] b ;
reg [7:0] c ;
wire [7:0] d ;
/*-----------------------------------------------\
-- --
\-----------------------------------------------*/
initial begin
clk = 1;
rst_n = 1;
#1000 rst_n = 0;
#4001 rst_n = 1;
repeat(10000)begin
d_case(a,b,c,{$random}%256,{$random}%256,{$random}%256);
#5000 ;
end
end
/*-----------------------------------------------\
-- --
\-----------------------------------------------*/
task d_case;
output [7:0] a;
output [7:0] b;
output [7:0] c;
input [7:0] a0;
input [7:0] b0;
input [7:0] c0;
begin
a = a0 ;
b = b0 ;
c = c0 ;
end
endtask
/*-----------------------------------------------\
-- clock period is 5ns --
\-----------------------------------------------*/
always begin
#2500 clk = ~clk;
end
/*-----------------------------------------------\
-- display --
\-----------------------------------------------*/
//-- debug signal
reg [7:0] a1,a2;
reg [7:0] b1,b2;
reg [7:0] c1,c2;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
a1 <= 8'bz;
a2 <= 8'bz;
b1 <= 8'bz;
b2 <= 8'bz;
c1 <= 8'bz;
c2 <= 8'bz;
end
else begin
a1 <= a ;
a2 <= a1;
b1 <= b ;
b2 <= b1;
c1 <= c ;
c2 <= c1;
end
end
always @ (d)begin
if((a2 > b2) && (a2 > c2))begin
if((b2 > c2) && (d == c2))begin
end
else if((b2 <= c2) && (d == b2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
else if((b2 > a2) && (b2 > c2))begin
if((a2 > c2) && (d == c2))begin
end
else if((a2 <= c2) && (d == a2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
else if((c2 > a2) && ( c2 > b2))begin
if((a2 > b2) && (d == b2))begin
end
else if((a2 <= b2) && (d == a2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
else if((a2 == b2) || (a2 == c2) || (b2 == c2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
main_mod u_main_mod(
.clk(clk),
.rst_n(rst_n),
.a (a ),
.b (b ),
.c (c ),
.d (d )
);
initial #60000000 $finish;
initial begin
$fsdbDumpfile("main_mod.fsdb");
$fsdbDumpvars ;
$fsdbDumpMDA ;
end
endmodule
五、结果分析
(1)TB结果
/*-----------------------------------------------\
-- display --
\-----------------------------------------------*/
//-- debug signal
reg [7:0] a1,a2;
reg [7:0] b1,b2;
reg [7:0] c1,c2;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
a1 <= 8'bz;
a2 <= 8'bz;
b1 <= 8'bz;
b2 <= 8'bz;
c1 <= 8'bz;
c2 <= 8'bz;
end
else begin
a1 <= a ;
a2 <= a1;
b1 <= b ;
b2 <= b1;
c1 <= c ;
c2 <= c1;
end
end
always @ (d)begin
if((a2 > b2) && (a2 > c2))begin
if((b2 > c2) && (d == c2))begin
end
else if((b2 <= c2) && (d == b2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
else if((b2 > a2) && (b2 > c2))begin
if((a2 > c2) && (d == c2))begin
end
else if((a2 <= c2) && (d == a2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
else if((c2 > a2) && ( c2 > b2))begin
if((a2 > b2) && (d == b2))begin
end
else if((a2 <= b2) && (d == a2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
else if((a2 == b2) || (a2 == c2) || (b2 == c2))begin
end
else begin
$display($realtime,", error:a = %d ;b = %d;c = %d;d = %d",a2,b2,c2,d);
end
end
可以看到,在a,b,c中如果出现x或z,则打印错误信息。
(2)波形图
由波形图可以知道,每次输出是输入的三个数据中的最小值。
(3)覆盖率
代码覆盖率100%
✍✍☛ 题库入口
经过一段时间的沉淀,发现入行IC行业,自己的底子还是很差,写的文章质量参差不齐,也没能解答大家的疑问。决定还是要实打实从基础学起,由浅入深。因此决定通过补充/完善基础知识的同时,通过题库刷题不断提高自己的设计水平,题库推荐给大家(点击直达),<题库记录>栏目不定期更新,欢迎前来讨论。
作者:xlinxdu
版权:本文版权归作者所有
转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。
本文含有隐藏内容,请 开通VIP 后查看