Forum Discussion

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

Problem with "constant driver error"

Hello,

I am trying to put together a simple one shot counter that gets trigered once every time an input signal (Gate) the counter just counts to some preloaded value and then just stops counting till the next time

Because I am a Verilog neophite I seem to struggle with the following error:

Error (10028): Can't resolve multiple constant drivers for net "temp" at PulseWidthCounter.v(25)

Any help or sugestions will greatly appreciated!!!

The code is as follows:

******************************************************************

module PulseWidthCounter(clk,CountVal,counterenable,Gate,PulseOut);

parameter SIZE = 20;

input clk;

input Gate;

input counterenable;

input CountVal;

output PulseOut = 0;

reg CounterVal;

reg clk1;

reg PulseOut;

reg temp = 0;

always @ (posedge counterenable)begin CounterVal <= CountVal; end

always @ (posedge Gate)begin temp <= 1'b1; end

always @ (posedge clk)

begin

if(temp == 1'b1)begin

clk1 <= clk1 +1;

if (clk1 < CounterVal)

PulseOut <= 1'b1;

else

PulseOut <= 1'b0; clk1 <=0; temp <= 0; end

end

endmodule

5 Replies

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

    --- Quote Start ---

    Hello,

    I am trying to put together a simple one shot counter that gets trigered once every time an input signal (Gate) the counter just counts to some preloaded value and then just stops counting till the next time

    Because I am a Verilog neophite I seem to struggle with the following error:

    Error (10028): Can't resolve multiple constant drivers for net "temp" at PulseWidthCounter.v(25)

    Any help or sugestions will greatly appreciated!!!

    The code is as follows:

    ******************************************************************

    module PulseWidthCounter(clk,CountVal,counterenable,Gate,PulseOut);

    parameter SIZE = 20;

    input clk;

    input Gate;

    input counterenable;

    input CountVal;

    output PulseOut = 0;

    reg CounterVal;

    reg clk1;

    reg PulseOut;

    reg temp = 0;

    always @ (posedge counterenable)begin CounterVal <= CountVal; end

    always @ (posedge Gate)begin temp <= 1'b1; end

    always @ (posedge clk)

    begin

    if(temp == 1'b1)begin

    clk1 <= clk1 +1;

    if (clk1 < CounterVal)

    PulseOut <= 1'b1;

    else

    PulseOut <= 1'b0; clk1 <=0; temp <= 0; end

    end

    endmodule

    --- Quote End ---

    Hi,

    you got this error, because you are driving "temp" in two processes.

    Would you like to achieve a counter, which starts counting at a rising of the signal "gate", then counts up to a certain value and then stops ( setting the counter to "0")?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you for your help, I do realize what the error is due to,

    And YES, that is exactly what I was looking to do.

    Is there another way around this? or simply put, how does one create a simple "one shot timer" in verilog, I have been searching for the answer in the web but can't seem to find an answer.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Hi,

    you got this error, because you are driving "temp" in two processes.

    Would you like to achieve a counter, which starts counting at a rising of the signal "gate", then counts up to a certain value and then stops ( setting the counter to "0")?

    --- Quote End ---

    Hi,

    I wrote an example for you, which maybe fits to your requirements.

    module PulseWidthCounter(clk,CountVal,Gate,PulseOut,reset);

    parameter SIZE = 20;

    input clk;

    input Gate;

    input CountVal;

    input reset;

    output PulseOut;

    reg CounterVal;

    reg clk1;

    reg PulseOut;

    // posedge detection of signal Gate

    reg temp;

    wire p_edge;

    always @(posedge clk) begin

    if (reset) temp <= 0;

    else temp <= Gate;

    end

    assign p_edge = Gate & !temp; // posedge detection

    // Counter

    always @(posedge clk) begin

    if(reset) begin

    CounterVal <= 0;

    PulseOut <= 0;

    end

    else if (p_edge) begin

    CounterVal <= CountVal;

    end

    else if (CounterVal > 0) begin

    CounterVal <= CounterVal - 1;

    PulseOut <= 1;

    end

    else begin

    CounterVal <= 0;

    PulseOut <= 0;

    end

    end

    endmodule

    With the reset signal you set the counter and the PulseOut to "0". That is useful especially

    for simulation, because you can bring the circuit to defined state.

    There is a edge detection build in, which detects the pos edge of the signal "Gate". In case of the edge the counter is load to the value defined by input "CountVal". The load pulse is only one clock cycle long. After that the counter counts down as long as the counter value is > 0 and the PulseOut signal is set to "1". At "0" the counter stops and the PulseOut is set to "0". Maybe this is a good starting point for you. Simulate the design and try to understand what I did.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The example has the disadvantage of not being fully synchronous, causing timing violations und unpredictable results if the gate edge comes at the wrong moment. Gate has to be synchronized to the main clk domain to avoid these effects.

    Furthermore, it doesn't work if the Gate signal is shorter than a clock period. Thus, I don't know if it's a solution to cbarberis problem.

    The original approach can be basically extended by a handshake signal to avoid the multiple driver issue.

    always @ (posedge Gate or posedge GateReset)
    begin 
      if (GateReset) 
        temp <= 1'b0; 
      else
        temp <= 1'b1; 
    end
    always @ (posedge clk) 
    begin
      if(temp == 1'b1)
        begin
          clk1 <= clk1 +1;
          if (clk1 < CounterVal)
            PulseOut <= 1'b1;
          else
            begin
              GateReset <= 1;
              PulseOut <= 1'b0; 
              clk1 <=0; 
            end
        end
      else
        GateReset <= 0;
    end
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you both; pletz and FvM for your help, I have slightly modified pletz code and got it to work exactly the way I wanted. Lookin both of your sugestions has given me a little more insight as to what I need to do. I was actually trying to make a simple variable pulse generator as part of a learning project for both the quartus tool and the verilog hdl.

    You are right FvM, regarding the Gate signal it has to be synchronized with the clock and the gate time must always be >> than the one shot pulse in order for thing to work correctly.