system verilog 始终在始终

system verilog always within always

我想知道是否允许这种语法

always_comb begin
    case (aaa)
    3'b000: always #(CLKREF_HALF_PERIOD + 5000ps) xclk=~xclk ;//000 at 80MHZ :
    3'b001: always #(3750ps + CLKREF_HALF_PERIOD) xclk=~xclk;//001 at 100MHZ
    3'b010: always #(1250ps + CLKREF_HALF_PERIOD) xclk=~xclk;//010 at 200MHZ
    3'b011: always #(0.252ns + CLKREF_HALF_PERIOD) xclk=~xclk;//011 at 333MHZ
    3'b100: always #(0.112ns + CLKREF_HALF_PERIOD) xclk=~xclk;//100 at 367MHZ

    default always #(CLKREF_HALF_PERIOD/1) xclk=~xclk;//default at 400MHZ   
            endcase 

我收到关于嵌套总是在案例中的编译错误。 我试图让时钟频率根据 aaa 的输入而改变。 然而这个问题更像是关于 "if an always within an always block is legal or not"

的问题

不允许嵌套程序块。我相信 aaaaaa 是这里的 参数 。如果是这样,您可以使用 generate 块。使用不同的时钟频率。这将使单个组合块一次处于活动状态。示例代码如下:

generate 
    case (aaaaaa)
    3'b000: always #(CLKREF_HALF_PERIOD + 5000ps) xclk=~xclk ;//000 at 80MHZ :
    3'b001: always #(3750ps + CLKREF_HALF_PERIOD) xclk=~xclk;//001 at 100MHZ
    3'b010: always #(1250ps + CLKREF_HALF_PERIOD) xclk=~xclk;//010 at 200MHZ
    3'b011: always #(0.252ns + CLKREF_HALF_PERIOD) xclk=~xclk;//011 at 333MHZ
    3'b100: always #(0.112ns + CLKREF_HALF_PERIOD) xclk=~xclk;//100 at 367MHZ

    default always #(CLKREF_HALF_PERIOD/1) xclk=~xclk;//default at 400MHZ 

endgenerate

如果 aaavariable/register/wire 那么您可以使用 forever 循环构造而不是内部 always 块。 Dave_59 的回答中更清楚地显示了示例用法。

有关 generate 块的更多信息,请参阅 IEEE 1800-2012 第 27.5 节。

永久循环解决方案不起作用,因为顶级 always 块无法退出 forever 循环并到达 case 语句的另一个分支。一个更简单的解决方案是使用一个 always 块来计算时钟延迟,并使用另一个 always 块来创建时钟。

int clk_delay;
always_comb
    case (aaa)
    3'b000: clk_delay = CLKREF_HALF_PERIOD + 5000ps; //000 at 80MHZ
    3'b001: clk_delay = 3750ps + CLKREF_HALF_PERIOD; //001 at 100MHZ
...
always #clk_delay xclk = ! xclk;