---------------------------------------------------------------------------------- -- Company: INSA-Toulouse -- Engineer: Paul Faure -- -- Create Date: 18.04.2021 21:19:41 -- Module Name: Etage4_Memoire - Structural -- Project Name: Processeur sécurisé -- Target Devices: Basys 3 ARTIX7 -- Tool Versions: Vivado 2016.4 -- -- Description: Etage 4 du processeur -- - Gestion de la mémoire -- - Gestion de la sauvegarde du contexte lors des appels de fonction -- -- Dependencies: -- - MemoireDonnees -- - MemoireAdressesRetour -- - LC -- - MUX ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Etage4_Memoire is Generic ( Nb_bits : Natural; -- Taille d'un mot binaire Mem_size : Natural; -- Taille de la mémoire de donnees (nombre de mots binaires stockables) Adresse_mem_size : Natural; -- Nombre de bits pour adresser la mémoire de donnees Instruction_bus_size : Natural; -- Nombre de bits du bus d'instruction (Taille d'un code instruction) Mem_EBP_size : Natural; -- Taille de la mémoire du contexte (profondeur d'appel maximale) Adresse_size_mem_EBP : Natural; -- Nombre de bits pour adresser la mémoire de contexte Bits_Controle_LC : STD_LOGIC_VECTOR; -- Vecteur de bit controlant le Link Controler (cf LC.vhd) Bits_Controle_MUX_IN : STD_LOGIC_VECTOR; -- Vecteur de bit controlant le multiplexer selectionnant A ou B comme adresse (cf MUX.vhd) Bits_Controle_MUX_IN_EBP : STD_LOGIC_VECTOR; -- Vecteur de bit controlant le multiplexer selectionnant si on doit ajouter ou non EBP à l'adresse (cf MUX.vhd) Bits_Controle_MUX_OUT : STD_LOGIC_VECTOR; -- Vecteur de bit controlant le multiplexer de sortie (cf MUX.vhd) Code_Instruction_CALL : STD_LOGIC_VECTOR; -- Numéro de l'instruction CALL Code_Instruction_RET : STD_LOGIC_VECTOR); -- Numéro de l'instruction RET Port ( CLK : in STD_LOGIC; -- Clock RST : in STD_LOGIC; -- Reset IN_A : in STD_LOGIC_VECTOR (Nb_bits - 1 downto 0); -- Entrée de l'opérande A IN_B : in STD_LOGIC_VECTOR (Nb_bits - 1 downto 0); -- Entrée de l'opérande B IN_Instruction : in STD_LOGIC_VECTOR (Instruction_bus_size - 1 downto 0); -- Entrée de l'instruction OUT_A : out STD_LOGIC_VECTOR (Nb_bits - 1 downto 0); -- Sortie de l'opérande A OUT_B : out STD_LOGIC_VECTOR (Nb_bits - 1 downto 0); -- Sortie de l'opérande B OUT_Instruction : out STD_LOGIC_VECTOR (Instruction_bus_size - 1 downto 0)); -- Sortie de l'instruction end Etage4_Memoire; architecture Structural of Etage4_Memoire is component MemoireDonnees is Generic (Nb_bits : Natural; -- Taille d'un mot en mémoire Addr_size : Natural; -- Nombre de bits nécessaires a l'adressage de la mémoire Mem_size : Natural); -- Nombre de mot stockables Port ( Addr : in STD_LOGIC_VECTOR (Addr_size-1 downto 0); -- L'adresse a laquelle il faut agir RW : in STD_LOGIC; -- Ce qu'il faut faire ('1' -> Read, '0' -> Write) D_IN : in STD_LOGIC_VECTOR (Nb_bits-1 downto 0); -- Data a ecrire (si RW = 0) CALL : in STD_LOGIC; -- '1' -> CALL en cours IN_EBP : in STD_LOGIC_VECTOR (Nb_bits-1 downto 0); -- Valeur d'EBP à stocker en cas de CALL IN_AddrRet : in STD_LOGIC_VECTOR (Nb_bits-1 downto 0); -- Valeur d'@ de retour à stocker en cas de CALL RET : in STD_LOGIC; -- '1' -> RET en cours OUT_EBP : out STD_LOGIC_VECTOR (Nb_bits-1 downto 0) := (others => '0'); -- Valeur d'EBP à renvoyer en cas de RET OUT_AddrRet : out STD_LOGIC_VECTOR (Nb_bits-1 downto 0) := (others => '0'); -- Valeur d'@ de retour à renvoyer en cas de RET RST : in STD_LOGIC; -- Reset CLK : in STD_LOGIC; -- Clock D_OUT : out STD_LOGIC_VECTOR (Nb_bits-1 downto 0) := (others => '0')); -- Sortie de la mémoire end component; component MemoireAdressesRetour is Generic (Nb_bits : Natural; Addr_size : Natural; Mem_size : Natural); Port ( R : in STD_LOGIC; W : in STD_LOGIC; D_IN : in STD_LOGIC_VECTOR (Nb_bits-1 downto 0); RST : in STD_LOGIC; CLK : in STD_LOGIC; D_OUT : out STD_LOGIC_VECTOR (Nb_bits-1 downto 0) := (others => '0'); E : out STD_LOGIC; F : out STD_LOGIC); end component; component LC is Generic (Instruction_Vector_Size : Natural; Command_size : Natural; Bits_Controle : STD_LOGIC_VECTOR); Port ( Instruction : in STD_LOGIC_VECTOR (Instruction_Vector_Size - 1 downto 0); Commande : out STD_LOGIC_VECTOR (Command_size - 1 downto 0)); end component; component MUX is Generic (Nb_bits : Natural; Instruction_Vector_Size : Natural; Bits_Controle : STD_LOGIC_VECTOR); Port ( Instruction : in STD_LOGIC_VECTOR (Instruction_Vector_Size - 1 downto 0); IN1 : in STD_LOGIC_VECTOR (Nb_bits - 1 downto 0); IN2 : in STD_LOGIC_VECTOR (Nb_bits - 1 downto 0); OUTPUT : out STD_LOGIC_VECTOR (Nb_bits - 1 downto 0)); end component; signal EBP : STD_LOGIC_VECTOR (Adresse_mem_size - 1 downto 0) := (others => '0'); -- EBP (offset à ajouter à l'adresse) signal New_EBP : STD_LOGIC_VECTOR (Adresse_mem_size - 1 downto 0) := (others => '0'); -- Nouvelle valeur d'EBP, a stocker lors d'un CALL (Cf fonctionnement MemoireAdressesRetour.vhd) signal Addr_MemoireDonnees : STD_LOGIC_VECTOR (Adresse_mem_size - 1 downto 0) := (others => '0'); -- Adresse entrante dans le composant de mémoire de donnees signal IN_Addr_MemoireDonnees : STD_LOGIC_VECTOR (Adresse_mem_size - 1 downto 0) := (others => '0'); -- Sortie du mux de choix d'adresse entre A et B signal Addr_MemoireDonnees_EBP : STD_LOGIC_VECTOR (Adresse_mem_size - 1 downto 0) := (others => '0'); -- Adresse avec EBP ajouté (IN_Addr_MemoireDonnees + BP) signal Commande_MemoireDonnees : STD_LOGIC_VECTOR (0 downto 0) := "0"; -- Sortie du Link Controler, signal de commande de la mémoire signal Sortie_MemoireDonnees : STD_LOGIC_VECTOR (Nb_bits - 1 downto 0) := (others => '0'); -- Sortie de la mémoire (a multiplexer) signal intern_OUT_B : STD_LOGIC_VECTOR (Nb_bits - 1 downto 0) := (others => '0'); -- Signal interne -- Signaux de la memoire de contexte signal R_Aux : STD_LOGIC := '0'; signal W_Aux : STD_LOGIC := '0'; signal E : STD_LOGIC; signal F : STD_LOGIC; -- Signaux inutiles signal OUT_EBP : STD_LOGIC_VECTOR (Nb_bits-1 downto 0); signal OUT_AddrRet : STD_LOGIC_VECTOR (Nb_bits-1 downto 0); begin instance_LC : LC -- Link controleur sur la mémoire de donnees generic map (Instruction_Vector_Size => Instruction_bus_size, Command_size => 1, Bits_Controle => Bits_Controle_LC) port map ( Instruction => IN_Instruction, Commande => Commande_MemoireDonnees); instance_MUX_IN : MUX -- Multiplexeur selectionnant A ou B pour adresse generic map (Nb_bits => Adresse_mem_size, Instruction_Vector_Size => Instruction_bus_size, Bits_Controle => Bits_Controle_MUX_IN) port map ( Instruction => IN_Instruction, IN1 => IN_A (Adresse_mem_size - 1 downto 0), IN2 => IN_B (Adresse_mem_size - 1 downto 0), OUTPUT => IN_Addr_MemoireDonnees); instance_MUX_IN_EBP : MUX -- Multiplexeur selectionnant l'adresse plus EBP ou l'adresse de base generic map (Nb_bits => Adresse_mem_size, Instruction_Vector_Size => Instruction_bus_size, Bits_Controle => Bits_Controle_MUX_IN_EBP) port map ( Instruction => IN_Instruction, IN1 => IN_Addr_MemoireDonnees, IN2 => Addr_MemoireDonnees_EBP, OUTPUT => Addr_MemoireDonnees); instance_MUX_OUT : MUX -- Multiplexeur selectionnant la sortie de l'étage (sur B) generic map (Nb_bits => Nb_bits, Instruction_Vector_Size => Instruction_bus_size, Bits_Controle => Bits_Controle_MUX_OUT) port map ( Instruction => IN_Instruction, IN1 => Sortie_MemoireDonnees, IN2 => IN_B, OUTPUT => intern_OUT_B); instance_MemoireDonnees : MemoireDonnees generic map (Nb_bits => Nb_bits, Addr_size => Adresse_mem_size, Mem_size => Mem_size) port map ( Addr => Addr_MemoireDonnees, RW => Commande_MemoireDonnees(0), D_IN => IN_B, CALL => '0', IN_EBP => (others => '0'), IN_AddrRet => (others => '0'), RET => '0', OUT_EBP => OUT_EBP, OUT_AddrRet => OUT_AddrRet, RST => RST, CLK => CLK, D_OUT => Sortie_MemoireDonnees); instance_MemoireEBP : MemoireAdressesRetour generic map (Nb_bits => Adresse_mem_size, Addr_size => Adresse_size_mem_EBP, Mem_size => Mem_EBP_size ) port map ( R => R_Aux, W => W_Aux, D_IN => New_EBP, RST => RST, CLK => CLK, D_OUT => EBP, E => E, F => F ); OUT_A <= (others => '0') when RST = '0' else IN_A; OUT_B <= (others => '0') when RST = '0' else intern_OUT_B; OUT_Instruction <= (others => '0') when RST = '0' else IN_Instruction; -- Controle de la mémoire de contexte (ici aussi un LC aurait été disproportionné) R_Aux <= '1' when IN_Instruction = Code_Instruction_RET else '0'; W_Aux <= '1' when IN_Instruction = Code_Instruction_CALL else '0'; Addr_MemoireDonnees_EBP <= IN_Addr_MemoireDonnees + EBP; New_EBP <= EBP + IN_B (Adresse_mem_size - 1 downto 0); end Structural;