写在前面
- 这个专栏的内容记录的是牛客的Verilog题库刷题,附带RTL\TestBench,并进行覆盖率收集。
- 牛客算是一个
Verilog宝藏刷题网站
了,网站提供在线仿真环境,不用自己找题(点击直达),<刷题记录>专栏,持续打卡中…
一、题目
(1)题目描述
对输入的32位数据进行奇偶校验,根据输入的sel情况(0是奇校验,1是偶校验),进行校验位(check)的输出。(时钟下降沿变化
)
(2) 信号示意图
(3) 波形示意图
(4)信号描述
信号 | 方向 | 类型 | 位宽 | 描述 |
---|---|---|---|---|
clk | input | wire | 1bit | 时钟 |
bus | input | wire | 32bit | 输入的数据总线,32bit |
sel | input | wire | 1bit | 校验方式的选择,0:选择奇校验;1选择偶校验 |
check | output | wire | 1bit | 校验位输出 |
二、RTL
module odd_even_check
(
input clk ,
input rst_n,
input [31:0] bus ,
input sel ,
output check
);
reg check_buff;
/*-----------------------------------------------\
-- clk :negedge --
-- sel = 0:odd --
-- sel = 1:even --
\-----------------------------------------------*/
always @ (negedge clk or negedge rst_n) begin
if (!rst_n) begin
check_buff <= 1'b0;
end
else if (sel == 1'b0) begin
check_buff <= ~^bus?1'b1:1'b0;
end
else if(sel == 1'b1) begin
check_buff <= ^bus?1'b1:1'b0;
end
end
assign check = check_buff;
endmodule
三、Testbench
`timescale 1ps/1ps
`define odd 2'b00
`define even 2'b01
`define random 2'b10
module tb_odd_even_check;
reg clk ;
reg rst_n ;
reg [31:0] bus ;
reg sel ;
reg check ;
/*-----------------------------------------------\
-- --
\-----------------------------------------------*/
initial begin
clk = 0;
rst_n = 1;
bus = 32'b0;
sel = 0;
#2500 rst_n = 0;
#2500 rst_n = 1;
bus_case(bus,0 );
sel_case(sel,`odd);
bus_case(bus,1 );
sel_case(sel,`even);
bus_case(bus,2 );
sel_case(sel,`even);
bus_case(bus,3 );
sel_case(sel,`even);
bus_case(bus,4 );
sel_case(sel,`odd );
bus_case(bus,5 );
sel_case(sel,`odd );
bus_case(bus,6 );
sel_case(sel,`odd );
bus_case(bus,7 );
sel_case(sel,`even);
bus_case(bus,8 );
sel_case(sel,`even);
bus_case(bus,9 );
sel_case(sel,`even);
repeat(100)begin
bus_case(bus,10 );
sel_case(sel,`random);
end
end
/*-----------------------------------------------\
-- --
\-----------------------------------------------*/
task bus_case;
output [31:0] a;
input [3 :0] b;
case(b)
0 : #10000 a = 32'd0 ;
1 : #10000 a = 32'd1 ;
2 : #10000 a = 32'd2 ;
3 : #10000 a = 32'd3 ;
4 : #10000 a = 32'd4 ;
5 : #10000 a = 32'd5 ;
6 : #10000 a = 32'd6 ;
7 : #10000 a = 32'd7 ;
8 : #10000 a = 32'd8 ;
9 : #10000 a = 32'd9 ;
10: #10000 a = {$random}%32'hFFFFFFFF;
endcase
endtask
task sel_case;
output a;
input [1:0] b;
case(b)
`odd : a = 1'b0 ;
`even : a = 1'b1 ;
`random: a = {$random}%2;
endcase
endtask
/*-----------------------------------------------\
-- clock period is 5ns --
\-----------------------------------------------*/
always begin
#2500 clk = ~clk;
end
/*-----------------------------------------------\
-- display --
\-----------------------------------------------*/
always @ (posedge clk) begin
if(sel == 0)begin
if((^bus) == 0)begin
if(check == 1);
else $display("odd error:bus = %b ; bus_check = %b ; check = %b",bus,~^bus,odd_even_check.check_buff);
end
else if((^bus) == 1)begin
if(check == 0);
else $display("odd error:bus = %b ; bus_check = %b ; check = %b",bus,~^bus,odd_even_check.check_buff);
end
end
else if(sel == 1)begin
if((^bus) == 0)begin
if(check == 0);
else $display("even error:bus = %b ; bus_check = %b ; check = %b",bus,^bus,odd_even_check.check_buff);
end
else if((^bus) == 1)begin
if(check == 1);
else $display("even error:bus = %b ; bus_check = %b ; check = %b",bus,^bus,odd_even_check.check_buff);
end
end
end
odd_even_check tb_odd_even_check(
.clk (clk ),
.rst_n (rst_n),
.bus (bus ),
.sel (sel ),
.check (check)
);
initial #1000000 $finish;
initial begin
$fsdbDumpfile("tb_odd_even_check.fsdb");
$fsdbDumpvars ;
$fsdbDumpMDA ;
end
endmodule
四、结果分析
(1)TB结果
没有打印错误信息,初步证明设计符合要求。
(2)波形图
波形图与预期时序吻合
(3)覆盖率
RTL总体覆盖率是95.8%,受分支覆盖率(83.3%)影响。RTL中,由于是时序电路,缺少的else分支不影响。
✍✍☛ 题库入口
经过一段时间的沉淀,发现入行IC行业,自己的底子还是很差,写的文章质量参差不齐,也没能解答大家的疑问。决定还是要实打实从基础学起,由浅入深。因此决定通过补充/完善基础知识的同时,通过题库刷题不断提高自己的设计水平,题库推荐给大家(点击直达),<题库记录>栏目不定期更新,欢迎前来讨论。
作者:xlinxdu
版权:本文版权归作者所有
转载:未经作者允许,禁止转载,转载必须保留此段声明,必须在文章中给出原文连接。