什么时候verilog状态机会出错?

时间:2014-01-13 06:41:24

标签: verilog fpga state-machine

这是我的verilog代码:

//state reg
(* syn_encoding = "safe" *)reg [3:0] ns_sig, cs_sig;
//state parameters
localparam 
    sLOW    = 4'b0001,
    sTO_HIGH    = 4'b0010,
    sHIGH   = 4'b0100,
    sTO_LOW = 4'b1000;

always @(posedge clk or negedge rst_n)
    if (!rst_n)
        cs_sig <= sLOW;
    else
        cs_sig <= ns_sig;

always @(*)
begin
    ns_sig = cs_sig;
    case (cs_sig)
        sLOW:
            if (sig == `HIGH)
                ns_sig = sTO_HIGH;
        sTO_HIGH:
            if (valid_HIGH == `ON)
                ns_sig = sHIGH;
            else if (sig == `OFF)
                ns_sig = sLOW;
        sHIGH:
            if (sig == `OFF)
                ns_sig = sTO_LOW;
        sTO_LOW:
            if (valid_LOW == `ON)
                ns_sig = sLOW;
            else if (sig == `ON)
                ns_sig = sHIGH;
        default:
            ns_sig = sLOW;
    endcase
end

always @(posedge clk)
begin
    if (cs_sig == sTO_HIGH)
        cnt_HIGH <= cnt_HIGH + {{(pWIDTH-1){1'b0}}, 1'b1};
    else
        cnt_HIGH <= {(pWIDTH){1'b0}};
end

assign
    valid_HIGH = (cnt_HIGH == pHIGH_DEPTH -1)? `ON:`OFF;

always @(posedge clk)
begin
    if (cs_sig == sTO_LOW)
        cnt_LOW <= cnt_LOW + {{(pWIDTH-1){1'b0}}, 1'b1};
    else
        cnt_LOW <= {(pWIDTH){1'b0}};
end

assign
    valid_LOW = (cnt_LOW == pLOW_DEPTH - 1)?`ON:`OFF;


always @(posedge clk)
begin
    if (cs_sig == sHIGH)
        sig_sf <= `HIGH;
    else if (cs_sig == sLOW)
        sig_sf <= `LOW;
end

它是一个二进制信号滤波器模块,旨在确定物理端口上的毛刺,并且可以同时用作延迟器。

它在模拟上运行良好,但不在船上。我在Altrea EP2C35芯片上运行代码,它时不时出错。通常,sig_sfpLOW_DEPTH(我将其设置为200)clks在输入sig后面,但有时只会落后2个。

我添加了一个信号标记,看看发生了什么,结果发现状态机出了问题。 signaltap上的有效值为:sLOW, sTO_LOW, sHIGH, s_TO_HIGH,就像我设置的那样。但它在4'h1的某个负边缘转到sig并重置为sLOW

但我不明白为什么,我确信来自发电机的输入波很好。

所以请帮助我,谢谢!!

1 个答案:

答案 0 :(得分:2)

您的always @(*)根据内部(时钟)信号和外部输入创建组合逻辑。外部输入可以随时改变,因此有时在always @(posedge clk)块中注册的逻辑会出现毛刺,因为组合逻辑的输出不符合FPGA中寄存器所需的建立和保持时间。在您可以对输入进行“大规模”去毛刺之前,您需要对输入进行单clk缩放去毛刺。您可以使用同步器执行此操作。

请参阅Understanding Metastability in FPGAs以获取Altera关于此主题的白皮书。如果您使用Google同步器/亚稳态,您会发现大量的参考资料。

您可能想知道为什么模拟没有显示问题。时间分析器会检测到这种问题,但您必须在约束文件中告诉它您的信号,以便它知道发生了什么。您的代码没有任何问题。问题是物理信号sig。如果时序分析仪知道它位于与clk无关的时钟域中,它可能会发出警告。

此外,您已经发现状态机中存在单热编码的危险:您的4位状态变量有4个有效值和12个无效的“漏洞”,您可能会陷入困境。