Search code examples
verilogquartus

Verilog - multiple edges in one block like in VHDL?


I'm using Quartus II, version 11.0 and I'm trying to port my VHDL code to Verilog (just for practice).

I need to check - how long 'a' line is low. There are working VHDL code:

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;

Very simple, it's working perfectly. But how can I do it using Verilog? This code:

// 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

Throws "сan't resolve multiple constant drivers" error. And this:

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

Throws "cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct" error.

This code is working:

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

But I need to reset a_low_time immediately after 'a' goes high but not on rising edge of clock.

How can I do it? Can't believe that I can't do so simple task.


Solution

  • Why do you need to reset a_low_time asynchronously? In any case, maybe you can use a as your reset line:

    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;
    

    Actually, since a is your reset, you shouldn't need to check it to increment:

    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;