library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity aula8 is generic ( stackMSB : integer := 3; -- tamanho maximo em bits de cada byte da pilha stackMax : integer := 7; -- tamanho maximo em bytes da pilha matrixMax : integer := 7; -- numero maximo de pilhas c_lambda : integer := 0; -- alfabeto de pilha c_e : integer := 1; c_g : integer := 2; c_h : integer := 3; c_n : integer := 4; c_t : integer := 5; c_u : integer := 6; c_v : integer := 7; c_w : integer := 8; c_gg : integer := 9; c_et : integer := 10; c_tg : integer := 11; linguaMSB : integer := 4; -- tamanho maximo em bits de cada caracter da linguagem a_EOS : integer := 0; a_forall : integer := 11; a_exists : integer := 12; a_x : integer := 13; a_c : integer := 14; a_f : integer := 15; a_R : integer := 16; a_underline : integer := 17; a_comma : integer := 18; a_equals : integer := 19; a_ne : integer := 20; a_wedge : integer := 21; a_vee : integer := 22; a_implies : integer := 23; a_iff : integer := 24; a_chave : integer := 25; f_chave : integer := 26; a_parentese : integer := 27; f_parentese : integer := 28; a_not : integer := 29; s_lambda : integer := 0; s_omega23 : integer := 23; s_omega35 : integer := 35; s_error : integer := 36; s_reset : integer := 37 ); port ( RESET : in std_logic; -- reset input CLOCK : in std_logic; -- clock input LER : in std_logic; S : in std_logic_vector(linguaMSB downto 0); -- control input SAIDA : out std_logic; -- data output VAZIO : out std_logic; T0 : out std_logic_vector(5 downto 0); T1 : out std_logic_vector(5 downto 0); T2 : out std_logic_vector(5 downto 0); SS0 : out std_logic_vector(2 downto 0); SS1 : out std_logic_vector(2 downto 0); SS2 : out std_logic_vector(2 downto 0) ); end aula8; architecture arch of aula8 is type my_state is array(5 downto 0) of std_logic; type my_cell is array (stackMSB downto 0) of std_logic; type my_stack is array (stackMax downto 0) of my_cell; type my_stackSize is array(stackMSB downto 0) of std_logic; type my_stacks is array (matrixMax downto 0) of my_stack; type my_states is array (matrixMax downto 0) of my_state; type my_stackSizes is array(matrixMax downto 0) of my_stackSize; type my_toposPilha is array(matrixMax downto 0) of my_cell; type my_busy is array(matrixMax downto 0) of boolean; shared variable old_pilha: my_stacks; shared variable old_estado: my_states := (others=>(others=>'0')); shared variable old_stackSize: my_stackSizes := (others=>(others=>'0')); shared variable old_busy: my_busy; shared variable pilha: my_stacks; shared variable estado: my_states := (others=>(others=>'0')); shared variable stackSize: my_stackSizes := (others=>(others=>'0')); shared variable busy: my_busy; shared variable OFLOW: std_logic_vector(matrixMax downto 0) := (others=>'0'); shared variable cmdLer: std_logic := '0'; shared variable boo: boolean; shared variable empty: std_logic := '0'; function cell(x: integer) return my_cell is begin return my_cell(to_unsigned(x, stackMSB + 1)); end; impure function topoPilha(i: integer) return my_cell is begin if unsigned(stackSize(i)) = 0 then return cell(0); else return pilha(i)(to_integer(unsigned(stackSize(i))) - 1); end if; end; impure function topoPilha2(i: integer) return my_cell is begin if unsigned(stackSize(i)) < 2 then return cell(0); else return pilha(i)(to_integer(unsigned(stackSize(i))) - 2); end if; end; function alpha(x: integer) return std_logic_vector is begin return std_logic_vector(to_unsigned(x, linguaMSB + 1)); end; function beta(x: integer) return my_state is begin return my_state(to_unsigned(x, 5 + 1)); end; procedure push(posicao: integer; pushar: my_cell) is begin if unsigned(stackSize(posicao)) = stackMax then oflow(posicao) := '1'; else pilha(posicao)(to_integer(unsigned(stackSize(posicao)))) := pushar; end if; if unsigned(stackSize(posicao)) < stackMax + 1 then stackSize(posicao) := my_stackSize(to_unsigned(to_integer(unsigned(stackSize(posicao))) + 1, stackMSB + 1)); end if; end; procedure createReality(processing: integer; prox: my_state; pushar: my_cell; popear: integer) is variable posicao: integer; begin posicao := 0; while (posicao <= matrixMax) and busy(posicao) loop posicao := posicao + 1; end loop; stackSize(posicao) := stackSize(processing); pilha(posicao) := pilha(processing); busy(posicao) := true; for i in 1 to popear loop pilha(posicao)(to_integer(unsigned(stackSize(posicao))) - 1) := (others=>'0'); stackSize(posicao) := my_stackSize(to_unsigned(to_integer(unsigned(stackSize(posicao))) - 1, stackMSB + 1)); end loop; if pushar = cell(c_tg) then push(posicao, cell(c_t)); push(posicao, cell(c_g)); elsif pushar /= cell(0) then push(posicao, pushar); end if; if oflow(posicao) = '0' then estado(posicao) := prox; else estado(posicao) := beta(s_error); end if; end; begin process(RESET) is begin if RESET = '1' then estado(0) := beta(s_reset); busy(0) := true; end if; end process; process is begin wait until rising_edge(clock); if (ler = '1') and (cmdLer = '0') and (reset = '0') then cmdLer := '1'; old_pilha := pilha; old_estado := estado; old_stackSize := stackSize; old_busy := busy; for i in 0 to matrixMax loop if old_busy(i) then boo := false; if old_estado(i) = beta(s_reset) then estado(0) := beta(s_lambda); pilha(0)(0) := (others=>'0'); stackSize(0) := (others=>'0'); busy(0) := true; for j in 1 to matrixMax loop busy(j) := false; end loop; end if; if (old_estado(i) = beta(s_lambda)) or (old_estado(i) = beta(s_reset)) then if S = alpha(a_forall) then createReality(i, beta(1), cell(0), 0); elsif S = alpha(a_exists) then createReality(i, beta(1), cell(0), 0); elsif S = alpha(a_not) then -- duplo createReality(i, beta(6), cell(0), 0); createReality(i, beta(25), cell(0), 0); elsif S = alpha(a_r) then createReality(i, beta(7), cell(0), 0); elsif S = alpha(a_parentese) then -- triplo push u, n, v|w. createReality(i, beta(24), cell(c_u), 0); createReality(i, beta(24), cell(c_n), 0); if topoPilha(i) = cell(c_v) then createReality(i, beta(24), cell(c_w), 1); end if; elsif S = alpha(a_f) then createReality(i, beta(26), cell(0), 0); elsif S = alpha(a_x) then createReality(i, beta(31), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(1) then if S = alpha(a_x) then createReality(i, beta(2), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(2) then if S = alpha(a_underline) then createReality(i, beta(3), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(3) then if S = alpha(a_chave) then createReality(i, beta(4), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(4) then if (0 < unsigned(S)) and (unsigned(S) < 11) then createReality(i, beta(5), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(5) then if (0 < unsigned(S)) and (unsigned(S) < 11) then createReality(i, beta(5), cell(0), 0); elsif S = alpha(f_chave) then createReality(i, beta(s_lambda), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(6) then if S = alpha(a_r) then createReality(i, beta(7), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(7) then if S = alpha(a_underline) then createReality(i, beta(8), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(8) then if S = alpha(a_chave) then createReality(i, beta(9), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(9) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(10), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(10) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(10), cell(0), 0); elsif S = alpha(f_chave) then createReality(i, beta(11), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(11) then if S = alpha(a_parentese) then createReality(i, beta(12), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(12) then if S = alpha(a_c) then createReality(i, beta(18), cell(0), 0); elsif S = alpha(a_x) then createReality(i, beta(18), cell(0), 0); elsif S = alpha(a_f) then createReality(i, beta(13), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(13) then if S = alpha(a_underline) then createReality(i, beta(14), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(14) then if S = alpha(a_chave) then createReality(i, beta(15), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(15) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(16), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(16) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(16), cell(0), 0); elsif S = alpha(f_chave) then -- push h createReality(i, beta(17), cell(c_h), 0); else boo := true; end if; elsif old_estado(i) = beta(17) then if S = alpha(a_parentese) then createReality(i, beta(12), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(18) then if S = alpha(a_underline) then createReality(i, beta(19), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(19) then if S = alpha(a_chave) then createReality(i, beta(20), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(20) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(21), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(21) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(21), cell(0), 0); elsif S = alpha(f_chave) then createReality(i, beta(22), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(22) then if S = alpha(a_comma) then createReality(i, beta(12), cell(0), 0); elsif S = alpha(f_parentese) then -- triplo: nada, pop h, pop v. createReality(i, beta(22), cell(0), 0); if topoPilha(i) = cell(c_h) then createReality(i, beta(22), cell(0), 1); elsif topoPilha(i) = cell(c_v) then createReality(i, beta(22), cell(0), 1); end if; else boo := true; end if; elsif old_estado(i) = beta(s_omega23) then if (S = alpha(a_wedge)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v elsif (S = alpha(a_vee)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v elsif (S = alpha(a_implies)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v elsif (S = alpha(a_iff)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v else boo := true; end if; elsif old_estado(i) = beta(24) then if S = alpha(a_f) then createReality(i, beta(26), cell(0), 0); elsif S = alpha(a_x) then createReality(i, beta(31), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(25) then if S = alpha(a_parentese) then -- triplo: push n, push u, w|v createReality(i, beta(24), cell(c_n), 0); createReality(i, beta(24), cell(c_u), 0); if topoPilha(i) = cell(c_v) then createReality(i, beta(24), cell(c_w), 1); end if; else boo := true; end if; elsif old_estado(i) = beta(26) then if S = alpha(a_underline) then createReality(i, beta(27), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(27) then if S = alpha(a_chave) then createReality(i, beta(28), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(28) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(29), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(29) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(29), cell(0), 0); elsif S = alpha(f_chave) then createReality(i, beta(30), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(30) then if S = alpha(a_parentese) then -- quadruplo: gg|g, g|et, push tg, g|e createReality(i, beta(24), cell(c_tg), 0); if topoPilha(i) = cell(c_e) then createReality(i, beta(24), cell(c_g), 1); if topoPilha2(i) = cell(c_t) then createReality(i, beta(24), cell(c_g), 1); end if; elsif topoPilha(i) = cell(c_g) then createReality(i, beta(24), cell(c_g), 0); end if; else boo := true; end if; elsif old_estado(i) = beta(31) then if S = alpha(a_underline) then createReality(i, beta(32), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(32) then if S = alpha(a_chave) then createReality(i, beta(33), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(33) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(34), cell(0), 0); else boo := true; end if; elsif old_estado(i) = beta(34) then if (1 <= unsigned(S)) and (unsigned(S) <= 10) then createReality(i, beta(34), cell(0), 0); elsif S = alpha(f_chave) then -- quadruplo: pop et, push t, g|g, pop e. createReality(i, beta(s_omega35), cell(c_t), 0); if topoPilha(i) = cell(c_g) then createReality(i, beta(s_omega35), cell(0), 0); elsif topoPilha(i) = cell(c_e) then createReality(i, beta(s_omega35), cell(0), 1); if topoPilha2(i) = cell(c_t) then createReality(i, beta(s_omega35), cell(0), 2); end if; end if; else boo := true; end if; elsif old_estado(i) = beta(s_omega35) then if S = alpha(a_comma) then createReality(i, beta(24), cell(0), 0); elsif S = alpha(a_equals) then createReality(i, beta(24), cell(c_e), 0); -- push e elsif S = alpha(a_ne) then createReality(i, beta(24), cell(c_e), 0); -- push e elsif S = alpha(f_parentese) then -- quadruplo: v|w, pop w, v|u, pop n. if topoPilha(i) = cell(c_w) then createReality(i, beta(s_omega23), cell(c_v), 1); createReality(i, beta(s_omega23), cell(0), 1); elsif topoPilha(i) = cell(c_u) then createReality(i, beta(s_omega23), cell(c_v), 1); elsif topoPilha(i) = cell(c_n) then createReality(i, beta(s_omega23), cell(0), 1); end if; createReality(i, beta(s_omega23), cell(0), 0); elsif (S = alpha(a_wedge)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v elsif (S = alpha(a_vee)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v elsif (S = alpha(a_implies)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v elsif (S = alpha(a_iff)) and (topoPilha(i) = cell(c_v)) then createReality(i, beta(s_lambda), cell(0), 0); -- v|v else boo := true; end if; else boo := true; end if; -- estados busy(i) := false; end if; -- if old_busy(i) end loop; -- for i elsif cmdLer = '1' then cmdLer := '0'; end if; boo := false; for i in 0 to matrixMax loop if busy(i) then boo := boo or (((estado(i) = beta(s_omega23)) or (estado(i) = beta(s_omega35))) and (unsigned(stackSize(i)) = 0)); end if; end loop; saida <= '0'; for j in 0 to matrixMax loop if busy(j) and (((estado(j) = beta(S_omega23)) or (estado(j) = beta(S_omega35))) and (unsigned(stackSize(j)) = 0)) then saida <= '1'; end if; end loop; empty := '1'; for j in 0 to matrixMax loop if busy(j) and (estado(j) /= beta(s_error)) then empty := '0'; -- nao esta errado se alguem estiver vivo. end if; end loop; vazio <= empty; for j in 0 to 5 loop T0(j) <= estado(0)(j); end loop; for j in 0 to 5 loop T1(j) <= estado(1)(j); end loop; for j in 0 to 5 loop T2(j) <= estado(2)(j); end loop; ss0(0) <= stackSize(0)(0); ss0(1) <= stackSize(0)(1); ss0(2) <= stackSize(0)(2); ss1(0) <= stackSize(1)(0); ss1(1) <= stackSize(1)(1); ss1(2) <= stackSize(1)(2); ss2(0) <= stackSize(2)(0); ss2(1) <= stackSize(2)(1); ss2(2) <= stackSize(2)(2); end process; end arch;