Electronic – VHDL Programming error. “couldn’t implement registers for assignments on this clock edge”

vhdl

I am new to VHDL and I'm trying to attempt to create an accelerator and speedometer. I want to use push buttons and 7 segments to implement. I want to be able to shift into each case statement and execute until a button is pressed. It will not simulate with the clock taken out, and the error above happens when I try to put a clock in. Any help?

    LIBRARY IEEE;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY GearCounterFirst IS
PORT(
  Clk : IN STD_LOGIC;
  Gas: IN STD_LOGIC;
  Speed : BUFFER STD_LOGIC_VECTOR (7 downto 0);
  Acc : BUFFER STD_LOGIC_VECTOR(4 downto 0);
  up: IN STD_LOGIC;
  down: IN STD_LOGIC;
  trans: BUFFER STD_LOGIC_VECTOR (2 downto 0)
  );
  END GearCounterFirst;

ARCHITECTURE Behavior OF GearCounterFirst IS
BEGIN
PROCESS (Clk,Speed, Gas, up, down, trans) 
BEGIN

    trans <= "000";

            if (up = '1' and rising_edge(Clk)) then
                trans <= trans + '1';
            else 
                trans <= trans;
            end if;

            if (down = '1' and rising_edge(Clk)) then
                trans <= trans - '1';
            else 
                trans <= trans; 
            end if;

case trans is
    when "000" => 
        if (gas = '1' and rising_edge(Clk)) then
            Speed <= Speed +4;
            Acc <= "11111";
        end if;

        if (gas = '0' and rising_edge(Clk)) then
            Speed <= Speed -4;
            Acc <= "00000";
        end if; 
    when "001" =>
        if (gas = '1' and rising_edge(Clk)) then
            Speed <= Speed -3;
            Acc <= "01111";
        end if;

        if (gas = '0' and rising_edge(Clk)) then
            Speed <= Speed -3;
            Acc <= "00000";
        end if;

    when "010" => 
        if (gas = '1') then
            Speed <= Speed +2;
            Acc <= "00111";
        end if;

        if (gas = '0') then
            Speed <= Speed +1;
            Acc <= "00000";
        end if;

    when "011" =>
        if (gas = '1') then
            Speed <= Speed +1;
            Acc <= "00011";
        end if;

        if (gas = '0') then
            Speed <= Speed -1;
            Acc <= "00000";
        end if;

    when "100" =>
        if (gas = '1') then
            Speed <= Speed +1;
            Acc <= "00001";
        end if; 

        if (gas = '0') then
            Speed <= Speed -1;
            Acc <= "00000";
        end if;
    when others =>
            Speed <= Speed -1; 
            Acc <= "00000";
end case;

END PROCESS;
END Behavior;

Best Answer

I encourage, that you start with a simpler example to learn VHDL.

If you want registers for trans, Speed, Accand so on, then you must group all assignments for each signal into a if(rising_edge(Clk)) block. You can use also such a block for all regarding signals at once; e.g.

PROCESS (Clk) -- just Clk now required 
BEGIN
  if(rising_edge(Clk)) then 
  -- all following assignments are now synchronous to the clock edge

        if (up = '1') hen
            trans <= trans + '1';
        else 
            trans <= trans; -- not needed, saved anyway if not assigned elsewhere
        end if;

        if (down = '1') then
            trans <= trans - '1';
        else 
            trans <= trans; 
        end if;

    case trans is
    when "000" => 
      if (gas = '1') then
        Speed <= Speed +4;
        Acc <= "11111";
      end if;

      if (gas = '0') then
          Speed <= Speed -4;
          Acc <= "00000";
      end if; 

    -- and so on
    end case;
  end if;
END PROCESS;    

EDIT: corrected code.

Furthermore trans must be defined as a signal in the architecture, so that, it can be initialized to "000":

ARCHITECTURE Behavior OF GearCounterFirst IS
  signal trans : std_logic_vector(2 downto 0) := "000";
BEGIN

But, now you also need a new name for output, e.g.: trans_o and an assignment after(!) the process:

trans_o <= trans;

The output should now be declared as out instead of buffer:

trans_o : out STD_LOGIC_VECTOR (2 downto 0)

Same signal declaration and assignment is required for Speed and Acc.

Related Topic