OpenCores
URL https://opencores.org/ocsvn/cortexi/cortexi/trunk

Subversion Repositories cortexi

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /cortexi
    from Rev 12 to Rev 13
    Reverse comparison

Rev 12 → Rev 13

/trunk/convinient/CortexItotal.vhd
0,0 → 1,3331
---------------------------------------------------------------
-- CortexI a CortexM3 CPU clone
-- Ulrich Riedel
-- 2009.09.10
-- supplied at LGPL
-- riedel@ziffernkasten.de
-- search for #MAIN# for CortexI CPU
---------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
package CortexIinclude is
 
constant SIZE_8BIT : std_logic_vector(1 downto 0) := "00";
constant SIZE_16BIT : std_logic_vector(1 downto 0) := "01";
constant SIZE_32BIT : std_logic_vector(1 downto 0) := "10";
constant SIZE_32SBIT : std_logic_vector(1 downto 0) := "11";
constant BS_ROL : std_logic_vector(2 downto 0) := "000";
constant BS_LSL : std_logic_vector(2 downto 0) := "001";
constant BS_ROR : std_logic_vector(2 downto 0) := "010";
constant BS_LSR : std_logic_vector(2 downto 0) := "011";
constant BS_ASR : std_logic_vector(2 downto 0) := "100";
 
end CortexIinclude;
 
package body CortexIinclude is
 
end CortexIinclude;
 
--------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
use work.CortexIinclude.ALL;
 
entity bshifter is Port(
din : in std_logic_vector(31 downto 0);
size : in std_logic_vector( 1 downto 0);
mode : in std_logic_vector( 2 downto 0);
count : in std_logic_vector( 4 downto 0);
cyOut : out std_logic;
dout : out std_logic_vector(31 downto 0)
);
end bshifter;
 
Library UNISIM;
use UNISIM.vcomponents.all;
 
architecture behavioral of bshifter is
 
signal shift : std_logic_vector(4 downto 0);
signal ENCODE : STD_LOGIC_VECTOR (17 downto 0);
signal WORDA : STD_LOGIC_VECTOR (17 downto 0);
signal WORDB : STD_LOGIC_VECTOR (17 downto 0);
signal WORDC : STD_LOGIC_VECTOR (17 downto 0);
signal WORDD : STD_LOGIC_VECTOR (17 downto 0);
 
signal OUTA : STD_LOGIC_VECTOR (35 downto 0);
signal OUTB : STD_LOGIC_VECTOR (35 downto 0);
signal OUTC : STD_LOGIC_VECTOR (35 downto 0);
signal OUTD : STD_LOGIC_VECTOR (35 downto 0);
 
signal temp : std_logic_vector(31 downto 0);
 
signal input : std_logic_vector(31 downto 0);
signal output : std_logic_vector(31 downto 0);
 
begin
 
process(din, size) -- data in multiplexor
begin
case size is
when SIZE_8BIT => -- 8bit
input <= din(7 downto 0) &
din(7 downto 0) &
din(7 downto 0) &
din(7 downto 0);
when SIZE_16BIT => -- 16bit
input <= din(15 downto 0) & din(15 downto 0);
when SIZE_32BIT | SIZE_32SBIT => -- 32bit
input <= din;
when others =>
null;
end case; -- size
end process;
process(output, size, mode) -- data output multiplexor
begin
case size is
when SIZE_8BIT => -- 8bit
case mode is
when "000" => -- ROL
dout <= output;
when "001" => -- LSL
dout <= output;
when "010" => -- ROR
dout <= output;
when "011" => -- LSR
dout <= x"000000" & output(31 downto 24);
when "100" => -- ASR
dout <= x"000000" & output(31 downto 24);
when others =>
dout <= output;
end case; -- mode
when SIZE_16BIT => -- 16bit
case mode is
when "000" => -- ROL
dout <= output;
when "001" => -- LSL
dout <= output;
when "010" => -- ROR
dout <= output;
when "011" => -- LSR
dout <= x"0000" & output(31 downto 16);
when "100" => -- ASR
dout <= x"0000" & output(31 downto 16);
when others =>
dout <= output;
end case; -- mode
when SIZE_32BIT | SIZE_32SBIT => -- 32bit
dout <= output;
when others =>
null;
end case; -- size
end process;
process(count, mode, temp, input)
begin
case mode is
when BS_ROL => -- ROL
shift <= count;
output <= temp;
cyOut <= input(conv_integer(32 - count));
when BS_LSL => -- LSL
shift <= count;
cyOut <= input(conv_integer(32 - count));
case count is
when "00000" =>
output <= temp;
when "00001" =>
output <= temp and "11111111111111111111111111111110";
when "00010" =>
output <= temp and "11111111111111111111111111111100";
when "00011" =>
output <= temp and "11111111111111111111111111111000";
when "00100" =>
output <= temp and "11111111111111111111111111110000";
when "00101" =>
output <= temp and "11111111111111111111111111100000";
when "00110" =>
output <= temp and "11111111111111111111111111000000";
when "00111" =>
output <= temp and "11111111111111111111111110000000";
when "01000" =>
output <= temp and "11111111111111111111111100000000";
when "01001" =>
output <= temp and "11111111111111111111111000000000";
when "01010" =>
output <= temp and "11111111111111111111110000000000";
when "01011" =>
output <= temp and "11111111111111111111100000000000";
when "01100" =>
output <= temp and "11111111111111111111000000000000";
when "01101" =>
output <= temp and "11111111111111111110000000000000";
when "01110" =>
output <= temp and "11111111111111111100000000000000";
when "01111" =>
output <= temp and "11111111111111111000000000000000";
when "10000" =>
output <= temp and "11111111111111110000000000000000";
when "10001" =>
output <= temp and "11111111111111100000000000000000";
when "10010" =>
output <= temp and "11111111111111000000000000000000";
when "10011" =>
output <= temp and "11111111111110000000000000000000";
when "10100" =>
output <= temp and "11111111111100000000000000000000";
when "10101" =>
output <= temp and "11111111111000000000000000000000";
when "10110" =>
output <= temp and "11111111110000000000000000000000";
when "10111" =>
output <= temp and "11111111100000000000000000000000";
when "11000" =>
output <= temp and "11111111000000000000000000000000";
when "11001" =>
output <= temp and "11111110000000000000000000000000";
when "11010" =>
output <= temp and "11111100000000000000000000000000";
when "11011" =>
output <= temp and "11111000000000000000000000000000";
when "11100" =>
output <= temp and "11110000000000000000000000000000";
when "11101" =>
output <= temp and "11100000000000000000000000000000";
when "11110" =>
output <= temp and "11000000000000000000000000000000";
when "11111" =>
output <= temp and "10000000000000000000000000000000";
when others =>
output <= temp;
end case; -- count
when BS_ROR => -- ROR
shift <= 32 - count;
output <= temp;
cyOut <= input(conv_integer(count - 1));
when BS_LSR => -- LSR
shift <= 32 - count;
cyOut <= input(conv_integer(count - 1));
case count is
when "00000" =>
output <= temp;
when "00001" =>
output <= temp and "01111111111111111111111111111111";
when "00010" =>
output <= temp and "00111111111111111111111111111111";
when "00011" =>
output <= temp and "00011111111111111111111111111111";
when "00100" =>
output <= temp and "00001111111111111111111111111111";
when "00101" =>
output <= temp and "00000111111111111111111111111111";
when "00110" =>
output <= temp and "00000011111111111111111111111111";
when "00111" =>
output <= temp and "00000001111111111111111111111111";
when "01000" =>
output <= temp and "00000000111111111111111111111111";
when "01001" =>
output <= temp and "00000000011111111111111111111111";
when "01010" =>
output <= temp and "00000000001111111111111111111111";
when "01011" =>
output <= temp and "00000000000111111111111111111111";
when "01100" =>
output <= temp and "00000000000011111111111111111111";
when "01101" =>
output <= temp and "00000000000001111111111111111111";
when "01110" =>
output <= temp and "00000000000000111111111111111111";
when "01111" =>
output <= temp and "00000000000000011111111111111111";
when "10000" =>
output <= temp and "00000000000000001111111111111111";
when "10001" =>
output <= temp and "00000000000000000111111111111111";
when "10010" =>
output <= temp and "00000000000000000011111111111111";
when "10011" =>
output <= temp and "00000000000000000001111111111111";
when "10100" =>
output <= temp and "00000000000000000000111111111111";
when "10101" =>
output <= temp and "00000000000000000000011111111111";
when "10110" =>
output <= temp and "00000000000000000000001111111111";
when "10111" =>
output <= temp and "00000000000000000000000111111111";
when "11000" =>
output <= temp and "00000000000000000000000011111111";
when "11001" =>
output <= temp and "00000000000000000000000001111111";
when "11010" =>
output <= temp and "00000000000000000000000000111111";
when "11011" =>
output <= temp and "00000000000000000000000000011111";
when "11100" =>
output <= temp and "00000000000000000000000000001111";
when "11101" =>
output <= temp and "00000000000000000000000000000111";
when "11110" =>
output <= temp and "00000000000000000000000000000011";
when "11111" =>
output <= temp and "00000000000000000000000000000001";
when others =>
output <= temp;
end case; -- count
when BS_ASR => -- ASR
shift <= 32 - count;
cyOut <= input(conv_integer(count - 1));
case count is
when "00000" =>
output <= (input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31));
when "00001" =>
output <= (temp and "01111111111111111111111111111111") or
(input(31) & "0000000000000000000000000000000");
when "00010" =>
output <= (temp and "00111111111111111111111111111111") or
(input(31) & input(31) &
"000000000000000000000000000000");
when "00011" =>
output <= (temp and "00011111111111111111111111111111") or
(input(31) & input(31) & input(31) &
"00000000000000000000000000000");
when "00100" =>
output <= (temp and "00001111111111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
"0000000000000000000000000000");
when "00101" =>
output <= (temp and "00000111111111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & "000000000000000000000000000");
when "00110" =>
output <= (temp and "00000011111111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) &
"00000000000000000000000000");
when "00111" =>
output <= (temp and "00000001111111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) &
"0000000000000000000000000");
when "01000" =>
output <= (temp and "00000000111111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
"000000000000000000000000");
when "01001" =>
output <= (temp and "00000000011111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & "00000000000000000000000");
when "01010" =>
output <= (temp and "00000000001111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & "0000000000000000000000");
when "01011" =>
output <= (temp and "00000000000111111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) &
"000000000000000000000");
when "01100" =>
output <= (temp and "00000000000011111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
"00000000000000000000");
when "01101" =>
output <= (temp and "00000000000001111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & "0000000000000000000");
when "01110" =>
output <= (temp and "00000000000000111111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & "000000000000000000");
when "01111" =>
output <= (temp and "00000000000000011111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) &
"00000000000000000");
when "10000" =>
output <= (temp and "00000000000000001111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
"0000000000000000");
when "10001" =>
output <= (temp and "00000000000000000111111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & "000000000000000");
when "10010" =>
output <= (temp and "00000000000000000011111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & "00000000000000");
when "10011" =>
output <= (temp and "00000000000000000001111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & "0000000000000");
when "10100" =>
output <= (temp and "00000000000000000000111111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
"000000000000");
when "10101" =>
output <= (temp and "00000000000000000000011111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & "00000000000");
when "10110" =>
output <= (temp and "00000000000000000000001111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & "0000000000");
when "10111" =>
output <= (temp and "00000000000000000000000111111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & "000000000");
when "11000" =>
output <= (temp and "00000000000000000000000011111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
"00000000");
when "11001" =>
output <= (temp and "00000000000000000000000001111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & "0000000");
when "11010" =>
output <= (temp and "00000000000000000000000000111111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & "000000");
when "11011" =>
output <= (temp and "00000000000000000000000000011111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & "00000");
when "11100" =>
output <= (temp and "00000000000000000000000000001111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
"0000");
when "11101" =>
output <= (temp and "00000000000000000000000000000111") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & "000");
when "11110" =>
output <= (temp and "00000000000000000000000000000011") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & "00");
when "11111" =>
output <= (temp and "00000000000000000000000000000001") or
(input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & input(31) &
input(31) & input(31) & input(31) & "0");
when others =>
output <= temp;
end case; -- count
when others =>
shift <= count;
output <= temp;
end case; -- mode
end process;
-------------- 32bit barrel shifter
ENCODE(17 downto 8) <= (others => '0');
WORDA(17 downto 16) <= (others => '0');
WORDB(17 downto 16) <= (others => '0');
WORDC(17 downto 16) <= (others => '0');
WORDD(17 downto 16) <= (others => '0');
WORDA(15 downto 8) <= input ( 7 downto 0);
WORDB(15 downto 8) <= input (15 downto 8);
WORDC(15 downto 8) <= input (23 downto 16);
WORDD(15 downto 8) <= input (31 downto 24);
WORDA(7 downto 0) <= input (31 downto 24);
WORDB(7 downto 0) <= input ( 7 downto 0);
WORDC(7 downto 0) <= input (15 downto 8);
WORDD(7 downto 0) <= input (23 downto 16);
ONE_HOT:
with SHIFT(2 downto 0) select
encode(7 downto 0) <=
"00000001" when "000", --0
"00000010" when "001", --1
"00000100" when "010", --2
"00001000" when "011", --3
"00010000" when "100", --4
"00100000" when "101", --5
"01000000" when "110", --6
"10000000" when others; --7
MULTA: MULT18X18 port map (A => WORDA, B => ENCODE, P => OUTA);
MULTB: MULT18X18 port map (A => WORDB, B => ENCODE, P => OUTB);
MULTC: MULT18X18 port map (A => WORDC, B => ENCODE, P => OUTC);
MULTD: MULT18X18 port map (A => WORDD, B => ENCODE, P => OUTD);
MUXA:
process(SHIFT, OUTA, OUTB, OUTC, OUTD)
begin
case SHIFT(4 downto 3) is
when "00" => temp(7 downto 0) <= OUTA(15 downto 8);
when "01" => temp(7 downto 0) <= OUTD(15 downto 8);
when "10" => temp(7 downto 0) <= OUTC(15 downto 8);
when others => temp(7 downto 0) <= OUTB(15 downto 8);
end case;
end process;
MUXB:
process(SHIFT, OUTA, OUTB, OUTC, OUTD)
begin
case SHIFT(4 downto 3) is
when "00" => temp(15 downto 8) <= OUTB(15 downto 8);
when "01" => temp(15 downto 8) <= OUTA(15 downto 8);
when "10" => temp(15 downto 8) <= OUTD(15 downto 8);
when others => temp(15 downto 8) <= OUTC(15 downto 8);
end case;
end process;
MUXC:
process(SHIFT, OUTA, OUTB, OUTC, OUTD)
begin
case SHIFT(4 downto 3) is
when "00" => temp(23 downto 16) <= OUTC(15 downto 8);
when "01" => temp(23 downto 16) <= OUTB(15 downto 8);
when "10" => temp(23 downto 16) <= OUTA(15 downto 8);
when others => temp(23 downto 16) <= OUTD(15 downto 8);
end case;
end process;
MUXD:
process(SHIFT, OUTA, OUTB, OUTC, OUTD)
begin
case SHIFT(4 downto 3) is
when "00" => temp(31 downto 24) <= OUTD(15 downto 8);
when "01" => temp(31 downto 24) <= OUTC(15 downto 8);
when "10" => temp(31 downto 24) <= OUTB(15 downto 8);
when others => temp(31 downto 24) <= OUTA(15 downto 8);
end case;
end process;
 
end behavioral;
 
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
 
entity Multiplier is
Port ( a : in STD_LOGIC_VECTOR (31 downto 0);
b : in STD_LOGIC_VECTOR (31 downto 0);
p : out STD_LOGIC_VECTOR (63 downto 0));
end Multiplier;
 
architecture Behavioral of Multiplier is
 
signal WORDAL : std_logic_vector(17 downto 0);
signal WORDAH : std_logic_vector(17 downto 0);
signal WORDBL : std_logic_vector(17 downto 0);
signal WORDBH : std_logic_vector(17 downto 0);
signal PROD0 : std_logic_vector(35 downto 0);
signal PROD1 : std_logic_vector(35 downto 0);
signal PROD2 : std_logic_vector(35 downto 0);
signal PROD3 : std_logic_vector(35 downto 0);
begin
 
-- A * B
-- B(15.. 0) * A(15..0)
-- B(15.. 0) * A(31..16)
-- B(31..16) * A(15.. 0)
-- B(31..16) * A(31..16)
WORDAL <= "00" & a(15 downto 0);
WORDAH <= "00" & a(31 downto 16);
WORDBL <= "00" & b(15 downto 0);
WORDBH <= "00" & b(31 downto 16);
MULTA: MULT18X18 port map (A => WORDAL, B => WORDBL, P => PROD0);
MULTB: MULT18X18 port map (A => WORDAH, B => WORDBL, P => PROD1);
MULTC: MULT18X18 port map (A => WORDAL, B => WORDBH, P => PROD2);
MULTD: MULT18X18 port map (A => WORDAH, B => WORDBH, P => PROD3);
 
p <= (x"00000000" & PROD0(31 downto 0)) +
(x"0000" & PROD1(31 downto 0) & x"0000") +
(x"0000" & PROD2(31 downto 0) & x"0000") +
(PROD3(31 downto 0) & x"00000000");
 
end Behavioral;
 
--################################################################
--###### AT HERE THE Cortex CPU ##################################
--################################################################
-- #MAIN#
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
use work.CortexIinclude.ALL;
 
Library UNISIM;
use UNISIM.vcomponents.all;
 
ENTITY CortexI IS
PORT(
clk : in std_logic;
rst : in std_logic;
irq : in std_logic;
addr : out std_logic_vector(31 downto 0);
wrl : out std_logic;
wrh : out std_logic;
datain : in std_logic_vector(15 downto 0);
dataout : out std_logic_vector(15 downto 0)
);
END CortexI;
 
ARCHITECTURE behavior OF CortexI IS
 
constant STATE_FETCH : std_logic_vector(6 downto 0) := "0000000";
constant STATE_READ1 : std_logic_vector(6 downto 0) := "0000001";
constant STATE_READ2 : std_logic_vector(6 downto 0) := "0000010";
constant STATE_WRITE1 : std_logic_vector(6 downto 0) := "0000011";
constant STATE_WRITE2 : std_logic_vector(6 downto 0) := "0000100";
constant STATE_RD0L : std_logic_vector(6 downto 0) := "0000101";
constant STATE_RD0H : std_logic_vector(6 downto 0) := "0000110";
constant STATE_RD1L : std_logic_vector(6 downto 0) := "0000111";
constant STATE_RD1H : std_logic_vector(6 downto 0) := "0001000";
constant STATE_RD2L : std_logic_vector(6 downto 0) := "0001001";
constant STATE_RD2H : std_logic_vector(6 downto 0) := "0001010";
constant STATE_RD3L : std_logic_vector(6 downto 0) := "0001011";
constant STATE_RD3H : std_logic_vector(6 downto 0) := "0001100";
constant STATE_RD4L : std_logic_vector(6 downto 0) := "0001101";
constant STATE_RD4H : std_logic_vector(6 downto 0) := "0001110";
constant STATE_RD5L : std_logic_vector(6 downto 0) := "0001111";
constant STATE_RD5H : std_logic_vector(6 downto 0) := "0010000";
constant STATE_RD6L : std_logic_vector(6 downto 0) := "0010001";
constant STATE_RD6H : std_logic_vector(6 downto 0) := "0010010";
constant STATE_RD7L : std_logic_vector(6 downto 0) := "0010011";
constant STATE_RD7H : std_logic_vector(6 downto 0) := "0010100";
constant STATE_RDPL : std_logic_vector(6 downto 0) := "0010101";
constant STATE_RDPH : std_logic_vector(6 downto 0) := "0010110";
constant STATE_WR0L : std_logic_vector(6 downto 0) := "0010111";
constant STATE_WR0H : std_logic_vector(6 downto 0) := "0011000";
constant STATE_WR1L : std_logic_vector(6 downto 0) := "0011001";
constant STATE_WR1H : std_logic_vector(6 downto 0) := "0011010";
constant STATE_WR2L : std_logic_vector(6 downto 0) := "0011011";
constant STATE_WR2H : std_logic_vector(6 downto 0) := "0011100";
constant STATE_WR3L : std_logic_vector(6 downto 0) := "0011101";
constant STATE_WR3H : std_logic_vector(6 downto 0) := "0011110";
constant STATE_WR4L : std_logic_vector(6 downto 0) := "0011111";
constant STATE_WR4H : std_logic_vector(6 downto 0) := "0100000";
constant STATE_WR5L : std_logic_vector(6 downto 0) := "0100001";
constant STATE_WR5H : std_logic_vector(6 downto 0) := "0100010";
constant STATE_WR6L : std_logic_vector(6 downto 0) := "0100011";
constant STATE_WR6H : std_logic_vector(6 downto 0) := "0100100";
constant STATE_WR7L : std_logic_vector(6 downto 0) := "0100101";
constant STATE_WR7H : std_logic_vector(6 downto 0) := "0100110";
constant STATE_WRPL : std_logic_vector(6 downto 0) := "0100111";
constant STATE_WRPH : std_logic_vector(6 downto 0) := "0101000";
constant STATE_RESET0 : std_logic_vector(6 downto 0) := "0101001";
constant STATE_RESET1 : std_logic_vector(6 downto 0) := "0101010";
constant STATE_RESET2 : std_logic_vector(6 downto 0) := "0101011";
constant STATE_RESET3 : std_logic_vector(6 downto 0) := "0101100";
constant STATE_IRQ : std_logic_vector(6 downto 0) := "0101101";
constant STATE_IRQ1 : std_logic_vector(6 downto 0) := "0101110";
constant STATE_IRQ2 : std_logic_vector(6 downto 0) := "0101111";
constant STATE_IRQ3 : std_logic_vector(6 downto 0) := "0110000";
constant STATE_IRQ4 : std_logic_vector(6 downto 0) := "0110001";
constant STATE_IRQ5 : std_logic_vector(6 downto 0) := "0110010";
constant STATE_IRQ6 : std_logic_vector(6 downto 0) := "0110011";
constant STATE_IRQ7 : std_logic_vector(6 downto 0) := "0110100";
constant STATE_IRQ8 : std_logic_vector(6 downto 0) := "0110101";
constant STATE_IRQ9 : std_logic_vector(6 downto 0) := "0110110";
constant STATE_IRQ10 : std_logic_vector(6 downto 0) := "0110111";
constant STATE_IRQ11 : std_logic_vector(6 downto 0) := "0111000";
constant STATE_IRQ12 : std_logic_vector(6 downto 0) := "0111001";
constant STATE_IRQ13 : std_logic_vector(6 downto 0) := "0111010";
constant STATE_IRQ14 : std_logic_vector(6 downto 0) := "0111011";
constant STATE_IRQ15 : std_logic_vector(6 downto 0) := "0111100";
constant STATE_IRQ16 : std_logic_vector(6 downto 0) := "0111101";
constant STATE_IRQ17 : std_logic_vector(6 downto 0) := "0111110";
constant STATE_RET : std_logic_vector(6 downto 0) := "0111111";
constant STATE_RET1 : std_logic_vector(6 downto 0) := "1000000";
constant STATE_RET2 : std_logic_vector(6 downto 0) := "1000001";
constant STATE_RET3 : std_logic_vector(6 downto 0) := "1000010";
constant STATE_RET4 : std_logic_vector(6 downto 0) := "1000011";
constant STATE_RET5 : std_logic_vector(6 downto 0) := "1000100";
constant STATE_RET6 : std_logic_vector(6 downto 0) := "1000101";
constant STATE_RET7 : std_logic_vector(6 downto 0) := "1000110";
constant STATE_RET8 : std_logic_vector(6 downto 0) := "1000111";
constant STATE_RET9 : std_logic_vector(6 downto 0) := "1001000";
constant STATE_RET10 : std_logic_vector(6 downto 0) := "1001001";
constant STATE_RET11 : std_logic_vector(6 downto 0) := "1001010";
constant STATE_RET12 : std_logic_vector(6 downto 0) := "1001011";
constant STATE_RET13 : std_logic_vector(6 downto 0) := "1001100";
constant STATE_RET14 : std_logic_vector(6 downto 0) := "1001101";
constant STATE_RET15 : std_logic_vector(6 downto 0) := "1001110";
constant STATE_RET16 : std_logic_vector(6 downto 0) := "1001111";
constant STATE_RET17 : std_logic_vector(6 downto 0) := "1010000";
 
constant CODE_LSL1 : std_logic_vector(6 downto 0) := "0000000";
constant CODE_LSR1 : std_logic_vector(6 downto 0) := "0000001";
constant CODE_ASR1 : std_logic_vector(6 downto 0) := "0000010";
constant CODE_ADD1 : std_logic_vector(6 downto 0) := "0000011";
constant CODE_SUB1 : std_logic_vector(6 downto 0) := "0000100";
constant CODE_ADD2 : std_logic_vector(6 downto 0) := "0000110";
constant CODE_SUB2 : std_logic_vector(6 downto 0) := "0000111";
constant CODE_MOV1 : std_logic_vector(6 downto 0) := "0001000";
constant CODE_CMP1 : std_logic_vector(6 downto 0) := "0001001";
constant CODE_ADD3 : std_logic_vector(6 downto 0) := "0001010";
constant CODE_SUB3 : std_logic_vector(6 downto 0) := "0001011";
constant CODE_AND1 : std_logic_vector(6 downto 0) := "0001100";
constant CODE_EOR1 : std_logic_vector(6 downto 0) := "0001101";
constant CODE_LSL2 : std_logic_vector(6 downto 0) := "0001110";
constant CODE_LSR2 : std_logic_vector(6 downto 0) := "0001111";
constant CODE_ASR2 : std_logic_vector(6 downto 0) := "0010000";
constant CODE_ADC1 : std_logic_vector(6 downto 0) := "0010001";
constant CODE_SBC1 : std_logic_vector(6 downto 0) := "0010010";
constant CODE_ROR1 : std_logic_vector(6 downto 0) := "0010011";
constant CODE_TST1 : std_logic_vector(6 downto 0) := "0010100";
constant CODE_NEG1 : std_logic_vector(6 downto 0) := "0010101";
constant CODE_CMP2 : std_logic_vector(6 downto 0) := "0010110";
constant CODE_CMN1 : std_logic_vector(6 downto 0) := "0010111";
constant CODE_ORR1 : std_logic_vector(6 downto 0) := "0011000";
constant CODE_MUL1 : std_logic_vector(6 downto 0) := "0011001";
constant CODE_BIC1 : std_logic_vector(6 downto 0) := "0011010";
constant CODE_MVN1 : std_logic_vector(6 downto 0) := "0011011";
constant CODE_ADD4 : std_logic_vector(6 downto 0) := "0011100";
constant CODE_CMP3 : std_logic_vector(6 downto 0) := "0011101";
constant CODE_CPY1 : std_logic_vector(6 downto 0) := "0011110";
constant CODE_BX1 : std_logic_vector(6 downto 0) := "0011111";
constant CODE_LDR1 : std_logic_vector(6 downto 0) := "0100000";
constant CODE_STR1 : std_logic_vector(6 downto 0) := "0100001";
constant CODE_STRH1 : std_logic_vector(6 downto 0) := "0100010";
constant CODE_STRB1 : std_logic_vector(6 downto 0) := "0100011";
constant CODE_LDRSB1 : std_logic_vector(6 downto 0) := "0100100";
constant CODE_LDR2 : std_logic_vector(6 downto 0) := "0100101";
constant CODE_LDRH1 : std_logic_vector(6 downto 0) := "0100110";
constant CODE_LDRB1 : std_logic_vector(6 downto 0) := "0100111";
constant CODE_LDRSH1 : std_logic_vector(6 downto 0) := "0101000";
constant CODE_STR2 : std_logic_vector(6 downto 0) := "0101001";
constant CODE_LDR3 : std_logic_vector(6 downto 0) := "0101010";
constant CODE_STRB2 : std_logic_vector(6 downto 0) := "0101011";
constant CODE_LDRB2 : std_logic_vector(6 downto 0) := "0101100";
constant CODE_STRH2 : std_logic_vector(6 downto 0) := "0101101";
constant CODE_LDRH2 : std_logic_vector(6 downto 0) := "0101110";
constant CODE_STR3 : std_logic_vector(6 downto 0) := "0101111";
constant CODE_LDR4 : std_logic_vector(6 downto 0) := "0110000";
constant CODE_ADD5 : std_logic_vector(6 downto 0) := "0110001";
constant CODE_ADD6 : std_logic_vector(6 downto 0) := "0110010";
constant CODE_ADD7 : std_logic_vector(6 downto 0) := "0110011";
constant CODE_SUB4 : std_logic_vector(6 downto 0) := "0110100";
constant CODE_SXTH1 : std_logic_vector(6 downto 0) := "0110101";
constant CODE_SXTB1 : std_logic_vector(6 downto 0) := "0110110";
constant CODE_UXTH1 : std_logic_vector(6 downto 0) := "0110111";
constant CODE_UXTB1 : std_logic_vector(6 downto 0) := "0111000";
constant CODE_PUSH1 : std_logic_vector(6 downto 0) := "0111001";
constant CODE_POP1 : std_logic_vector(6 downto 0) := "0111010";
constant CODE_STMIA1 : std_logic_vector(6 downto 0) := "0111011";
constant CODE_LDMIA1 : std_logic_vector(6 downto 0) := "0111100";
constant CODE_BCC1 : std_logic_vector(6 downto 0) := "0111101";
constant CODE_SWI1 : std_logic_vector(6 downto 0) := "0111110";
constant CODE_B1 : std_logic_vector(6 downto 0) := "0111111";
constant CODE_BLX1 : std_logic_vector(6 downto 0) := "1000000";
constant CODE_BLX2 : std_logic_vector(6 downto 0) := "1000001";
constant CODE_BL1 : std_logic_vector(6 downto 0) := "1000010";
constant CODE_NOP : std_logic_vector(6 downto 0) := "1000011";
constant CODE_XXX : std_logic_vector(6 downto 0) := "1111111";
constant N_FLAG : integer := 31;
constant Z_FLAG : integer := 30;
constant C_FLAG : integer := 29;
constant V_FLAG : integer := 28;
 
constant WRITE_B_LOW : std_logic_vector(3 downto 0) := "0000";
constant WRITE_B_HIGH : std_logic_vector(3 downto 0) := "0001";
constant WRITE_H_BOTH : std_logic_vector(3 downto 0) := "0010";
constant WRITE_H_LOW : std_logic_vector(3 downto 0) := "0011";
constant WRITE_H_HIGH : std_logic_vector(3 downto 0) := "0100";
constant WRITE_W_LOW : std_logic_vector(3 downto 0) := "0101";
constant WRITE_W_HIGH : std_logic_vector(3 downto 0) := "0110";
constant WRITE_W_LOWB : std_logic_vector(3 downto 0) := "0111";
constant WRITE_W_MID : std_logic_vector(3 downto 0) := "1000";
constant WRITE_W_HIGHB : std_logic_vector(3 downto 0) := "1001";
 
constant ADDR_PC : std_logic_vector(1 downto 0) := "00";
constant ADDR_SP : std_logic_vector(1 downto 0) := "01";
constant ADDR_RS : std_logic_vector(1 downto 0) := "10";
constant ADDR_RT : std_logic_vector(1 downto 0) := "11";
 
 
type typeRegisters is array (0 to 15) of std_logic_vector(31 downto 0);
signal theRegisters : typeRegisters;
signal cpsrRegister : std_logic_Vector(31 downto 0);
signal cpuState : std_logic_vector( 6 downto 0);
signal opcode : std_logic_vector(15 downto 0);
signal addrMux : std_logic_vector( 1 downto 0);
signal address : std_logic_vector(31 downto 0);
signal irq_d : std_logic;
signal irqRequest : std_logic;
signal writeL : std_logic;
signal writeH : std_logic;
signal shiftResult : std_logic_vector(31 downto 0);
signal cyShiftOut : std_logic;
signal shiftMode : std_logic_vector( 2 downto 0);
signal shiftCount : std_logic_vector( 4 downto 0);
signal shiftIn : std_logic_vector(31 downto 0);
signal LDMread : std_logic_vector( 7 downto 0);
 
signal unitControl : std_logic_vector( 6 downto 0);
signal unitControl2 : std_logic_vector( 6 downto 0);
signal factor1 : std_logic_vector(31 downto 0);
signal factor2 : std_logic_vector(31 downto 0);
signal product : std_logic_vector(63 downto 0);
signal branch : std_logic;
signal datain20 : integer range 0 to 15;
signal datain53 : integer range 0 to 15;
signal datain86 : integer range 0 to 15;
signal datain108 : integer range 0 to 15;
 
signal opcode20 : integer range 0 to 15;
signal opcode53 : integer range 0 to 15;
signal opcode86 : integer range 0 to 15;
signal opcode108 : integer range 0 to 15;
component bshifter Port (
din : in std_logic_vector(31 downto 0);
size : in std_logic_vector( 1 downto 0);
mode : in std_logic_vector( 2 downto 0);
count : in std_logic_vector( 4 downto 0);
cyOut : out std_logic;
dout : out std_logic_vector(31 downto 0)
);
end component;
 
component Multiplier -- 32 x 32 = 64 bit unsigned product multiplier
port(a : in std_logic_vector(31 downto 0); -- multiplicand
b : in std_logic_vector(31 downto 0); -- multiplier
p : out std_logic_vector(63 downto 0)); -- product
end component;
begin
 
datain20 <= conv_integer("0" & datain( 2 downto 0));
datain53 <= conv_integer("0" & datain( 5 downto 3));
datain86 <= conv_integer("0" & datain( 8 downto 6));
datain108 <= conv_integer("0" & datain(10 downto 8));
opcode20 <= conv_integer("0" & opcode( 2 downto 0));
opcode53 <= conv_integer("0" & opcode( 5 downto 3));
opcode86 <= conv_integer("0" & opcode( 8 downto 6));
opcode108 <= conv_integer("0" & opcode(10 downto 8));
--#################################################################
-- barrel shifter
shiftMode <= BS_LSL when (unitControl = CODE_LSL1) or (unitControl = CODE_LSL2) else
BS_LSR when (unitControl = CODE_LSR1) or (unitControl = CODE_LSR2) else
BS_ASR when (unitControl = CODE_ASR1) or (unitControl = CODE_ASR2) else
BS_ROR;
shiftCount <= datain(10 downto 6)
when (unitControl = CODE_LSL1) or (unitControl = CODE_LSR1) or (unitControl = CODE_ASR1) else
theRegisters(datain53)(4 downto 0);
shiftIn <= theRegisters(datain53)
when (unitControl = CODE_LSL1) or (unitControl = CODE_LSR1) or (unitControl = CODE_ASR1) else
theRegisters(datain20);
barrelShifter : bshifter Port map(
din => shiftIn, --: in std_logic_vector(31 downto 0);
size => SIZE_32BIT, --: in std_logic_vector( 1 downto 0);
mode => shiftMode, --: in std_logic_vector( 2 downto 0);
count => shiftCount, --: in std_logic_vector( 4 downto 0);
cyOut => cyShiftOut, --: out std_logic;
dout => shiftResult --: out std_logic_vector(31 downto 0)
);
--#################################################################
-- multiplier
multip : Multiplier Port map(
a => factor1,
b => factor2,
p => product
);
factor1 <= theRegisters(datain20);
factor2 <= theRegisters(datain53);
--#################################################################
-- decodes instruction bits to control bits for other ARMT units
process(datain)
begin
case datain(15 downto 11) is
when "00000" => unitControl <= CODE_LSL1;
when "00001" => unitControl <= CODE_LSR1;
when "00010" => unitControl <= CODE_ASR1;
when "00011" =>
case datain(10 downto 9) is
when "00" => unitControl <= CODE_ADD1;
when "01" => unitControl <= CODE_SUB1;
when "10" => unitControl <= CODE_ADD2;
when "11" => unitControl <= CODE_SUB2;
when others => unitControl <= CODE_XXX;
end case;
when "00100" => unitControl <= CODE_MOV1;
when "00101" => unitControl <= CODE_CMP1;
when "00110" => unitControl <= CODE_ADD3;
when "00111" => unitControl <= CODE_SUB3;
when "01000" =>
if datain(10) = '0' then
case datain(9 downto 6) is
when "0000" => unitControl <= CODE_AND1;
when "0001" => unitControl <= CODE_EOR1;
when "0010" => unitControl <= CODE_LSL2;
when "0011" => unitControl <= CODE_LSR2;
when "0100" => unitControl <= CODE_ASR2;
when "0101" => unitControl <= CODE_ADC1;
when "0110" => unitControl <= CODE_SBC1;
when "0111" => unitControl <= CODE_ROR1;
when "1000" => unitControl <= CODE_TST1;
when "1001" => unitControl <= CODE_NEG1;
when "1010" => unitControl <= CODE_CMP2;
when "1011" => unitControl <= CODE_CMN1;
when "1100" => unitControl <= CODE_ORR1;
when "1101" => unitControl <= CODE_MUL1;
when "1110" => unitControl <= CODE_BIC1;
when "1111" => unitControl <= CODE_MVN1;
when others => unitControl <= CODE_XXX;
end case;
else
case datain(9 downto 8) is
when "00" => unitControl <= CODE_ADD4;
when "01" => unitControl <= CODE_CMP3;
when "10" => unitControl <= CODE_CPY1; -- MOV
when "11" => unitControl <= CODE_BX1;
when others => unitControl <= CODE_XXX;
end case;
end if;
when "01001" => unitControl <= CODE_LDR1;
when "01010" =>
case datain(10 downto 9) is
when "00" => unitControl <= CODE_STR1;
when "01" => unitControl <= CODE_STRH1;
when "10" => unitControl <= CODE_STRB1;
when "11" => unitControl <= CODE_LDRSB1;
when others => unitControl <= CODE_XXX;
end case;
when "01011" =>
case datain(10 downto 9) is
when "00" => unitControl <= CODE_LDR2;
when "01" => unitControl <= CODE_LDRH1;
when "10" => unitControl <= CODE_LDRB1;
when "11" => unitControl <= CODE_LDRSH1;
when others => unitControl <= CODE_XXX;
end case;
when "01100" => unitControl <= CODE_STR2;
when "01101" => unitControl <= CODE_LDR3;
when "01110" => unitControl <= CODE_STRB2;
when "01111" => unitControl <= CODE_LDRB2;
when "10000" => unitControl <= CODE_STRH2;
when "10001" => unitControl <= CODE_LDRH2;
when "10010" => unitControl <= CODE_STR3;
when "10011" => unitControl <= CODE_LDR4;
when "10100" => unitControl <= CODE_ADD5;
when "10101" => unitControl <= CODE_ADD6;
when "10110" =>
case datain(10 downto 7) is
when "0000" => unitControl <= CODE_ADD7;
when "0001" => unitControl <= CODE_SUB4;
when "0100" =>
if datain(6) = '0' then
unitControl <= CODE_SXTH1;
else
unitControl <= CODE_SXTB1;
end if;
when "0101" =>
if datain(6) = '0' then
unitControl <= CODE_UXTH1;
else
unitControl <= CODE_UXTB1;
end if;
when "1000" | "1001" | "1010" | "1011" =>
unitControl <= CODE_PUSH1;
when others => unitControl <= CODE_XXX;
end case;
when "10111" =>
if datain(10 downto 8) = "100" or datain(10 downto 8) = "101" then
unitControl <= CODE_POP1;
else
unitControl <= CODE_NOP;
end if;
when "11000" => unitControl <= CODE_STMIA1;
when "11001" => unitControl <= CODE_LDMIA1;
when "11010" | "11011" =>
-- if datain(11 downto 8) = "1111" then
-- unitControl <= CODE_SWI1;
-- else
unitControl <= CODE_BCC1;
-- end if;
when "11100" => unitControl <= CODE_B1;
when "11101" => unitControl <= CODE_BLX1;
when "11110" => unitControl <= CODE_BLX2;
when "11111" => unitControl <= CODE_BL1;
when others => unitControl <= CODE_XXX;
end case; -- datain(15 downto 11)
end process;
wrl <= writeL;
wrH <= writeH;
--#################################################################
-- address bus multiplexer
addr <= theRegisters(15) when addrMux = ADDR_PC else
theRegisters(13) when addrMux = ADDR_SP else
address;
 
--#################################################################
-- check flags for branch
process(datain, cpsrRegister)
begin
case datain(11 downto 8) is
when "0000" => -- EQ
if cpsrRegister(Z_FLAG) = '1' then
branch <= '1';
else
branch <= '0';
end if;
when "0001" => -- NE
if cpsrRegister(Z_FLAG) = '0' then
branch <= '1';
else
branch <= '0';
end if;
when "0010" => -- CS
if cpsrRegister(C_FLAG) = '1' then
branch <= '1';
else
branch <= '0';
end if;
when "0011" => -- CC
if cpsrRegister(C_FLAG) = '0' then
branch <= '1';
else
branch <= '0';
end if;
when "0100" => -- MI
if cpsrRegister(N_FLAG) = '1' then
branch <= '1';
else
branch <= '0';
end if;
when "0101" => -- PL
if cpsrRegister(N_FLAG) = '0' then
branch <= '1';
else
branch <= '0';
end if;
when "0110" => -- VS
if cpsrRegister(V_FLAG) = '1' then
branch <= '1';
else
branch <= '0';
end if;
when "0111" => -- VC
if cpsrRegister(V_FLAG) = '0' then
branch <= '1';
else
branch <= '0';
end if;
when "1000" => -- HI
if cpsrRegister(C_FLAG) = '1' and cpsrRegister(Z_FLAG) = '0' then
branch <= '1';
else
branch <= '0';
end if;
when "1001" => -- LS
if cpsrRegister(C_FLAG) = '0' or cpsrRegister(Z_FLAG) = '1' then
branch <= '1';
else
branch <= '0';
end if;
when "1010" => -- GE
if cpsrRegister(N_FLAG) = cpsrRegister(V_FLAG) then
branch <= '1';
else
branch <= '0';
end if;
when "1011" => -- LT
if cpsrRegister(N_FLAG) /= cpsrRegister(V_FLAG) then
branch <= '1';
else
branch <= '0';
end if;
when "1100" => -- GT
if cpsrRegister(Z_FLAG) = '0' and (cpsrRegister(N_FLAG) = cpsrRegister(V_FLAG)) then
branch <= '1';
else
branch <= '0';
end if;
when "1101" => -- LE
if cpsrRegister(Z_FLAG) = '1' or (cpsrRegister(N_FLAG) /= cpsrRegister(V_FLAG)) then
branch <= '1';
else
branch <= '0';
end if;
when "1110" => -- AL
branch <= '1';
when others =>
branch <= '0';
end case; -- datain(11 downto 8)
end process;
 
--#################################################################
-- ARMT cpu main state machine
process(rst, clk)
variable tres : std_logic_vector(32 downto 0);
variable tsum : std_logic_vector(31 downto 0);
variable op1 : std_logic;
variable op2 : std_logic;
variable opr : std_logic;
begin
if rising_edge(clk) then
if rst = '0' then
theRegisters( 0) <= x"00000000";
theRegisters( 1) <= x"00000000";
theRegisters( 2) <= x"00000000";
theRegisters( 3) <= x"00000000";
theRegisters( 4) <= x"00000000";
theRegisters( 5) <= x"00000000";
theRegisters( 6) <= x"00000000";
theRegisters( 7) <= x"00000000";
theRegisters( 8) <= x"00000000";
theRegisters( 9) <= x"00000000";
theRegisters(10) <= x"00000000";
theRegisters(11) <= x"00000000";
theRegisters(12) <= x"00000000";
theRegisters(13) <= x"00000000"; -- SP
theRegisters(14) <= x"00000000"; -- LR
theRegisters(15) <= x"00000000"; -- PC
cpsrRegister <= x"00000000";
cpuState <= STATE_RESET0;
writeL <= '1';
writeH <= '1';
LDMread <= x"00";
addrMux <= ADDR_PC;
address <= x"00000000";
irq_d <= '1';
irqRequest <= '0';
unitControl2 <= "0000000";
else
irq_d <= irq;
if (irq = '0') and (irq_d = '1') then --and (flagI = '0') then -- irq falling edge ?
irqRequest <= '1';
end if;
case cpuState is
when STATE_RESET0 => -- ##################################################
theRegisters(13)(15 downto 0) <= datain; -- STACK low
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_RESET1;
when STATE_RESET1 => -- ##################################################
theRegisters(13)(31 downto 16) <= datain; -- STACK high
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_RESET2;
when STATE_RESET2 => -- ##################################################
address(15 downto 0) <= datain and x"FFFE"; -- PC low make even address
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_RESET3;
when STATE_RESET3 => -- ##################################################
theRegisters(15) <= datain & address(15 downto 0); -- PC high
cpuState <= STATE_FETCH;
when STATE_IRQ => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= cpsrRegister(15 downto 0);
cpuState <= STATE_IRQ1;
when STATE_IRQ1 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(15)(31 downto 16);
cpuState <= STATE_IRQ2;
when STATE_IRQ2 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(15)(15 downto 0);
cpuState <= STATE_IRQ3;
when STATE_IRQ3 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(14)(31 downto 16); -- ??? FFFFFFF9
cpuState <= STATE_IRQ4;
when STATE_IRQ4 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(14)(15 downto 0); -- ??? FFFFFFF9
cpuState <= STATE_IRQ5;
when STATE_IRQ5 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(12)(31 downto 16);
cpuState <= STATE_IRQ6;
when STATE_IRQ6 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(12)(15 downto 0);
cpuState <= STATE_IRQ7;
when STATE_IRQ7 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_IRQ8;
when STATE_IRQ8 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(3)(15 downto 0);
cpuState <= STATE_IRQ9;
when STATE_IRQ9 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_IRQ10;
when STATE_IRQ10 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(2)(15 downto 0);
cpuState <= STATE_IRQ11;
when STATE_IRQ11 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_IRQ12;
when STATE_IRQ12 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(1)(15 downto 0);
cpuState <= STATE_IRQ13;
when STATE_IRQ13 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_IRQ14;
when STATE_IRQ14 => -- ####################################################
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(0)(15 downto 0);
cpuState <= STATE_IRQ15;
when STATE_IRQ15 => -- ####################################################
writeL <= '1';
writeH <= '1';
theRegisters(14) <= x"FFFFFFF9"; -- exception return value
address <= x"00000008"; -- NMI vector
addrMux <= ADDR_RS;
cpuState <= STATE_IRQ16;
when STATE_IRQ16 => -- ###################################################
theRegisters(15)(15 downto 0) <= datain and x"FFFE";
address <= address + 2;
cpuState <= STATE_IRQ17;
when STATE_IRQ17 => -- ###################################################
theRegisters(15)(31 downto 16) <= datain;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when STATE_RET => -- #####################################################
addrMux <= ADDR_SP;
cpuState <= STATE_RET1;
when STATE_RET1 => -- #####################################################
theRegisters(0)(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET2;
when STATE_RET2 => -- #####################################################
theRegisters(0)(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET3;
when STATE_RET3 => -- #####################################################
theRegisters(1)(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET4;
when STATE_RET4 => -- #####################################################
theRegisters(1)(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET5;
when STATE_RET5 => -- #####################################################
theRegisters(2)(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET6;
when STATE_RET6 => -- #####################################################
theRegisters(2)(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET7;
when STATE_RET7 => -- #####################################################
theRegisters(3)(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET8;
when STATE_RET8 => -- #####################################################
theRegisters(3)(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET9;
when STATE_RET9 => -- #####################################################
theRegisters(12)(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET10;
when STATE_RET10 => -- #####################################################
theRegisters(12)(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET11;
when STATE_RET11 => -- #####################################################
theRegisters(14)(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET12;
when STATE_RET12 => -- #####################################################
theRegisters(14)(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET13;
when STATE_RET13 => -- #####################################################
theRegisters(15)(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET14;
when STATE_RET14 => -- #####################################################
theRegisters(15)(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET15;
when STATE_RET15 => -- #####################################################
cpsrRegister(15 downto 0) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
cpuState <= STATE_RET16;
when STATE_RET16 => -- #####################################################
cpsrRegister(31 downto 16) <= datain;
theRegisters(13) <= theRegisters(13) + 2;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when STATE_FETCH => -- ###################################################
unitControl2 <= unitControl;
opcode <= datain;
if irqrequest = '1' then -- irq ???
irqrequest <= '0';
cpuState <= STATE_IRQ;
theRegisters(13) <= theRegisters(13) - 2;
addrMux <= ADDR_SP;
dataout <= cpsrRegister(31 downto 16);
writeL <= '0';
writeH <= '0';
else
case unitControl is
when CODE_LSL1 | CODE_LSR1 | CODE_ASR1 |
CODE_LSL2 | CODE_LSR2 | CODE_ASR2 |
CODE_ROR1 =>
theRegisters(datain20) <= shiftResult;
cpsrRegister(N_FLAG) <= shiftResult(31);
if shiftResult = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
cpsrRegister(C_FLAG) <= cyShiftOut;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_CPY1 => -- Rd = Rm
if (datain(7) & datain(2 downto 0) = "1111") then
theRegisters(conv_integer(datain(7) & datain(2 downto 0))) <=
theRegisters(conv_integer(datain(6 downto 3)));
else
theRegisters(conv_integer(datain(7) & datain(2 downto 0))) <=
theRegisters(conv_integer(datain(6 downto 3)));
theRegisters(15) <= theRegisters(15) + 2;
end if;
when CODE_ADD4 => -- Rd = Rd + Rm
if (datain(7) & datain(2 downto 0) = "1111") then
theRegisters(conv_integer(datain(7) & datain(2 downto 0))) <=
theRegisters(conv_integer(datain(7) & datain(2 downto 0))) +
theRegisters(conv_integer(datain(6 downto 3)));
else
theRegisters(conv_integer(datain(7) & datain(2 downto 0))) <=
theRegisters(conv_integer(datain(7) & datain(2 downto 0))) +
theRegisters(conv_integer(datain(6 downto 3)));
theRegisters(15) <= theRegisters(15) + 2;
end if;
when CODE_ADD6 => -- Rn = SP + imm
theRegisters(datain108) <=
theRegisters(13) +
(x"00000" & "00" & datain(7 downto 0) & "00");
theRegisters(15) <= theRegisters(15) + 2;
when CODE_ADD7 => -- SP = SP + imm
theRegisters(13) <= theRegisters(13) +
(x"00000" & "000" & datain(6 downto 0) & "00");
theRegisters(15) <= theRegisters(15) + 2;
when CODE_SUB4 => -- SP = SP - imm
theRegisters(13) <= theRegisters(13) -
(x"00000" & "000" & datain(6 downto 0) & "00");
theRegisters(15) <= theRegisters(15) + 2;
when CODE_ADD1 =>
tres := ("0" & theRegisters(datain53)) +
("0" & theRegisters(datain86));
theRegisters(datain20) <=
theRegisters(datain53) +
theRegisters(datain86);
cpsrRegister(C_FLAG) <= tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain53)(31);
op2 := theRegisters(datain86)(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and op2 and not opr) or
(not op1 and not op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_SUB1 =>
tres := ("0" & theRegisters(datain53)) -
("0" & theRegisters(datain86));
theRegisters(datain20) <=
theRegisters(datain53) -
theRegisters(datain86);
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain53)(31);
op2 := theRegisters(datain86)(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_ADD2 =>
tres := ("0" & theRegisters(datain53)) +
("0" & x"0000000" & "0" & datain(8 downto 6));
theRegisters(datain20) <=
theRegisters(datain53) +
(x"0000000" & "0" & datain(8 downto 6));
cpsrRegister(C_FLAG) <= tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain53)(31);
op2 := '0';
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and op2 and not opr) or
(not op1 and not op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_SUB2 =>
tres := ("0" & theRegisters(datain53)) -
("0" & x"0000000" & "0" & datain(8 downto 6));
theRegisters(datain20) <=
theRegisters(datain53) -
(x"0000000" & "0" & datain(8 downto 6));
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain53)(31);
op2 := '0';
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_MOV1 =>
tres := "0" & x"000000" & datain(7 downto 0);
theRegisters(datain108) <= x"000000" & datain(7 downto 0);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_CMP1 =>
tres := ("0" & theRegisters(datain108)) -
("0" & x"000000" & datain(7 downto 0));
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain108)(31);
op2 := '0';
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_ADD3 =>
tres := ("0" & theRegisters(datain108)) +
("0" & x"000000" & datain(7 downto 0));
theRegisters(datain108) <=
theRegisters(datain108) +
(x"000000" & datain(7 downto 0));
cpsrRegister(C_FLAG) <= tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain108)(31);
op2 := '0';
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and op2 and not opr) or
(not op1 and not op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_SUB3 =>
tres := ("0" & theRegisters(datain108)) -
("0" & x"000000" & datain(7 downto 0));
theRegisters(datain108) <=
theRegisters(datain108) -
(x"000000" & datain(7 downto 0));
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain108)(31);
op2 := '0';
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_AND1 =>
tres := ("0" & theRegisters(datain20)) and
("0" & theRegisters(datain53));
theRegisters(datain20) <=
theRegisters(datain20) and
theRegisters(datain53);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_EOR1 =>
tres := ("0" & theRegisters(datain20)) xor
("0" & theRegisters(datain53));
theRegisters(datain20) <=
theRegisters(datain20) xor
theRegisters(datain53);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_ADC1 =>
tres := ("0" & theRegisters(datain20)) +
("0" & theRegisters(datain53)) +
(x"00000000" & cpsrRegister(C_FLAG));
theRegisters(datain20) <=
theRegisters(datain20) +
theRegisters(datain53) +
("000" & x"0000000" & cpsrRegister(C_FLAG));
cpsrRegister(C_FLAG) <= tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain20)(31);
op2 := theRegisters(datain53)(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and op2 and not opr) or
(not op1 and not op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_SBC1 =>
tres := ("0" & theRegisters(datain20)) -
("0" & theRegisters(datain53)) -
("000" & x"0000000" & (not cpsrRegister(C_FLAG)));
theRegisters(datain20) <=
theRegisters(datain20) -
theRegisters(datain53) -
("000" & x"0000000" & (not cpsrRegister(C_FLAG)));
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain20)(31);
op2 := theRegisters(datain53)(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_TST1 =>
tres := ("0" & theRegisters(datain20)) and
("0" & theRegisters(datain53));
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_NEG1 =>
tres := ("0" & x"00000000") -
("0" & theRegisters(datain53));
theRegisters(datain20) <=
x"00000000" -
theRegisters(datain53);
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain20)(31);
op2 := theRegisters(datain53)(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_CMP2 =>
tres := ("0" & theRegisters(datain20)) -
("0" & theRegisters(datain53));
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain20)(31);
op2 := theRegisters(datain53)(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_CMN1 =>
tres := ("0" & theRegisters(datain20)) +
("0" & theRegisters(datain53));
cpsrRegister(C_FLAG) <= tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(datain20)(31);
op2 := theRegisters(datain53)(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and op2 and not opr) or
(not op1 and not op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_ORR1 =>
tres := ("0" & theRegisters(datain20)) or
("0" & theRegisters(datain53));
theRegisters(datain20) <=
theRegisters(datain20) or
theRegisters(datain53);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_MUL1 =>
theRegisters(datain20) <= product(31 downto 0);
cpsrRegister(N_FLAG) <= product(31);
if product(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_BIC1 =>
tres := ("0" & theRegisters(datain20)) and
not ("0" & theRegisters(datain53));
theRegisters(datain20) <=
theRegisters(datain20) and
not theRegisters(datain53);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_MVN1 =>
tres := not ("0" & theRegisters(datain53));
theRegisters(datain20) <=
not theRegisters(datain53);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
theRegisters(15) <= theRegisters(15) + 2;
when CODE_CMP3 =>
tres := ("0" & theRegisters(conv_integer(datain(7) & datain(2 downto 0)))) -
("0" & theRegisters(conv_integer(datain(6) & datain(5 downto 3))));
cpsrRegister(C_FLAG) <= not tres(32);
cpsrRegister(N_FLAG) <= tres(31);
if tres(31 downto 0) = 0 then
cpsrRegister(Z_FLAG) <= '1';
else
cpsrRegister(Z_FLAG) <= '0';
end if;
op1 := theRegisters(conv_integer(datain(7) & datain(2 downto 0)))(31);
op2 := theRegisters(conv_integer(datain(6) & datain(5 downto 3)))(31);
opr := tres(31);
cpsrRegister(V_FLAG) <= (op1 and not op2 and not opr) or
(not op1 and op2 and opr);
theRegisters(15) <= theRegisters(15) + 2;
when CODE_BX1 =>
if theRegisters(14) = x"FFFFFFF9" then -- EXC_RETURN ?
if datain(6 downto 3) = "1110" then
cpuState <= STATE_RET;
else
theRegisters(15) <= theRegisters(conv_integer(datain(6 downto 3)))(31 downto 1) & "0";
theRegisters(14) <= theRegisters(15) + 2;
end if;
else
theRegisters(15) <= theRegisters(conv_integer(datain(6 downto 3)))(31 downto 1) & "0";
if datain(6 downto 3) /= "1110" then
theRegisters(14) <= theRegisters(15) + 2;
end if;
end if;
when CODE_LDR1 =>
address <= (theRegisters(15) and x"FFFFFFFC") +
(x"00000" & "00" & datain(7 downto 0) & "00") + x"00000004";
addrMux <= ADDR_RS;
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_READ1;
when CODE_LDR4 =>
address <= theRegisters(13) +
(x"00000" & "00" & datain(7 downto 0) & "00");
addrMux <= ADDR_RS;
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_READ1;
when CODE_STR1 | CODE_STRH1 =>
address <= theRegisters(datain53) +
theRegisters(datain86);
addrMux <= ADDR_RS;
writeL <= '0';
writeH <= '0';
dataout <= theRegisters(datain20)(15 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_WRITE1;
when CODE_STRB1 =>
address <= theRegisters(datain53) +
theRegisters(datain86);
tsum := theRegisters(datain53) +
theRegisters(datain86);
addrMux <= ADDR_RS;
if tsum(0) = '0' then
writeL <= '0';
writeH <= '1';
else
writeL <= '1';
writeH <= '0';
end if;
dataout <= theRegisters(datain20)(7 downto 0) &
theRegisters(datain20)(7 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_WRITE1;
when CODE_LDRSB1 | CODE_LDR2 | CODE_LDRH1 | CODE_LDRB1 | CODE_LDRSH1 =>
address <= theRegisters(datain53) +
theRegisters(datain86);
addrMux <= ADDR_RS;
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_READ1;
when CODE_STR2 =>
address <= theRegisters(datain53) +
(x"000000" & "0" & datain(10 downto 6) & "00");
addrMux <= ADDR_RS;
writeL <= '0';
writeH <= '0';
dataout <= theRegisters(datain20)(15 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_WRITE1;
when CODE_LDR3 =>
address <= theRegisters(datain53) +
(x"000000" & "0" & datain(10 downto 6) & "00");
addrMux <= ADDR_RS;
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_READ1;
when CODE_STRB2 =>
address <= theRegisters(datain53) +
(x"000000" & "000" & datain(10 downto 6));
tsum := theRegisters(datain53) +
(x"000000" & "000" & datain(10 downto 6));
addrMux <= ADDR_RS;
if tsum(0) = '0' then
writeL <= '0';
writeH <= '1';
else
writeL <= '1';
writeH <= '0';
end if;
dataout <= theRegisters(datain20)(7 downto 0) &
theRegisters(datain20)(7 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_WRITE1;
when CODE_LDRB2 =>
address <= theRegisters(datain53) +
(x"000000" & "000" & datain(10 downto 6));
addrMux <= ADDR_RS;
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_READ1;
when CODE_LDRH2 =>
address <= theRegisters(datain53) +
(x"000000" & "00" & datain(10 downto 6) & "0");
addrMux <= ADDR_RS;
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_READ1;
when CODE_STRH2 =>
address <= theRegisters(datain53) +
(x"000000" & "00" & datain(10 downto 6) & "0");
addrMux <= ADDR_RS;
writeL <= '0';
writeH <= '0';
dataout <= theRegisters(datain20)(15 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_WRITE1;
when CODE_STR3 =>
address <= theRegisters(13) +
(x"00000" & "00" & datain(7 downto 0) & "00");
addrMux <= ADDR_RS;
writeL <= '0';
writeH <= '0';
dataout <= theRegisters(datain108)(15 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_WRITE1;
when CODE_ADD5 =>
theRegisters(datain108) <=
theRegisters(15) + (x"00000" & "00" & datain(7 downto 0) & "00");
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_FETCH;
when CODE_SXTH1 =>
theRegisters(datain20) <=
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15) &
theRegisters(datain53)(15 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_FETCH;
when CODE_SXTB1 =>
theRegisters(datain20) <=
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7) &
theRegisters(datain53)(7 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_FETCH;
when CODE_UXTH1 =>
theRegisters(datain20) <= x"0000" &
theRegisters(datain53)(15 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_FETCH;
when CODE_UXTB1 =>
theRegisters(datain20) <= x"000000" &
theRegisters(datain53)(7 downto 0);
theRegisters(15) <= theRegisters(15) + 2;
cpuState <= STATE_FETCH;
when CODE_PUSH1 =>
theRegisters(15) <= theRegisters(15) + 2;
if datain(8 downto 0) = 0 then
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
addrMux <= ADDR_SP;
writeL <= '0';
writeH <= '0';
if datain(8) = '1' then
dataout <= theRegisters(14)(31 downto 16);
cpuState <= STATE_WRPH;
elsif datain(7) = '1' then
dataout <= theRegisters(7)(31 downto 16);
cpuState <= STATE_WR7H;
elsif datain(6) = '1' then
dataout <= theRegisters(6)(31 downto 16);
cpuState <= STATE_WR6H;
elsif datain(5) = '1' then
dataout <= theRegisters(5)(31 downto 16);
cpuState <= STATE_WR5H;
elsif datain(4) = '1' then
dataout <= theRegisters(4)(31 downto 16);
cpuState <= STATE_WR4H;
elsif datain(3) = '1' then
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_WR3H;
elsif datain(2) = '1' then
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2H;
elsif datain(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when CODE_POP1 =>
theRegisters(15) <= theRegisters(15) + 2;
if datain(8 downto 0) = 0 then
cpuState <= STATE_FETCH;
else
addrMux <= ADDR_SP;
if datain(0) = '1' then
cpuState <= STATE_RD0L;
elsif datain(1) = '1' then
cpuState <= STATE_RD1L;
elsif datain(2) = '1' then
cpuState <= STATE_RD2L;
elsif datain(3) = '1' then
cpuState <= STATE_RD3L;
elsif datain(4) = '1' then
cpuState <= STATE_RD4L;
elsif datain(5) = '1' then
cpuState <= STATE_RD5L;
elsif datain(6) = '1' then
cpuState <= STATE_RD6L;
elsif datain(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_NOP =>
theRegisters(15) <= theRegisters(15) + 2;
when CODE_STMIA1 =>
theRegisters(15) <= theRegisters(15) + 2;
if datain(7 downto 0) = 0 then
cpuState <= STATE_FETCH;
else
address <= theRegisters(datain108);
addrMux <= ADDR_RS;
writeL <= '0';
writeH <= '0';
if datain(0) = '1' then
dataout <= theRegisters(0)(15 downto 0);
cpuState <= STATE_WR0H;
elsif datain(1) = '1' then
dataout <= theRegisters(1)(15 downto 0);
cpuState <= STATE_WR1H;
elsif datain(2) = '1' then
dataout <= theRegisters(2)(15 downto 0);
cpuState <= STATE_WR2H;
elsif datain(3) = '1' then
dataout <= theRegisters(3)(15 downto 0);
cpuState <= STATE_WR3H;
elsif datain(4) = '1' then
dataout <= theRegisters(4)(15 downto 0);
cpuState <= STATE_WR4H;
elsif datain(5) = '1' then
dataout <= theRegisters(5)(15 downto 0);
cpuState <= STATE_WR5H;
elsif datain(6) = '1' then
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6H;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
end if;
when CODE_LDMIA1 =>
LDMread <= x"00";
theRegisters(15) <= theRegisters(15) + 2;
if datain(7 downto 0) = 0 then
cpuState <= STATE_FETCH;
else
address <= theRegisters(datain108);
addrMux <= ADDR_RS;
if datain(0) = '1' then
cpuState <= STATE_RD0L;
elsif datain(1) = '1' then
cpuState <= STATE_RD1L;
elsif datain(2) = '1' then
cpuState <= STATE_RD2L;
elsif datain(3) = '1' then
cpuState <= STATE_RD3L;
elsif datain(4) = '1' then
cpuState <= STATE_RD4L;
elsif datain(5) = '1' then
cpuState <= STATE_RD5L;
elsif datain(6) = '1' then
cpuState <= STATE_RD6L;
else
cpuState <= STATE_RD7L;
end if;
end if;
when CODE_BCC1 =>
if branch = '1' then
theRegisters(15) <= theRegisters(15) + (
datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) &
datain(7 downto 0) & "0") + x"00000004";
else
theRegisters(15) <= theRegisters(15) + 2;
end if;
when CODE_B1 =>
theRegisters(15) <= theRegisters(15) + (
datain(10) & datain(10) & datain(10) & datain(10) &
datain(10) & datain(10) & datain(10) & datain(10) &
datain(10) & datain(10) & datain(10) & datain(10) &
datain(10) & datain(10) & datain(10) & datain(10) &
datain(10) & datain(10) & datain(10) & datain(10) &
datain(10 downto 0) & "0") + x"00000004";
when CODE_BLX2 =>
theRegisters(14) <= theRegisters(15) + (
datain(10) & datain(10) & datain(10) & datain(10) &
datain(10) & datain(10) & datain(10) & datain(10) &
datain(10) &
datain(10 downto 0) & x"000") + x"00000004";
theRegisters(15) <= theRegisters(15) + 2;
when CODE_BL1 =>
theRegisters(15) <= theRegisters(14) + (x"00000" &
datain(10 downto 0) & "0");
theRegisters(14) <= theRegisters(15) + 2;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl
end if; -- irqrequest
when STATE_READ1 => -- ##################################################
case unitControl2 is
when CODE_LDRH1 | CODE_LDRH2 =>
theRegisters(opcode20)(15 downto 0) <= datain;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when CODE_LDRSH1 =>
theRegisters(opcode20)(15 downto 0) <= datain;
theRegisters(opcode20)(31 downto 16) <=
datain(15) & datain(15) & datain(15) & datain(15) & datain(15) & datain(15) &
datain(15) & datain(15) & datain(15) & datain(15) & datain(15) & datain(15) &
datain(15) & datain(15) & datain(15) & datain(15);
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when CODE_LDR1 | CODE_LDR4 =>
theRegisters(opcode108)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_READ2;
when CODE_LDR2 | CODE_LDR3 =>
theRegisters(opcode20)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_READ2;
when CODE_LDRSB1 =>
if address(0) = '0' then
theRegisters(opcode20)(7 downto 0) <= datain(7 downto 0);
theRegisters(opcode20)(31 downto 8) <=
datain(7) & datain(7) & datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) & datain(7) & datain(7) & datain(7) &
datain(7) & datain(7) & datain(7) & datain(7) & datain(7) & datain(7);
else
theRegisters(opcode20)(7 downto 0) <= datain(15 downto 8);
theRegisters(opcode20)(31 downto 8) <=
datain(15) & datain(15) & datain(15) & datain(15) & datain(15) & datain(15) &
datain(15) & datain(15) & datain(15) & datain(15) & datain(15) & datain(15) &
datain(15) & datain(15) & datain(15) & datain(15) & datain(15) & datain(15) &
datain(15) & datain(15) & datain(15) & datain(15) & datain(15) & datain(15);
end if;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when CODE_LDRB1 | CODE_LDRB2 =>
if address(0) = '0' then
theRegisters(opcode20)(7 downto 0) <= datain(7 downto 0);
else
theRegisters(opcode20)(7 downto 0) <= datain(15 downto 8);
end if;
theRegisters(opcode20)(31 downto 8) <= x"000000";
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_READ2 => -- ##################################################
case unitControl2 is
when CODE_LDR1 | CODE_LDR4 =>
theRegisters(opcode108)(31 downto 16) <= datain;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when CODE_LDR2 | CODE_LDR3 =>
theRegisters(opcode20)(31 downto 16) <= datain;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_RD0L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(0)(15 downto 0) <= datain;
cpuState <= STATE_RD0H;
when CODE_LDMIA1 =>
LDMread(0) <= '1';
theRegisters(0)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD0H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_RD0H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(0)(31 downto 16) <= datain;
if opcode(8 downto 1) = 0 then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
if opcode(1) = '1' then
cpuState <= STATE_RD1L;
elsif opcode(2) = '1' then
cpuState <= STATE_RD2L;
elsif opcode(3) = '1' then
cpuState <= STATE_RD3L;
elsif opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
elsif opcode(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
if opcode(7 downto 1) = 0 then
addrMux <= ADDR_PC;
if opcode108 = 0 then
theRegisters(0)(31 downto 16) <= datain;
else
theRegisters(opcode108) <= address + 2;
end if;
cpuState <= STATE_FETCH;
else
theRegisters(0)(31 downto 16) <= datain;
if opcode(1) = '1' then
cpuState <= STATE_RD1L;
elsif opcode(2) = '1' then
cpuState <= STATE_RD2L;
elsif opcode(3) = '1' then
cpuState <= STATE_RD3L;
elsif opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
else
cpuState <= STATE_RD7L;
end if;
end if;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_RD1L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(1)(15 downto 0) <= datain;
cpuState <= STATE_RD1H;
when CODE_LDMIA1 =>
LDMread(1) <= '1';
theRegisters(1)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD1H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD1H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(1)(31 downto 16) <= datain;
if opcode(8 downto 2) = 0 then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
if opcode(2) = '1' then
cpuState <= STATE_RD2L;
elsif opcode(3) = '1' then
cpuState <= STATE_RD3L;
elsif opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
elsif opcode(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
if opcode(7 downto 2) = 0 then
theRegisters(1)(31 downto 16) <= datain;
if opcode108 /= 1 then
if LDMread(opcode108) /= '1' then
theRegisters(opcode108) <= address + 2;
end if;
end if;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(1)(31 downto 16) <= datain;
if opcode(2) = '1' then
cpuState <= STATE_RD2L;
elsif opcode(3) = '1' then
cpuState <= STATE_RD3L;
elsif opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
else
cpuState <= STATE_RD7L;
end if;
end if;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD2L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(2)(15 downto 0) <= datain;
cpuState <= STATE_RD2H;
when CODE_LDMIA1 =>
LDMread(2) <= '1';
theRegisters(2)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD2H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD2H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(2)(31 downto 16) <= datain;
if opcode(8 downto 3) = 0 then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
if opcode(3) = '1' then
cpuState <= STATE_RD3L;
elsif opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
elsif opcode(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
if opcode(7 downto 3) = 0 then
addrMux <= ADDR_PC;
theRegisters(2)(31 downto 16) <= datain;
if opcode108 /= 2 then
if LDMread(opcode108) /= '1' then
theRegisters(opcode108) <= address + 2;
end if;
end if;
cpuState <= STATE_FETCH;
else
theRegisters(2)(31 downto 16) <= datain;
if opcode(3) = '1' then
cpuState <= STATE_RD3L;
elsif opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
else
cpuState <= STATE_RD7L;
end if;
end if;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD3L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(3)(15 downto 0) <= datain;
cpuState <= STATE_RD3H;
when CODE_LDMIA1 =>
LDMread(3) <= '1';
theRegisters(3)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD3H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD3H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(3)(31 downto 16) <= datain;
if opcode(8 downto 4) = 0 then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
if opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
elsif opcode(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
if opcode(7 downto 4) = 0 then
addrMux <= ADDR_PC;
theRegisters(3)(31 downto 16) <= datain;
if opcode108 /= 3 then
if LDMread(opcode108) /= '1' then
theRegisters(opcode108) <= address + 2;
end if;
end if;
cpuState <= STATE_FETCH;
else
theRegisters(3)(31 downto 16) <= datain;
if opcode(4) = '1' then
cpuState <= STATE_RD4L;
elsif opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
else
cpuState <= STATE_RD7L;
end if;
end if;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD4L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(4)(15 downto 0) <= datain;
cpuState <= STATE_RD4H;
when CODE_LDMIA1 =>
LDMread(4) <= '1';
theRegisters(4)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD4H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD4H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(4)(31 downto 16) <= datain;
if opcode(8 downto 5) = 0 then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
if opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
elsif opcode(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
if opcode(7 downto 5) = 0 then
addrMux <= ADDR_PC;
theRegisters(4)(31 downto 16) <= datain;
if opcode108 /= 4 then
if LDMread(opcode108) /= '1' then
theRegisters(opcode108) <= address + 2;
end if;
end if;
cpuState <= STATE_FETCH;
else
theRegisters(4)(31 downto 16) <= datain;
if opcode(5) = '1' then
cpuState <= STATE_RD5L;
elsif opcode(6) = '1' then
cpuState <= STATE_RD6L;
else
cpuState <= STATE_RD7L;
end if;
end if;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD5L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(5)(15 downto 0) <= datain;
cpuState <= STATE_RD5H;
when CODE_LDMIA1 =>
LDMread(5) <= '1';
theRegisters(5)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD5H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD5H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(5)(31 downto 16) <= datain;
if opcode(8 downto 6) = 0 then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
if opcode(6) = '1' then
cpuState <= STATE_RD6L;
elsif opcode(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
if opcode(7 downto 6) = 0 then
addrMux <= ADDR_PC;
theRegisters(5)(31 downto 16) <= datain;
if opcode108 /= 5 then
if LDMread(opcode108) /= '1' then
theRegisters(opcode108) <= address + 2;
end if;
end if;
cpuState <= STATE_FETCH;
else
theRegisters(5)(31 downto 16) <= datain;
if opcode(6) = '1' then
cpuState <= STATE_RD6L;
else
cpuState <= STATE_RD7L;
end if;
end if;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD6L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(6)(15 downto 0) <= datain;
cpuState <= STATE_RD6H;
when CODE_LDMIA1 =>
LDMread(7) <= '1';
theRegisters(6)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD6H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD6H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(6)(31 downto 16) <= datain;
if opcode(8 downto 7) = 0 then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
if opcode(7) = '1' then
cpuState <= STATE_RD7L;
else
cpuState <= STATE_RDPL;
end if;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
if opcode(7) = '0' then
addrMux <= ADDR_PC;
theRegisters(6)(31 downto 16) <= datain;
if opcode108 /= 6 then
if LDMread(opcode108) /= '1' then
theRegisters(opcode108) <= address + 2;
end if;
end if;
cpuState <= STATE_FETCH;
else
theRegisters(6)(31 downto 16) <= datain;
cpuState <= STATE_RD7L;
end if;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD7L => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(7)(15 downto 0) <= datain;
cpuState <= STATE_RD7H;
when CODE_LDMIA1 =>
LDMread(7) <= '1';
theRegisters(7)(15 downto 0) <= datain;
address <= address + 2;
cpuState <= STATE_RD7H;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RD7H => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(7)(31 downto 16) <= datain;
if opcode(8) = '0' then
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
cpuState <= STATE_RDPL;
end if;
when CODE_LDMIA1 =>
address <= address + 2;
theRegisters(7)(31 downto 16) <= datain;
if opcode108 /= 7 then
if LDMread(opcode108) /= '1' then
theRegisters(opcode108) <= address + 2;
end if;
end if;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RDPL => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
if theRegisters(14) = x"FFFFFFF9" then
cpuState <= STATE_RET;
else
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(15)(15 downto 0) <= datain;
cpuState <= STATE_RDPH;
end if;
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_RDPH => -- ##################################################
case unitControl2 is
when CODE_POP1 =>
theRegisters(13) <= theRegisters(13) + 2;
theRegisters(15)(31 downto 16) <= datain;
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
 
 
when STATE_WRITE1 => -- ##################################################
case unitControl2 is
when CODE_STR1 | CODE_STR2 =>
address <= address + 2;
dataout <= theRegisters(opcode20)(31 downto 16);
cpuState <= STATE_WRITE2;
when CODE_STRH1 | CODE_STRB1 | CODE_STRB2 | CODE_STRH2 =>
addrMux <= ADDR_PC;
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
when CODE_STR3 =>
address <= address + 2;
dataout <= theRegisters(opcode108)(31 downto 16);
cpuState <= STATE_WRITE2;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WRITE2 => -- ##################################################
case unitControl2 is
when CODE_STR1 | CODE_STR2 | CODE_STR3 =>
addrMux <= ADDR_PC;
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
 
when others =>
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WRPH => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(14)(15 downto 0);
cpuState <= STATE_WRPL;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WRPL => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(7 downto 0) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
if opcode(7) = '1' then
dataout <= theRegisters(7)(31 downto 16);
cpuState <= STATE_WR7H;
elsif opcode(6) = '1' then
dataout <= theRegisters(6)(31 downto 16);
cpuState <= STATE_WR6H;
elsif opcode(5) = '1' then
dataout <= theRegisters(5)(31 downto 16);
cpuState <= STATE_WR5H;
elsif opcode(4) = '1' then
dataout <= theRegisters(4)(31 downto 16);
cpuState <= STATE_WR4H;
elsif opcode(3) = '1' then
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_WR3H;
elsif opcode(2) = '1' then
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2H;
elsif opcode(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR7H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(7)(31 downto 16);
cpuState <= STATE_WR7L;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR7L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(6 downto 0) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
if opcode(6) = '1' then
dataout <= theRegisters(6)(31 downto 16);
cpuState <= STATE_WR6H;
elsif opcode(5) = '1' then
dataout <= theRegisters(5)(31 downto 16);
cpuState <= STATE_WR5H;
elsif opcode(4) = '1' then
dataout <= theRegisters(4)(31 downto 16);
cpuState <= STATE_WR4H;
elsif opcode(3) = '1' then
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_WR3H;
elsif opcode(2) = '1' then
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2H;
elsif opcode(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when CODE_STMIA1 =>
address <= address + 2;
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR6H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(6)(31 downto 16);
cpuState <= STATE_WR6L;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR6L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(5 downto 0) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
if opcode(5) = '1' then
dataout <= theRegisters(5)(31 downto 16);
cpuState <= STATE_WR5H;
elsif opcode(4) = '1' then
dataout <= theRegisters(4)(31 downto 16);
cpuState <= STATE_WR4H;
elsif opcode(3) = '1' then
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_WR3H;
elsif opcode(2) = '1' then
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2H;
elsif opcode(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when CODE_STMIA1 =>
address <= address + 2;
if opcode(7) = '0' then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WR5H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(5)(15 downto 0);
cpuState <= STATE_WR5L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(5)(31 downto 16);
cpuState <= STATE_WR5L;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR5L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(4 downto 0) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
if opcode(4) = '1' then
dataout <= theRegisters(4)(31 downto 16);
cpuState <= STATE_WR4H;
elsif opcode(3) = '1' then
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_WR3H;
elsif opcode(2) = '1' then
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2H;
elsif opcode(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when CODE_STMIA1 =>
address <= address + 2;
if opcode(7 downto 6) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
else
if opcode(6) = '1' then
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6H;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WR4H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(4)(15 downto 0);
cpuState <= STATE_WR4L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(4)(31 downto 16);
cpuState <= STATE_WR4L;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR4L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(3 downto 0) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
if opcode(3) = '1' then
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_WR3H;
elsif opcode(2) = '1' then
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2H;
elsif opcode(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when CODE_STMIA1 =>
address <= address + 2;
if opcode(7 downto 5) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
else
if opcode(5) = '1' then
dataout <= theRegisters(5)(15 downto 0);
cpuState <= STATE_WR5H;
elsif opcode(6) = '1' then
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6H;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WR3H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(3)(15 downto 0);
cpuState <= STATE_WR3L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(3)(31 downto 16);
cpuState <= STATE_WR3L;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR3L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(2 downto 0) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
if opcode(2) = '1' then
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2H;
elsif opcode(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when CODE_STMIA1 =>
address <= address + 2;
if opcode(7 downto 4) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
else
if opcode(4) = '1' then
dataout <= theRegisters(4)(15 downto 0);
cpuState <= STATE_WR4H;
elsif opcode(5) = '1' then
dataout <= theRegisters(5)(15 downto 0);
cpuState <= STATE_WR5H;
elsif opcode(6) = '1' then
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6H;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WR2H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(2)(15 downto 0);
cpuState <= STATE_WR2L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(2)(31 downto 16);
cpuState <= STATE_WR2L;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR2L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(1 downto 0) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
if opcode(1) = '1' then
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1H;
else
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
end if;
when CODE_STMIA1 =>
address <= address + 2;
if opcode(7 downto 3) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
else
if opcode(3) = '1' then
dataout <= theRegisters(3)(15 downto 0);
cpuState <= STATE_WR3H;
elsif opcode(4) = '1' then
dataout <= theRegisters(4)(15 downto 0);
cpuState <= STATE_WR4H;
elsif opcode(5) = '1' then
dataout <= theRegisters(5)(15 downto 0);
cpuState <= STATE_WR5H;
elsif opcode(6) = '1' then
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6H;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WR1H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(1)(15 downto 0);
cpuState <= STATE_WR1L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(1)(31 downto 16);
cpuState <= STATE_WR1L;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR1L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
if opcode(0) = '0' then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
else
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0H;
end if;
when CODE_STMIA1 =>
address <= address + 2;
if opcode(7 downto 2) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
else
if opcode(2) = '1' then
dataout <= theRegisters(2)(15 downto 0);
cpuState <= STATE_WR2H;
elsif opcode(3) = '1' then
dataout <= theRegisters(3)(15 downto 0);
cpuState <= STATE_WR3H;
elsif opcode(4) = '1' then
dataout <= theRegisters(4)(15 downto 0);
cpuState <= STATE_WR4H;
elsif opcode(5) = '1' then
dataout <= theRegisters(5)(15 downto 0);
cpuState <= STATE_WR5H;
elsif opcode(6) = '1' then
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6H;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
 
when STATE_WR0H => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
theRegisters(13) <= theRegisters(13) - 2;
dataout <= theRegisters(0)(15 downto 0);
cpuState <= STATE_WR0L;
when CODE_STMIA1 =>
address <= address + 2;
dataout <= theRegisters(0)(31 downto 16);
cpuState <= STATE_WR0L;
 
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when STATE_WR0L => -- ##################################################
case unitControl2 is
when CODE_PUSH1 =>
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
cpuState <= STATE_FETCH;
when CODE_STMIA1 =>
address <= address + 2;
if opcode(7 downto 1) = 0 then
writeL <= '1';
writeH <= '1';
addrMux <= ADDR_PC;
theRegisters(opcode108) <= address + 2;
cpuState <= STATE_FETCH;
else
if opcode(1) = '1' then
dataout <= theRegisters(1)(15 downto 0);
cpuState <= STATE_WR1H;
elsif opcode(2) = '1' then
dataout <= theRegisters(2)(15 downto 0);
cpuState <= STATE_WR2H;
elsif opcode(3) = '1' then
dataout <= theRegisters(3)(15 downto 0);
cpuState <= STATE_WR3H;
elsif opcode(4) = '1' then
dataout <= theRegisters(4)(15 downto 0);
cpuState <= STATE_WR4H;
elsif opcode(5) = '1' then
dataout <= theRegisters(5)(15 downto 0);
cpuState <= STATE_WR5H;
elsif opcode(6) = '1' then
dataout <= theRegisters(6)(15 downto 0);
cpuState <= STATE_WR6H;
else
dataout <= theRegisters(7)(15 downto 0);
cpuState <= STATE_WR7H;
end if;
end if;
when others =>
writeL <= '1';
writeH <= '1';
cpuState <= STATE_FETCH;
end case; -- unitControl2
when others =>
cpuState <= STATE_FETCH;
end case; -- cpuState
end if; -- rst = '0'
end if; -- rising_edge(clk)
end process;
end behavior;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.