我可以在Verilog任务中传递时钟信号作为输入参数吗



我在VCS(G-2012.09)中编写了一个测试台来验证SPI模块。

下面是一个从SPI主机获取字节的任务:

task get_byte;
begin
    repeat(8) @(posedge spck)
    begin
        if (spss == 1'b0)
            tmp = {tmp[6:0], mosi};
    end
    $display ("[Time:%dns]---->Get a byte: 0x%h", $stime, tmp);
end
endtask

它有效。然后我想参数化这个任务,并将代码替换为:

task get_byte;
    input clk, oen, din;
    output [7:0] byte;
begin
    byte = 8'd0;
    repeat(8) @(posedge clk)
    begin
        if (oen == 1'b0)
            byte = {byte[6:0], din};
    end
    $display ("[Time:%dns]---->Get a byte: 0x%h", $stime, byte);
end
endtask

但是,当我用get_byte(spck, spss, mosi, tmp)调用该任务并在VCS中运行测试台时,它卡住了。在该任务中,spck似乎没有作为clk进行传递。

那么,是否有一条规则,即时钟信号不能用作任务中的输入参数,或者我做错了什么?

在一个旧的stackerflow问题中,您可以找到以下答案:

在Verilog中,参数是按值传递给任务的。这意味着clock的值在任务调用的生存期内是固定的。您的任务将永远找不到clock中的posedge,并且将永远等待。

所以答案是:您可以使用clk作为任务的输入参数,但它不能作为"标准"时钟工作。

如果您将任务声明为automatic并通过引用传递输入(在任务的端口定义中使用ref关键字而不是input关键词),则可以按照您的要求执行

使用时钟而不将其声明为输入,就像在第一个任务中所做的那样。通过引用传递也不起作用,因为任务将尝试在任务结束时设置时钟信号,模拟器将抛出错误。

您可能想要有几个引用不同clk名称的任务,例如:

get_byte_spclk(...)
get_byte_clk(...)

正如邱所说,这是行不通的。然而,你可以做一个技巧。请参阅下面的代码:

task my_task;
@(posedge testbench.name_of_the_signal_you_want_to_use_as_refernce)
Do something here
endtask

所以你基本上必须给出时钟信号的路径,类似于:

testbech.instance_of_instantiated_module.clock_signal_name

最新更新