Verilog - несколько ребер в одном блоке, как в VHDL?

Я использую Quartus II версии 11.0 и пытаюсь перенести свой VHDL-код на Verilog (просто для практики).

Мне нужно проверить, насколько длинна линия «а». Есть рабочий код VHDL:

process (clock, a)
begin
    -- on each rising edge of clock...
    if (rising_edge(clock))
    then -- count how long 'a' is low
        if (a = '0' and a_low_time < 3)
        then
            a_low_time <= a_low_time + 1;
        end if;
    end if;
    -- reset counter if 'a' is not low
    if a = '1' then
        a_low_time <= 0;
    end if;
end process;

Очень просто, работает отлично. Но как мне это сделать с помощью Verilog? Этот код:

// on each rising edge of clock...
always @ (posedge clock)
begin
    // count how long 'a' is low
    if (!a && a_low_time < 3)
        a_low_time <= a_low_time + 1;
end

// reset counter if 'a' is high
always @ (*)
begin
    if (a)
        a_low_time <= 0;
end

Выдает ошибку "не удается разрешить несколько постоянных драйверов". И это:

always @ (posedge clock, posedge a)
begin
    if (!a && a_low_time < 3)
        a_low_time <= a_low_time + 1;
    else if (a)
        a_low_time <= 0;
end

Выдает ошибку «не удается сопоставить операнд(ы) в условии с соответствующими ребрами в охватывающем элементе управления событиями всегда создаваемой конструкции».

Этот код работает:

always @ (posedge clock)
begin
    if (!a && a_low_time < 3)
        a_low_time <= a_low_time + 1;
    else if (a)
        a_low_time <= 0;
end

Но мне нужно сбросить a_low_time сразу после того, как «a» станет высоким, но не на переднем фронте часов.

Как мне это сделать? Не могу поверить, что я не могу выполнить такую ​​простую задачу.


person Cluster    schedule 24.02.2015    source источник
comment
Уже спрашивали и отвечали на сайте EE, читайте electronics.stackexchange.com/q/28369/1743   -  person Ben Voigt    schedule 25.02.2015


Ответы (1)


Зачем вам асинхронно сбрасывать a_low_time? В любом случае, возможно, вы можете использовать в качестве строки сброса:

always @(posedge clock or posedge a)
begin
    if (a)
        a_low_time <= 0;
    else if (!a && a_low_time < 3)
        a_low_time <= a_low_time + 1;

На самом деле, поскольку a - это ваш сброс, вам не нужно проверять его для увеличения:

always @(posedge clock or posedge a)
begin
    if (a)
        a_low_time <= 0;
    else if (a_low_time < 3)
        a_low_time <= a_low_time + 1;
person Michael    schedule 24.02.2015
comment
И мне это нужно для MMC3 IRQ, основанного на строке A12: wiki.nesdev.com/w /index.php/MMC3 Эта строка используется PPU, который работает асинхронно с основным процессором. - person Cluster; 25.02.2015
comment
@Cluster Я всегда думал, что то, как блок always различает линию часов и линию сброса, немного ... странно (и, возможно, неинтуитивно) - person Michael; 25.02.2015