library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_signed.all; --NUMERO LE: 50 --NUMERO REGISTRI: 42 --FREQUENZA MASSIMA: 347.71 MHz --DEVICE: EP2S15F484C3 entity CONTROLLORE is port ( CLK : in std_logic; RESET : in std_logic; --INTERFACCIA LETTORE CODICE A BARRE START: in std_logic; SERIAL_DATA : in std_logic; --SEMAFORO ACCESSI GREEN: out std_logic; YELLOW: out std_logic; RED: out std_logic; --CONTROLLO TORNELLO APRI_TORNELLO: out std_logic; FINE_CORSA: in std_logic; --ALLARME ALARM: out std_logic; CODE : out unsigned(7 downto 0) ); end CONTROLLORE; architecture esame of CONTROLLORE is type stato is(idle,lettura,confronta,controlla,autorizza,chiudi_tornello,allarme); signal cs,ns: stato; signal DATI: unsigned(8 downto 0); signal enable_dato,fineciclo: std_logic; signal count,next_count: unsigned(2 downto 0); --seconda parte signal trentasecondi,enable30,enable_tessera: std_logic; signal count30,next_count30: unsigned(14 downto 0); signal TESSERA_LETTA: unsigned(7 downto 0); begin -- parte sequenziale della FSM process(clk) begin if clk'event and clk='1' then if reset='1' then cs <= idle; else cs <= ns; end if; end if; end process; --shifter register campionamento NUMERO SERIALE shift_reg: for i in 0 to 7 generate ff_i: process(CLK) begin if CLK'event and CLK='1' then if RESET='1' then DATI(i+1) <= '0'; elsif enable_dato = '1' then DATI(i+1) <= DATI(i); end if; end if; end process; end generate; DATI(0) <= serial_data; --CONTATORE FINO A 8 process(clk,reset) begin if clk'event and clk='1' then if reset='1' or fineciclo='1' then count <= (others => '0'); elsif enable_dato='1' then count<= next_count; end if; end if; end process; next_count <= count + conv_unsigned(1,3); fineciclo<='1' when count=conv_unsigned(7,3) else '0'; --parte combinatoria process(cs,fineciclo,START,DATI,FINE_CORSA,trentasecondi,TESSERA_LETTA) begin GREEN<='0'; YELLOW<='0'; RED<='0'; enable_dato<='0'; APRI_TORNELLO<='0'; ALARM<='0'; CODE<=conv_unsigned(0,8); enable30<='1'; enable_tessera<='0'; case cs is when idle=> RED<='1'; if START='1' then ns<=lettura; else ns<=cs; end if; when lettura=> YELLOW<='1'; enable_dato<='1'; if fineciclo='1' then ns<=confronta; else ns<=cs; end if; when confronta=> YELLOW<='1'; if (DATI(8 downto 1)=conv_unsigned(3,8) or DATI(8 downto 1)=conv_unsigned(15,8) or DATI(8 downto 1)=conv_unsigned(63,8) or DATI(8 downto 1)=conv_unsigned(255,8)) then ns<=controlla; else ns<=idle; end if; when controlla=> YELLOW<='1'; if DATI(8 downto 1)=TESSERA_LETTA then ns<=allarme; else ns<=autorizza; end if; when autorizza=> GREEN<='1'; enable_tessera<='1'; APRI_TORNELLO<='1'; if FINE_CORSA='1' then ns<=chiudi_tornello; else ns<=cs; end if; when chiudi_tornello=> RED<='1'; APRI_TORNELLO<='0'; ns<=idle; when allarme=> enable30<='1'; ALARM<='1'; RED<='1'; CODE<=TESSERA_LETTA; if trentasecondi='1' then ns<=idle; else ns<=cs; end if; when others=> ns<=idle; end case; end process; --seconda parte --contatore 30 secondi --30*1000=30000 ==> N=15 bit process(clk,reset,trentasecondi) begin if clk'event and clk='1' then if reset='1' or trentasecondi='1' then count30 <= (others => '0'); elsif enable30='1' then count30<= next_count30; end if; end if; end process; next_count30 <= count30 + conv_unsigned(1,15); trentasecondi<='1' when count30 =conv_unsigned(3,15) else '0'; --nella realtà conv_unsigned(29999,15) --REGISTRO PER LA TESSERA GIA' LETTA process(clk,reset) begin if clk'event and clk='1' then if reset='1' then TESSERA_LETTA<=conv_unsigned(0,8); elsif enable_tessera='1' then TESSERA_LETTA<=DATI(8 downto 1); end if; end if; end process; end esame;