Skip to content

Instantly share code, notes, and snippets.

@fbegyn
Last active November 8, 2017 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fbegyn/51306934b96f184bfc36d197793ecff8 to your computer and use it in GitHub Desktop.
Save fbegyn/51306934b96f184bfc36d197793ecff8 to your computer and use it in GitHub Desktop.
-------------------------------------------------------------
-- authors: Tom Davidson and Peter Bertels
-- date: 2009-10-14
-------------------------------------------------------------
-- Complex Systems Design Methodology
-- Calculator - top level
-------------------------------------------------------------
library ieee, std;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
entity calculator is
generic (
BITS: integer := 10
);
port (
--keyboard input signals
zero : in std_ulogic;
one : in std_ulogic;
two : in std_ulogic;
three : in std_ulogic;
four : in std_ulogic;
five : in std_ulogic;
six : in std_ulogic;
seven : in std_ulogic;
eight : in std_ulogic;
nine : in std_ulogic;
plus : in std_ulogic;
minus : in std_ulogic;
multiply : in std_ulogic;
divide : in std_ulogic;
enter : in std_ulogic;
-- control signal(s)
clk : in std_ulogic;
rst : in std_ulogic;
-- output signals
error : out std_ulogic;
display : out std_ulogic_vector(BITS-1 downto 0)
);
end calculator;
architecture behavioural of calculator is
--state definition
type state is (idle, read1, read2, read1_wait, read2_wait, write, write_wait, reset);
signal curState, nextState : state;
--pressed keyboard signals
signal zero_pressed : std_ulogic;
signal one_pressed : std_ulogic;
signal two_pressed : std_ulogic;
signal three_pressed : std_ulogic;
signal four_pressed : std_ulogic;
signal five_pressed : std_ulogic;
signal six_pressed : std_ulogic;
signal seven_pressed : std_ulogic;
signal eight_pressed : std_ulogic;
signal nine_pressed : std_ulogic;
signal plus_pressed : std_ulogic;
signal minus_pressed : std_ulogic;
signal multiply_pressed : std_ulogic;
signal divide_pressed : std_ulogic;
signal enter_pressed : std_ulogic;
signal rst_buttons : std_ulogic;
--stack communication
signal valid : std_ulogic;
signal stack_in : std_ulogic_vector(BITS-1 downto 0);
signal stack_out : std_ulogic_vector(BITS-1 downto 0);
signal pop : std_ulogic;
signal push : std_ulogic;
begin
STACK: entity work.stack(behaviour)
generic map (
BITS => BITS,
SIZE_LOG2 => 3
)
port map (
clk => clk,
rst => rst,
push => push,
pop => pop,
data_in => stack_in,
data_out => stack_out,
data_valid => valid,
error => error
);
latches: process (clk, rst_buttons) is
variable zero_latched : std_ulogic := '0';
variable one_latched : std_ulogic := '0';
variable two_latched : std_ulogic := '0';
variable three_latched : std_ulogic := '0';
variable four_latched : std_ulogic := '0';
variable five_latched : std_ulogic := '0';
variable six_latched : std_ulogic := '0';
variable seven_latched : std_ulogic := '0';
variable eight_latched : std_ulogic := '0';
variable nine_latched : std_ulogic := '0';
variable plus_latched : std_ulogic := '0';
variable minus_latched : std_ulogic := '0';
variable multiply_latched : std_ulogic := '0';
variable divide_latched : std_ulogic := '0';
variable enter_latched : std_ulogic := '0';
begin
if rst_buttons = '1' then
zero_pressed <= '0';
one_pressed <= '0';
two_pressed <= '0';
three_pressed <= '0';
four_pressed <= '0';
five_pressed <= '0';
six_pressed <= '0';
seven_pressed <= '0';
eight_pressed <= '0';
nine_pressed <= '0';
plus_pressed <= '0';
minus_pressed <= '0';
multiply_pressed<= '0';
divide_pressed <= '0';
enter_pressed <= '0';
elsif rising_edge(clk) then
if zero = '1' then
zero_latched := '1';
elsif zero = '0' and zero_latched = '1' then
zero_latched := '0';
zero_pressed <= '1';
end if;
if one = '1' then
one_latched := '1';
elsif one = '0' and one_latched = '1' then
one_latched := '0';
one_pressed <= '1';
end if;
if two = '1' then
two_latched := '1';
elsif two = '0' and two_latched = '1' then
two_latched := '0';
two_pressed <= '1';
end if;
if three = '1' then
three_latched := '1';
elsif three = '0' and three_latched = '1' then
three_latched := '0';
three_pressed <= '1';
end if;
if four = '1' then
four_latched := '1';
elsif four = '0' and four_latched = '1' then
four_latched := '0';
four_pressed <= '1';
end if;
if five = '1' then
five_latched := '1';
elsif five = '0' and five_latched = '1' then
five_latched := '0';
five_pressed <= '1';
end if;
if six = '1' then
six_latched := '1';
elsif six = '0' and six_latched = '1' then
six_latched := '0';
six_pressed <= '1';
end if;
if seven = '1' then
seven_latched := '1';
elsif seven = '0' and seven_latched = '1' then
seven_latched := '0';
seven_pressed <= '1';
end if;
if eight = '1' then
eight_latched := '1';
elsif eight = '0' and eight_latched = '1' then
eight_latched := '0';
eight_pressed <= '1';
end if;
if nine = '1' then
nine_latched := '1';
elsif nine = '0' and nine_latched = '1' then
nine_latched := '0';
nine_pressed <= '1';
end if;
if plus = '1' then
plus_latched := '1';
elsif plus = '0' and plus_latched = '1' then
plus_latched := '0';
plus_pressed <= '1';
end if;
if minus = '1' then
minus_latched := '1';
elsif minus = '0' and minus_latched = '1' then
minus_latched := '0';
minus_pressed <= '1';
end if;
if multiply = '1' then
multiply_latched := '1';
elsif multiply = '0' and multiply_latched = '1' then
multiply_latched := '0';
multiply_pressed <= '1';
end if;
if divide = '1' then
divide_latched := '1';
elsif divide = '0' and divide_latched = '1' then
divide_latched := '0';
divide_pressed <= '1';
end if;
if enter = '1' then
enter_latched := '1';
elsif enter = '0' and enter_latched = '1' then
enter_latched := '0';
enter_pressed <= '1';
end if;
end if;
end process latches;
statecalc: process(curState, clk, rst)
begin
if rst = '1' then
nextState <= reset;
else
case curState is
when read1 =>
nextState <= read1_wait;
when read1_wait =>
if valid = '1' then
nextState <= read2;
else
nextState <= read1_wait;
end if;
when read2 =>
nextState <= read2_wait;
rst_buttons <= '1';
when read2_wait =>
if valid = '1' then
nextState <= write;
else
nextState <= read2_wait;
end if;
when write =>
if valid = '0' then
nextState <= write_wait;
else
nextState <= write;
end if;
when write_wait =>
if valid = '1' then
nextState <= idle;
else
nextState <= write_wait;
end if;
when idle =>
if enter_pressed = '1' then
nextState <= write;
rst_buttons <= '1';
elsif plus_pressed = '1' then
nextState <= read1;
elsif minus_pressed = '1' then
nextState <= read1;
elsif divide_pressed = '1' then
nextState <= read1;
elsif multiply_pressed = '1' then
nextState <= read1;
elsif zero_pressed = '1' then
rst_buttons <= '1';
elsif one_pressed = '1' then
rst_buttons <= '1';
elsif two_pressed = '1' then
rst_buttons <= '1';
elsif three_pressed = '1' then
rst_buttons <= '1';
elsif four_pressed = '1' then
rst_buttons <= '1';
elsif five_pressed = '1' then
rst_buttons <= '1';
elsif six_pressed = '1' then
rst_buttons <= '1';
elsif seven_pressed = '1' then
rst_buttons <= '1';
elsif eight_pressed = '1' then
rst_buttons <= '1';
elsif nine_pressed = '1' then
rst_buttons <= '1';
elsif enter_pressed = '1' then
rst_buttons <= '1';
else
rst_buttons <= '0';
end if;
when others =>
nextState <= idle;
end case;
end if;
end process;
stateTran: process(clk, rst)
begin
if rst = '1' then
curState <= nextState;
else
if rising_edge(clk) then
curState <= nextState;
end if;
end if;
end process;
statebehaviour: process(curState, clk)
variable number : integer;
variable number2 : integer;
variable result : integer;
begin
case curState is
when idle =>
if zero_pressed = '1' then
number := number2;
elsif one_pressed = '1' then
number := number2+1;
elsif two_pressed = '1' then
number := number2+2;
elsif three_pressed = '1' then
number := number2+3;
elsif four_pressed = '1' then
number := number2+4;
elsif five_pressed = '1' then
number := number2+5;
elsif six_pressed = '1' then
number := number2+6;
elsif seven_pressed = '1' then
number := number2+7;
elsif eight_pressed = '1' then
number := number2+8;
elsif nine_pressed = '1' then
number := number2+9;
end if;
number2 := number*10;
result := number;
when read1 =>
number := to_integer(signed(stack_out));
pop <= '1';
when read1_wait =>
pop <= '0';
when read2 =>
number2 := to_integer(signed(stack_out));
if plus_pressed = '1' then
result := number2 + number;
elsif minus_pressed = '1' then
result := number2 - number;
elsif divide_pressed = '1' then
result := number2 / number;
elsif multiply_pressed = '1' then
result := number2 * number;
end if;
pop <= '1';
when read2_wait =>
pop <= '0';
when write =>
stack_in <= std_ulogic_vector(to_signed(result, BITS));
push <= '1';
when write_wait =>
--rst_buttons <= '1';
push <= '0';
number := 0;
display <= std_ulogic_vector(to_signed(result, BITS));
when reset =>
number := 0;
when others =>
number := 0;
end case;
end process;
end architecture behavioural;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment