Verilog 我想添加一个检查器,当启用为';1';。时钟频率是随机的(未知)

Verilog 我想添加一个检查器,当启用为';1';。时钟频率是随机的(未知),verilog,system-verilog,system-verilog-assertions,Verilog,System Verilog,System Verilog Assertions,假设我们有一个名为“clk”的信号,我们希望确保当“enable”为“1”时clk切换。“clk”的频率不知道。这个怎么样 module top(); reg clk; reg enable; always @(posedge enable) begin automatic bit toggled=1'b0; automatic process p; fork begin p =

假设我们有一个名为“clk”的信号,我们希望确保当“enable”为“1”时clk切换。“clk”的频率不知道。

这个怎么样

module top();
  
  reg clk;
  reg enable;
  
  always @(posedge enable)
    begin
      automatic bit toggled=1'b0;
      automatic process p;
      
      fork
        begin
          p = process::self();
          $display("%t expecting CLK toggle ...", $time);
          @(clk) toggled = 1'b1;
          $display("%t CLK toggled!", $time);
        end
      join_none
      
      @(negedge enable);
      if (!toggled) $error("CLK not toggled!");
      p.kill();
    end
  
  initial
    begin
      
      clk = 1'b0;
      enable = 1'b0;
      $dumpfile("dump.vcd"); $dumpvars;
      
      repeat(3)
      begin
        #5;
        enable <= 1'b1;
        #5;
        clk <= ~clk;
        #5;
        enable <= 1'b0;
      
        #5;
        enable <= 1'b1;
        #5;
        //clk <= ~clk;
        #5;
        enable <= 1'b0;
      end
      
      #5;
      $finish();
      
    end
  
endmodule : top
moduletop();
注册时钟;
注册启用;
始终@(posedge启用)
开始
自动位切换=1'b0;
自动过程p;
叉
开始
p=进程::self();
$display(“%t预期时钟切换…”,$time);
@(时钟)切换=1'b1;
$display(“%t CLK toggled!”,$time);
结束
加入
@(负边缘启用);
如果(!toggled)$error(“CLK未切换!”);
p、 杀死();
结束
最初的
开始
clk=1'b0;
启用=1'b0;
$dumpfile(“dump.vcd”)$垃圾场;
重复(3)
开始
#5;

启用我认为您需要的是某种时钟选通,我们将创建一个版本的时钟,该时钟不会开始切换,除非该块方框图中的高启用如下所示

因此,如果您有一个标准单元,那么您可以在代码中使用其中一个单元,以防您没有标准单元。下面是描述上述电路的RTL

module latch(clk, in, out);
  
  
  input clk, in;
  output reg out;
  
  
  always@(*) begin 
    if(clk) begin
        out <= in;
    end
  end
  
  
  
endmodule


module clk_gate(clk_in, en, clk_out);
  
  input clk_in;
  input en;
  output clk_out;
  
  wire latch_out;
  
  latch u1 (.in(en), .clk(~clk_in), .out(latch_out)); 
  and u2 (clk_out, latch_out, clk_in);
  
  
  
endmodule




其中clk_out是门控的
版本的时钟,仅当启用为1时才启用。现在,您可以随时使用该版本的时钟,而不是原始时钟
注:
out
是锁存器的输出,
clk\u out
是时钟选通电路的输出

是否有其他(更快的)时钟用作参考?我想如果需要,我们可以通过initial forever#0.5 clk=~clk生成更快的时钟
`timescale 1ns/1ns
module tb();
  
  wire out;
  wire clk_out;
  reg in, clk, en;
  always #5 clk = ~clk;
  
  latch DUT_latch( .clk(clk), .in(in), .out(out));
  clk_gate DUT_clk_gate( .clk_in(clk), .en(en), .clk_out(clk_out));
  
  initial begin 
    $dumpfile("dump.vcd");
    $dumpvars(1);

    clk = 0;
    in = 0;
    en = 0;
    #7
    in = 1;
    en = 1;
    #3
    in = 0;
    en = 0;
    #8
    in = 1;
    en = 1;
    
    #100
    $stop;
  end
  

  
  
endmodule