diff --git a/src/Decoder.vhd b/src/Decoder.vhd index 6daab93..9ffe06b 100644 --- a/src/Decoder.vhd +++ b/src/Decoder.vhd @@ -9,11 +9,12 @@ use IEEE.numeric_std.all; -- Entity decode: Decoder currently supporting read operations entity Decoder is port( - Instruction : in std_logic_vector(15 downto 0); -- Instruction from instruction memory - AluOpcd : out std_logic_vector(3 downto 0); -- alu opcode - RegOp1 : out std_logic_vector(3 downto 0); -- Rj: first register to read - RegOp2 : out std_logic_vector(3 downto 0); -- Rk: second register to read - RegWrite : out std_logic_vector(3 downto 0) -- Ri: the register to write to + Instruction : in std_logic_vector(15 downto 0); -- Instruction from instruction memory + AluOpcd : out std_logic_vector(3 downto 0); -- alu opcode + RegOp1 : out std_logic_vector(3 downto 0); -- Rj: first register to read + RegOp2 : out std_logic_vector(3 downto 0); -- Rk: second register to read + RegWrite : out std_logic_vector(3 downto 0); -- Ri: the register to write to + BranchEnable : out std_logic ); end Decoder; @@ -34,9 +35,16 @@ begin case Instruction(3 downto 0) is when "0000" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" | "1000" | "1010" => AluOpcd <= Instruction(3 downto 0); -- R-Types when "0001" | "1001" => AluOpcd <= Instruction(7 downto 4); -- S-Types - when "1110" => AluOpcd <= Instruction(7 downto 4); -- B-Types (to be debated) + when "1110" => AluOpcd <= Instruction(15 downto 12); -- B-Types (to be debated) when others => AluOpcd <= "1111"; -- if unsure, do nothing end case; + + -- BranchEnable + case Instruction(3 downto 0) is + when "0001" | "1001" | "0100" | "1100" | "0101" | "1101" => + BranchEnable <= '1'; + when others => BranchEnable <= '0'; + end case; end process Decode; end Implementation; diff --git a/src/branch.vhd b/src/branch.vhd new file mode 100644 index 0000000..3de3d53 --- /dev/null +++ b/src/branch.vhd @@ -0,0 +1,27 @@ +-- branch.vhd +-- Date: Thu Feb 1 06:03:29 2024 +-- Author: Yannick Reiß +-- E-Mail: schnick@nickr.eu +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity Branch is + port ( + BranchEnable : in std_logic; + AluResult : in std_logic_vector(15 downto 0); + PC : in std_logic_vector(15 downto 0); + PMNext : in std_logic_vector(15 downto 0); + JumpSuggest : out std_logic; + PCCalc : out std_logic_vector(15 downto 0) + ); +end Branch; + +architecture Implementation of Branch is + +begin + + PCCalc <= std_logic_vector(signed(PC) + signed(PMNext)); + JumpSuggest <= BranchEnable and AluResult(0); + +end Implementation; diff --git a/src/control.vhd b/src/control.vhd new file mode 100644 index 0000000..e69de29 diff --git a/src/cpu16.vhd b/src/cpu16.vhd index b6f7e06..53f3920 100644 --- a/src/cpu16.vhd +++ b/src/cpu16.vhd @@ -47,6 +47,8 @@ architecture Implementation of Cpu16 is 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'; begin -- Include Entities @@ -96,11 +98,12 @@ begin Decoder : entity work.Decoder(Implementation) port map( - Instruction => RawInstruction, - AluOpcd => AluOpcode, - RegOp1 => RegisterRegister1, - RegOp2 => RegisterRegister2, - RegWrite => RegisterRegisterW + Instruction => RawInstruction, + AluOpcd => AluOpcode, + RegOp1 => RegisterRegister1, + RegOp2 => RegisterRegister2, + RegWrite => RegisterRegisterW, + BranchEnable => BranchEnable ); ImmUseless : entity work.Immediate(Implementation) @@ -113,7 +116,7 @@ begin port map( Clk => Clk, PcEnable => PcEnable, - AddrCalc => AluResult, + AddrCalc => PcAddrCalc, Jump => Jump, Addr => InstructionCounter ); @@ -130,6 +133,16 @@ begin ClientW => I2CClientOut ); + BranchEnabler : entity work.Branch(Implementation) + port map( + BranchEnable => BranchEnable, + AluResult => AluResult, + PC => InstructionCounter, + PMNext => NextInstruction, + JumpSuggest => Jump, + PCCalc => PcAddrCalc + ); + AluSetInput : process(ImmediateValue, InstructionCounter, RegisterDataOut1, RegisterDataOut2) begin @@ -141,8 +154,6 @@ begin AluIn2 <= ImmediateValue; when others => AluIn1 <= InstructionCounter; AluIn2 <= RegisterDataOut2; - - end case; end process AluSetInput;