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;
1 Answer 1
I encourage, that you start with a simpler example to learn VHDL.
If you want registers for trans
, Speed
, Acc
and 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
.
-
\$\begingroup\$ I have edited the code, but the transmission (trans) turns negative when the gas is left off. Is this because of the trans <= trans - '1' statement? \$\endgroup\$Marcus Ashley LowDBs– Marcus Ashley LowDBs2015年11月18日 00:40:11 +00:00Commented Nov 18, 2015 at 0:40
-
\$\begingroup\$ As long as
up
ordown
are high at a clock-edgetrans
will be incremented / decremented. Due to a high clock frequency, a high state of a button will be seen at mutiple consecutive clock edges. \$\endgroup\$Martin Zabel– Martin Zabel2015年11月18日 00:46:31 +00:00Commented Nov 18, 2015 at 0:46