library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity CONTROLLORE is port ( CLK : in std_logic; RESET : in std_logic; PROG : in std_logic; SERIALLINE : in std_logic; CONFIG : in unsigned(1 downto 0); NUM : in unsigned(9 downto 0); READY0 : out std_logic; READY1 : out std_logic; READY2 : out std_logic; READY3 : out std_logic; WORD : out unsigned(31 downto 0); ADDRESS : out unsigned(9 downto 0)); end CONTROLLORE ; architecture A of CONTROLLORE is type state is (idle, programma, attesa, start, B0, B1, B2, B3, B4, B5, B6, B7, campiona, stop, confronta); signal present_state, next_state : state; signal fineciclo, campionaTbit : std_logic; signal en_Tbit : std_logic; signal current_cycle, next_cycle: unsigned(13 downto 0); signal num_reg : unsigned(9 downto 0); signal config_reg: unsigned(1 downto 0); signal num_byte, num_byteseguente : unsigned (1 downto 0); signal fineword : std_logic; signal fine_num : std_logic; signal lungTbit : unsigned(13 downto 0); signal numerocicli : unsigned(13 downto 0); signal mezzalungTbit: unsigned(12 downto 0); signal enR0, enR1, enR2, enR3: std_logic; signal enW0, enW1, enW2, enW3: std_logic; signal contanum, contanum_seguente : unsigned(9 downto 0); signal q: unsigned(8 downto 0); signal enpar : std_logic; signal word0, word1, word2,word3 : unsigned(7 downto 0); signal load, enaddr : std_logic; signal address_int, next_address_int, address_init : unsigned(9 downto 0); begin -- parte sequenziale della FSM process(clk) begin if clk'event and clk = '1' then if reset = '1' then present_state <= idle; else present_state <= next_state; end if; end if; end process; -- processo combinatorio, calcolo uscite e stato successivo process(present_state, PROG, SERIALLINE, fineciclo, fine_num) begin en_Tbit <= '0'; enpar <= '0'; load <= '0'; --- case present_state is when idle => if PROG = '1' then next_state <= programma; else next_state <= idle; end if; when programma => load <= '1'; next_state <= attesa; when attesa => if SERIALLINE = '0' then next_state <= start; else next_state <= attesa; end if; when start => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B0; else next_state <= start; end if; when B0 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B1; else next_state <= B0; end if; when B1 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B2; else next_state <= B1; end if; when B2 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B3; else next_state <= B2; end if; when B3 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B4; else next_state <= B3; end if; when B4 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B5; else next_state <= B4; end if; when B5 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B6; else next_state <= B5; end if; when B6 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= B7; else next_state <= B6; end if; when B7 => en_Tbit <= '1'; if fineciclo = '1' then next_state <= campiona; else next_state <= B7; end if; when campiona => en_Tbit <= '0'; enpar <= '1'; next_state <= stop; when stop => en_Tbit <= '1'; if fineciclo = '1' then next_state <= confronta; else next_state <= stop; end if; when confronta => if fine_num = '0' then next_state <= attesa; else next_state <= idle; end if; when others => next_state <= idle; end case; end process; -- contatore a 14 bit per Tbit process(clk) begin if clk'event and clk = '1' then if reset = '1' or fineciclo = '1' then current_cycle <= conv_unsigned(0,14); elsif en_tbit = '1' then current_cycle <= next_cycle; end if; end if; end process; -- valore successivo di conteggio next_cycle <= current_cycle + conv_unsigned(1,14); -- ultimo ciclo di lettura numerocicli <= conv_unsigned(lungTbit,14) - conv_unsigned(1,14); fineciclo <= '1' when current_cycle = conv_unsigned(numerocicli,14) else '0'; -- ciclo per campionare mezzalungTbit(12 downto 0) <= lungTbit(13 downto 1); campionaTbit <= '1' when current_cycle = conv_unsigned(mezzalungTbit,15) else '0'; -- registri in cui memorizzo i dati di programmazione; vengono ---- abilitato da PROG process(clk) begin if clk'event and clk = '1' then if reset = '1' then num_reg <= conv_unsigned(1000,10); elsif PROG = '1' then num_reg <= num; end if; end if; end process; process(clk) begin if clk'event and clk = '1' then if reset = '1' then config_reg <= conv_unsigned(0,2); elsif PROG = '1' then config_reg <= config; end if; end if; end process; ---- multiplexer per definire la lunghezza di Tbit process(config_reg) begin case config_reg is when "00" => --- lungTbit <= conv_unsigned(10,14); lungTbit <= conv_unsigned(2,14); when "01" => --- lungTbit <= conv_unsigned(100,14); lungTbit <= conv_unsigned(2,14); when "10" => --- lungTbit <= conv_unsigned(1000,14); lungTbit <= conv_unsigned(4,14); when "11" => ---- lungTbit <= conv_unsigned(10000,14); lungTbit <= conv_unsigned(4,14); when others => lungTbit <= conv_unsigned(0,14); end case; end process; -- contatore a 2 bit per contare i 4 byte per la creazione della parola process(clk) begin if clk'event and clk = '1' then if reset = '1' then num_byte <= conv_unsigned(3,2); elsif enpar = '1' then num_byte <= num_byteseguente; end if; end if; end process; -- valore successivo di conteggio num_byteseguente <= num_byte - conv_unsigned(1,2); -- ultimo ciclo di lettura -- fineword <= '1' when num_byte = conv_unsigned(0,2) else '0'; ---- multiplexer per definire i segnali di enable per Ready process(config_reg) begin case config_reg is when "00" => enR0 <= '1'; enR1 <= '0'; enR2 <= '0'; enR3 <= '0'; when "01" => enR0 <= '0'; enR1 <= '1'; enR2 <= '0'; enR3 <= '0'; when "10" => enR0 <= '0'; enR1 <= '0'; enR2 <= '1'; enR3 <= '0'; when "11" => enR0 <= '0'; enR1 <= '0'; enR2 <= '0'; enR3 <= '1'; when others => enR0 <= '0'; enR1 <= '0'; enR2 <= '0'; enR3 <= '0'; end case; end process; ---- contatore numero di byte e confronto con NUM process(clk) begin if clk'event and clk = '1' then if reset = '1' or fine_num = '1' then contanum <= conv_unsigned(0,10); elsif enpar = '1' then contanum <= contanum_seguente; end if; end if; end process; -- valore successivo di conteggio contanum_seguente <= contanum + conv_unsigned(1,10); -- ultimo ciclo di lettura fine_num <= '1' when contanum = conv_unsigned(num_reg,10) else '0'; --- 4 ff per generare i segnali Ready process(clk) begin if clk'event and clk = '1' then if reset = '1' then Ready0 <= '0'; elsif enR0 = '1' and fine_num ='1' then Ready0 <= '1' ; end if; end if; end process; process(clk) begin if clk'event and clk = '1' then if reset = '1' then Ready1 <= '0'; elsif enR1 = '1' and fine_num ='1' then Ready1 <= '1' ; end if; end if; end process; process(clk) begin if clk'event and clk = '1' then if reset = '1' then Ready2 <= '0'; elsif enR2 = '1' and fine_num ='1' then Ready2 <= '1' ; end if; end if; end process; process(clk) begin if clk'event and clk = '1' then if reset = '1' then Ready3 <= '0'; elsif enR3 = '1' and fine_num ='1' then Ready3 <= '1' ; end if; end if; end process; ---- registro a scorrimento shift_reg0: for I in 0 to 7 generate ff_I : process(CLK) begin if CLK'event and CLK='1' then if RESET='1' then q(I+1) <= '0'; elsif campionaTbit='1' then q(I+1) <= q(I); end if; end if; end process; end generate; q(0) <= serialline; --- 4 registri a 8 bit per campionare lo shift register process(CLK) begin if CLK'event and CLK='1' then if RESET='1' then word0 <= conv_unsigned(0,8); elsif enw0 ='1' and enpar = '1' then word0 <= conv_unsigned(q(8 downto 1), 8); end if; end if; end process; WORD(7 downto 0) <= word0; process(CLK) begin if CLK'event and CLK='1' then if RESET='1' then word1 <= conv_unsigned(0,8); elsif enw1 ='1' and enpar = '1' then word1 <= conv_unsigned(q(8 downto 1), 8); end if; end if; end process; WORD(15 downto 8) <= word1; process(CLK) begin if CLK'event and CLK='1' then if RESET='1' then word2 <= conv_unsigned(0,8); elsif enw2 ='1' and enpar = '1'then word2 <= conv_unsigned(q(8 downto 1), 8); end if; end if; end process; WORD(23 downto 16) <= word2; process(CLK) begin if CLK'event and CLK='1' then if RESET='1' then word3 <= conv_unsigned(0,8); elsif enw3 ='1' and enpar = '1' then word3 <= conv_unsigned(q(8 downto 1), 8); end if; end if; end process; WORD(31 downto 24) <= word3; ---- multiplexer gestire word in funzione del byte che si sta leggendo process(num_byte) begin case num_byte is when "00" => enW0 <= '0'; enW1 <= '1'; enW2 <= '0'; enW3 <= '1'; when "01" => enW0 <= '0'; enW1 <= '0'; enW2 <= '1'; enW3 <= '0'; when "10" => enW0 <= '0'; enW1 <= '1'; enW2 <= '0'; enW3 <= '0'; when "11" => enW0 <= '1'; enW1 <= '0'; enW2 <= '0'; enW3 <= '0'; when others => enW0 <= '0'; enW1 <= '0'; enW2 <= '0'; enW3 <= '0'; end case; end process; enaddr <= enW3 and enpar; ---- contatore con load ed enable per la gestione degli indirizzi process(clk) begin if clk'event and clk = '1' then if reset = '1' then address_int <= conv_unsigned(0,10); elsif load = '1' then address_int <= address_init; elsif enaddr = '1' then address_int <= next_address_int; end if; end if; end process; -- valore successivo di conteggio next_address_int <= address_int + conv_unsigned(1,10); address <= address_int; --- mux per definire la base per la generazione degli indirizzi process(config_reg) begin case config_reg is when "00" => address_init <= conv_unsigned(1023,10); --- valore iniziale -1 when "01" => address_init <= conv_unsigned(255,10); when "10" => address_init <= conv_unsigned(511,10); when "11" => address_init <= conv_unsigned(727,10); when others => address_init <= conv_unsigned(0,10); end case; end process; end A;