cpu16/src/cpu16.vhd

178 lines
6.5 KiB
VHDL

-- cpu16.vhd
-- Date: Tue Jan 30 15:19:09 2024
-- Author: Yannick Reiß
-- E-Mail: schnick@nickr.eu
library IEEE;
use IEEE.std_logic_1164.all;
entity Cpu16 is
port (
Clk : in std_logic;
Switches : in std_logic_vector(15 downto 0);
SDA : inout std_logic;
SCL : inout std_logic;
LED : out std_logic_vector(15 downto 0);
RGB : out std_logic_vector(7 downto 0)
);
end Cpu16;
architecture Implementation of Cpu16 is
signal RamAddrA : std_logic_vector(15 downto 0) := (others => '0');
signal RamAddrB : std_logic_vector(15 downto 0) := (others => '0');
signal RamWriteEnable : std_logic := '0';
signal RamDataWrite : std_logic_vector(15 downto 0) := (others => '0');
signal RamReadA : std_logic_vector(15 downto 0) := (others => '0');
signal RamReadB : std_logic_vector(15 downto 0) := (others => '0');
signal AluOpcode : std_logic_vector(3 downto 0) := "1111"; -- Some nop operation
signal AluIn1 : std_logic_vector(15 downto 0) := (others => '0');
signal AluIn2 : std_logic_vector(15 downto 0) := (others => '0');
signal AluResult : std_logic_vector(15 downto 0) := (others => '0');
signal RegisterWriteEnable : std_logic := '0';
signal RegisterRegister1 : std_logic_vector(3 downto 0) := (others => '0');
signal RegisterRegister2 : std_logic_vector(3 downto 0) := (others => '0');
signal RegisterRegisterW : std_logic_vector(3 downto 0) := (others => '0');
signal RegisterDataIn : std_logic_vector(15 downto 0) := (others => '0');
signal RegisterDataOut1 : std_logic_vector(15 downto 0) := (others => '0');
signal RegisterDataOut2 : std_logic_vector(15 downto 0) := (others => '0');
signal InstructionCounter : std_logic_vector(15 downto 0) := (others => '0');
signal RawInstruction : std_logic_vector(15 downto 0) := (others => '0');
signal DecoderRegOp1 : std_logic_vector(3 downto 0) := (others => '0');
signal DecoderRegOp2 : std_logic_vector(3 downto 0) := (others => '0');
signal DecoderRegWrite : std_logic_vector(3 downto 0) := (others => '0');
signal NextInstruction : std_logic_vector(15 downto 0) := (others => '0');
signal ImmediateValue : std_logic_vector(15 downto 0) := (others => '0');
signal PcEnable : std_logic := '0';
signal Jump : std_logic := '0';
signal I2CClient : std_logic_vector(15 downto 0) := (others => '0');
signal I2CClientOut : std_logic_vector(15 downto 0) := (others => '0');
signal I2CServer : std_logic_vector(15 downto 0) := (others => '0');
signal PcAddrCalc : std_logic_vector(15 downto 0) := (others => '0');
signal BranchEnable : std_logic := '0';
signal JumpEnable : std_logic := '0';
signal State : std_logic_vector(2 downto 0) := (others => '0');
begin
-- Include Entities
Ramblock : entity work.Ram(Behavioral)
port map(
Clk => Clk,
AddrA => RamAddrA,
AddrB => RamAddrB,
WriteEnable => RamWriteEnable,
DataIn => RamDataWrite,
ReadA => RamReadA,
ReadB => RamReadB,
DirectIn => Switches,
DirectOut => LED,
I2CClientIn => I2CClientOut,
I2CClientOut => I2CClient,
I2CServerOut => I2CServer
);
Alu : entity work.Alu(Implementation)
port map(
alu_op => AluOpcode,
input1 => AluIn1,
input2 => AluIn2,
result => AluResult
);
Regs : entity work.Registerset(Implementation)
port map(
Clk => Clk,
WriteEnable => RegisterWriteEnable,
Register1 => RegisterRegister1,
Register2 => RegisterRegister2,
RegisterW => RegisterRegisterW,
DataIn => RegisterDataIn,
DataOut1 => RegisterDataOut1,
DataOut2 => RegisterDataOut2
);
Instructions : entity work.ProgramMemory(Implementation)
port map(
Clk => Clk,
InstrAddr => InstructionCounter,
Instruction => RawInstruction,
Immediate => NextInstruction
);
Decoder : entity work.Decoder(Implementation)
port map(
Instruction => RawInstruction,
AluOpcd => AluOpcode,
RegOp1 => RegisterRegister1,
RegOp2 => RegisterRegister2,
RegWrite => RegisterRegisterW,
BranchEnable => BranchEnable
);
ImmUseless : entity work.Immediate(Implementation)
port map(
ImmIn => NextInstruction,
ImmOut => ImmediateValue
);
PC : entity work.ProgramCounter(Implementation)
port map(
Clk => Clk,
PcEnable => PcEnable,
AddrCalc => PcAddrCalc,
Jump => JumpEnable,
Addr => InstructionCounter
);
I2C_Adapter : entity work.I2C(Implementation)
port map(
Clk => Clk,
SDA_In => SDA,
SCL_In => SCL,
ClientR => I2CClient,
ServerR => I2CServer,
SDA_Out => SDA,
SCL_Out => SCL,
ClientW => I2CClientOut
);
BranchEnabler : entity work.Branch(Implementation)
port map(
BranchEnable => BranchEnable,
AluResult => AluResult,
PC => InstructionCounter,
PMNext => NextInstruction,
JumpSuggest => Jump,
PCCalc => PcAddrCalc
);
ControlHandler : entity work.Control(Implementation)
port map(
Clk => Clk,
Instruction => RawInstruction,
JumpSuggest => Jump,
EnablePC => PcEnable,
EnableRam => RamWriteEnable,
EnableRegs => RegisterWriteEnable,
EnableJump => JumpEnable,
StateOut => State
);
AluSetInput : process(ImmediateValue, InstructionCounter, RegisterDataOut1,
RegisterDataOut2)
begin
case RawInstruction(3 downto 0) is
when "0000" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" | "1000" | "1010" | "1110" => AluIn1 <= RegisterDataOut1;
AluIn2 <= RegisterDataOut2;
when "0001" | "1001" => AluIn1 <= RegisterDataOut1;
AluIn2 <= ImmediateValue;
when others => AluIn1 <= InstructionCounter;
AluIn2 <= RegisterDataOut2;
end case;
end process AluSetInput;
RGB <= Switches(7 downto 0);
end Implementation;