写在前面
- 这个专栏的内容记录的是Verilog题库解题过程,附带RTL\TestBench,并进行相关
覆盖率收集
。- 该题库算是一个
Verilog宝藏刷题网站
了,提供在线仿真环境(题库),<刷题记录>专栏,持续打卡中…
一、题目
(1)题目描述
根据指示信号select的不同,对输入信号a,b实现不同的运算。输入信号a,b为8bit有符号数,当select信号为0,输出a;当select信号为1,输出b;当select信号为2,输出a+b;当select信号为3,输出a-b.
(2) 状态转换
select | c[9:0] |
---|---|
00 | a |
01 | b |
10 | a+b |
11 | a-b |
(3)信号示意图
(4)端口描述
信号 | 方向 | 类型 | 位宽 | 描述 |
---|---|---|---|---|
clk | input | wire | 1bit | 时钟,时钟周期为5ns |
rst_n | input | wire | 1bit | 异步下降沿有效 |
a[7:0] | input | wire | 8bit | 输入的数据 |
b[7:0] | input | wire | 8bit | 输入的数据 |
select[1:0] | input | wire | 2bit | 0:输出a; 1:输出b; 2:输出a+b; 3:输出a-b; |
c[8:0] | output | reg | 9bit | 输出的有符号结果 |
二、分析
注意有符号数运算的数据溢出情况,需要进行位宽扩展。
三、RTL
module data_select(
input clk ,
input rst_n ,
input signed [7:0] a ,
input signed [7:0] b ,
input [1:0] select,
output reg signed [8:0] c
);
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
c <= 9'sb0;
end
else begin
case(select)
2'b00:c <= {a[7],a} ;
2'b01:c <= {b[7],b} ;
2'b10:c <= {a[7],a} + {b[7],b};
2'b11:c <= {a[7],a} - {b[7],b};
default:c <= 9'sb0;
endcase
end
end
endmodule
四、Testbench
`timescale 1ps/1ps
module tb_data_select;
reg clk ;
reg rst_n ;
reg signed [7:0] a ;
reg signed [7:0] b ;
reg [1:0] select ;
wire signed [8:0] c ;
/*-----------------------------------------------\
-- --
\-----------------------------------------------*/
//-- debug signal
initial begin
clk = 1;
rst_n = 1;
#1000 rst_n = 0;
#4001 rst_n = 1;
repeat(20000)begin
#5000 d_case(a,b,select);
end
end
/*-----------------------------------------------\
-- --
\-----------------------------------------------*/
task d_case;
output signed [7:0] a;//a
output signed [7:0] b;//b
output [1:0] s;//select
begin
a = $random%256;
b = $random%256;
s = {$random}%4;
end
endtask
/*-----------------------------------------------\
-- clock period is 5ns --
\-----------------------------------------------*/
always begin
#2500 clk = ~clk;
end
/*-----------------------------------------------\
-- display --
\-----------------------------------------------*/
always @ (c)begin
if((select == 0) && (rst_n == 1))begin
if(c == {a[7],a});
else begin
$display($realtime,",signed a = %b;signed c = %b",{a[7],a},c);
end
end
else if((select == 1) && (rst_n == 1))begin
if(c == {b[7],b});
else begin
$display($realtime,",signed b = %b;signed c = %b",{b[7],b},c);
end
end
else if((select == 2) && (rst_n == 1))begin
if(c == {a[7],a} + {b[7],b});
else begin
$display($realtime,",signed a = %b;signed b = %b;a+b = %b;signed c = %b",{a[7],a},{b[7],b},{a[7],a} + {b[7]},c);
end
end
else if((select == 3) && (rst_n == 1))begin
if(c == {a[7],a} - {b[7],b});
else begin
$display($realtime,",signed a = %b;signed b = %b;a-b = %b;signed c = %b",{a[7],a},{b[7],b},{a[7],a} - {b[7]},c);
end
end
end
data_select u_data_select(
.clk (clk ),
.rst_n (rst_n ),
.a (a ),
.b (b ),
.select (select),
.c (c)
);
initial #60000000 $finish;
initial begin
$fsdbDumpfile("data_select.fsdb");
$fsdbDumpvars ;
$fsdbDumpMDA ;
end
endmodule
五、结果分析
(1)TB结果
TBdisplay无打印错误信息,初步检查无误。
(2)波形图
a | b | select | a+b | a-b | c |
---|---|---|---|---|---|
0010_0100 | 1000_0001 | 1 | - | - | 1_1000_0001 |
1100_0110 | 1100_0101 | 2 | - | 1_1000_1011 | |
1110_1000 | 1100_0101 | 0 | - | - | 1_1110_1000 |
0111_1000 | 1000_1001 | 3 | - | 0_1110_1111 |
由波形和计算可以知道,结果与预期一致
(3)覆盖率
RTL代码覆盖率达到100%。
✍✍☛ 题库入口
经过一段时间的沉淀,发现入行IC行业,自己的底子还是很差,写的文章质量参差不齐,也没能解答大家的疑问。决定还是要实打实从基础学起,由浅入深。因此决定通过补充/完善基础知识的同时,通过题库刷题不断提高自己的设计水平,题库推荐给大家(点击直达),<题库记录>栏目不定期更新,欢迎前来讨论。
作者:xlinxdu
版权:本文版权归作者所有
转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。