前面我们学习了specify...endspecify 具体是什么东西。今天,我们使用specify block 中定义的延时,来进行一次仿真。看看到底是背后如何运转的呢。
一个用 specify 指定延迟的与门逻辑描述如下:
- module and_gate(
- output Z,
- input A, B);
-
- assign Z = A & B ;
-
- specify
- specparam t_rise = 1.3:1.5:1.7 ;
- specparam t_fall = 1.1:1.3:1.6 ;
- (A, B *> Z) = (t_rise, t_fall) ;
- endspecify
-
- endmodule
一个用 specify 指定延迟的 D 触发器描述如下:
- module d_gate(
- output Q ,
- input D, CP);
-
- reg Q_r ;
- always @(posedge CP)
- Q_r <= D ;
- assign Q = Q_r ;
-
- specify
- if (D == 1'b1)
- (posedge CP => (Q +: D)) = (1.3:1.5:1.7, 1.1:1.4:1.9) ;
- if (D == 1'b0)
- (posedge CP => (Q +: D)) = (1.2:1.4:1.6, 1.0:1.3:1.8) ;
- $setup(D, posedge CP, 1);
- endspecify
-
- endmodule
顶层模块描述如下,主要功能是将与逻辑的输出结果输入到 D 触发器进行缓存。
- module top(
- output and_out,
- input in1, in2, clk);
-
- wire res_tmp ;
- and_gate u_and(res_tmp, in1, in2);
- d_gate u_dt(and_out, res_tmp, clk);
-
- endmodule
testbench 描述如下,仿真时设置 "+maxdelays",使用最大延迟值。
- `timescale 1ns/1ps
- module test ;
- wire and_out ;
- reg in1, in2 ;
- reg clk ;
-
- initial begin
- clk = 0 ;
- forever begin
- #(10/2) clk = ~clk ;
- end
- end
-
- initial begin
- in1 = 0 ; in2 = 0 ;
- # 32 ;
- in1 = 1 ; in2 = 1 ;
- # 13 ;
- in1 = 1 ; in2 = 0 ;
- end
-
- top u_top(
- .and_out (and_out),
- .in1 (in1),
- .in2 (in2),
- .clk (clk));
-
- initial begin
- forever begin
- #100;
- if ($time >= 1000) $finish ;
- end
- end
-
- endmodule // test
仿真时序如下所示,由图可知:
综上所述,仿真结果符合设计参数。

其实,我们可以做一个延伸。修改代码如下:
- module top(
- output and_out,
- input in1, in2, clk);
-
- wire res_tmp;
- wire res_tmp_tmp;
-
- assign res_tmp_tmp = res_tmp;
-
- specify
-
- ( res_tmp => res_tmp_tmp) = (2:3:4, 3:4:5);
-
- endspecfiy
-
- and_gate u_and(res_tmp, in1, in2);
- d_gate u_dt(and_out, res_tmp_tmp, clk);
-
- endmodule
修改上面代码,重新进行仿真,我们会发现,Z -> D 之间,将会有 4 ns 的延时存在。
