Verilog 确定性行为

问题描述

以下代码是确定性的吗?即它可以触发错误1或错误2吗?有没有推荐的方法生成 clk2(与 clk3 相同)

module test();
    reg         clk1;
    reg         clk2;
    reg         clk3;
    reg         reset;

    initial
    begin
        clk1 <= 0;
        forever
        begin
            #100;
            clk1 <= ~clk1; // 2x freq of clk2/clk3
        end
    end

    always @(posedge clk1)
    begin
        if(reset)   clk2 <= 0;
        else        clk2 <= ~clk2;
    end

    initial
    begin
        clk3 <= 0;
        #300;
        forever
        begin
            #200;
            clk3 <= ~clk3;
        end
    end

    initial
    begin
        reset <= 1;
        #500;
        reset <= 0;
        #100;
        repeat (20) @(posedge clk1);
        $display("Test end");
        $finish;
    end

    always @(posedge clk2)
    begin
        if(clk1 == 0)   $display("Error1");
    end
    
    always @(posedge clk3)
    begin
        if(clk1 == 0)   $display("Error2");
    end
endmodule;

解决方法

您的代码有问题,但与确定性无关——它是完全确定性的。这是使用 NBA function TabBarIcon(props: { color: string; } & ( { name: React.ComponentProps<typeof Ionicons>['name']; type: 'Ionicons'; } | { name: React.ComponentProps<typeof Feather>['name']; type: 'Feather'; })) { if (props.type === 'Ionicons') return <Ionicons size={30} style={{ marginBottom: -3 }} {...props} />; else if (props.type === 'Feather') return <Feather size={30} style={{ marginBottom: -3 }} {...props} />; else return <View />; } 产生问题的一种情况。 <=clk2clk1 之后的 delta 周期内更新。这意味着如果您有从后者到 clk3 之类的时钟域交叉

clk2

所以永远不要使用 NBA 来分配时钟。