Created
January 18, 2017 13:28
-
-
Save fohte/8089276bf5c30e3bbbe2c6de1c23879e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; | |
use ieee.std_logic_1164.all; | |
use ieee.std_logic_unsigned.all; | |
entity calc is | |
generic ( | |
DIV_BITS: integer := 20; | |
SEGMENT_CLEAR: std_logic_vector(7 downto 0) := "11111111"; | |
SEGMENT_0: std_logic_vector(7 downto 0) := "00000011"; | |
SEGMENT_1: std_logic_vector(7 downto 0) := "10011111"; | |
SEGMENT_2: std_logic_vector(7 downto 0) := "00100101"; | |
SEGMENT_3: std_logic_vector(7 downto 0) := "00001101"; | |
SEGMENT_4: std_logic_vector(7 downto 0) := "10011001"; | |
SEGMENT_5: std_logic_vector(7 downto 0) := "01001001"; | |
SEGMENT_6: std_logic_vector(7 downto 0) := "01000001"; | |
SEGMENT_7: std_logic_vector(7 downto 0) := "00011111"; | |
SEGMENT_8: std_logic_vector(7 downto 0) := "00000001"; | |
SEGMENT_9: std_logic_vector(7 downto 0) := "00001001"; | |
SEGMENT_PLUS: std_logic_vector(7 downto 0) := "10011101"; | |
SEGMENT_MINUS: std_logic_vector(7 downto 0) := "11111101"; | |
SEGMENT_TIMES: std_logic_vector(7 downto 0) := "10010001"; | |
SEGMENT_DIVIDE: std_logic_vector(7 downto 0) := "10110101" | |
); | |
port ( | |
clk: in std_logic; | |
sw1, sw2, sw3, sw4: in std_logic; | |
led_left, led_center, led_right: out std_logic_vector(7 downto 0) | |
); | |
end calc; | |
architecture rtl of calc is | |
-- state machine | |
type NUMBER_STATE is (NUM_0, NUM_1, NUM_2, NUM_3, NUM_4, NUM_5, NUM_6, NUM_7, NUM_8, NUM_9); | |
type OPERATOR_STATE is (OP_PLUS, OP_MINUS, OP_TIMES, OP_DIVIDE); | |
type MODE_STATE is (MODE_INPUT, MODE_RESULT); | |
-- mode | |
signal current_mode: MODE_STATE := MODE_INPUT; | |
signal next_mode: MODE_STATE; | |
-- for result mode | |
signal result: integer := 0; | |
signal first_digit_led, second_digit_led: std_logic_vector(7 downto 0); | |
signal first_digit, second_digit: integer := 0; | |
-- for input mode | |
signal left_item_state, left_item_next_state, right_item_state, right_item_next_state: NUMBER_STATE; | |
signal op_state, op_next_state: OPERATOR_STATE; | |
signal left_item, right_item: integer := 0; | |
signal left_item_led, right_item_led, center_item_led: std_logic_vector(7 downto 0); | |
-- switch | |
signal clk_sw: std_logic := '0'; | |
signal div_counter: std_logic_vector(DIV_BITS - 1 downto 0) := (others => '0'); | |
signal sw1_latch_on, sw2_latch_on, sw3_latch_on, sw4_latch_on: std_logic := '0'; | |
signal sw1_node, sw2_node, sw3_node, sw4_node: std_logic := '1'; | |
begin | |
process (clk) | |
begin | |
if clk'event and clk = '1' then | |
div_counter <= div_counter + 1; | |
end if; | |
end process; | |
clk_sw <= div_counter(DIV_BITS - 1); | |
process (clk_sw) | |
begin | |
if clk_sw'event and clk_sw = '1' then | |
sw1_node <= sw1; | |
sw2_node <= sw2; | |
sw3_node <= sw3; | |
sw4_node <= sw4; | |
end if; | |
end process; | |
process (clk) | |
begin | |
if clk'event and clk = '1' then | |
if sw1_node = '0' and sw1_latch_on = '0' then | |
sw1_latch_on <= '1'; | |
elsif sw1_node = '1' and sw1_latch_on = '1' then | |
sw1_latch_on <= '0'; | |
elsif sw1_node = '0' and sw1_latch_on = '1' then | |
sw1_latch_on <= '1'; | |
end if; | |
end if; | |
end process; | |
process (clk) | |
begin | |
if clk'event and clk = '1' then | |
if sw2_node = '0' and sw2_latch_on = '0' then | |
sw2_latch_on <= '1'; | |
elsif sw2_node = '1' and sw2_latch_on = '1' then | |
sw2_latch_on <= '0'; | |
elsif sw2_node = '0' and sw2_latch_on = '1' then | |
sw2_latch_on <= '1'; | |
end if; | |
end if; | |
end process; | |
process (clk) | |
begin | |
if clk'event and clk = '1' then | |
if sw3_node = '0' and sw3_latch_on = '0' then | |
sw3_latch_on <= '1'; | |
elsif sw3_node = '1' and sw3_latch_on = '1' then | |
sw3_latch_on <= '0'; | |
elsif sw3_node = '0' and sw3_latch_on = '1' then | |
sw3_latch_on <= '1'; | |
end if; | |
end if; | |
end process; | |
process (clk) | |
begin | |
if clk'event and clk = '1' then | |
if sw4_node = '0' and sw4_latch_on = '0' then | |
sw4_latch_on <= '1'; | |
elsif sw4_node = '1' and sw4_latch_on = '1' then | |
sw4_latch_on <= '0'; | |
elsif sw4_node = '0' and sw4_latch_on = '1' then | |
sw4_latch_on <= '1'; | |
end if; | |
end if; | |
end process; | |
-- press the switching left number button (SW4) | |
process (sw4_latch_on) | |
begin | |
if sw4_latch_on = '1' then | |
left_item_state <= left_item_next_state; | |
end if; | |
end process; | |
-- change the left number | |
process (left_item_state) | |
begin | |
case left_item_state is | |
when NUM_0 => | |
left_item_led <= SEGMENT_0; | |
left_item <= 0; | |
left_item_next_state <= NUM_1; | |
when NUM_1 => | |
left_item_led <= SEGMENT_1; | |
left_item <= 1; | |
left_item_next_state <= NUM_2; | |
when NUM_2 => | |
left_item_led <= SEGMENT_2; | |
left_item <= 2; | |
left_item_next_state <= NUM_3; | |
when NUM_3 => | |
left_item_led <= SEGMENT_3; | |
left_item <= 3; | |
left_item_next_state <= NUM_4; | |
when NUM_4 => | |
left_item_led <= SEGMENT_4; | |
left_item <= 4; | |
left_item_next_state <= NUM_5; | |
when NUM_5 => | |
left_item_led <= SEGMENT_5; | |
left_item <= 5; | |
left_item_next_state <= NUM_6; | |
when NUM_6 => | |
left_item_led <= SEGMENT_6; | |
left_item <= 6; | |
left_item_next_state <= NUM_7; | |
when NUM_7 => | |
left_item_led <= SEGMENT_7; | |
left_item <= 7; | |
left_item_next_state <= NUM_8; | |
when NUM_8 => | |
left_item_led <= SEGMENT_8; | |
left_item <= 8; | |
left_item_next_state <= NUM_9; | |
when NUM_9 => | |
left_item_led <= SEGMENT_9; | |
left_item <= 9; | |
left_item_next_state <= NUM_0; | |
when others => null; | |
end case; | |
end process; | |
-- press the switching right number button (SW2) | |
process (sw2_latch_on) | |
begin | |
if sw2_latch_on = '1' then | |
right_item_state <= right_item_next_state; | |
end if; | |
end process; | |
-- change the right number | |
process (right_item_state) | |
begin | |
case right_item_state is | |
when NUM_0 => | |
right_item_led <= SEGMENT_0; | |
right_item <= 0; | |
right_item_next_state <= NUM_1; | |
when NUM_1 => | |
right_item_led <= SEGMENT_1; | |
right_item <= 1; | |
right_item_next_state <= NUM_2; | |
when NUM_2 => | |
right_item_led <= SEGMENT_2; | |
right_item <= 2; | |
right_item_next_state <= NUM_3; | |
when NUM_3 => | |
right_item_led <= SEGMENT_3; | |
right_item <= 3; | |
right_item_next_state <= NUM_4; | |
when NUM_4 => | |
right_item_led <= SEGMENT_4; | |
right_item <= 4; | |
right_item_next_state <= NUM_5; | |
when NUM_5 => | |
right_item_led <= SEGMENT_5; | |
right_item <= 5; | |
right_item_next_state <= NUM_6; | |
when NUM_6 => | |
right_item_led <= SEGMENT_6; | |
right_item <= 6; | |
right_item_next_state <= NUM_7; | |
when NUM_7 => | |
right_item_led <= SEGMENT_7; | |
right_item <= 7; | |
right_item_next_state <= NUM_8; | |
when NUM_8 => | |
right_item_led <= SEGMENT_8; | |
right_item <= 8; | |
right_item_next_state <= NUM_9; | |
when NUM_9 => | |
right_item_led <= SEGMENT_9; | |
right_item <= 9; | |
right_item_next_state <= NUM_0; | |
when others => null; | |
end case; | |
end process; | |
-- press the switching operator button (SW3) | |
process (sw3_latch_on) | |
begin | |
if sw3_latch_on = '1' then | |
op_state <= op_next_state; | |
end if; | |
end process; | |
-- change the operator | |
process (op_state) | |
begin | |
case op_state is | |
when OP_PLUS => | |
center_item_led <= SEGMENT_PLUS; | |
op_next_state <= OP_MINUS; | |
when OP_MINUS => | |
center_item_led <= SEGMENT_MINUS; | |
op_next_state <= OP_TIMES; | |
when OP_TIMES => | |
center_item_led <= SEGMENT_TIMES; | |
op_next_state <= OP_DIVIDE; | |
when OP_DIVIDE => | |
center_item_led <= SEGMENT_DIVIDE; | |
op_next_state <= OP_PLUS; | |
when others => null; | |
end case; | |
end process; | |
-- press the mode change button (SW1) | |
process (sw1_latch_on) | |
begin | |
if sw1_latch_on = '1' then | |
current_mode <= next_mode; | |
end if; | |
end process; | |
-- change mode | |
process (current_mode) | |
begin | |
case current_mode is | |
when MODE_INPUT => | |
next_mode <= MODE_RESULT; | |
when MODE_RESULT => | |
case op_state is | |
when OP_PLUS => | |
result <= left_item + right_item; | |
when OP_MINUS => | |
result <= left_item - right_item; | |
when OP_TIMES => | |
result <= left_item * right_item; | |
when OP_DIVIDE => | |
result <= left_item / right_item; | |
when others => null; | |
end case; | |
-- first_digit <= result mod 10; | |
first_digit <= (result - (10 * (result / 10))); | |
-- second_digit <= result mod 100 - first_digit; | |
second_digit <= (result - (100 * (result / 100))) - first_digit; | |
next_mode <= MODE_INPUT; | |
when others => null; | |
end case; | |
end process; | |
process (first_digit) | |
begin | |
case first_digit is | |
when 0 => | |
first_digit_led <= SEGMENT_0; | |
when 1 => | |
first_digit_led <= SEGMENT_1; | |
when 2 => | |
first_digit_led <= SEGMENT_2; | |
when 3 => | |
first_digit_led <= SEGMENT_3; | |
when 4 => | |
first_digit_led <= SEGMENT_4; | |
when 5 => | |
first_digit_led <= SEGMENT_5; | |
when 6 => | |
first_digit_led <= SEGMENT_6; | |
when 7 => | |
first_digit_led <= SEGMENT_7; | |
when 8 => | |
first_digit_led <= SEGMENT_8; | |
when 9 => | |
first_digit_led <= SEGMENT_9; | |
when others => null; | |
end case; | |
end process; | |
process (second_digit) | |
begin | |
case second_digit is | |
when 0 => | |
second_digit_led <= SEGMENT_CLEAR; | |
when 1 => | |
second_digit_led <= SEGMENT_1; | |
when 2 => | |
second_digit_led <= SEGMENT_2; | |
when 3 => | |
second_digit_led <= SEGMENT_3; | |
when 4 => | |
second_digit_led <= SEGMENT_4; | |
when 5 => | |
second_digit_led <= SEGMENT_5; | |
when 6 => | |
second_digit_led <= SEGMENT_6; | |
when 7 => | |
second_digit_led <= SEGMENT_7; | |
when 8 => | |
second_digit_led <= SEGMENT_8; | |
when 9 => | |
second_digit_led <= SEGMENT_9; | |
when others => null; | |
end case; | |
end process; | |
-- output led | |
process (sw1_latch_on, sw2_latch_on, sw3_latch_on, sw4_latch_on) | |
begin | |
case current_mode is | |
when MODE_INPUT => | |
led_left <= left_item_led; | |
led_center <= center_item_led; | |
led_right <= right_item_led; | |
when MODE_RESULT => | |
led_right <= first_digit_led; | |
led_center <= second_digit_led; | |
led_left <= SEGMENT_CLEAR; | |
when others => null; | |
end case; | |
end process; | |
end rtl; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment