library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity CPU is Port ( clk : in STD_LOGIC; rst : in STD_LOGIC ); end CPU; architecture Behavioral of CPU is constant NOP : std_logic_vector(7 downto 0) := "00000000"; constant ADD : std_logic_vector(7 downto 0) := "00000001"; constant MUL : std_logic_vector(7 downto 0) := "00000010"; constant SOU : std_logic_vector(7 downto 0) := "00000011"; constant DIV : std_logic_vector(7 downto 0) := "00000100"; constant COP : std_logic_vector(7 downto 0) := "00000101"; constant AFC : std_logic_vector(7 downto 0) := "00000110"; constant LOAD : std_logic_vector(7 downto 0) := "00000111"; constant STORE: std_logic_vector(7 downto 0) := "00001000"; -- constant HALT : std_logic_vector(7 downto 0) := "00001001"; constant MX1: std_logic_vector(8 downto 0) := "100111110"; constant MX2: std_logic_vector(8 downto 0) := "000011110"; constant needBubbles: std_logic_vector(8 downto 0) := "111111110"; COMPONENT ALU PORT( A : IN std_logic_vector(7 downto 0); B : IN std_logic_vector(7 downto 0); S : OUT std_logic_vector(7 downto 0); O : OUT std_logic; Z : OUT std_logic; C : OUT std_logic; Ctrl : IN std_logic_vector(1 downto 0) ); END COMPONENT; COMPONENT registers PORT( addr_A : IN std_logic_vector(0 to 3); addr_B : IN std_logic_vector(0 to 3); addr_W : IN std_logic_vector(0 to 3); W : IN std_logic; DATA : IN std_logic_vector(0 to 7); RST : IN std_logic; CLK : IN std_logic; QA : OUT std_logic_vector(0 to 7); QB : OUT std_logic_vector(0 to 7) ); END COMPONENT; COMPONENT instruction_memory PORT( addr : IN std_logic_vector(7 downto 0); q : OUT std_logic_vector(31 downto 0); clk : IN std_logic ); END COMPONENT; COMPONENT data_memory PORT( addr : IN std_logic_vector(7 downto 0); data : IN std_logic_vector(7 downto 0); rw : IN std_logic; rst : IN std_logic; clk : IN std_logic; q : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal halted : std_logic := '0'; -- Interfaces composants signal ALU_A : std_logic_vector(7 downto 0); signal ALU_B : std_logic_vector(7 downto 0); signal ALU_S : std_logic_vector(7 downto 0); signal ALU_O : std_logic; signal ALU_Z : std_logic; signal ALU_C : std_logic; signal ALU_Ctrl : std_logic_vector(1 downto 0); signal registers_addr_A : std_logic_vector(3 downto 0) := (others => '0'); signal registers_addr_B : std_logic_vector(3 downto 0) := (others => '0'); signal registers_addr_W : std_logic_vector(3 downto 0) := (others => '0'); signal registers_W : std_logic := '0'; signal registers_DATA : std_logic_vector(7 downto 0) := (others => '0'); signal registers_QA : std_logic_vector(7 downto 0); signal registers_QB : std_logic_vector(7 downto 0); signal data_memory_addr : std_logic_vector(7 downto 0) := (others => '0'); signal data_memory_data : std_logic_vector(7 downto 0) := (others => '0'); signal data_memory_rw : std_logic := '1'; signal data_memory_q : std_logic_vector(7 downto 0); signal instr_memory_addr : std_logic_vector(7 downto 0) := (others => '0'); signal instr_memory_q : std_logic_vector(31 downto 0); -- Etage 1 signal IP : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal OP1 : STD_LOGIC_VECTOR(7 downto 0) := NOP; signal A1 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal B1 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal C1 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); -- Etage 2 signal OP2 : STD_LOGIC_VECTOR(7 downto 0) := NOP; signal A2 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal B2 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal C2 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); -- Etage 3 signal OP3 : STD_LOGIC_VECTOR(7 downto 0) := NOP; signal A3 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal B3 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); -- Etage 4 signal OP4 : STD_LOGIC_VECTOR(7 downto 0) := NOP; signal A4 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal B4 : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal bubble : integer := 3; begin myalu: ALU PORT MAP ( A => alu_a, B => alu_b, S => alu_s, O => alu_o, Z => alu_z, C => alu_c, Ctrl => alu_ctrl ); reg: registers PORT MAP ( addr_A => registers_addr_A, addr_B => registers_addr_B, addr_W => registers_addr_W, W => registers_W, DATA => registers_data, RST => rst, CLK => clk, QA => registers_qa, QB => registers_qb ); data_mem: data_memory PORT MAP ( addr => data_memory_addr, data => data_memory_data, rw => data_memory_rw, rst => rst, clk => clk, q => data_memory_q ); instr_mem: instruction_memory PORT MAP ( addr => instr_memory_addr, q => instr_memory_q, clk => clk ); instr_memory_addr <= IP; registers_addr_W <= A4(3 downto 0); registers_W <= '0' when (OP4 = NOP or OP4 = STORE) else '1'; registers_data <= B4; registers_addr_A <= B1(3 downto 0); registers_addr_B <= C1(3 downto 0); ALU_A <= B2; ALU_B <= C2; ALU_Ctrl <= OP2(1 downto 0); data_memory_RW <= '0' when (OP3 = STORE) else '1'; data_memory_addr <= A3 when (OP3 = STORE) else B3; data_memory_data <= B3; C1 <= instr_memory_q(7 downto 0) when (bubble = 0) else "00000000"; B1 <= instr_memory_q(15 downto 8) when (bubble = 0) else "00000000"; A1 <= instr_memory_q(23 downto 16) when (bubble = 0) else "00000000"; OP1 <= instr_memory_q(31 downto 24) when (bubble = 0) else NOP; process begin wait until CLK'event and CLK='1'; if (halted = '0') then -- Etage 3 -> 4 OP4 <= OP3; A4 <= A3; if (OP3 = LOAD) then B4 <= data_memory_Q; else B4 <= B3; end if; -- Etage 2 -> 3 OP3 <= OP2; A3 <= A2; if (MX2(to_integer(unsigned(OP2))) = '1') then B3 <= ALU_S; else B3 <= B2; end if; -- Etage 1 -> 2 OP2 <= OP1; A2 <= A1; if (MX1(to_integer(unsigned(OP1))) = '1') then B2 <= registers_QA; else B2 <= B1; end if; C2 <= registers_QB; -- Memoire -> etage 1 if (bubble = 0) then IP <= IP + 1; if (needBubbles(to_integer(unsigned(instr_memory_q(31 downto 24)))) = '1') then bubble <= 3; end if; else bubble <= bubble - 1; end if; end if; end process; end Behavioral;