Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Counter and time delay

Hi,

I'm very new in Quartus, I just started a couple of days ago.

The situation is that I've 4 inputs (only one of these can be active at time) and every time input changes to another, I need to increase the same counter. I've tried to do this with block diagram (I don't know anything about v-files) but I haven't found any counter block. So how I solve this very simple problem?

Second, when the input goes high, I need to keep it high only, lets say, 25 microseconds. I haven't found any time delay block either.

So every time the input state changes I need to increase the counter and give a short pulse to the same output.

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Basically you need a clock to generate the delay, possibly debounce the input, easy detect edges on mutiple inputs. If the timing isn't critical, also the internal clock oscillator of a MAX II CPLD can be used, with FPGA, you very likely have a crystal oscillator available on your board.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Okey, I have been studying Verilog and I managed to write what I wanted but I still can't build a timer. I've tried e.g.

    always @ (posedge pulse_in)

    begin

    pulse_out = 1;

    repeat (5) begin

    @ (posedge clk) ;

    end

    pulse_out = 0; [/INDENT]

    end

    but Quartus doesn't allow this (multiple event control statements not supported for synthesis). So what would be a solution?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Another problem is in a counter I wrote. I works fine but how do I reset it with posedge reset?

    I would like to write something like this but Quartus doesn't allow it:

    always @ (posedge reset) begin

    count <= 0:

    end

    always @ (posedge increaseCounter) begin

    count <= count + 1;

    end

    The way I have it now is presented below:

    always @ (posedge inc_counter or posedge reset) begin

    if (reset) begin

    count <= 16'b0000_0000_0000_0000;

    end

    else begin

    count <= count + 1'b1;

    end[/INDENT]

    end

    The problem is that reset keeps its value 1 and I don't want to reset counter then but only @ posedge reset. I remember I read somewhere how to check which posedge is the actual trigger but I couldn't find it again.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The last version is basically correct. You should also review the HDL templates available in Quartus editor context menu.

    I did'nt exactly understand your reset problem. The reset as shown is an asynchronous, level sensitive reset, don't be confused by the posedge keyword in this regard, it's required Verilog syntax but doesn't actually mean an edge. An asynchronous reset can be level sensitive only. The counter flip-flops can have only one clock input, that's the same situation as with any hardware counter IC.

    Alternatively, you can have a synchronous reset that is operating in conjunction with clock input.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Here's the code for counter that works fine. It resets the counter when reset goes from 0 to 1.

    always @(posedge clk) begin

    if (reset) begin

    if (!oldReset) begin[/INDENT]

    count <= 0;[/INDENT][/INDENT]

    end[/INDENT]

    oldReset <= 1;[/INDENT]

    //increase counter[/INDENT]

    if (count_enable) begin[/INDENT]

    count <= count+1;[/INDENT][/INDENT]

    end[/INDENT]

    end

    else begin

    oldReset <= 0;[/INDENT]

    //increase counter[/INDENT]

    if (count_enable) begin[/INDENT]

    count <= count+1;[/INDENT][/INDENT]

    end[/INDENT]

    end

    end

    And here's the code for holding:

    always @ (posedge clk) begin

    if (in_pulse) begin

    counter <= 0;

    out_pulse <= 1;[/INDENT]

    end

    else begin

    counter <= counter +1;

    if (counter > 1250) begin[/INDENT]

    out_pulse <= 0;

    if (counter > 1000000000) begin[/INDENT][/INDENT]

    counter <= 1250;[/INDENT][/INDENT][/INDENT]

    end[/INDENT][/INDENT]

    end[/INDENT]

    else begin[/INDENT]

    out_pulse <= 1;[/INDENT][/INDENT]

    end[/INDENT]

    end

    end