Problem Set 4
-- problemset4_1.vhd
-- Problem 1 (/option)
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all;
entity problem1 is
port (keypad : in std_logic_vector (9 downto 0); -- the keypad inputs
openin : in std_logic; -- high when the door is open
warning : out std_logic; -- high for 'buzzer'
alarm : out std_logic; -- high when 'alarm'
clk : in std_logic); -- 1 Hz clock
end entity problem1;
architecture fsm of problem1 is
type state is (idle, first, second, third, OK, OKopen, troubleidle, troublefirst,
troublesecond, troublethird, alarmidle, alarmfirst, alarmsecond, alarmthird);
signal n_s, p_s : state;
signal count : std_logic;
signal counter : std_logic_vector (4 downto 0);
--put my signals here;
begin
fsm : process (p_s, keypad, openin, counter)
begin
case p_s is
when idle => -- Waiting for something to happen
alarm <= '0';
warning <= '0';
if keypad = "0010000000" -- User enters 7
then n_s <= first;
count <= '0';
elsif openin = '1' -- User opened door
then n_s <= troubleidle;
count <= '1';
else n_s <= idle;
count <= '0';
end if;
when first => -- First number has been entered
alarm <= '0';
warning <= '0';
if openin = '1' -- User opened door
then n_s <= troublefirst;
count <= '1';
elsif keypad = "0000000000" -- no input
then n_s <= first;
count <= '0';
elsif keypad = "0010000000" -- User enters second 7
then n_s <= second;
count <= '0';
else n_s <= idle; -- Some other input
count <= '0';
end if;
when second => -- Second number has been entered
alarm <= '0';
warning <= '0';
if openin = '1' -- User opened door
then n_s <= troublesecond;
count <= '1';
elsif keypad = "0000000000" -- no input
then n_s <= second;
count <= '0';
elsif keypad = "1000000000" -- User enters third code number
then n_s <= third;
count <= '0';
elsif keypad <= "0010000000" -- This is the SECOND 7 in a row
then n_s <= second;
count <= '0';
else n_s <= idle; -- Some other input
count <= '0';
end if;
when third => -- Third number has been entered
alarm <= '0';
warning <= '0';
if openin = '1' -- User opened door
then n_s <= troublethird;
count <= '1';
elsif keypad = "0000000000" -- no input
then n_s <= third;
count <= '0';
elsif keypad = "0000000010" -- User enters third code number
then n_s <= OK;
count <= '0';
else n_s <= idle; -- Some other input
count <= '0';
end if;
when OK => -- Code has been input
alarm <= '0';
warning <= '0';
if openin = '1' -- User opened door
then n_s <= OKopen;
count <= '0';
else n_s <= OK; -- Wait for user to open door
count <= '0';
end if;
when OKopen => -- When code entered and then door open
alarm <= '0';
warning <= '0';
if openin = '0' -- Door closes
then n_s <= idle;
count <= '0';
else n_s <= OKopen; -- Wait for door to close
count <= '0';
end if;
when troubleidle => -- No code entered but door was opened
alarm <= '0';
warning <= '1';
if counter = "11110"
then n_s <= alarmidle;
count <= '0';
elsif keypad = "0010000000" -- User enters first code number
then n_s <= troublefirst;
count <= '1';
else n_s <= troubleidle; -- Any other or no input
count <= '1';
end if;
when troublefirst => -- First code entered, but door was opened
alarm <= '0';
warning <= '1';
if counter = "11110" -- If timer up to 30 s set off alarm
then n_s <= alarmfirst;
count <= '0';
elsif keypad = "0000000000" -- No input
then n_s <= troublefirst;
count <= '1';
elsif keypad = "0010000000" -- User enters second code number
then n_s <= troublesecond;
count <= '1';
else n_s <= troubleidle; -- Any other input
count <= '1';
end if;
when troublesecond => -- Second code entered, but door was opened
alarm <= '0';
warning <= '1';
if counter = "11110" -- If timer up to 30 s set off alarm
then n_s <= alarmsecond;
count <= '0';
elsif keypad = "0000000000" -- No input
then n_s <= troublesecond;
count <= '1';
elsif keypad = "0010000000" -- User enters SECOND 7 in a row
then n_s <= troublesecond;
count <= '1';
elsif keypad = "1000000000" -- User enters third code number
then n_s <= troublethird;
count <= '1';
else n_s <= troubleidle; -- Any other input
count <= '1';
end if;
when troublethird => -- Third code entered, but door was opened
alarm <= '0';
warning <= '1';
if counter = "11110" -- If timer up to 30 s set off alarm
then n_s <= alarmthird;
count <= '0';
elsif keypad = "0000000000" -- No input
then n_s <= troublethird;
count <= '1';
elsif keypad = "0000000010" -- User enters final code number
then if openin = '1'
then n_s <= OKopen;
count <= '0';
else n_s <= idle;
count <= '0';
end if;
else n_s <= troubleidle; -- Any other input
count <= '1';
end if;
when alarmidle => -- Alarm going off and no code entered
alarm <= '1';
warning <= '0';
if keypad = "0010000000" -- User inputs first code number
then n_s <= alarmfirst;
count <= '0';
else n_s <= alarmidle; -- Any other input or no input
count <= '0';
end if;
when alarmfirst => -- First code entered but alarm going off
alarm <= '1';
warning <= '0';
if keypad = "0010000000" -- User inputs second code number
then n_s <= alarmsecond;
count <= '0';
elsif keypad = "0000000000" -- No input
then n_s <= alarmfirst;
count <= '0';
else n_s <= alarmidle; -- Any other input
count <= '0';
end if;
when alarmsecond => -- Second code entered but alarm going off
alarm <= '1';
warning <= '0';
if keypad = "1000000000" -- User inputs third code number
then n_s <= alarmthird;
count <= '0';
elsif keypad = "0000000000" -- No input
then n_s <= alarmsecond;
count <= '0';
elsif keypad = "0010000000" -- User inputs second code number
then n_s <= alarmsecond;
count <= '0';
else n_s <= alarmidle; -- Any other input
count <= '0';
end if;
when alarmthird => -- Third code entered but alarm going off
alarm <= '1';
warning <= '0';
if keypad = "0000000010" -- User inputs final code number
then if openin = '1'
then n_s <= OKopen;
count <= '0';
else n_s <= idle;
count <= '0';
end if;
elsif keypad = "0000000000" -- No input
then n_s <= alarmthird;
count <= '0';
else n_s <= alarmidle; -- Any other input
count <= '0';
end if;
end case;
end process;
clocked : process (clk, count)
begin
if rising_edge(clk)
then p_s <= n_s;
if count = '1'
then counter <= counter + 1;
else counter <= "00000";
end if;
end if;
end process;
end fsm;
-------------------------------------------------------
-- problemset4_2.vhd
-- Problem Set 4 Problem 2
library ieee;
use ieee.std_logic_1164.all;
use work.std_arith.all;
entity divider is port (a, b: in std_logic_vector(6 downto 0);
start, clk: in std_logic;
q, r : out std_logic_vector (6 downto 0);
busy: out std_logic);
end divider;
architecture fsm of divider is
type states is (idle, calc);
signal state, n_state : states;
signal remain, quo, div : std_logic_vector (6 downto 0);
signal i : std_logic_vector (2 downto 0);
begin
process (clk)
variable rmndr : std_logic_vector (6 downto 0);
begin
if rising_edge(clk) then
case state is
when idle =>
i <= "000";
if start = '1' then
n_state <= calc;
busy <= '1';
div <= a(5 downto 0) & '0';
remain <= "000000" & a(6);
quo <= "0000000";
else
n_state <= idle;
busy <= '0';
r <= remain;
q <= quo;
end if;
when calc =>
if remain >= b then
quo <= quo(5 downto 0) & '1';
rmndr := remain - b;
else
quo <= quo(5 downto 0) & '0';
rmndr := remain;
end if;
div <= div(5 downto 0) & '0';
if i = "110" then
n_state <= idle;
remain <= rmndr;
else
i <= i + 1;
remain <= rmndr(5 downto 0) & div(6);
busy <= '1';
n_state <= calc;
end if;
end case;
end if;
end process;
process(clk)
begin
if falling_edge(clk) then
state <= n_state;
end if;
end process;
end fsm;