Когда конечный автомат Verilog может пойти не так?

Это мой код 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_sf будет на pLOW_DEPTH (я установил его на 200) тактов после входа sig, но иногда это будет всего на 2 клика позади.

Я добавил сигнал, чтобы посмотреть, что произошло, и оказалось, что конечный автомат дал сбой. Допустимые значения в signaltap: sLOW, sTO_LOW, sHIGH, s_TO_HIGH, как я и установил. Но он перешел к 4'h1 на каком-то отрицательном фронте sig и сбрасывается до sLOW.

Но я не понимаю, почему, я уверен, что входная волна от генератора просто прекрасна.

Так ПОМОГИТЕ мне с этим, спасибо!!


person Mr.Zhou    schedule 13.01.2014    source источник


Ответы (1)


Ваш always @(*) создает комбинаторную логику на основе внутренних (синхронизированных) сигналов и вашего внешнего ввода. Внешний вход может измениться в любое время, поэтому иногда ваша зарегистрированная логика в блоках always @(posedge clk) будет сталкиваться с ошибками, потому что выход вашей комбинаторной логики не соответствует времени установки и удержания, требуемому регистрами в FPGA. Прежде чем вы сможете выполнить «крупномасштабное» устранение сбоев вашего ввода, вам необходимо выполнить однократное устранение сбоев вашего ввода. Вы делаете это с помощью синхронизатора.

Технический документ см. в разделе Понимание метастабильности в ПЛИС. на тему Altera. Если вы используете синхронизатор / метастабильность Google, вы найдете множество ссылок.

Вам может быть интересно, почему моделирование не показывает проблему. Такого рода проблемы обнаруживаются временным анализатором, но вы должны сообщить ему о своих сигналах в файле ограничений, чтобы он знал, что происходит. С вашим кодом все в порядке. Проблема в физическом сигнале sig. Если бы анализатор времени знал, что он находится в домене часов, не связанном с clk, он мог бы предупредить вас.

Кроме того, вы обнаружили опасность однократного кодирования в машинах состояний: ваши 4-битные переменные состояния имеют 4 допустимых значения и 12 недопустимых «дыр», в которые вы можете попасть, оставив вашу машину в подвешенном состоянии.

person Ben Jackson    schedule 13.01.2014
comment
большое спасибо. Несколько минут назад я изменил атрибут кодировки на user и закодировал состояния 2-битным кодом Грея, и программа заработала правильно. И согласно вашему ответу, я думаю, мне нужно добавить FF между sig и конечным автоматом, и тогда все будет в порядке. - person Mr.Zhou; 13.01.2014