Counter with a final state machine structure in VHDL. QUARTUS - vhdl

I've produced this VHDL code and testing it with a VWF file seems that it works. But the finite state machine that my code produces (I can see it using the QUARTUS tool "state machine viewer") it seems to be wrong. In this FSM seems that in each state it is possible to reach any one else state.
According to my project goals I need a counter that counts from zero to nine and it changes its value according to the value of two input signals w0 and w1. If w0 and w1 are both zero, the counter attends in its current state, if w0 is 0 and w1 is 1 the counter increases by one, if w0 is 1 and w1 is 0 the counter increases by two, if w0 and w1 are both 1 the counter decrements by one. There are also a clock signal and a reset signal.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY counter IS
PORT(clk, reset :in std_logic;
w :in std_logic_vector(1 DOWNTO 0);
cont :out std_logic_vector(3 DOWNTO 0););
END;
ARCHITECTURE arch_counter OF counter IS
TYPE state IS (zero, one, two, three, four, five, six, seven, eight, nine);
SIGNAL numbCorr, numbFuture :state;
BEGIN
PROCESS(w, numbCorr)
BEGIN
CASE numbCorr IS
WHEN zero => IF w = "00" THEN numbFuture <= zero;
ELSIF w = "01" THEN numbFuture <= one;
ELSIF w = "10" THEN numbFuture <= two;
ELSIF w = "11" THEN numbFuture <= zero;
END IF;
cont <= "0000";
WHEN one => IF w = "00" THEN numbFuture <= one;
ELSIF w = "01" THEN numbFuture <= two;
ELSIF w = "10" THEN numbFuture <= three;
ELSIF w = "11" THEN numbFuture <= zero;
END IF;
cont <= "0001";
WHEN two => IF w = "00" THEN numbFuture <= two;
ELSIF w = "01" THEN numbFuture <= three;
ELSIF w = "10" THEN numbFuture <= four;
ELSIF w = "11" THEN numbFuture <= one;
END IF;
cont <= "0010";
WHEN three => IF w = "00" THEN numbFuture <= three;
ELSIF w = "01" THEN numbFuture <= four;
ELSIF w = "10" THEN numbFuture <= five;
ELSIF w = "11" THEN numbFuture <= two;
END IF;
cont <= "0011";
WHEN four => IF w = "00" THEN numbFuture <= four;
ELSIF w = "01" THEN numbFuture <= five;
ELSIF w = "10" THEN numbFuture <= six;
ELSIF w = "11" THEN numbFuture <= three;
END IF;
cont <= "0100";
WHEN five => IF w = "00" THEN numbFuture <= five;
ELSIF w = "01" THEN numbFuture <= six;
ELSIF w = "10" THEN numbFuture <= seven;
ELSIF w = "11" THEN numbFuture <= four;
END IF;
cont <= "0101";
WHEN six => IF w = "00" THEN numbFuture <= six;
ELSIF w = "01" THEN numbFuture <= seven;
ELSIF w = "10" THEN numbFuture <= eight;
ELSIF w = "11" THEN numbFuture <= five;
END IF;
cont <= "0110";
WHEN seven => IF w = "00" THEN numbFuture <= seven;
ELSIF w = "01" THEN numbFuture <= eight;
ELSIF w = "10" THEN numbFuture <= nine;
ELSIF w = "11" THEN numbFuture <= six;
END IF;
cont <= "0111";
WHEN eight => IF w = "00" THEN numbFuture <= eight;
ELSIF w = "01" THEN numbFuture <= nine;
ELSIF w = "10" THEN numbFuture <= nine;
ELSIF w = "11" THEN numbFuture <= eight;
END IF;
cont <= "1000";
WHEN nine => IF w = "00" THEN numbFuture <= nine;
ELSIF w = "01" THEN numbFuture <= nine;
ELSIF w = "10" THEN numbFuture <= nine;
ELSIF w = "11" THEN numbFuture <= eight;
END IF;
cont <= "1001";
END CASE;
END PROCESS;
PROCESS(clk)
BEGIN
IF (rising_edge(clk)) THEN
IF reset = '0' THEN numbCorr <= numbFuture ;
ELSE numbCorr <= zero;
END IF;
END IF;
END PROCESS;
END;
I think with this code is not possible that if the current state is "zero" the future state will be for example "seven" (from the FSM viewer seems that is possible). It is correct or I'm wrong?
this is the FSM produced by quartus (the numberState are in Italian because my original code was in italian to)

Related

Testbench for FSM

I'm trying to implement a testbench for the following fsm in created in vhdl. The problem is that currently, I'm not seeing any state transitions in the test bench. The simulation stays at state 0.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_Challenge is
Port ( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end FPGA_Challenge;
architecture Behavioral of FPGA_Challenge is
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x:std_logic;
signal y:std_logic;
signal count : integer:= 0;
--signal tmp: std_logic:= '1';
begin
process(clk_in, reset)
begin
if rising_edge(clk_in)then
if reset = '1'then -- Goes back to known state (state 0)
state <= s0;
count <= 0;
else
count <= count + 1;
case state is
-- Initial state- if button is pressed, then LED is lit and machine goes to state 2, if not it stays in state 1
when s0 =>
if (button <= '1') then
led <= '1';
state <= s1;
else
state <= s0;
led <= '0'; --is this necessary?
end if;
-- Beginning of preamble detection(states 1-17)
-- Count = ((freq in) / (freq out))/ 2 -1 = (100 MHz/ 2 MHz)/ 2 -1 = 50/2 - 1 (due to 50% duty cycle)
when s1=> -- do I need to put led = '1' in each state because it stays on ?
if (count = 25 -1) then
count <= 0;
if (data_line = '1')then
y <= '0';
-- led = '1';
state <= s2;
else
-- led = '1';
y <= '0';
state <= s1;
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s2 =>
if (count = 25-1) then
count <= 0;
if (data_line = '0')then
y <= '0';
-- led = '1';
state <= s3;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s3 =>
if (count = 25-1)then
count <= 0; ----reinitializes count
if (data_line <= '1')then
y <= '0';
-- led = '1';
state <= s4;
else
state <= s1;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s4 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s5;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s5 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s6;
else
state <= s4;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s6 =>
if (count= 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s7 =>
if (count = 25-1)then
count<= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s7;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s8 =>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
-- led = '1';
state <= s9;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s9 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s10;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s10=>
if (count = 25-1)then
count <= 0;
if (data_line <='1')then
y <= '0';
--led = '1';
state <= s11;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s11 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s12;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s12 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
--led = '1';
state <= s13;
else
state <= s2;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s13 =>
if (count = 25-1)then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s14;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s14 =>
if (count = 25-1)then
count <=0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s15;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s15 =>
if (count = 25-1)then
count <=0;
if (data_line <='0') then
y <= '0';
-- led = '1';
state <= s16;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s16 =>
if (count = 25-1) then
count <= 0;
if (data_line <='0')then
y <= '0';
-- led = '1';
state <= s17;
else
state <= s2;
y <= '0';
-- led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s17 =>
if (count = 25-1)then
count <= 0;
if (data_line ='1')then
y <= '1';
-- led = '1';
state <= s18;
else
state <= s1;
y <= '0';
--led = '1';
end if;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when s18 => -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s19;
else
count <= count + 1;
end if;
-- clock_out <= tmp;
when s19=> -- no real condition here except varying period of clock
if (count = 25)then
count <= 0; ----reinitializes count
state <= s0;
else
count <= count + 1;
end if;
--clock_out <= tmp;
when others=>
null;
end case;
end if;
end if;
end process;
end architecture;
The following is the testbench I have so far. I have internal signals such as y(output for each state), and count(counter for how long I'm in a state) that I probably should be using as drivers in the testbench. Any input is appreciated
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity FPGA_tb is
-- Port ( );
end FPGA_tb;
architecture Behavioral of FPGA_tb is
component FPGA_Challenge is
Port( led : out STD_LOGIC;
clk_in : in STD_LOGIC; -- 100 MHZ internal clock
reset : in STD_LOGIC; -- is reset necessary
button : in STD_LOGIC;
data_line : in STD_LOGIC);
end component;
signal led : STD_LOGIC;
signal clk_in : STD_LOGIC; -- 100 MHZ internal clock
signal reset : STD_LOGIC; -- is reset necessary
signal button : STD_LOGIC;
signal data_line : STD_LOGIC;
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20);
signal state: state_type;
signal x,y: std_logic;
signal count : integer:= 0;
begin
UUT: FPGA_Challenge
PORT MAP(
led => led,
clk_in => clk_in,
reset => reset,
button => button,
data_line => data_line
);
Testing: Process
begin
--wait until rising_edge(clk_in);
--wait until rising_edge(clk_in);
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '0';
button <= '1';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '1';
WAIT For 10ns;
clk_in <='0';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
clk_in <='1';
reset <= '1';
button <= '0';
data_line <= '0';
WAIT For 10ns;
end process;
end Behavioral;
Try this in the testbench to have a running clock and proper reset
signal clk_in : STD_LOGIC := '1'; -- 100 MHZ internal clock
signal reset : STD_LOGIC := '1'; -- is reset necessary
clk_in <=NOT clk_in after 10ns;
reset <= 0 after 30ns;
play with button after the reset. that is, from 40ns

How to make a key generated, 7 segment display, output persist after the key is released? [VHDL]

I'm trying to read input from the keypad and I want the number entered by the user to persist on a 7 segment display until another key is pressed.
Currently, the 7 segment display output disappears when the key is released. How can I make the 7 segment display output persist?
This is my entire code :
ARCHITECTURE Behavioral OF keypad IS
SIGNAL t1, t2, t3, t4: STD_LOGIC_VECTOR (1 TO 4) := "1111";
SIGNAL curr : STD_LOGIC_VECTOR(1 TO 4) := "0111";
BEGIN
proc_1: PROCESS
BEGIN
WAIT UNTIL rising_edge(clk);
IF curr <= "0111" THEN t1<= row ;
curr <= "1011";
ELSIF curr <= "1011" THEN t2<= row ;
curr <= "1101";
ELSIF curr <= "1101" THEN t3<= row ;
curr <= "1110";
ELSIF curr <= "1110" THEN t4<= row ;
curr <= "0111";
ELSE
curr <= "0111";
END IF ;
END PROCESS ;
proc_2: PROCESS (t1, t2, t3, t4)
BEGIN
hit <= '1';
IF t1(1) = '0' THEN sevenseg <= "1001111" ; --1
ELSIF t1(2) = '0' THEN sevenseg <= "1001100" ; --4
ELSIF t1(3) = '0' THEN sevenseg <= "0001111" ; --7
ELSIF t1(4) = '0' THEN sevenseg <= "1111111" ; --*
ELSIF t2(1) = '0' THEN sevenseg <= "0010010" ; --2
ELSIF t2(2) = '0' THEN sevenseg <="0100100" ; --5
ELSIF t2(3) = '0' THEN sevenseg <= "0000000" ; --8
ELSIF t2(4) = '0' THEN sevenseg <= "0000001" ; --0
ELSIF t3(1) = '0' THEN sevenseg <= "0000110" ; --3
ELSIF t3(2) = '0' THEN sevenseg <= "0100000" ; --6
ELSIF t3(3) = '0' THEN sevenseg <= "0000100" ; --9
ELSIF t3(4) = '0' THEN sevenseg <= "1111111" ; --#
ELSIF t4(1) = '0' THEN sevenseg <= "0001000" ; --A
ELSIF t4(2) = '0' THEN sevenseg <= "1111111" ; --B
ELSIF t4(3) = '0' THEN sevenseg <= "0110001" ; --C
ELSIF t4(4) = '0' THEN sevenseg <= "1111111" ; --D
ELSE
hit <= '0';
END IF;
END PROCESS;
col <= curr ;
END Behavioral ;

Can't find the issues and latches are generated

My code generates two latches, could please someone help me finding why?
According to Xilinx ISE latches are generated because of "try_counter" which is a counter for how many times you get a numeric sequence wrong. (which is the main point of my code).
I don't know what else to do.
entity moore is
Port ( badgeSx : in STD_LOGIC;
badgeDx : in STD_LOGIC;
col : in std_logic_vector (1 to 3);
row : in std_logic_vector (1 to 4);
clk : in std_logic;
rst : in std_logic;
unlock : out STD_LOGIC
);
end moore;
architecture Behavioral of moore is
type stato is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
signal current_state,next_state : stato;
signal badge : std_logic_vector(1 downto 0);
signal count, new_count: integer range 0 to 28;
signal temp_unlock : std_logic :='0';
signal timeover : std_logic :='0';
begin
badge <= badgeDx & badgeSx; --concatenazione dei badge
--processo sequenziale
current_state_register: process(clk)
begin
if rising_edge(clk) then
if (rst = '1') then
current_state <= s0;
count <= 0;
else
current_state <= next_state;
count <= new_count;
end if;
end if;
end process;
process (current_state,badge,col,row,timeover)
variable try_counter: integer range 0 to 3;
begin
case current_state is
when s0 =>
try_counter := 0;
temp_unlock <= '0';
unlock <='0';
if(badge ="01" and row = "0000" and col = "000" ) then
next_state <= s1;
else
next_state <= s0;
end if;
when s1 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s2 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
else
next_state <= s3;
end if;
when s3 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s4 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
else
next_state <= s5;
end if;
when s5 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s6 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
else
next_state <= s7;
end if;
when s7 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s8 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
else
next_state <= s9;
end if;
when s9 =>
temp_unlock <= '0';
unlock <= '1';
if (badge = "10") then
next_state <= s0;
else
next_state <= s5;
end if;
when others =>
next_state <= s0;
end case;
end process;
Contatore_TIMER : process(temp_unlock,count)
begin
if temp_unlock = '1' then
if count = 28 then
new_count<=0;
timeover<='1';
else
new_count<=count+1;
timeover<='0';
end if;
else
new_count<=0;
timeover <= '0';
end if;
end process;
end Behavioral;
The code nearly works as expected (I mean it compiles and I don't get any error) but the RTL schematic isn't what it is supposed to be since it synthesises latches in the process.
In the apparently combinatorial process with process (current_state,badge,col,row,timeover), the variable try_counter is used to store information (sequential behaviour), which is only updated when process evaluation is triggered. This will very likely to generate the 2 latches, which matches the value range from 0 to 3 for try_counter.
To fix this, you can define try_counter as a signal, and include it in the sensitivity list for the process.
Having try_counter as a signal will also ease debugging, since the current state can easily be inspected in waveforms.

Signal parameter in a subprogram is not supported error

My code is about a ping pang game using VHDL and maxplus2. I can't get it complied.
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_unsigned.all;
-- use ieee.std_logic_arith.all;
entity center is
port (
clk: in std_logic;
ca: in std_logic;
cb: in std_logic;
enable: in std_logic;
a: in std_logic;
b: in std_logic;
ball: out std_logic_vector(16 downto 0);
sa: out std_ulogic;
sb: out std_ulogic;
over: inout std_ulogic
);
end center;
architecture behavior of center is
signal direction : integer range 0 to 2;
signal num : integer range -1 to 17;
begin
process (enable,ca,cb,a,b,clk)
begin
if enable = '0' then
over <= '0';
sa <= '0';
sb <= '0';
elsif enable = '1' and rising_edge(clk) then
if direction = 2 then
if ca = '1' then
direction <= 0;
num <= 1;
elsif cb = '1' then
direction <= 1;
num <= 16;
else
direction <= 2;
num <= 8;
end if;
elsif direction = 0 and num > 0 then
if b = '1' then
if num < 2 then
num <= num - 1;
direction <= 1;
else
direction <= 2;
sa <= '1' after 10 ns;
sb <= '0' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
elsif direction = 1 and num <= 16 then
if a = '1' then
if num >= 14 then
num <= num + 1;
direction <= 2;
else
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
elsif direction = 0 and num = -1 then
num <= 8;
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
elsif direction = 0 and num = -1 then
num <= 8;
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
end process;
end architecture behavior;
But I get a error:
signal parameter in a subprogram is not supported
I am confused, I don't know why I get this error.
I think as David also said you need to provide more information.
What it looks like for me is that your are writing a test bench the above code cannot be synthesized correctly. ISE will tell you that your syntax is ok but the delays are ignored IE the after keyword. The after keyword is only used in simulation.
That said i would also clean up the code there are a lot of redundancies. FX
The last two elsif statements. only one is needed. and the sensitivity list. only clk and enable should be there.
I've tried to clean up your code:
process (enable,clk)
begin
if enable = '0' then
over <= '0';
sa <= '0';
sb <= '0';
elsif rising_edge(clk) then
case( direction ) is
when 0 =>
if num > 0 then
if b = '1' then
if num < 2 then
num <= num - 1;
direction <= 1;
else
direction <= 2;
sa <= '1' after 10 ns;
sb <= '0' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
elsif num = -1 then
num <= 8;
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
when 1 =>
if num <= 16 then
if a = '1' then
if num >= 14 then
num <= num + 1;
direction <= 2;
else
direction <= 2;
sa <= '0' after 10 ns;
sb <= '1' after 10 ns;
over <= not over after 10 ns;
end if;
end if;
end if;
when 2 =>
if ca = '1' then
direction <= 0;
num <= 1;
elsif cb = '1' then
direction <= 1;
num <= 16;
else
direction <= 2;
num <= 8;
end if;
when others => NULL;
end case ;
end if;
end process;
Try and remove your after keywords and see if it will compile then.

Addition of 2 numbers from keyboard using spartan 3 (vhdl)

My task is to take 2 inputs from keyboard which is numbers from 0 to 9 and to add them. Problem is in
STORING these numbers.i want to save first press(input no.) into "a" and second press(input no.) into
"b" but by using following code first press stores in both a and b. 2nd press is of no use. here
scan_code = scancode of the pressed button (output of keyboard interfacing code)
a = number in binary (for example if first time i press "1" then the code check the scancode and assign the binary value of "1" to a).
Any one who can help?
process (clk, scan_code, cin)
variable scancode1 : std_logic_vector (7 downto 0) := "00000000";
variable cin2 : std_logic_vector(2 downto 0);
begin
if(clk'event and clk = '1') then
scancode1 := scan_code;
a <= "0000";
b <="0000";
if (scancode1 = "00010110") then
a <= "0001";
elsif (scancode1 = "00011110") then
a <="0010";
elsif (scancode1 = "00100110") then
a <="0011";
elsif (scancode1 = "00100101") then
a <="0100";
elsif (scancode1 = "00101110") then
a <="0101";
elsif(scancode1 = "00110110") then
a <="0110";
elsif (scancode1 = "00111101") then
a <="0111";
elsif (scancode1 = "00111110") then
a <="1000";
elsif (scancode1 = "01000110") then
a <="1001";
elsif (scancode1 = "01000101") then
a <="0000";
end if;
if (scancode1 = "01010101") then --scancode for + sign
a <=a;
end if;
if (scancode1 = "00010110") then
b <="0001";
elsif (scancode1 = "00011110") then
b <="0010";
elsif (scancode1 = "00100110") then
b <="0011";
elsif (scancode1 = "00100101") then
b <="0100";
elsif (scancode1 = "00101110") then
b <="0101";
elsif(scancode1 = "00110110") then
b <="0110";
elsif (scancode1 = "00111101") then
b <="0111";
elsif (scancode1 = "00111110") then
b <="1000";
elsif (scancode1 = "01000110") then
b <="1001";
elsif (scancode1 = "01000101") then
b <="0000";
end if;
sum(0) <= a(0) xor b(0) xor cin;
cin2(0) := (a(0) and b(0)) or (cin and (a(0) xor b(0)));
sum(1) <= a(1) xor b(1) xor cin2(0);
cin2(1) := (a(1) and b(1)) or (cin2(0) and (a(1) xor b(1)));
sum(2) <= a(2) xor b(2) xor cin2(1);
cin2(2) := (a(2) and b(2)) or (cin2(1) and (a(2) xor b(2)));
sum(3) <= a(3) xor b(3) xor cin2(2);
cout <= (a(3) and b(3)) or (cin2(2) and (a(3) xor b(3)));
end if;
end process;
"a" and "b" are updating at the same time as you wrote it like that (same "scancodes" are checked for "a" and "b" on the same clockedge). think about using an event trigger like in the following example:
...
if reset='1' then
a<=(others => '0');
b<=(others => '0');
event_last<='0';
event_nr<=0;
elsif rising_edge(clk) then
event_last<=event;
-- trigger on "rising edge" of event
if event='1' and event_last='0' then
case event_nr is
-- first event is "a"
when 0 =>
event_nr<=1;
if (scancode1 = "00010110") then
a <= "0001";
...
-- second event is "b"
when others =>
event_nr<=0;
if (scancode1 = "00010110") then
b <= "0001";
...
end case;
...
...

Resources