1.简述
随机化验证在数字ic验证中十分重要,使用频率也比较高。为了比较直观地地使用随机数,我结合小工程来学习;
2.被测试代码
我以38译码器代码为例,做随机化验证,下面是源码:
module decoder_38(
//clk & rst
input clk ,
input rst ,
//decoder inout
input en ,
input [2:0] A ,
//decoder output
output reg [7:0] Y
);
always @(posedge clk or negedge rst) begin
if(!rst)
Y <= 8'b1111_1111;
else if(en == 1'b1)
case(A)
3'b000 : Y <= 8'b1111_1110;
3'b001 : Y <= 8'b1111_1101;
3'b010 : Y <= 8'b1111_1011;
3'b011 : Y <= 8'b1111_0111;
3'b100 : Y <= 8'b1110_1111;
3'b101 : Y <= 8'b1101_1111;
3'b110 : Y <= 8'b1011_1111;
3'b111 : Y <= 8'b0111_1111;
default : Y <= 8'b111_1111;
endcase
else
Y <= 8'b1111_1111;
end
endmodule
3.teastbench
module tb;
logic clk = 0 ;
logic rst = 0 ;
logic en = 0 ;
logic [2:0] A = 3'd0 ;
logic [7:0] Y ;
always #10 clk = ~clk ;
//声明一个生成随机数的类
class packet;
rand bit [2:0] number; //声明随机数
constraint c {number>=0; number<=7;} //约束随机数的范围
endclass
packet numb; //声明一个句柄,相当于把类实例化
initial begin
#50; rst = 1;
#50;
numb = new(); //分配空间
en = 1;
for(int i = 0; i < 10; i++) begin
assert(numb.randomize()); //使用断言
A = numb.number; //将随机值付给A端口
$display("******** random_A = %d***********/n",numb.number);
#100;
end
en = 0;
#100;
$finish;
end
//************* 以前verilog写法,现在注释掉 ********************
/*initial begin
#50 rst = 1;
#50
en = 1;
A = 3'd2;
#20
A = 3'd6;
#30
A = 3'd5;
#30
A = 3'd0;
#20
A = 3'd3;
#50
en = 0;
#10
A = 3'd2;
#100
$finish;
end
*/
//**********************************************
decoder_38 u_decoder(
.clk (clk ),
.rst (rst ),
.en (en ),
.A (A ),
.Y (Y )
);
//----------------------------------
//产生名为tb.fsdb的文件
//----------------------------------
initial begin
$fsdbDumpfile("tb.fsdb");
$fsdbDumpvars;
end
endmodule
4.vcs仿真
5.总结
边学边实践,可能在有些地方认识不够深入有错误的地方,欢迎大家指正,希望多多交流!!!
欢迎关注我的公众号:芯王国,有更多的FPGA&数字IC的技术分享,还可以获取开源FPGA项目!