【问题标题】:variable clock generation in verilog using task使用任务在verilog中生成可变时钟
【发布时间】:2015-01-21 05:42:39
【问题描述】:

我已使用以下代码生成时钟(无论我通过任务传递的哪个值都会创建该频率),但该代码仅在我使用 CLKSEL_global = clksel_local(即阻塞分配)时才有效,但这会产生增量延迟。

如何在不引入增量延迟的情况下生成可变时钟?是他们使用任务的另一种方式。我正在使用任务,以便我可以传递真实值

`timescale 1ns/1ps
module tb();
  real CLKSEL_global;

  reg CLK7;


  new dut(clk,clk_out);

  task task_CLOCK;
    input real clksel_local;
    begin
      CLKSEL_global = clksel_local;
    end
  endtask

  initial begin
    CLK7 = 0;
    forever begin
      #(500.0/CLKSEL_global) CLK7 = 1;
      #(500.0/CLKSEL_global) CLK7 = 0;
    end
  end


  initial begin
    task_CLOCK(340.0);
  end

  initial begin
    #100 $finish ;
  end
endmodule

【问题讨论】:

  • 是的,它不是部分,可以删除
  • 只需要同时删除行`new dut(clk,clk_out);` 那么问题就是CLK7

标签: verilog clock


【解决方案1】:

这个解决方案感觉像一个讨厌的黑客,但我认为达到了要求。更改时钟频率时,它将在下一个边沿更改,但允许 @(posedge clk) 用于您要更改的边沿。变化其实是上升沿之后的1ns

通常您会设置频率并让它在边缘生效,从而提供一个完整的设置周期。

module tb();
  real CLKSEL_global = 500;
  reg clk;

  task task_CLOCK;
    input real clksel_local;
    begin
      CLKSEL_global <= clksel_local;
    end
  endtask

  initial begin
    #1ns;        
    clk = 1'b0;
    forever begin  
      #((500.0ns/CLKSEL_global) -1ns) clk = ~clk;
    end
  end

  initial begin
    $dumpfile("dump.vcd"); $dumpvars;

    task_CLOCK(1);
    repeat(2)
      @(posedge clk);

    task_CLOCK(2);
    repeat(2)
      @(posedge clk);

    $finish ;
  end
endmodule

EDA Playground 上的上述工作副本。

【讨论】:

  • real CLKSEL_global = 1 会产生一个问题,即前 500ns clk = 0 然后开始切换
  • 感谢您的回答,我要做的是创建任务,以便可以像 task_clock(340.0) #40 task_clock(170.0) 一样更改 clk 频率,即获得所需的频率但增量延迟在任务中创建倾斜,这对我来说是个问题,我正在尝试创建一个通用时钟生成器,我在其中传递值并生成时钟
  • @ra-one 重写了答案。看看这是否更接近。
  • 为什么在永远循环中使用#1ns?我可以通过将下一行修改为 #((500.0ns/CLKSEL_global) clk = ~clk; 来删除它吗?
  • @Jithin 你试过了吗? #1ns; 可能在 for 循环之前,但没有一些初始延迟,除法为 0,因此 sim 锁定。 Verilog 模拟的黄金法则,在时间 0 永远不要做任何事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
相关资源
最近更新 更多