时钟
现有如下模块声明:
java
module dut ( input clk ) ;
编写一个测试激励模块:对dut模块完成单次例化(实例名可自定义),并生成一路时钟信号驱动dut的clk输入端口。时钟周期为10皮秒,时钟初始电平为低电平0,第一次电平跳变由0变为1。
参考答案
java
/*
模块类型:Testbench仿真测试文件(无外部输入输出端口)
时间精度声明:`timescale 时间单位/时间精度 → 1ps为基础计时单位,最小仿真步进1ps
功能说明:
1. 生成周期10ps的方波时钟clk,初始电平为低
2. 例化待测试模块dut,把自建时钟接入dut的clk端口
3. 通过延时反转电平实现时钟持续振荡,用于驱动被测模块运行仿真
*/
`timescale 1ps / 1ps // 仿真全局时间规则:单位1ps,精度1ps
module top_module ;
reg clk = 1'b0; // 仿真内部时钟寄存器,初始值低电平0
dut tb_dut(.clk(clk)); // 例化被测模块dut,命名实例tb_dut,clk端口绑定自建时钟
always #5 clk = ~clk; // 每隔5ps翻转clk电平,时钟周期=5*2=10ps,占空比50%
endmodule
输出结果

测试激励1
编写一段Verilog测试平台,使其为输出信号A与B生成下述波形:

参考答案
java
// 仿真时间尺度定义:基础计时单位1ps,仿真最小时间分辨精度1ps
// 代码中 #N 延时代表延迟N皮秒,仿真器可识别最小时间变动为1ps
`timescale 1ps / 1ps
// 顶层波形生成模块,仅用于仿真输出两路时序信号,不可综合为硬件电路
// 端口说明:A、B为波形观测输出,在initial过程块内赋值,因此声明为reg类型
module top_module (
output reg A,
output reg B
);
// initial块特性:仿真启动后只执行一次,按顺序执行延时+电平赋值,专门用于生成测试激励波形
initial begin
// 仿真初始时刻(0ps):初始化两路输出默认电平为低
A = 1'b0;
B = 1'b0;
// 保持当前电平不变,延时等待10ps,仿真时间推进至10ps
#10;
A = 1'b1; // 10ps时刻:信号A从低电平翻转为高电平
// 继续延时5ps,累计时长10+5=15ps,仿真时间推进至15ps
#5;
B = 1'b1; // 15ps时刻:信号B从低电平翻转为高电平
// 继续延时5ps,累计时长15+5=20ps,仿真时间推进至20ps
#5;
A = 1'b0; // 20ps时刻:信号A从高电平翻转为低电平
// 继续延时20ps,累计时长20+20=40ps,仿真时间推进至40ps
#20;
B = 1'b0; // 40ps时刻:信号B从高电平翻转为低电平
// 继续延时10ps,累计时长40+10=50ps,覆盖完整观测时间区间
#10;
// 后续无赋值操作,A、B维持低电平保持不变
end
endmodule
输出结果

与门
现有待测试的与门如下:
java
module andgate (
input [1:0] in,
output out);
编写一个测试平台,例化该与门,并通过生成下述时序图完成全部4组输入组合的测试:

参考答案
java
// 仿真专属全局时间尺度指令:延时计数单位为1ps,仿真引擎可识别的最小时间精度为1ps
// 代码中#N代表延迟N皮秒,精度约束避免微小延时偏差干扰波形观测
`timescale 1ps / 1ps
// Testbench测试顶层模块,仅用于仿真激励生成与待测模块挂载,无对外输入输出端口,不可综合为硬件电路
module top_module;
// 定义2位寄存器型激励信号in,拆分in[1]、in[0]作为双输入与门的两路独立输入
reg [1:0] in;
// 定义线网型观测信号out,接收待测与门的运算输出,线网适配模块端口连续赋值输出特性
wire out;
// 端口命名式例化待测模块andgate,实例别名tb_andgate
// .in(in):把tb内2bit激励总线对接与门输入端口
// .out(out):把与门输出对接tb观测线网,用于抓取输出波形
andgate tb_andgate(.in(in),.out(out));
// initial过程块:仿真启动仅执行一次,按时间节拍修改in电平,生成多组输入测试激励
initial begin
// 仿真0ps初始时刻:两路输入全部拉低,输入组合 in=2'b00
in[0] = 1'b0;
in[1] = 1'b0;
// 延时10ps至10ps节点:仅低位in[0]拉高,输入组合变为2'b01
#10 in[0] = 1'b1;
// 再延时10ps至20ps节点:高位in[1]拉高、低位in[0]拉低,输入组合变为2'b10
#10;
in[1] = 1'b1;
in[0] = 1'b0;
// 再延时10ps至30ps节点:低位in[0]重新拉高,两路全1,输入组合变为2'b11
#10 in[0] = 1'b1;
end
endmodule
输出结果

测试激励2
下方波形图设置时钟信号、输入信号与信号s:

模块q7包含如下声明:
java
module q7 (
input clk,
input in,
input [2:0] s,
output out);
编写一个测试平台,例化模块q7,并生成与上方波形完全一致的输入信号。
参考答案
java
// 仿真全局时间尺度编译指令
// 格式:`timescale 时间单位 / 仿真精度
// 含义:代码延时#N以ps为单位计时,仿真器最小可识别时间变化为1ps
`timescale 1ps / 1ps
// Testbench顶层测试模块:仅用于仿真生成激励、挂载待测模块、观测输出波形
// 无对外输入输出端口,包含时钟生成、激励赋值、DUT例化三部分,不可综合为硬件电路
module top_module;
// reg型信号:可在always/initial过程块内主动赋值,用作可控测试激励
reg clk = 1'b0; // 时钟激励信号,上电初始电平强制拉低
reg in; // 单比特数据输入激励,由initial块分时修改电平
reg [2:0] s; // 3位多路控制选择激励,取值范围0~7,控制待测模块工作模式
// wire型信号:仅承接待测模块输出、用于波形观测,不能在过程块直接赋值
wire out; // 待测模块输出观测线,实时反馈模块运算结果
// 命名式端口绑定例化待测模块q7,实例别名tb_q7
// 优势:不受端口书写顺序影响,配对清晰不易出错
q7 tb_q7(
.clk(clk), // 将本地生成时钟接入待测模块时钟端口
.in(in), // 将单比特数据激励接入待测模块数据输入端
.s(s), // 将3位控制激励接入待测模块模式选择端
.out(out) // 将待测模块输出连接本地观测线网
);
// 时钟生成逻辑:无限循环翻转电平,生成周期10ps、占空比50%方波时钟
always #5 clk = ~clk;
// 时序拆解:初始clk=0 → 5ps翻1 →10ps翻0,单次高低电平持续5ps,完整周期10ps
// initial过程块:仿真启动后从上至下仅执行一次,按时间节拍切换in、s激励电平
initial begin
// 仿真0ps初始时刻配置基础激励电平
in = 1'b0; // 数据输入默认低电平
s = 3'd2; // 控制位初始值设为十进制2
#10; // 延时10ps,仿真推进至10ps节点
s = 3'd6; // 10ps时刻更新控制位为十进制6
#10; // 再延时10ps,累计耗时20ps
in = 1'b1; // 20ps时刻拉高数据输入in
s = 3'd2; // 同步把控制位改回十进制2
#10; // 再延时10ps,累计耗时30ps
in = 1'b0; // 30ps时刻拉低数据输入in
s = 3'd7; // 同步更新控制位为十进制7
#10; // 再延时10ps,累计耗时40ps
in = 1'b1; // 40ps时刻再次拉高数据输入in
s = 3'd0; // 同步更新控制位为十进制0
#30; // 再延时30ps,累计耗时70ps
in = 1'b0; // 70ps时刻拉低数据输入in
#5; // 收尾延时5ps,仿真推进至75ps,激励序列全部结束
end
endmodule
输出结果

T触发器
现有一个T触发器模块,其声明如下:
java
module tff (
input clk,
input reset, // active-high synchronous reset
input t, // toggle
output q);
编写一个测试平台,例化一个T触发器,先对该T触发器执行复位操作,再将其翻转至"1"状态。
参考答案
java
// 仿真全局时间尺度编译指令
// 格式:`timescale 时间单位 / 仿真精度
// 规则:代码内#N延时以1ps为基础单位计时,仿真引擎可识别的最小时间波动为1ps
`timescale 1ps / 1ps
// Testbench顶层测试模块:仅用于仿真生成时钟、复位、控制激励,挂载待测T触发器并观测输出波形
// 无对外输入输出端口,全部逻辑仅仿真生效,无法综合为实际硬件电路
module top_module ;
// reg类型变量:可在always/initial过程块主动赋值,作为可控测试激励
reg clk = 1'b0; // 时钟激励,上电默认低电平,通过循环翻转生成周期方波
reg reset; // 复位控制激励,高电平有效,控制触发器复位状态
reg t; // T触发器模式控制输入,决定触发器保持/翻转行为
// 时钟生成逻辑:无限循环翻转电平,高低电平持续时长均为5ps,完整时钟周期=10ps
always #5 clk = ~clk;
// wire类型变量:被动承接待测模块输出,仅用于波形观测,禁止在过程块内直接赋值修改
wire q; // T触发器输出观测线,实时反馈寄存结果
// 命名端口绑定方式例化待测模块tff,实例别名tb_tff
// 命名绑定不受端口排列顺序影响,配对直观、修改容错性高,是工业通用写法
tff tb_tff(
.clk(clk), // 本地生成时钟接入触发器时钟输入端
.reset(reset), // 复位激励接入触发器复位端口
.t(t), // T模式控制激励接入触发器控制端
.q(q) // 触发器输出对接本地观测线网
);
// initial过程块:仿真上电后从上至下只执行一轮,通过边沿等待语句同步时钟节拍下发激励
initial begin
// 0ps初始时刻:拉高复位,触发器进入强制复位状态
reset = 1'b1;
// 0ps初始时刻:T输入拉低,触发器默认锁定保持模式
t = 1'b0;
// 阻塞等待:暂停当前流程,直到检测到第一个时钟下降沿再继续执行后续代码
@(negedge clk);
// 时钟下降沿节点:拉低复位信号,解除强制复位,触发器进入正常工作状态
reset = 1'b0;
// 阻塞等待:暂停当前流程,直到检测到下一个时钟上升沿再继续执行后续代码
@(posedge clk);
// 时钟上升沿节点:拉高T输入,触发器开启每周期翻转输出的工作模式
t = 1'b1;
end
endmodule
输出结果
