按键抖动仿真Testbench(repeat、task、random)的用法

本文介绍Verilog中random、task及repeat关键字的用法,通过实例演示如何使用这些关键字进行按键随机抖动仿真,包括产生随机数、定义任务及重复执行等技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


之前一讲,我们是用了简单的TB的写法,产生的是固定的抖动。
下面我们要用到随机函数、task任务、repeat函数来生成随机的抖动仿真
https://blog.youkuaiyun.com/ciscomonkey/article/details/86485111

一、关键字的用法

1、random的用法

$ random这一系列函数可以产生一个有符号的32bit随机整数。一般的用法是$ random %b, 其中b>0; 这样就会生成一个范围在(-b+1):(b-1)中的随机数。
如果只得到正数的随机数,可采用{$random}%b来产生。

比如我们可以用于随机时间: {$random}%20_000_000 表示的是20_000_000以内的随机数。

2、task的用法

task和function综合出来的电路都是组合电路,如果你想在task和function来写时序功能,那你需要的是module而不是这两个。

task <任务名>
<端口及其数据类型声明语句>
<组合语句1>
<组合语句2>
<组合语句n>
endtask

任务的调用的语法如下:
<任务名>(顶层端口1,顶层端口2,。。。顶层端口n)

task只综合组合逻辑部分。

实际例子如下:

//任务task使用示例
module test 
(
    input [3:0] A, B, 
    input CIN, 
    output [3:0] S, 
    output COUT
);

reg [1:0] S0, S1, S2, S3;

task ADD;
    input A, B, CIN;
    output [1:0] C;
    reg [1:0] C;
    reg S, COUT;
    begin
        S = A ^ B ^ CIN;
        COUT = (A&B) | (A&CIN) | (B&CIN);
        C = {COUT, S};
    end
endtask

always @(A or B or CIN)
begin
    ADD (A[0], B[0], CIN, S0);
    ADD (A[1], B[1], S0[1], S1);
    ADD (A[2], B[2], S1[1], S2);
    ADD (A[3], B[3], S2[1], S3);
    S = {S3[0], S2[0], S1[0], S0[0]};
    COUT = S3[1];
end

endmodule

3、repeat的用法

表示重复执行的次数,不可以综合
语法结构

repeat(常数)
begin
...
end

二、按键随机抖动仿真(testbench训练)

运用上面讲述的三个函数,进行仿真,也就是说,我们随机的隔一段时间,就把key翻转一次,一共执行key翻转50次的65535ns随机变量的抖动,来模拟的抖动,那么我的最大抖动时间就是random的最大数*50(假设每次都随机数去取了最大数)

`timescale 1ns/1ns
`define clk_period 20

module key_filter_tb;
		
	reg clk;
	reg rst_n;

	reg key;
	
	wire key_flag;
	wire key_state;
	
	key_filter key_filter(
		.clk(clk),
		.rst_n(rst_n),
		.key(key),
		.key_flag(key_flag),
		.key_state(key_state)
	);
	
		initial begin
	 	rst_n = 1'b0;
		#(`clk_period*10) rst_n = 1'b1;
		#(`clk_period*10 + 1);
		press_key(39999999,49999999);
		
		press_key(59999999,49999999);
		press_key(159999999,99999999);
	 
	 end
	
	initial clk = 1;
	always#(`clk_period/2) clk = ~clk;

	reg [15:0]myrand;
	 task press_key;
		input [31:0]press_time;
		input [31:0]release_time;
		begin
			repeat(50)begin
				myrand = {$random}%65536;
				#myrand key = ~key;			
			end
			key = 0;
			#press_time;
			
			repeat(50)begin
				myrand = {$random}%65536;
				#myrand key = ~key;			
			end
			key = 1;
			#release_time;		
		end	
	endtask
	endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值