Electronic – VHDL error: multiple constant drivers for net

cyclonevhdl

I can't find how to deal with the error: "multiple constant drives" which occures when I try to read and set the same net in a single process.

I need to set the "output" for some clock cycles on the rising edge of "enable" input and then reset the "output". My code:

library ieee;
use ieee.std_logic_1164.all;

entity trigger_slave is
    generic (
        OUT_ON_PERIOD   : integer := 10 - 1                                 
    );
    port (
        enable          : in std_logic; 
        clk_1MHz        : in std_logic;                                                                         
        OUTPUT          : buffer std_logic                           
    );
end trigger_slave;

architecture behavior of trigger_slave is

begin   
    process (enable)
    begin
        if (rising_edge(enable)) then
            OUTPUT <= '1';
        end if;
    end process;

    process (clk_1MHz)  
        variable counter        : integer range 0 to OUT_ON_PERIOD := 0;
    begin
        if (rising_edge(clk_1MHz) and OUTPUT = '1') then        -- here is the problem!
            if (counter = OUT_ON_PERIOD) then
                counter := 0;
                OUTPUT <= '0';
            else 
                counter := counter + 1;
                OUTPUT <= '1';
            end if;         
        end if;
    end process;

end behavior;

Please, help me with this code. Thank you very much.

Best Answer

I know you're a beginner but your VHDL does read like you're trying to write a computer programme, not design a digital logic circuit.

Read up on synchronous digital logic design, plenty on the internet.

Then, after that, read up on VHDL and look at how it can implement the circuit you want. Remember: the circuit design (no matter how broadly) comes first, VHDL design second.

In the meantime, here's the design you wanted. (I haven't compiled it with ModelSim so there might be typos'.)

library ieee;
use ieee.std_logic_1164.all;

entity TRIGGER_SLAVE is
  generic(
    OUT_ON_PERIOD                 : integer := 10 - 1
  );
  port(
    CLK                           : in  std_logic;
    RST                           : in  std_logic;
    ENABLE                        : in  std_logic;
    OUTPUT                        : out std_logic
  );
end entity TRIGGER_SLAVE;

architecture behaviour of TRIGGER_SLAVE is
  signal delayCtr                 : natural range 0 to OUT_ON_PERIOD;
  signal enableOld1               : std_logic;

begin

  pDelay : process(RST, CLK) is
  begin
    if (RST = '1') then
      delayCtr    <=   0 ;
      enableOld1  <=  '0';
      OUTPUT      <=  '0';`

    elsif rising_edge(CLK) then

      -- Keep old enable level from 1 CLK ago, for edge detection.
      enableOld1  <=  ENABLE;

      -- Reload delay counter on ENABLE rising edge then run it down to zero.
      if (ENABLE = '1' and enableOld1 = '0') then
        delayCtr  <=  OUT_ON_PERIOD;

      elsif (delayCtr /= 0) then
        delayCtr  <=  delayCtr - 1;

      end if;

      -- Assert OUTPUT while the delay counter is running.
      if (delayCtr /= 0) then
        OUTPUT  <=  '1';
      else
        OUTPUT  <=  '0';
      end if;
    end if;
  end process pDelay;

end architecture behaviour;

You didn't have a reset input but the design needs one. Besides that and as general guidelines: don't use variables, use signals; only use rising_edge with a clock; don't use state machines unless you absolutely have to (some use them for everything, a bad habit).

Incidentally, the problem in your design was that you had two processes driving one output port.

Related Topic