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; |