235 lines
6 KiB
VHDL
235 lines
6 KiB
VHDL
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);
|
|
signal registers_addr_B : std_logic_vector(3 downto 0);
|
|
signal registers_addr_W : std_logic_vector(3 downto 0);
|
|
signal registers_W : std_logic := '0';
|
|
signal registers_DATA : std_logic_vector(7 downto 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);
|
|
signal data_memory_data : std_logic_vector(7 downto 0);
|
|
signal data_memory_rw : std_logic;
|
|
signal data_memory_q : std_logic_vector(7 downto 0);
|
|
|
|
signal instr_memory_addr : std_logic_vector(7 downto 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);
|
|
signal A1 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal B1 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal C1 : STD_LOGIC_VECTOR(7 downto 0);
|
|
|
|
-- Etage 2
|
|
signal OP2 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal A2 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal B2 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal C2 : STD_LOGIC_VECTOR(7 downto 0);
|
|
|
|
-- Etage 3
|
|
signal OP3 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal A3 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal B3 : STD_LOGIC_VECTOR(7 downto 0);
|
|
|
|
-- Etage 4
|
|
signal OP4 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal A4 : STD_LOGIC_VECTOR(7 downto 0);
|
|
signal B4 : STD_LOGIC_VECTOR(7 downto 0);
|
|
|
|
signal bubble : integer := 2;
|
|
|
|
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;
|
|
|
|
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
|
|
C1 <= instr_memory_q(7 downto 0);
|
|
B1 <= instr_memory_q(15 downto 8);
|
|
A1 <= instr_memory_q(23 downto 16);
|
|
OP1 <= instr_memory_q(31 downto 24);
|
|
IP <= IP + 1;
|
|
if (needBubbles(to_integer(unsigned(instr_memory_q(31 downto 24)))) = '1') then
|
|
bubble <= 3;
|
|
end if;
|
|
else
|
|
C1 <= "00000000";
|
|
B1 <= "00000000";
|
|
A1 <= "00000000";
|
|
OP1 <= NOP;
|
|
bubble <= bubble - 1;
|
|
end if;
|
|
end if;
|
|
|
|
end process;
|
|
|
|
end Behavioral;
|
|
|