1
0
mirror of https://github.com/j-core/j-core-ice40.git synced 2026-01-11 23:52:49 +00:00

Import from the git version found in work/nickg on my trash can mac

This commit is contained in:
J 2019-03-03 14:48:57 -05:00
commit eaad427655
25 changed files with 4178 additions and 0 deletions

88
asymmetric_ram.vhd Normal file
View File

@ -0,0 +1,88 @@
-- An assemtric ram with a 16-bit wide read-only port and a 32-bit wide
-- read/write port.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity asymmetric_ram is
generic (
-- Bit width of the data addressed by the 16-bit read port. Addresses of
-- the 32-bit read/write port have one less bits.
ADDR_WIDTH : integer := 14
);
port (
clkA : in std_logic;
clkB : in std_logic;
enA : in std_logic;
addrA : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
doA : out std_logic_vector(15 downto 0);
enB : in std_logic;
weB : in std_logic_vector(3 downto 0);
addrB : in std_logic_vector(ADDR_WIDTH - 2 downto 0);
diB : in std_logic_vector(31 downto 0);
doB : out std_logic_vector(31 downto 0)
);
end asymmetric_ram;
architecture behavioral of asymmetric_ram is
constant NUM_WORDS : integer := 2**ADDR_WIDTH;
type ram_type is array (0 to NUM_WORDS-1) of std_logic_vector(15 downto 0);
impure function load_binary(filename : string) return ram_type is
type binary_file is file of character;
file f : binary_file;
variable c : character;
variable mem : ram_type;
begin
file_open(f, filename, read_mode);
for i in ram_type'range loop
mem(i) := (others => '0');
-- read 2 bytes and store in big endian order
for bi in 1 downto 0 loop
if not endfile(f) then
read(f, c);
mem(i)((bi+1)*8 - 1 downto bi*8) :=
std_logic_vector(to_unsigned(character'pos(c), 8));
end if;
end loop;
end loop;
file_close(f);
return mem;
end;
signal ram : ram_type := load_binary("ram.img");
begin
process (clkA)
begin
if clkA'event and clkA = '1' then
if enA = '1' then
doA <= ram(to_integer(unsigned(addrA)));
end if;
end if;
end process;
process (clkB)
variable readB : std_logic_vector(31 downto 0);
begin
if clkB'event and clkB = '1' then
if enB = '1' then
if weB(3) = '1' then
ram(to_integer(unsigned(addrB & '0')))(15 downto 8) <= diB(31 downto 24);
end if;
if weB(2) = '1' then
ram(to_integer(unsigned(addrB & '0')))(7 downto 0) <= diB(23 downto 16);
end if;
if weB(1) = '1' then
ram(to_integer(unsigned(addrB & '1')))(15 downto 8) <= diB(15 downto 8);
end if;
if weB(0) = '1' then
ram(to_integer(unsigned(addrB & '1')))(7 downto 0) <= diB(7 downto 0);
end if;
readB(31 downto 16) := ram(to_integer(unsigned(addrB & '0')));
readB(15 downto 0) := ram(to_integer(unsigned(addrB & '1')));
doB <= readB;
end if;
end if;
end process;
end behavioral;

214
bus_monitor.vhd Normal file
View File

@ -0,0 +1,214 @@
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use work.monitor_pkg.all;
use work.cpu2j0_pack.all;
entity bus_monitor is
generic ( memblock : string := "IF");
port (
-- fault : in std_logic;
clk : in std_logic;
rst : in std_logic;
cpu_bus_o : in cpu_data_o_t;
cpu_bus_i : in cpu_data_i_t
);
end bus_monitor;
architecture structure of bus_monitor is
signal timeout : timeout_t;
signal fault : std_logic;
--signal dinxu : std_logic := '0';
begin
timeout_cnt_i: timeout_cnt port map(clk => clk, rst => rst,
enable => cpu_bus_o.en,
ack => cpu_bus_i.ack,
fault => fault,
timeout => timeout);
monitor1 : process
begin
wait on cpu_bus_o.en, fault;
-- enable can only go low after ack for current bus cycle is high
if not fault'event and (cpu_bus_o.en = '0') then
if (cpu_bus_i.ack = '0') then
report "Enable did not see ACK for " & memblock severity warning;
end if;
end if;
if not cpu_bus_o.en'event and (fault = '1') then
report "ACK timeout - do not reach in time for " & memblock severity warning;
end if;
end process;
monitor11: process (cpu_bus_o.a, cpu_bus_o.en)
begin
if cpu_bus_o.a'event and (cpu_bus_i.ack = '0') and (cpu_bus_o.en = '1') and not cpu_bus_o.en'event then
report "Address changed but did not see ACK for " & memblock severity warning;
end if;
end process;
monitor2 : process (cpu_bus_i.ack)
begin
if cpu_bus_i.ack'event and (cpu_bus_i.ack = '1') and (cpu_bus_o.en = '0') then
report "ACK raises while Enable low for " & memblock severity warning;
end if;
end process;
monitor3 : process
begin
wait on cpu_bus_o.en, cpu_bus_i.ack;
if not cpu_bus_o.en'event and (cpu_bus_i.ack = '0') and (cpu_bus_o.en = '0') then
if (cpu_bus_o.en'last_event >= 10 ns) then
report "ACK falling delay is greater than 1 CC for " & memblock severity warning;
end if;
end if;
end process;
monitor4 : process (cpu_bus_o.rd)
begin
if cpu_bus_o.rd'event and (cpu_bus_o.rd = '0') and (cpu_bus_i.ack = '0') then
report "Rd did not see ACK for " & memblock severity warning;
end if;
end process;
monitor5 : process (cpu_bus_o.wr)
begin
if cpu_bus_o.wr'event and (cpu_bus_o.wr = '0') and (cpu_bus_i.ack = '0') then
report "Wr did not see ACK for " & memblock severity warning;
end if;
end process;
monitoren : process(cpu_bus_o)
begin
if cpu_bus_o.en'event and (cpu_bus_o.en = '1') then
if (cpu_bus_o.wr = '1') then
for i in 0 to 31 loop
if (cpu_bus_o.a(i) /= '0') and (cpu_bus_o.a(i) /= '1') then
report "Writing without address " & memblock severity warning;
exit;
end if;
end loop;
for i in 0 to 31 loop
if (cpu_bus_o.d(i) /= '0') and (cpu_bus_o.d(i) /= '1') then
report "Writing without data " & memblock severity warning;
exit;
end if;
end loop;
for i in 0 to 3 loop
if (cpu_bus_o.we(i) /= '0') and (cpu_bus_o.we(i) /= '1') then
report "Writing without Byte lane enable " & memblock severity warning;
exit;
end if;
end loop;
elsif (cpu_bus_o.rd = '1') then -- Wr is 0 and Rd is 1
for i in 0 to 31 loop
if (cpu_bus_o.a(i) /= '0') and (cpu_bus_o.a(i) /= '1') then
report "Reading without address " & memblock severity warning;
exit;
end if;
end loop;
else
report "Enable with no Rd and no Wr " & memblock severity warning;
end if;
end if;
end process;
monitorx : process
begin
wait on cpu_bus_o, cpu_bus_i;
-- check if X on bus lines
for i in 0 to 31 loop
if (cpu_bus_o.a(i) = 'X') then
report "address has an X for " & memblock severity warning;
exit;
end if;
end loop;
if (cpu_bus_o.en = 'X') then
report "enable is has X for " & memblock severity warning;
end if;
if (cpu_bus_o.rd = 'X') then
report "Read is has X for " & memblock severity warning;
end if;
if (cpu_bus_o.wr = 'X') then
report "Write has X for " & memblock severity warning;
end if;
for i in 0 to 3 loop
if (cpu_bus_o.we(i) = 'X') then
report "Byte lane Write Enable has an X for " & memblock severity warning;
exit;
end if;
end loop;
for i in 0 to 31 loop
if (cpu_bus_o.d(i) = 'X') then
report "Write data has an X for " & memblock severity warning;
exit;
end if;
end loop;
for i in 0 to 31 loop
if (cpu_bus_i.d(i) = 'X') then
report "Data readback has an X for " & memblock severity warning;
exit;
end if;
end loop;
if (cpu_bus_i.ack = 'X') then
report "ACK is has X for " & memblock severity warning;
end if;
-- Commented out this test because the way the buses are split into
-- slave buses copies the same WE signal across all slave buses, even
-- ones that are not enabled.
-- check WE is 0 when EN is 0
--if cpu_bus_o.en'event and (cpu_bus_o.en = '0') and (cpu_bus_o.we /= "0000") then
-- report "Write Enable non-zero when En=0 for " & memblock severity warning;
--end if;
-- check WE is valid when EN and WR are 1
if cpu_bus_o.en'event and (cpu_bus_o.en = '1' and cpu_bus_o.wr = '1') and (cpu_bus_o.we /= "1111")
and (cpu_bus_o.we /= "1100") and (cpu_bus_o.we /= "0011")
and (cpu_bus_o.we /= "1000") and (cpu_bus_o.we /= "0100")
and (cpu_bus_o.we /= "0010") and (cpu_bus_o.we /= "0001") then
report "Write Enable invalid when En=wr=1 for " & memblock severity warning;
end if;
-- check when we have WR that WE will be nonzero
if (cpu_bus_o.wr = '1') and (cpu_bus_o.we = "0000") then
report "We have Write without enabling any byte lane for " & memblock severity warning;
end if;
-- check when we have read that WE will be zero
if (cpu_bus_o.rd = '1') and (cpu_bus_o.we /= "0000") then
report "We have Read with non-zero WE for " & memblock severity warning;
end if;
end process;
end structure;

504
components_pkg.vhd Normal file
View File

@ -0,0 +1,504 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.cpu2j0_pack.all;
package cpu2j0_components_pack is
constant bits_exp : natural := 5;
constant bits : natural := 2**bits_exp;
type arith_func_t is (ADD, SUB);
type arith_sr_func_t is (ZERO,
OVERUNDERFLOW,
UGRTER_EQ, SGRTER_EQ,
UGRTER, SGRTER,
DIV0S, DIV1);
type logic_func_t is (LOGIC_NOT, LOGIC_AND, LOGIC_OR, LOGIC_XOR);
type logic_sr_func_t is (ZERO, BYTE_EQ);
type shiftfunc_t is (LOGIC, ARITH, ROTATE, ROTC);
type alumanip_t is (SWAP_BYTE, SWAP_WORD, EXTEND_UBYTE, EXTEND_UWORD, EXTEND_SBYTE, EXTEND_SWORD, EXTRACT, SET_BIT_7);
type sr_t is record
t, s, q, m : std_logic;
int_mask : std_logic_vector(3 downto 0);
end record;
-- if size becomes part of the bus, mem_size_t will move into cpu2j0_pack
type mem_size_t is (BYTE, WORD, LONG);
type debug_state_t is ( RUN, READY, AWAIT_IF, AWAIT_BREAK );
type bus_val_t is record
en : std_logic;
d : std_logic_vector(bits-1 downto 0);
end record;
constant BUS_VAL_RESET : bus_val_t := ('0', (others => '0'));
type ybus_val_pipeline_t is array (2 downto 0) of bus_val_t;
type datapath_reg_t is record
pc : std_logic_vector(bits-1 downto 0);
sr : sr_t;
mac_s : std_logic;
data_o_size: mem_size_t;
data_o_lock: std_logic;
data_o : cpu_data_o_t;
inst_o : cpu_instruction_o_t;
pc_inc : std_logic_vector(31 downto 0);
if_dr : std_logic_vector(15 downto 0);
if_dr_next : std_logic_vector(15 downto 0);
illegal_delay_slot : std_logic;
illegal_instr : std_logic;
if_en : std_logic;
m_dr : std_logic_vector(31 downto 0);
m_dr_next : std_logic_vector(31 downto 0);
m_en : std_logic;
slot : std_logic;
-- pipelines the enter_debug signal to delay it so that single stepping
-- instructions works and debug mode is re-entered after one instruction.
-- The length of this depends on how many microcode lines there are in the
-- break instruction after it has raised the debug control line.
enter_debug: std_logic_vector(3 downto 0);
old_debug : std_logic;
stop_pc_inc : std_logic;
debug_state: debug_state_t;
debug_o : cpu_debug_o_t;
-- pipeline of inserted values to override y-bus. Values go in at 'left and
-- move downto 'right
ybus_override : ybus_val_pipeline_t;
end record;
constant DATAPATH_RESET : datapath_reg_t := (pc => (others => '0'), sr => (int_mask => "1111", others => '0'), mac_s => '0', data_o_size => BYTE, data_o_lock => '0', data_o => NULL_DATA_O, inst_o => NULL_INST_O, pc_inc => (others => '0'), if_dr => (others => '0'), if_dr_next => (others => '0'), illegal_delay_slot => '0', illegal_instr => '0', if_en => '0', m_dr => (others => '0'), m_dr_next => (others => '0'), m_en => '0', slot => '1', enter_debug => (others => '0'), old_debug => '0', stop_pc_inc => '0', debug_state => RUN, debug_o => (ack => '0', d => (others => '0'), rdy => '0'), ybus_override => (others => BUS_VAL_RESET));
subtype regnum_t is std_logic_vector(4 downto 0);
component register_file is
generic ( ADDR_WIDTH : integer; NUM_REGS : integer; REG_WIDTH : integer );
port (
clk : in std_logic;
rst : in std_logic;
ce : in std_logic;
addr_ra : in std_logic_vector(ADDR_WIDTH-1 downto 0);
dout_a : out std_logic_vector(REG_WIDTH-1 downto 0);
addr_rb : in std_logic_vector(ADDR_WIDTH-1 downto 0);
dout_b : out std_logic_vector(REG_WIDTH-1 downto 0);
dout_0 : out std_logic_vector(REG_WIDTH-1 downto 0);
we_wb : in std_logic;
w_addr_wb : in std_logic_vector(ADDR_WIDTH-1 downto 0);
din_wb : in std_logic_vector(REG_WIDTH-1 downto 0);
we_ex : in std_logic;
w_addr_ex : in std_logic_vector(ADDR_WIDTH-1 downto 0);
din_ex : in std_logic_vector(REG_WIDTH-1 downto 0);
wr_data_o : out std_logic_vector(REG_WIDTH-1 downto 0)
);
end component register_file;
-- Adds or subtracts a and b with carry-in and carry-out. The carry-out
-- (borrow for subtraction) bit is in the left-most bit of the result, which is
-- one bit wider than the inputs
function arith_unit(
a : std_logic_vector;
b : std_logic_vector;
func : arith_func_t;
ci : std_logic)
return std_logic_vector;
-- based on the input and output of the arith_unit, update the SR register
-- flags for different operations
function arith_update_sr(
sr_in : sr_t;
a_msb : std_logic;
b_msb : std_logic;
value : std_logic_vector;
co_or_borrow : std_logic;
arithfunc : arith_func_t;
func : arith_sr_func_t)
return sr_t;
-- Returns either the bitwise AND, OR or XOR of a and b or the NOT of b
function logic_unit(
a : std_logic_vector;
b : std_logic_vector;
func : logic_func_t)
return std_logic_vector;
-- based on the output of the logic_unit, update the SR register flags for
-- different operations
function logic_update_sr(
sr_in : sr_t;
value : std_logic_vector;
func : logic_sr_func_t;
constant byte_width : integer := 8)
return sr_t;
function is_zero(a : std_logic_vector) return std_logic;
function bshifter(a,b : std_logic_vector; c : std_logic; ops : shiftfunc_t) return std_logic_vector;
function manip(x, y : std_logic_vector(31 downto 0); func : alumanip_t)
return std_logic_vector;
end package;
package body cpu2j0_components_pack is
constant NO_WARNING: BOOLEAN := FALSE; -- default to emit warnings
function or_reduce(a : std_logic_vector) return std_logic is
variable r : std_logic := '0';
begin
for i in a'range loop
r := r or a(i);
end loop;
return r;
end;
-- Like or_reduce, but doesn't not completely reduce to a single bit. Instead
-- it splits the input into bytes, reduces each, and returns a vector
function or_reduce_bytes(a : std_logic_vector; constant byte_width : integer)
return std_logic_vector is
constant num_bytes : integer := natural((real(a'length) / real(byte_width)));
variable r : std_logic_vector(num_bytes - 1 downto 0);
begin
for i in r'range loop
r(i) := or_reduce(a((i + 1) * byte_width - 1 downto i * byte_width));
end loop;
return r;
end;
function is_zero(a : std_logic_vector) return std_logic is
variable r : std_logic := '0';
begin
return not or_reduce(a);
end;
-- xor every bit in vector a by bit b
function xor_all(a : std_logic_vector; b : std_logic) return std_logic_vector is
alias av : std_logic_vector(a'length - 1 downto 0) is a;
variable bv : std_logic_vector(a'length - 1 downto 0) := (others => b);
begin
return av xor bv;
end;
function to_bit(b: boolean) return std_logic is
begin
if b then
return '1';
else
return '0';
end if;
end;
function arith_unit(
a : std_logic_vector;
b : std_logic_vector;
func : arith_func_t;
ci : std_logic)
return std_logic_vector is
alias xa : std_logic_vector(a'length - 1 downto 0) is a;
alias xb : std_logic_vector(b'length - 1 downto 0) is b;
variable is_sub : std_logic;
variable b2 : std_logic_vector(xb'range);
variable sum : unsigned(a'length downto 0);
variable carry_in : unsigned(a'length downto 0);
begin
if a'length /= b'length then
assert NO_WARNING
report "arith_unit: Arg size mismatch. Returning 0"
severity WARNING;
sum := to_unsigned(0, sum'length);
return std_logic_vector(sum);
end if;
is_sub := to_bit(func = SUB);
-- if ADD, then r = A+B+ci
-- if SUB, then r = A-B-ci = A+not(B)+1-ci
-- Perform a subtraction by negating the B operand. Take the twos complement
-- by first flipping the bits and then xor-ing the ci to implement the +1.
b2 := xor_all(xb, is_sub);
-- If is_sub=0, then ci behaves normally. If is_sub=1 then
-- r = A+not(B)+1-ci = A+not(B)+1-1 = A+not(B) when ci = 1
-- = A+not(B)+1 when ci = 0
-- Xor-ing the ci by is_sub gives the correct calculation.
carry_in := (others => '0');
carry_in(0) := is_sub xor ci;
sum := ('0' & unsigned(xa)) + ('0' & unsigned(b2)) + carry_in;
-- convert left-most bit to a borrow instead of carry out when doing a subtraction
sum(sum'left) := sum(sum'left) xor is_sub;
return std_logic_vector(sum);
end;
function logic_unit(
a : std_logic_vector;
b : std_logic_vector;
func : logic_func_t)
return std_logic_vector is
alias xa : std_logic_vector(a'length - 1 downto 0) is a;
alias xb : std_logic_vector(b'length - 1 downto 0) is b;
variable r : std_logic_vector(xa'range);
begin
if a'length /= b'length then
assert NO_WARNING
report "logic_unit: Arg size mismatch. Returning 0"
severity WARNING;
r := (others => '0');
return r;
end if;
case func is
when LOGIC_NOT =>
r := xor_all(xb, '1');
when LOGIC_AND =>
r := xa and xb;
when LOGIC_OR =>
r := xa or xb;
when LOGIC_XOR =>
r := xa xor xb;
end case;
return r;
end;
function arith_update_sr(
sr_in : sr_t;
a_msb : std_logic;
b_msb : std_logic;
value : std_logic_vector;
co_or_borrow : std_logic;
arithfunc : arith_func_t;
func : arith_sr_func_t)
return sr_t is
alias v : std_logic_vector(value'length - 1 downto 0) is value;
variable sr_out : sr_t := sr_in;
variable v_msb : std_logic := v(v'left);
variable is_sub : std_logic := to_bit(arithfunc = SUB);
variable value_zero : std_logic := is_zero(v);
variable common_gr_eq, sign_gr_eq, unsign_gr_eq : std_logic;
begin
-- logic common to both signed and unsigned comparisons.
-- common_gr = '1' => a >= b, but not the converse
common_gr_eq := (not(a_msb) and not(b_msb) and not(v_msb)) or
(a_msb and b_msb and not(v_msb));
sign_gr_eq := common_gr_eq or (not(a_msb) and b_msb);
unsign_gr_eq := common_gr_eq or (a_msb and not(b_msb));
case func is
when ZERO =>
sr_out.t := is_zero(v);
when OVERUNDERFLOW =>
sr_out.t := (not(a_msb) and not(b_msb xor is_sub) and v_msb) or
(a_msb and (b_msb xor is_sub) and not(v_msb));
when UGRTER =>
sr_out.t := unsign_gr_eq and not(value_zero);
when UGRTER_EQ =>
sr_out.t := unsign_gr_eq;
when SGRTER =>
sr_out.t := sign_gr_eq and not(value_zero);
when SGRTER_EQ =>
sr_out.t := sign_gr_eq;
when DIV0S =>
sr_out.q := a_msb;
sr_out.m := b_msb;
sr_out.t := a_msb xor b_msb;
when DIV1 =>
sr_out.q := a_msb xor sr_in.m xor co_or_borrow;
sr_out.t := not (sr_out.q xor sr_in.m);
end case;
return sr_out;
end;
function logic_update_sr(
sr_in : sr_t;
value : std_logic_vector;
func : logic_sr_func_t;
constant byte_width : integer := 8)
return sr_t is
alias v : std_logic_vector(value'length - 1 downto 0) is value;
variable sr_out : sr_t := sr_in;
begin
case func is
when ZERO =>
sr_out.t := is_zero(v);
when BYTE_EQ =>
-- assumes the value is a xor b
sr_out.t := or_reduce(xor_all(or_reduce_bytes(v, byte_width), '1'));
end case;
return sr_out;
end;
function left_rotate(a : std_logic_vector; b : std_logic_vector) return std_logic_vector is
constant num_bits : integer := a'length;
variable sr, yr : std_logic_vector(a'range);
variable offset : integer range 0 to num_bits/2;
variable k : integer;
begin
yr := a;
offset := num_bits/2;
for i in b'range loop
if b(i) = '1' then
for j in a'range loop
if j + offset >= num_bits then k := j + offset - num_bits;
else k := j + offset; end if;
sr(k) := yr(j);
end loop;
else
for j in a'range loop
sr(j) := yr(j);
end loop;
end if;
offset := offset/2;
yr := sr;
end loop;
return yr;
end function;
function calf_fcn(b : unsigned) return std_logic_vector is
constant b_left : integer := b'length - 1;
constant result_bits : integer := 2 ** b'length;
--variable ib : natural range 0 to result_bits-1 := to_integer(b);
variable ib : natural := to_integer(b);
variable f : std_logic_vector(result_bits-1 downto 0) := (others => '0');
begin
for i in f'range loop
if i < ib then f(i) := '1'; end if;
end loop;
return f;
end function;
function calp_fcn(f : std_logic_vector; rotate, left : std_logic) return std_logic_vector is
variable p : std_logic_vector(f'range);
begin
for i in f'range loop
p(i) := (f(i) xor left) or rotate;
end loop;
return p;
end function;
function caly_fcn(y, p : std_logic_vector; ops : shiftfunc_t; left, c, a : std_logic) return std_logic_vector is
variable t : std_logic_vector(y'range);
variable s : std_logic := '0';
-- assumes y and p have the same range and that their 'right is 0
constant num_bits : integer := p'length;
begin
if ops = arith and left = '0' then s := a; end if;
if p(0) = '1' then t(0) := y(0);
elsif left = '1' and ops = rotc then t(0) := c;
else t(0) := s; end if;
if p(num_bits-1) = '1' then t(num_bits-1) := y(num_bits-1);
elsif left = '0' and ops = rotc then t(num_bits-1) := c;
else t(num_bits-1) := s; end if;
for i in 1 to num_bits-2 loop
if p(i) = '1' then t(i) := y(i);
else t(i) := s; end if;
end loop;
return t;
end function;
function bshifter(a,b : std_logic_vector; c : std_logic; ops : shiftfunc_t) return std_logic_vector is
variable left, rot : std_logic := '0';
constant a_left : integer := a'length - 1;
constant b_left : integer := b'length - 1;
alias xa : std_logic_vector(a_left downto 0) is a;
alias xb : std_logic_vector(b_left downto 0) is b;
variable b_mag : std_logic_vector(b_left-1 downto 0);
variable f, p, y1, y : std_logic_vector(a_left downto 0);
begin
-- Verify argument lengths match. The b argument is a sign bit plus
-- N bits, and the a arg must be 2^N bits.
if integer(a'length) /= integer(2 ** (b'length - 1)) then
assert NO_WARNING
report "BSHIFTER: Arg size mismatch, returning A"
severity WARNING;
return a;
end if;
-- split b into a shift magnitude and shift direction
b_mag := xb(b_mag'range);
left := not xb(b_left);
if ops = rotate then rot := '1'; end if;
f := calf_fcn(unsigned(b_mag));
p := calp_fcn(f, rot, left);
y1 := left_rotate(xa, b_mag);
y := caly_fcn(y1, p, ops, left, c, xa(a_left));
return y;
end function;
function manip(x, y : std_logic_vector(31 downto 0); func : alumanip_t)
return std_logic_vector is
variable b0, b1, b2, b3 : std_logic_vector(7 downto 0);
variable sign_bit : std_logic;
variable sign_byte : std_logic_vector(7 downto 0);
begin
if func = EXTEND_SBYTE then
sign_bit := y(7);
else
sign_bit := y(15);
end if;
sign_byte := (others => sign_bit);
-- assign each byte of output separately to group same cases
case func is
when SWAP_BYTE
| SET_BIT_7 => b3 := y(31 downto 24);
when EXTEND_UBYTE
| EXTEND_UWORD => b3 := (others => '0');
when EXTEND_SBYTE
| EXTEND_SWORD => b3 := sign_byte;
-- others is SWAP_WORD or EXTRACT
when others => b3 := y(15 downto 8);
end case;
case func is
when SWAP_BYTE
| SET_BIT_7 => b2 := y(23 downto 16);
when EXTEND_UBYTE
| EXTEND_UWORD => b2 := (others => '0');
when EXTEND_SBYTE
| EXTEND_SWORD => b2 := sign_byte;
-- others is SWAP_WORD or EXTRACT
when others => b2 := y(7 downto 0);
end case;
case func is
when SWAP_BYTE => b1 := y(7 downto 0);
when SWAP_WORD => b1 := y(31 downto 24);
when EXTEND_UBYTE => b1 := (others => '0');
when EXTEND_UWORD
| EXTEND_SWORD
| SET_BIT_7 => b1 := y(15 downto 8);
when EXTEND_SBYTE => b1 := sign_byte;
-- others is EXTRACT
when others => b1 := x(31 downto 24);
end case;
case func is
when SWAP_BYTE => b0 := y(15 downto 8);
when SWAP_WORD => b0 := y(23 downto 16);
when EXTEND_UBYTE
| EXTEND_UWORD
| EXTEND_SBYTE
| EXTEND_SWORD => b0 := y(7 downto 0);
when SET_BIT_7 => b0 := '1' & y(6 downto 0);
-- others is EXTRACT
when others => b0 := x(23 downto 16);
end case;
return b3 & b2 & b1 & b0;
end function;
end cpu2j0_components_pack;

80
cpu.vhd Normal file
View File

@ -0,0 +1,80 @@
library ieee;
use ieee.std_logic_1164.all;
use work.cpu2j0_pack.all;
use work.decode_pack.all;
use work.cpu2j0_components_pack.all;
use work.datapath_pack.all;
use work.mult_pkg.all;
entity cpu is port (
clk : in std_logic;
rst : in std_logic;
db_o : out cpu_data_o_t;
db_lock : out std_logic;
db_i : in cpu_data_i_t;
inst_o : out cpu_instruction_o_t;
inst_i : in cpu_instruction_i_t;
debug_o : out cpu_debug_o_t;
debug_i : in cpu_debug_i_t;
event_o : out cpu_event_o_t;
event_i : in cpu_event_i_t);
end entity cpu;
architecture stru of cpu is
signal slot, if_stall : std_logic;
signal mac_i : mult_i_t;
signal mac_o : mult_o_t;
signal reg : reg_ctrl_t;
signal func : func_ctrl_t;
signal mem : mem_ctrl_t;
signal instr : instr_ctrl_t;
signal mac : mac_ctrl_t;
signal pc : pc_ctrl_t;
signal buses : buses_ctrl_t;
signal t_bcc : std_logic;
signal ibit : std_logic_vector(3 downto 0);
signal if_dr : std_logic_vector(15 downto 0);
signal enter_debug, debug, mask_int : std_logic;
signal event_ack : std_logic;
signal slp_o : std_logic;
signal sr : sr_ctrl_t;
signal illegal_delay_slot : std_logic;
signal illegal_instr : std_logic;
begin
event_o.ack <= event_ack;
event_o.lvl <= ibit;
event_o.slp <= slp_o;
event_o.dbg <= debug;
u_decode: decode
port map (clk => clk, rst => rst, slot => slot,
enter_debug => enter_debug, debug => debug,
if_dr => if_dr, if_stall => if_stall,
illegal_delay_slot => illegal_delay_slot,
illegal_instr => illegal_instr,
mac_busy => mac_o.busy,
reg => reg, func => func, sr => sr, mac => mac, mem => mem, instr => instr, pc => pc,
buses => buses,
t_bcc => t_bcc,
event_i => event_i, event_ack => event_ack,
ibit => ibit,
slp => slp_o,
mask_int => mask_int);
u_mult : mult port map (clk => clk, rst => rst, slot => slot, a => mac_i, y => mac_o);
mac_i.wr_m1 <= mac.com1; mac_i.command <= mac.com2;
mac_i.wr_mach <= mac.wrmach; mac_i.wr_macl <= mac.wrmacl;
u_datapath : datapath port map (clk => clk, rst => rst, slot => slot,
debug => debug, enter_debug => enter_debug,
db_lock => db_lock, db_o => db_o, db_i => db_i, inst_o => inst_o, inst_i => inst_i,
debug_o => debug_o, debug_i => debug_i,
reg => reg, func => func, sr_ctrl => sr, mac => mac, mem => mem, pc_ctrl => pc,
buses => buses, instr => instr,
macin1 => mac_i.in1, macin2 => mac_i.in2, mach => mac_o.mach, macl => mac_o.macl,
mac_s => mac_i.s,
t_bcc => t_bcc, ibit => ibit, if_dr => if_dr, if_stall => if_stall,
mask_int => mask_int,
illegal_delay_slot => illegal_delay_slot,
illegal_instr => illegal_instr);
end architecture stru;

98
cpu2j0_pkg.vhd Normal file
View File

@ -0,0 +1,98 @@
-- Interface Library for the HS-2J0 CPU core
library ieee;
use ieee.std_logic_1164.all;
package cpu2j0_pack is
type cpu_instruction_o_t is record
en : std_logic;
a : std_logic_vector(31 downto 1);
jp : std_logic;
end record;
constant NULL_INST_O : cpu_instruction_o_t := (en => '0', a => (others => '0'), jp => '0');
type cpu_instruction_i_t is record
d : std_logic_vector(15 downto 0);
ack : std_logic;
end record;
type cpu_data_o_t is record
en : std_logic;
a : std_logic_vector(31 downto 0);
rd : std_logic;
wr : std_logic;
we : std_logic_vector(3 downto 0);
d : std_logic_vector(31 downto 0);
end record;
constant NULL_DATA_O : cpu_data_o_t := (en => '0', a => (others => '0'), rd => '0', wr => '0', we => "0000", d => (others => '0'));
type cpu_data_i_t is record
d : std_logic_vector(31 downto 0);
ack : std_logic;
end record;
type cpu_debug_o_t is record
ack : std_logic;
d : std_logic_vector(31 downto 0);
rdy : std_logic;
end record;
type cpu_debug_cmd_t is (BREAK, STEP, INSERT, CONTINUE);
type cpu_debug_i_t is record
en : std_logic;
cmd : cpu_debug_cmd_t;
ir : std_logic_vector(15 downto 0);
d : std_logic_vector(31 downto 0);
d_en : std_logic;
end record;
constant CPU_DEBUG_NOP : cpu_debug_i_t := (en => '0', cmd => BREAK, ir => (others => '0'), d => (others => '0'), d_en => '0');
type cpu_event_cmd_t is (INTERRUPT, ERROR, BREAK, RESET_CPU);
type cpu_event_i_t is record
en : std_logic;
cmd : cpu_event_cmd_t;
vec : std_logic_vector(7 downto 0);
msk : std_logic;
lvl : std_logic_vector(3 downto 0);
end record;
constant NULL_CPU_EVENT_I : cpu_event_i_t := (en => '0',
cmd => INTERRUPT,
vec => (others => '0'),
msk => '0',
lvl => (others => '1'));
type cpu_event_o_t is record
ack : std_logic;
lvl : std_logic_vector(3 downto 0);
slp : std_logic;
dbg : std_logic;
end record;
component cpu is port (
clk : in std_logic;
rst : in std_logic;
db_o : out cpu_data_o_t;
db_lock : out std_logic;
db_i : in cpu_data_i_t;
inst_o : out cpu_instruction_o_t;
inst_i : in cpu_instruction_i_t;
debug_o : out cpu_debug_o_t;
debug_i : in cpu_debug_i_t;
event_o : out cpu_event_o_t;
event_i : in cpu_event_i_t);
end component cpu;
function loopback_bus(b : cpu_data_o_t) return cpu_data_i_t;
end cpu2j0_pack;
package body cpu2j0_pack is
function loopback_bus(b : cpu_data_o_t) return cpu_data_i_t is
variable r : cpu_data_i_t;
begin
r.ack := b.en;
r.d := (others => '0');
return r;
end function loopback_bus;
end cpu2j0_pack;

172
cpu_pure_tb.vhh Normal file
View File

@ -0,0 +1,172 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.cpu2j0_pack.all;
use work.monitor_pkg.all;
use work.data_bus_pkg.all;
entity cpu_pure_tb is
end;
architecture behaviour of cpu_pure_tb is
type instrd_bus_i_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_data_i_t;
type instrd_bus_o_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_data_o_t;
signal instr_master_o : cpu_instruction_o_t;
signal instr_master_i : cpu_instruction_i_t := (( others => 'Z' ),'0');
signal instr_slaves_i : instr_bus_i_t;
signal instr_slaves_o : instr_bus_o_t;
signal instrd_slaves_i : instrd_bus_i_t;
signal instrd_slaves_o : instrd_bus_o_t;
signal data_master_o : cpu_data_o_t;
signal data_master_i : cpu_data_i_t := (( others => 'Z' ),'0');
signal data_slaves_i : data_bus_i_t;
signal data_slaves_o : data_bus_o_t;
signal sram_d_o : cpu_data_o_t;
signal debug_i : cpu_debug_i_t := CPU_DEBUG_NOP;
signal debug_i_cmd : std_logic_vector(1 downto 0) := "00";
signal debug_o : cpu_debug_o_t;
signal slp_o : std_logic;
signal event_i : cpu_event_i_t := NULL_CPU_EVENT_I;
signal event_o : cpu_event_o_t;
signal clk : std_logic := '1';
signal rst : std_logic := '1';
constant clk_period : time := 8 ns;
signal dummy : bit;
signal pio_data_o : cpu_data_o_t := NULL_DATA_O;
signal pio_data_i : cpu_data_i_t := (ack => '0', d => (others => '0'));
signal data_select : data_bus_device_t;
shared variable ENDSIM : boolean := false;
signal db_we : std_logic_vector(3 downto 0);
begin
rst <= '1', '0' after 10 ns;
clk_gen : process
begin
if ENDSIM = false then
clk <= '0';
wait for (clk_period / 2);
clk <= '1';
wait for (clk_period / 2);
else
wait;
end if;
end process;
process (data_master_o)
variable dev : data_bus_device_t;
begin
if data_master_o.en = '0' then
dev := DEV_NONE;
else
dev := decode_data_address(data_master_o.a);
-- Make SRAM the default. Would prefer not to do this, but not
-- sure how many things depend on defaulting to SRAM. For example,
-- my build of sdboot has a 4 byte stack at 0x300000 and loading
-- it in gdb prints errors.
if dev = DEV_NONE then
dev := DEV_SRAM;
end if;
end if;
data_select <= dev;
end process;
data_buses(master_i => data_master_i, master_o => data_master_o,
selected => data_select,
slaves_i => data_slaves_i, slaves_o => data_slaves_o);
data_slaves_i(DEV_NONE) <= loopback_bus(data_slaves_o(DEV_NONE));
data_slaves_i(DEV_SPI) <= loopback_bus(data_slaves_o(DEV_SPI));
data_slaves_i(DEV_UART0) <= loopback_bus(data_slaves_o(DEV_UART0));
data_slaves_i(DEV_DDR) <= loopback_bus(data_slaves_o(DEV_DDR));
pio_data_i.d <= (others => '0');
pio_data_i.ack <= pio_data_o.en;
instruction_buses(master_i => instr_master_i, master_o => instr_master_o,
selected => decode_instr_address(instr_master_o.a),
slaves_i => instr_slaves_i, slaves_o => instr_slaves_o);
pio_data_o <= data_slaves_o(DEV_PIO);
data_slaves_i(DEV_PIO) <= pio_data_i;
with debug_i_cmd select
debug_i.cmd <=
BREAK when "00",
STEP when "01",
INSERT when "10",
CONTINUE when others;
splice_instr_data_bus(instr_slaves_o(DEV_DDR), instr_slaves_i(DEV_DDR),
instrd_slaves_o(DEV_DDR), instrd_slaves_i(DEV_DDR));
cpu1: cpu
port map(clk => clk, rst => rst,
db_o => data_master_o, db_i => data_master_i,
inst_o => instr_master_o, inst_i => instr_master_i,
debug_o => debug_o, debug_i => debug_i,
event_i => event_i, event_o => event_o);
mon_mem_bus: bus_monitor generic map (memblock => "data sram")
port map(clk => clk, rst => rst,
cpu_bus_o => data_slaves_o(DEV_SRAM),
cpu_bus_i => data_slaves_i(DEV_SRAM));
mon_instr_sram_bus: bus_monitor generic map (memblock => "instruction sram fetch")
port map(clk => clk, rst => rst,
cpu_bus_o => instrd_slaves_o(DEV_SRAM),
cpu_bus_i => instrd_slaves_i(DEV_SRAM));
mon_instr_ddr_bus: bus_monitor generic map (memblock => "instruction ddr fetch")
port map(clk => clk, rst => rst,
cpu_bus_o => instrd_slaves_o(DEV_DDR),
cpu_bus_i => instrd_slaves_i(DEV_DDR));
sram : entity work.cpu_sram
port map(clk => clk,
ibus_i => instr_slaves_o(DEV_SRAM),
ibus_o => instr_slaves_i(DEV_SRAM),
db_i => data_slaves_o(DEV_SRAM),
db_o => data_slaves_i(DEV_SRAM));
-- intercept and print PIO and UART writes
process
variable uart_line : line;
variable l : line;
variable c : character;
begin
loop
wait until clk'event and clk = '1';
if pio_data_o.wr = '1' and pio_data_o.a = x"ABCD0000" then
write(l, string'("LED: Write "));
-- hwrite(l, pio_data_o.d);
write(l, " at " & time'image(now));
writeline(output, l);
end if;
if data_slaves_o(DEV_UART0).wr = '1' and data_slaves_o(DEV_UART0).a = x"ABCD0104" then
c := character'val(to_integer(unsigned(data_slaves_o(DEV_UART0).d(7 downto 0))));
if character'pos(c) = 10 then -- newline
writeline(output, uart_line);
else
write(uart_line, c);
if c = ';' then
-- hack to better display the gdb remote protocol messages
writeline(output, uart_line);
end if;
end if;
end if;
end loop;
end process;
end;

46
cpu_sram.vhd Normal file
View File

@ -0,0 +1,46 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.cpu2j0_pack.all;
entity cpu_sram is
port (
clk : in std_logic;
ibus_i : in cpu_instruction_o_t;
ibus_o : out cpu_instruction_i_t;
db_i : in cpu_data_o_t;
db_o : out cpu_data_i_t
);
end;
architecture struc of cpu_sram is
signal db_we : std_logic_vector(3 downto 0);
signal iclk : std_logic;
begin
db_we <= (db_i.wr and db_i.we(3)) &
(db_i.wr and db_i.we(2)) &
(db_i.wr and db_i.we(1)) &
(db_i.wr and db_i.we(0));
-- clk memory on negative edge to avoid wait states
iclk <= not clk;
r : entity work.asymmetric_ram
generic map (ADDR_WIDTH => 14)
port map(clkA => iclk,
clkB => iclk,
enA => ibus_i.en,
addrA => ibus_i.a(14 downto 1),
doA => ibus_o.d,
enB => db_i.en,
weB => db_we,
addrB => db_i.a(14 downto 2),
diB => db_i.d,
doB => db_o.d);
-- simply ack immediately. Should this simulate different delays?
db_o.ack <= db_i.en;
ibus_o.ack <= ibus_i.en;
end architecture struc;

236
data_bus_pkg.vhd Normal file
View File

@ -0,0 +1,236 @@
library ieee;
use ieee.std_logic_1164.all;
use work.cpu2j0_pack.all;
package data_bus_pkg is
type data_bus_device_t is (
DEV_NONE
,DEV_PIO
,DEV_SPI
,DEV_AIC
,DEV_UART0
,DEV_UART1
,DEV_UARTGPS
,DEV_SRAM
,DEV_DDR
,DEV_BL0
,DEV_EMAC
,DEV_I2C
);
type data_bus_i_t is array(data_bus_device_t'left to data_bus_device_t'right) of cpu_data_i_t;
type data_bus_o_t is array(data_bus_device_t'left to data_bus_device_t'right) of cpu_data_o_t;
type ext_bus_device_t is (
DEV_BL0,
DEV_EMAC,
DEV_I2C,
DEV_DDR
);
type ext_irq_device_t is (
DEV_EMAC,
DEV_I2C,
DEV_1PPS,
DEV_EXT
);
type ext_to_int_data_bus_t is array(ext_bus_device_t'left to ext_bus_device_t'right) of data_bus_device_t;
type ext_to_int_irq_t is array(ext_irq_device_t'left to ext_irq_device_t'right) of integer range 0 to 7;
-- arrays for mapping mcu_lib's data bus and irq ports to the internal versions
constant ext_to_int_data : ext_to_int_data_bus_t := (
DEV_BL0 => DEV_BL0,
DEV_EMAC => DEV_EMAC,
DEV_I2C => DEV_I2C,
DEV_DDR => DEV_NONE
);
constant ext_to_int_irq : ext_to_int_irq_t := (
DEV_EMAC => 0,
DEV_I2C => 7,
DEV_1PPS => 5,
DEV_EXT => 3
);
-- TODO: Should instruction bus have a DEV_NONE? Depends on if all reads
-- outside DDR should be mapped to SRAM.
type instr_bus_device_t is (
DEV_DDR,
DEV_SRAM);
type instr_bus_i_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_instruction_i_t;
type instr_bus_o_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_instruction_o_t;
function mask_data_o(d: cpu_data_o_t; en : std_logic)
return cpu_data_o_t;
function decode_data_address(addr : std_logic_vector(31 downto 0))
return data_bus_device_t;
procedure data_buses(signal master_i : out cpu_data_i_t;
signal master_o : in cpu_data_o_t;
selected : in data_bus_device_t;
signal slaves_i : in data_bus_i_t;
signal slaves_o : out data_bus_o_t);
function decode_instr_address(addr : std_logic_vector(31 downto 1))
return instr_bus_device_t;
procedure instruction_buses(signal master_i : out cpu_instruction_i_t;
signal master_o : in cpu_instruction_o_t;
selected : in instr_bus_device_t;
signal slaves_i : in instr_bus_i_t;
signal slaves_o : out instr_bus_o_t);
procedure splice_instr_data_bus(signal instr_o : in cpu_instruction_o_t;
signal instr_i : out cpu_instruction_i_t;
signal data_o : out cpu_data_o_t;
signal data_i : in cpu_data_i_t);
end data_bus_pkg;
package body data_bus_pkg is
-- convert boolean to std_logic
function to_bit(b : boolean) return std_logic is
begin
if b then
return '1';
else
return '0';
end if;
end function to_bit;
-- return a cpu_data_o_t with the en, rd, and wr bits masked by the given en bit
function mask_data_o(d: cpu_data_o_t; en : std_logic)
return cpu_data_o_t is
variable r : cpu_data_o_t := d;
begin
r.en := en and d.en;
r.rd := en and d.rd;
r.wr := en and d.wr;
return r;
end function mask_data_o;
function is_prefix(addr : std_logic_vector;
prefix : std_logic_vector)
return boolean is
begin
return addr(addr'left downto (addr'left - prefix'high + prefix'low)) = prefix;
end function is_prefix;
-- determine device from data address
function decode_data_address(addr : std_logic_vector(31 downto 0))
return data_bus_device_t is
begin
case addr(31 downto 28) is
when x"1" =>
return DEV_DDR;
when x"a" =>
case addr(27 downto 16) is
when x"bcd" =>
case addr(15 downto 8) is
when x"00" =>
case addr(7 downto 6) is
when "00" =>
return DEV_PIO;
when "01" =>
return DEV_SPI;
when "10" =>
return DEV_I2C;
when others =>
return DEV_NONE;
end case;
when x"01" =>
return DEV_UART0;
when x"02" =>
return DEV_AIC;
when x"03" =>
return DEV_UART1;
when x"04" =>
return DEV_UARTGPS;
when others =>
return DEV_NONE;
end case;
when x"bce" =>
return DEV_EMAC;
when x"bd0" =>
return DEV_BL0;
when others =>
return DEV_NONE;
end case;
when others =>
-- TODO: This maps more addresses than necessary to SRAM, so the SRAM
-- will appear to be repeated in the address space. We should be able
-- to map fewer addresses to SRAM (only those that start with 18 zero
-- bits). However, the SRAM was previously the default, so it's likely
-- programs rely on that. For example, my build of sdboot has a 4 byte
-- stack at 0x300000 and loading it in gdb prints errors when default
-- is DEV_NONE. For now, leave SRAM as the default.
return DEV_SRAM;
end case;
end function decode_data_address;
-- connect master and slave data buses
procedure data_buses(signal master_i : out cpu_data_i_t;
signal master_o : in cpu_data_o_t;
selected : in data_bus_device_t;
signal slaves_i : in data_bus_i_t;
signal slaves_o : out data_bus_o_t) is
variable selected_device : data_bus_device_t;
begin
if master_o.en = '1' then
selected_device := selected;
else
selected_device := DEV_NONE;
end if;
-- FIXME: This blows chunks master_temp_i := slaves_i(selected_device);
-- ensure the data is 0 when it's not a read.
-- TODO: Is this necessary? Will the CPU use the data when it's not a read?
if master_o.rd = '1' then
master_i.d <= slaves_i(selected_device).d;
else
master_i.d <= (others => '0');
end if;
master_i.ack <= slaves_i(selected_device).ack;
-- split outgoing data bus, masked by device
for dev in data_bus_device_t'left to data_bus_device_t'right loop
slaves_o(dev) <= mask_data_o(master_o, to_bit(dev = selected_device));
end loop;
end;
-- determine device from instruction address
function decode_instr_address(addr : std_logic_vector(31 downto 1))
return instr_bus_device_t is
begin
if is_prefix(addr, x"1") then
return DEV_DDR;
else
-- TODO: Should we have a DEV_NONE here and explicitly check for SRAM's
-- prefix of zeros?
return DEV_SRAM;
end if;
end function decode_instr_address;
-- connect master and slave instruction buses
procedure instruction_buses(signal master_i : out cpu_instruction_i_t;
signal master_o : in cpu_instruction_o_t;
selected : in instr_bus_device_t;
signal slaves_i : in instr_bus_i_t;
signal slaves_o : out instr_bus_o_t) is
begin
-- select incoming bus
master_i <= slaves_i(selected);
-- split outgoing bus, masked by device
for dev in instr_bus_device_t'left to instr_bus_device_t'right loop
slaves_o(dev) <= master_o;
slaves_o(dev).en <= master_o.en and to_bit(dev = selected);
end loop;
end;
-- Connect an instruction bus to a data bus. The instruction bus is on the
-- master side. The data bus is on the slave side.
procedure splice_instr_data_bus(signal instr_o : in cpu_instruction_o_t;
signal instr_i : out cpu_instruction_i_t;
signal data_o : out cpu_data_o_t;
signal data_i : in cpu_data_i_t) is
begin
-- request path
data_o.en <= instr_o.en;
data_o.a <= instr_o.a(31 downto 1) & "0";
data_o.rd <= instr_o.en;
data_o.wr <= '0';
data_o.we <= "0000"; -- WE is "0000" for reads
data_o.d <= (others => '0');
-- reply path
instr_i.ack <= data_i.ack;
if instr_o.a(1) = '0' then
instr_i.d <= data_i.d(31 downto 16);
else
instr_i.d <= data_i.d(15 downto 0);
end if;
end;
end data_bus_pkg;

466
datapath.vhd Normal file
View File

@ -0,0 +1,466 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.cpu2j0_pack.all;
use work.cpu2j0_components_pack.all;
use work.datapath_pack.all;
use work.decode_pack.all;
entity datapath is
port (
clk : in std_logic;
rst : in std_logic;
debug : in std_logic;
enter_debug : out std_logic;
slot : out std_logic;
reg : in reg_ctrl_t;
func : in func_ctrl_t;
sr_ctrl : in sr_ctrl_t;
mac : in mac_ctrl_t;
mem : in mem_ctrl_t;
instr : in instr_ctrl_t;
pc_ctrl : in pc_ctrl_t;
buses : in buses_ctrl_t;
db_lock : out std_logic;
db_o : out cpu_data_o_t;
db_i : in cpu_data_i_t;
inst_o : out cpu_instruction_o_t;
inst_i : in cpu_instruction_i_t;
debug_o : out cpu_debug_o_t;
debug_i : in cpu_debug_i_t;
macin1 : out std_logic_vector(31 downto 0);
macin2 : out std_logic_vector(31 downto 0);
mach : in std_logic_vector(31 downto 0);
macl : in std_logic_vector(31 downto 0);
mac_s : out std_logic;
t_bcc : out std_logic;
ibit : out std_logic_vector(3 downto 0);
if_dr : out std_logic_vector(15 downto 0);
if_stall : out std_logic;
mask_int : out std_logic;
illegal_delay_slot : out std_logic;
illegal_instr : out std_logic
);
end entity datapath;
architecture stru of datapath is
subtype reg_t is std_logic_vector(31 downto 0);
signal gpf_zwd, pc, reg_x, reg_y, reg_0, xbus, ybus, ybus_temp, zbus, wbus : std_logic_vector(31 downto 0);
signal sr : sr_t;
signal sfto : std_logic;
-- alu ports
signal aluiny, aluinx : std_logic_vector(31 downto 0);
signal reg_wr_data_o : std_logic_vector(31 downto 0);
signal ybus_override : bus_val_t;
signal slot_o : std_logic;
signal div1_arith_func : arith_func_t;
signal arith_func : arith_func_t;
signal arith_out : std_logic_vector(32 downto 0);
signal logic_out : std_logic_vector(31 downto 0);
signal this_c : datapath_reg_t;
signal this_r : datapath_reg_t := DATAPATH_RESET;
-- The functions to_sr and to_slv convert between the sr record and its CPU register representation.
function to_sr(a : std_logic_vector(31 downto 0)) return sr_t is
variable r : sr_t;
begin
r.m := a(M); r.q := a(Q); r.int_mask := a(I3 downto I0); r.s := a(S); r.t := a(T);
return r;
end to_sr;
function to_slv(sr : sr_t) return std_logic_vector is
variable r : std_logic_vector(31 downto 0) := (others => '0');
begin
r(M) := sr.m; r(Q) := sr.q; r(I3 downto I0) := sr.int_mask; r(S) := sr.s; r(T) := sr.t;
return r;
end to_slv;
-- A bit vector from a single bit
function to_slv(b : std_logic; s : integer) return std_logic_vector is
variable r : std_logic_vector(s-1 downto 0);
begin
r := (others => b);
return r;
end to_slv;
function to_data_o(mem : mem_ctrl_t; addr : std_logic_vector(31 downto 0);
data : std_logic_vector(31 downto 0))
return cpu_data_o_t is
variable r : cpu_data_o_t := NULL_DATA_O;
begin
if mem.issue = '1' then
r.en := '1';
r.wr := mem.wr;
r.rd := not mem.wr;
r.a := addr;
-- for writes, prepare we and d signals
if mem.wr = '1' then
case mem.size is
when LONG =>
r.d := data; r.we := "1111";
when WORD =>
if addr(1) = '0' then r.we := "1100";
else r.we := "0011"; end if;
r.d := data(15 downto 0) & data(15 downto 0);
when BYTE =>
-- TODO: Use shift or rotate operator instead of case?
case addr(1 downto 0) is
when "00" => r.we := "1000";
when "01" => r.we := "0100";
when "10" => r.we := "0010";
when others => r.we := "0001";
end case;
r.d := data(7 downto 0) & data(7 downto 0) & data(7 downto 0) & data(7 downto 0);
end case;
end if;
end if;
return r;
end to_data_o;
function to_inst_o(instr : instr_ctrl_t; addr : std_logic_vector(31 downto 0);
-- default to jump=1 unless caller knows address is incremented PC
jp : std_logic := '1')
return cpu_instruction_o_t is
variable r : cpu_instruction_o_t := NULL_INST_O;
begin
if instr.issue = '1' then
r.en := '1';
r.a := addr(31 downto 1);
r.jp := jp;
end if;
return r;
end to_inst_o;
function align_read_data(d : std_logic_vector(31 downto 0); bus_o : cpu_data_o_t; size : mem_size_t)
return std_logic_vector is
variable r : std_logic_vector(31 downto 0);
begin
case size is
when BYTE =>
case bus_o.a(1 downto 0) is
when "00" => r := to_slv(d(31), 24) & d(31 downto 24);
when "01" => r := to_slv(d(23), 24) & d(23 downto 16);
when "10" => r := to_slv(d(15), 24) & d(15 downto 8);
when others => r := to_slv(d( 7), 24) & d( 7 downto 0);
end case;
when WORD =>
case bus_o.a(1) is
when '0' => r := to_slv(d(31), 16) & d(31 downto 16);
when others => r := to_slv(d(15), 16) & d(15 downto 0);
end case;
when others => r := d;
end case;
return r;
end align_read_data;
begin
-- Multiplexors for the internal buses
with buses.x_sel select xbus <= reg_x when SEL_REG, pc when SEL_PC, buses.imm_val when others;
with buses.y_sel select ybus_temp <= reg_y when SEL_REG, pc when SEL_PC, mach when SEL_MACH, macl when SEL_MACL, to_slv(sr) when SEL_SR, buses.imm_val when others;
ybus <= ybus_override.d when ybus_override.en = '1' else ybus_temp;
gpf_zwd <= pc when pc_ctrl.wrpr = '1' else zbus;
u_regfile : register_file
generic map (ADDR_WIDTH => 5,
NUM_REGS => 21,
REG_WIDTH => 32)
port map(clk => clk, rst => rst, ce => slot_o, addr_ra => reg.num_x, dout_a => reg_x,
addr_rb => reg.num_y, dout_b => reg_y, dout_0 => reg_0,
we_wb => reg.wr_w, w_addr_wb => reg.num_w, din_wb => wbus,
we_ex => reg.wr_z, w_addr_ex => reg.num_z, din_ex => gpf_zwd,
wr_data_o => reg_wr_data_o);
-- setup arithmetic inputs function
with func.alu.inx_sel select
aluinx <= xbus(31 downto 2) & "00" when SEL_FC,
xbus(30 downto 0) & sr.t when SEL_ROTCL, -- used for DIV1
(others => '0') when SEL_ZERO,
xbus when others;
with func.alu.iny_sel select
aluiny <= buses.imm_val when SEL_IMM,
reg_0 when SEL_R0,
ybus when others;
-- DIV1 decides the arith function at runtime based on m=q. Override
-- the arith func set by decoder when DIV1.
div1_arith_func <= SUB when sr.m = sr.q else ADD;
arith_func <= div1_arith_func when func.arith.sr = DIV1 else func.arith.func;
arith_out <= arith_unit(aluinx, aluiny, arith_func, func.arith.ci_en and sr.t);
logic_out <= logic_unit(aluinx, aluiny, func.logic_func);
with buses.z_sel select zbus <=
arith_out(31 downto 0) when SEL_ARITH,
logic_out when SEL_LOGIC,
bshifter(xbus, ybus(31) & ybus(4 downto 0),
sr.t, func.shift) when SEL_SHIFT,
manip(xbus, ybus, func.alu.manip) when SEL_MANIP,
ybus when SEL_YBUS,
wbus when SEL_WBUS;
sfto <= xbus(xbus'left) when ybus(31) = '0' else xbus(xbus'right);
with mac.sel1 select macin1 <= xbus when SEL_XBUS, zbus when SEL_ZBUS, wbus when others;
with mac.sel2 select macin2 <= ybus when SEL_YBUS, zbus when SEL_ZBUS, wbus when others;
ibit <= sr.int_mask;
datapath : process(this_r,pc_ctrl,wbus,zbus,sr_ctrl, xbus, ybus, mac,mem, instr, db_i, inst_i, debug, debug_i,reg_wr_data_o, logic_out, arith_out, arith_func, func, sfto)
variable this : datapath_reg_t;
variable if_ad : std_logic_vector(31 downto 0);
variable ma_ad, ma_dw : std_logic_vector(31 downto 0);
variable next_state : debug_state_t;
begin
this := this_r;
this.debug_o.ack := '0';
next_state := this.debug_state;
if this.old_debug = '0' and debug = '1' and -- debug input rose
-- meaning BREAK
-- instruction ran
(this.debug_state = RUN or this.debug_state = AWAIT_BREAK) then
next_state := AWAIT_IF;
-- stop requesting debug mode once we're in debug mode
this.enter_debug := (others => '0');
elsif this.debug_state = RUN and debug_i.en = '1' and debug_i.cmd = BREAK then
-- schedule entering debug mode
-- TODO: we could probably set enter_debug(0) = '1' to
-- immediately enter, but need to be careful that mask_int is
-- set early enough to avoid an interrupt during debugging.
this.enter_debug(this.enter_debug'left) := '1';
next_state := AWAIT_BREAK;
end if;
this.old_debug := debug;
-- check if data bus transaction finished
if this.data_o.en = '1' and db_i.ack = '1' then
-- FIXME: Drop en, unless keep_cyc='1'
this.m_dr_next := align_read_data(db_i.d, this.data_o, this.data_o_size);
this.m_en := '1';
this.data_o := NULL_DATA_O;
end if;
-- check if instruction bus transaction finished
if this.inst_o.en = '1' and inst_i.ack = '1' then
this.if_dr_next := inst_i.d;
this.if_en := '1';
this.inst_o := NULL_INST_O;
elsif this.debug_state = READY and debug_i.en = '1' then
-- handle debug command
case debug_i.cmd is
when BREAK =>
-- A BREAK cmd when already in the READY state does nothing
this.debug_o.ack := '1';
when INSERT =>
-- use the instruction from the debug register
this.if_dr_next := debug_i.ir;
this.if_en := '1';
this.stop_pc_inc := '1';
-- latch the y-bus override into start of pipeline
this.ybus_override(this.ybus_override'left) := ( en => debug_i.d_en, d => debug_i.d );
-- await instruction fetch before processing next debug command
next_state := AWAIT_IF;
when STEP =>
-- fetch a real instruction to execute next
this.inst_o := to_inst_o(instr, this.pc);
-- leave debug mode but schedule an enter_debug to get back into debug mode
this.enter_debug(this.enter_debug'left) := '1';
next_state := AWAIT_BREAK;
when CONTINUE =>
-- fetch a real instruction to execute next
this.inst_o := to_inst_o(instr, this.pc);
this.enter_debug(this.enter_debug'left) := '0';
next_state := RUN;
end case;
end if;
if this.stop_pc_inc = '1' then
this.pc_inc := this.pc;
end if;
if this.slot = '1' then
-- Shift enter_debug pipeline along. The left-most bit is duplicated.
-- The right-most bit becomes the enter_debug output.
this.enter_debug := this.enter_debug(this.enter_debug'left) &
this.enter_debug(this.enter_debug'left downto 1);
end if;
if this.data_o.en = '0' and this.inst_o.en = '0' and this.debug_state /= READY then
-- present data read by completed transactions
if this.m_en = '1' then
this.m_dr := this.m_dr_next;
this.m_en := '0';
end if;
if this.if_en = '1' then
this.if_dr := this.if_dr_next;
this.illegal_delay_slot := check_illegal_delay_slot(this.if_dr);
this.illegal_instr := check_illegal_instruction(this.if_dr);
this.if_en := '0';
end if;
this.slot := '1';
else
-- Slot is output as a combinatorial signal. Other blocks use it to
-- determine if a rising clock edge is the start of a new CPU slot
-- or whether the current slot is stretched into the next cycle.
this.slot := '0';
end if;
if this.slot = '1' then
-- start new memory transactions
if mem.issue = '1' and this.data_o.en = '0' then
-- start new data request
case mem.addr_sel is
when SEL_XBUS => ma_ad := xbus;
when SEL_YBUS => ma_ad := ybus;
when SEL_ZBUS => ma_ad := zbus;
end case;
case mem.wdata_sel is
when SEL_YBUS => ma_dw := ybus;
when SEL_ZBUS => ma_dw := zbus;
end case;
this.data_o_size := mem.size;
this.data_o := to_data_o(mem, ma_ad, ma_dw);
end if;
if instr.issue = '1' then
if this.debug_state = RUN or this.debug_state = AWAIT_BREAK then
if this.inst_o.en = '0' then
-- start new instruction request
if instr.addr_sel = '0' then if_ad := this.pc_inc;
else if_ad := zbus;
end if;
this.inst_o := to_inst_o(instr, if_ad, instr.addr_sel);
end if;
elsif this.debug_state = AWAIT_IF or next_state = AWAIT_IF then
-- In debug mode, an instruction fetch issue is our signal to
-- pause the CPU. Later we will either allow the instruction
-- fetch from memory to proceed or we'll insert an instruction.
-- Also check for next_state=AWAIT_IF to skip AWAIT_IF state
-- when decoder is already requesting an instruction.
next_state := READY;
-- Move y-bus override through its pipeline to use in EX
-- stage. Currently the pipeline is short such that the INSERT
-- value used in an instruction has to come in the subsequent
-- INSERT command. Will likely increase pipeline size.
for i in 1 to this.ybus_override'left loop
this.ybus_override(i-1) := this.ybus_override(i);
end loop;
this.ybus_override(this.ybus_override'left) := BUS_VAL_RESET;
end if;
end if;
-- update PC
if pc_ctrl.wr_z = '1' then this.pc := zbus;
elsif pc_ctrl.inc = '1' then this.pc := this.pc_inc; end if;
-- update SR
case sr_ctrl.sel is
when SEL_PREV =>
-- leave sr unchanged
when SEL_WBUS =>
this.sr := to_sr(wbus);
when SEL_ZBUS =>
this.sr := to_sr(zbus);
when SEL_DIV0U =>
this.sr.m := '0';
this.sr.q := '0';
this.sr.t := '0';
when SEL_ARITH =>
this.sr := arith_update_sr(
this.sr,
-- although it feels like aluinx and aluiny have the proper
-- MSB bits here, for DIV1 aluinx has already been shifted
-- left one and the MSB we want is lost. Use xbus instead
-- (and use ybus for symmetry).
-- aluinx(aluinx'left),
-- aluiny(aluiny'left),
xbus(xbus'left),
ybus(ybus'left),
arith_out(31 downto 0),
arith_out(arith_out'left),
arith_func,
func.arith.sr);
when SEL_LOGIC =>
this.sr := logic_update_sr(this.sr, logic_out, func.logic_sr);
when SEL_INT_MASK =>
this.sr.int_mask := sr_ctrl.ilevel;
when SEL_SET_T =>
-- leave most of sr unchanged, but set the T bit
case sr_ctrl.t is
when SEL_CLEAR =>
this.sr.t := '0';
when SEL_SET =>
this.sr.t := '1';
when SEL_SHIFT =>
this.sr.t := sfto;
when SEL_CARRY =>
this.sr.t := arith_out(arith_out'left);
end case;
end case;
if mac.s_latch = '1' then this.mac_s := this.sr.s; end if;
this.data_o_lock := mem.lock;
end if;
this.pc_inc := std_logic_vector(unsigned(this.pc)+2);
-- all debug commands are ACKed when either the RUN or READY state are
-- reached.
if (next_state = RUN or next_state = READY) then
if this.debug_o.ack = '0' and debug_i.en = '1' then
if debug_i.cmd = INSERT then
-- latch the value being written to the register file for the debug
-- output.
this.debug_o.d := reg_wr_data_o;
else
-- latch the PC value to simplify debugging and profiling.
-- Without this multiple inserts, including a JSR and RTS are
-- needed to get the PC.
this.debug_o.d := this.pc;
end if;
end if;
this.debug_o.ack := debug_i.en;
this.stop_pc_inc := '0';
end if;
this.debug_state := next_state;
if this.debug_state = READY then
this.debug_o.rdy := '1';
else
this.debug_o.rdy := '0';
end if;
this_c <= this;
end process;
datapath_r0 : process(clk, rst)
begin
if rst='1' then
this_r <= DATAPATH_RESET;
elsif clk='1' and clk'event then
this_r <= this_c;
end if;
end process;
pc <= this_r.pc;
sr <= this_r.sr;
mac_s <= this_r.mac_s;
db_lock <= this_r.data_o_lock;
db_o <= this_r.data_o;
inst_o <= this_r.inst_o;
if_dr <= this_r.if_dr;
illegal_delay_slot <= this_r.illegal_delay_slot;
illegal_instr <= this_r.illegal_instr;
wbus <= this_r.m_dr;
slot_o <= this_c.slot;
-- Need to output T combinatorially so that decoder can make
-- conditional branch decisions
t_bcc <= this_c.sr.t;
enter_debug <= this_r.enter_debug(0);
mask_int <= '0' when this_r.debug_state = RUN and this_r.enter_debug = (this_r.enter_debug'range => '0') else '1';
debug_o <= this_c.debug_o;
ybus_override <= this_r.ybus_override(0);
if_stall <= '0';
slot <= slot_o;
end architecture stru;

55
datapath_pkg.vhd Normal file
View File

@ -0,0 +1,55 @@
library ieee;
use ieee.std_logic_1164.all;
use work.cpu2j0_pack.all;
use work.decode_pack.all;
use work.cpu2j0_components_pack.all;
use work.mult_pkg.all;
package datapath_pack is
-- SR bit Positions
constant T : integer range 0 to 9 := 0;
constant S : integer range 0 to 9 := 1;
constant I0 : integer range 0 to 9 := 4;
constant I1 : integer range 0 to 9 := 5;
constant I2 : integer range 0 to 9 := 6;
constant I3 : integer range 0 to 9 := 7;
constant Q : integer range 0 to 9 := 8;
constant M : integer range 0 to 9 := 9;
component datapath is port (
clk : in std_logic;
rst : in std_logic;
debug : in std_logic;
enter_debug : out std_logic;
slot : out std_logic;
reg : in reg_ctrl_t;
func : in func_ctrl_t;
sr_ctrl : in sr_ctrl_t;
mac : in mac_ctrl_t;
mem : in mem_ctrl_t;
instr : in instr_ctrl_t;
pc_ctrl : in pc_ctrl_t;
buses : in buses_ctrl_t;
db_lock : out std_logic;
db_o : out cpu_data_o_t;
db_i : in cpu_data_i_t;
inst_o : out cpu_instruction_o_t;
inst_i : in cpu_instruction_i_t;
debug_o : out cpu_debug_o_t;
debug_i : in cpu_debug_i_t;
macin1 : out std_logic_vector(31 downto 0);
macin2 : out std_logic_vector(31 downto 0);
mach : in std_logic_vector(31 downto 0);
macl : in std_logic_vector(31 downto 0);
mac_s : out std_logic;
t_bcc : out std_logic;
ibit : out std_logic_vector(3 downto 0);
if_dr : out std_logic_vector(15 downto 0);
if_stall : out std_logic;
mask_int : out std_logic;
illegal_delay_slot : out std_logic;
illegal_instr : out std_logic);
end component datapath;
end package;

192
decode.vhd Normal file
View File

@ -0,0 +1,192 @@
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
-- This file is generated. Changing this file directly is probably
-- not what you want to do. Any changes will be overwritten next time
-- the generator is run.
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.decode_pack.all;
use work.cpu2j0_components_pack.all;
use work.mult_pkg.all;
use work.cpu2j0_pack.all;
entity decode is
port (
clk : in std_logic;
enter_debug : in std_logic;
event_i : in cpu_event_i_t;
ibit : in std_logic_vector(3 downto 0);
if_dr : in std_logic_vector(15 downto 0);
if_stall : in std_logic;
illegal_delay_slot : in std_logic;
illegal_instr : in std_logic;
mac_busy : in std_logic;
mask_int : in std_logic;
rst : in std_logic;
slot : in std_logic;
t_bcc : in std_logic;
buses : out buses_ctrl_t;
debug : out std_logic;
event_ack : out std_logic;
func : out func_ctrl_t;
instr : out instr_ctrl_t;
mac : out mac_ctrl_t;
mem : out mem_ctrl_t;
pc : out pc_ctrl_t;
reg : out reg_ctrl_t;
slp : out std_logic;
sr : out sr_ctrl_t
);
end;
architecture arch of decode is
signal debug_o : std_logic;
signal delay_jump : std_logic;
signal dispatch : std_logic;
signal event_ack_0 : std_logic;
signal ex : pipeline_ex_t;
signal ex_stall : pipeline_ex_stall_t;
signal id : pipeline_id_t;
signal ilevel_cap : std_logic;
signal mac_stall_sense : std_logic;
signal maskint_next : std_logic;
signal maskint_o : std_logic;
signal next_id_stall : std_logic;
signal op : operation_t;
signal pipeline_c : pipeline_t;
signal pipeline_r : pipeline_t;
signal wb : pipeline_wb_t;
signal wb_stall : pipeline_wb_stall_t;
constant STAGE_EX_RESET : pipeline_ex_t := (imm_val => x"00000000", xbus_sel => SEL_IMM, ybus_sel => SEL_IMM, regnum_z => "00000", regnum_x => "00000", regnum_y => "00000", alumanip => SWAP_BYTE, aluinx_sel => SEL_XBUS, aluiny_sel => SEL_YBUS, arith_func => ADD, arith_ci_en => '0', arith_sr_func => ZERO, logic_func => LOGIC_NOT, logic_sr_func => ZERO, mac_busy => '0', ma_wr => '0', mem_lock => '0', mem_size => BYTE);
constant STAGE_WB_RESET : pipeline_wb_t := (regnum_w => "00000", mac_busy => '0');
constant STAGE_EX_STALL_RESET : pipeline_ex_stall_t := (wrpc_z => '0', wrsr_z => '0', ma_issue => '0', wrpr_pc => '0', zbus_sel => SEL_ARITH, sr_sel => SEL_PREV, t_sel => SEL_CLEAR, mem_addr_sel => SEL_XBUS, mem_wdata_sel => SEL_ZBUS, wrreg_z => '0', wrmach => '0', wrmacl => '0', shiftfunc => LOGIC, mulcom1 => '0', mulcom2 => NOP, macsel1 => SEL_XBUS, macsel2 => SEL_YBUS);
constant STAGE_WB_STALL_RESET : pipeline_wb_stall_t := (mulcom1 => '0', wrmach => '0', wrmacl => '0', wrreg_w => '0', wrsr_w => '0', macsel1 => SEL_XBUS, macsel2 => SEL_YBUS, mulcom2 => NOP);
constant PIPELINE_RESET : pipeline_t := (ex1 => STAGE_EX_RESET, ex1_stall => STAGE_EX_STALL_RESET, wb1 => STAGE_WB_RESET, wb2 => STAGE_WB_RESET, wb3 => STAGE_WB_RESET, wb1_stall => STAGE_WB_STALL_RESET, wb2_stall => STAGE_WB_STALL_RESET, wb3_stall => STAGE_WB_STALL_RESET);
begin
maskint_o <= (mask_int or maskint_next);
debug <= debug_o;
core : decode_core
port map (
clk => clk,
debug => debug_o,
delay_jump => delay_jump,
dispatch => dispatch,
enter_debug => enter_debug,
event_ack_0 => event_ack_0,
event_i => event_i,
ex => ex,
ex_stall => ex_stall,
ibit => ibit,
id => id,
if_dr => if_dr,
if_stall => if_stall,
ilevel_cap => ilevel_cap,
illegal_delay_slot => illegal_delay_slot,
illegal_instr => illegal_instr,
mac_busy => mac_busy,
mac_stall_sense => mac_stall_sense,
maskint_next => maskint_o,
p => pipeline_r,
rst => rst,
slot => slot,
t_bcc => t_bcc,
event_ack => event_ack,
if_issue => instr.issue,
ifadsel => instr.addr_sel,
ilevel => sr.ilevel,
incpc => pc.inc,
next_id_stall => next_id_stall,
op => op
);
table : decode_table
port map (
clk => clk,
next_id_stall => next_id_stall,
op => op,
t_bcc => t_bcc,
debug => debug_o,
delay_jump => delay_jump,
dispatch => dispatch,
event_ack_0 => event_ack_0,
ex => ex,
ex_stall => ex_stall,
id => id,
ilevel_cap => ilevel_cap,
mac_s_latch => mac.s_latch,
mac_stall_sense => mac_stall_sense,
maskint_next => maskint_next,
slp => slp,
wb => wb,
wb_stall => wb_stall
);
-- pipeline controls signals
process(ex, ex_stall, wb, wb_stall, next_id_stall, pipeline_r, slot)
variable pipe : pipeline_t;
begin
pipe := pipeline_r;
if slot = '1' then
pipe.wb3 := pipe.wb2;
pipe.wb2 := pipe.wb1;
pipe.wb1 := wb;
pipe.ex1 := ex;
pipe.wb3_stall := pipe.wb2_stall;
pipe.wb2_stall := pipe.wb1_stall;
if next_id_stall = '1' then
pipe.ex1_stall := STAGE_EX_STALL_RESET;
pipe.wb1_stall := STAGE_WB_STALL_RESET;
else
pipe.ex1_stall := ex_stall;
pipe.wb1_stall := wb_stall;
end if;
end if;
pipeline_c <= pipe;
end process;
process(clk, rst)
begin
if rst = '1' then
pipeline_r <= PIPELINE_RESET;
elsif (clk = '1' and clk'event) then
pipeline_r <= pipeline_c;
end if;
end process;
-- assign outputs
func.alu.inx_sel <= pipeline_r.ex1.aluinx_sel;
func.alu.iny_sel <= pipeline_r.ex1.aluiny_sel;
func.alu.manip <= pipeline_r.ex1.alumanip;
func.arith.ci_en <= pipeline_r.ex1.arith_ci_en;
func.arith.func <= pipeline_r.ex1.arith_func;
func.arith.sr <= pipeline_r.ex1.arith_sr_func;
buses.imm_val <= pipeline_r.ex1.imm_val;
func.logic_func <= pipeline_r.ex1.logic_func;
func.logic_sr <= pipeline_r.ex1.logic_sr_func;
mem.wr <= pipeline_r.ex1.ma_wr;
mem.lock <= pipeline_r.ex1.mem_lock;
mem.size <= pipeline_r.ex1.mem_size;
reg.num_w <= pipeline_r.wb3.regnum_w;
reg.num_x <= pipeline_r.ex1.regnum_x;
reg.num_y <= pipeline_r.ex1.regnum_y;
reg.num_z <= pipeline_r.ex1.regnum_z;
buses.x_sel <= pipeline_r.ex1.xbus_sel;
buses.y_sel <= pipeline_r.ex1.ybus_sel;
mem.issue <= pipeline_r.ex1_stall.ma_issue;
mem.addr_sel <= pipeline_r.ex1_stall.mem_addr_sel;
mem.wdata_sel <= pipeline_r.ex1_stall.mem_wdata_sel;
func.shift <= pipeline_r.ex1_stall.shiftfunc;
sr.t <= pipeline_r.ex1_stall.t_sel;
pc.wr_z <= pipeline_r.ex1_stall.wrpc_z;
pc.wrpr <= pipeline_r.ex1_stall.wrpr_pc;
reg.wr_z <= pipeline_r.ex1_stall.wrreg_z;
buses.z_sel <= pipeline_r.ex1_stall.zbus_sel;
reg.wr_w <= pipeline_r.wb3_stall.wrreg_w;
-- assign combined outputs
mac.com1 <= (pipeline_r.ex1_stall.mulcom1 or pipeline_r.wb3_stall.mulcom1);
mac.wrmach <= (pipeline_r.ex1_stall.wrmach or pipeline_r.wb3_stall.wrmach);
mac.wrmacl <= (pipeline_r.ex1_stall.wrmacl or pipeline_r.wb3_stall.wrmacl);
mac.sel1 <= pipeline_r.ex1_stall.macsel1 when (pipeline_r.ex1_stall.mulcom1 or pipeline_r.ex1_stall.wrmach) = '1' else pipeline_r.wb3_stall.macsel1;
mac.sel2 <= pipeline_r.ex1_stall.macsel2 when (pipeline_r.ex1_stall.mulcom2 /= NOP or pipeline_r.ex1_stall.wrmacl = '1') else pipeline_r.wb3_stall.macsel2;
mac.com2 <= pipeline_r.ex1_stall.mulcom2 when pipeline_r.ex1_stall.mulcom2 /= NOP else pipeline_r.wb3_stall.mulcom2;
sr.sel <= SEL_WBUS when pipeline_r.wb3_stall.wrsr_w = '1' else pipeline_r.ex1_stall.sr_sel;
end;

286
decode_body.vhd Normal file
View File

@ -0,0 +1,286 @@
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
-- This file is generated. Changing this file directly is probably
-- not what you want to do. Any changes will be overwritten next time
-- the generator is run.
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.decode_pack.all;
use work.cpu2j0_components_pack.all;
use work.mult_pkg.all;
package body decode_pack is
function predecode_rom_addr (code : std_logic_vector(15 downto 0)) return std_logic_vector is
variable addr : std_logic_vector(7 downto 0);
begin
case code(15 downto 12) is
when x"0" =>
-- 0000 0000 0000 1000 => 00000000 CLRT
-- 0000 0000 0000 1001 => 00000011 NOP
-- 0000 0000 0000 1011 => 00001000 RTS
-- 0000 0000 0001 1000 => 00001010 SETT
-- 0000 0000 0001 1001 => 00000010 DIV0U
-- 0000 0000 0001 1011 => 00001011 SLEEP
-- 0000 0000 0010 1000 => 00000001 CLRMAC
-- 0000 0000 0010 1011 => 00000100 RTE
-- 0000 0000 0011 1011 => 00001111 BGND
-- 0000 mmmm 0000 0011 => 01001110 BSRF Rm
-- 0000 mmmm 0010 0011 => 01001100 BRAF Rm
-- 0000 nnnn 0000 0010 => 00100010 STC SR, Rn
-- 0000 nnnn 0000 1010 => 00100101 STS MACH, Rn
-- 0000 nnnn 0001 0010 => 00100011 STC GBR, Rn
-- 0000 nnnn 0001 1010 => 00100110 STS MACL, Rn
-- 0000 nnnn 0010 0010 => 00100100 STC VBR, Rn
-- 0000 nnnn 0010 1001 => 00010011 MOVT Rn
-- 0000 nnnn 0010 1010 => 00100111 STS PR, Rn
-- 0000 nnnn mmmm 0100 => 10001100 MOV.B Rm, @(R0, Rn)
-- 0000 nnnn mmmm 0101 => 10001101 MOV.W Rm, @(R0, Rn)
-- 0000 nnnn mmmm 0110 => 10001110 MOV.L Rm, @(R0, Rn)
-- 0000 nnnn mmmm 0111 => 01100111 MUL.L Rm, Rn
-- 0000 nnnn mmmm 1100 => 10001111 MOV.B @(R0, Rm), Rn
-- 0000 nnnn mmmm 1101 => 10010000 MOV.W @(R0, Rm), Rn
-- 0000 nnnn mmmm 1110 => 10010001 MOV.L @(R0, Rm), Rn
-- 0000 nnnn mmmm 1111 => 01111110 MAC.L @Rm+, @Rn+
addr(0) := not ((not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(5) and code(3) and not code(2) and not code(1) and not code(0)) or (not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(5) and code(4) and code(3) and not code(2) and not code(1)) or (not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(4) and code(3) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(4) and not code(3) and not code(2) and code(1)) or (not code(7) and not code(6) and not code(5) and code(4) and code(3) and not code(2) and code(1) and not code(0)) or (code(3) and code(2) and code(0)) or (not code(3) and code(2) and not code(0)));
addr(1) := not ((not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(4) and code(3) and not code(2) and not code(1) and not code(0)) or (not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(4) and code(3) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and code(5) and not code(4) and not code(3) and not code(2) and code(1)) or (not code(7) and not code(6) and not code(5) and not code(4) and code(3) and not code(2) and code(1) and not code(0)) or (not code(3) and code(2) and not code(1)) or (code(2) and not code(1) and code(0)) or (code(3) and code(2) and code(1) and not code(0)));
addr(2) := not ((not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(4) and code(3) and not code(2) and not code(1) and not code(0)) or (not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(5) and code(3) and not code(2) and code(0)) or (not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(5) and code(3) and not code(2) and not code(1)) or (not code(7) and not code(6) and code(5) and not code(4) and code(3) and not code(2) and not code(1) and code(0)) or (not code(7) and not code(6) and not code(5) and not code(3) and not code(2) and code(1) and not code(0)) or (code(3) and code(2) and not code(1) and code(0)) or (code(3) and code(2) and code(1) and not code(0)));
addr(3) := ((not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(5) and code(3) and not code(2) and code(1) and code(0)) or (not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and not code(5) and code(4) and code(3) and not code(2) and not code(1) and not code(0)) or (not code(11) and not code(10) and not code(9) and not code(8) and not code(7) and not code(6) and code(4) and code(3) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(4) and not code(3) and not code(2) and code(1) and code(0)) or (code(3) and code(2) and code(1) and code(0)) or (not code(3) and code(2) and not code(1)) or (not code(3) and code(2) and not code(0)) or (code(2) and not code(1) and not code(0)));
addr(4) := ((not code(7) and not code(6) and code(5) and not code(4) and code(3) and not code(2) and not code(1) and code(0)) or (code(3) and code(2) and code(0)) or (code(3) and code(2) and code(1)));
addr(5) := ((not code(7) and not code(6) and not code(5) and not code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(4) and not code(2) and code(1) and not code(0)) or (code(2) and code(1) and code(0)));
addr(6) := ((not code(7) and not code(6) and not code(4) and not code(3) and not code(2) and code(1) and code(0)) or (code(2) and code(1) and code(0)));
addr(7) := ((code(2) and not code(1)) or (code(2) and not code(0)));
when x"1" =>
-- 0001 nnnn mmmm dddd => 10010110 MOV.L Rm, @(disp, Rn)
addr := x"96";
when x"2" =>
-- 0010 nnnn mmmm 0000 => 01111000 MOV.B Rm, @Rn
-- 0010 nnnn mmmm 0001 => 01111001 MOV.W Rm, @Rn
-- 0010 nnnn mmmm 0010 => 01111010 MOV.L Rm, @Rn
-- 0010 nnnn mmmm 0011 => 01011010 CAS.L Rm, Rn, @R0
-- 0010 nnnn mmmm 0100 => 10001001 MOV.B Rm,@-Rn
-- 0010 nnnn mmmm 0101 => 10001010 MOV.W Rm,@-Rn
-- 0010 nnnn mmmm 0110 => 10001011 MOV.L Rm,@-Rn
-- 0010 nnnn mmmm 0111 => 01011111 DIV0S Rm, Rn
-- 0010 nnnn mmmm 1000 => 01110011 TST Rm, Rn
-- 0010 nnnn mmmm 1001 => 01010011 AND Rm, Rn
-- 0010 nnnn mmmm 1010 => 01110100 XOR Rm, Rn
-- 0010 nnnn mmmm 1011 => 01101101 OR Rm, Rn
-- 0010 nnnn mmmm 1100 => 01011001 CMP /STR Rm, Rn
-- 0010 nnnn mmmm 1101 => 01110101 XTRACT Rm, Rn
-- 0010 nnnn mmmm 1110 => 01101001 MULU.W Rm, Rn
-- 0010 nnnn mmmm 1111 => 01101000 MULS.W Rm, Rn
addr(0) := not ((not code(3) and not code(2) and code(1)) or (code(3) and code(2) and code(1) and code(0)) or (not code(2) and code(1) and not code(0)) or (not code(3) and not code(2) and not code(0)) or (not code(3) and code(2) and not code(1) and code(0)));
addr(1) := ((code(3) and not code(2) and not code(1)) or (not code(3) and code(1)) or (not code(3) and code(2) and code(0)));
addr(2) := ((not code(3) and code(2) and code(1) and code(0)) or (code(3) and not code(2) and code(1)) or (code(3) and code(2) and not code(1) and code(0)));
addr(3) := not ((code(3) and not code(2) and not code(0)) or (code(3) and not code(1) and code(0)));
addr(4) := not ((code(3) and code(1) and code(0)) or (not code(3) and code(2) and not code(1)) or (code(2) and code(1) and not code(0)));
addr(5) := not ((code(3) and not code(2) and not code(1) and code(0)) or (code(2) and not code(1) and not code(0)) or (not code(3) and code(1) and code(0)) or (not code(3) and code(2)));
addr(6) := not ((not code(3) and code(2) and not code(1)) or (not code(3) and code(2) and not code(0)));
addr(7) := ((not code(3) and code(2) and not code(1)) or (not code(3) and code(2) and not code(0)));
when x"3" =>
-- 0011 nnnn mmmm 0000 => 01010100 CMP /EQ Rm, Rn
-- 0011 nnnn mmmm 0010 => 01010101 CMP /HS Rm, Rn
-- 0011 nnnn mmmm 0011 => 01010110 CMP /GE Rm, Rn
-- 0011 nnnn mmmm 0100 => 01011110 DIV1 Rm, Rn
-- 0011 nnnn mmmm 0101 => 01100001 DMULU.L Rm, Rn
-- 0011 nnnn mmmm 0110 => 01010111 CMP /HI Rm, Rn
-- 0011 nnnn mmmm 0111 => 01011000 CMP /GT Rm, Rn
-- 0011 nnnn mmmm 1000 => 01101110 SUB Rm, Rn
-- 0011 nnnn mmmm 1010 => 01101111 SUBC Rm, Rn
-- 0011 nnnn mmmm 1011 => 01110000 SUBV Rm, Rn
-- 0011 nnnn mmmm 1100 => 01010000 ADD Rm, Rn
-- 0011 nnnn mmmm 1101 => 01100000 DMULS.L Rm, Rn
-- 0011 nnnn mmmm 1110 => 01010001 ADDC Rm, Rn
-- 0011 nnnn mmmm 1111 => 01010010 ADDV Rm, Rn
addr(0) := ((code(1) and not code(0)) or (not code(3) and code(2) and not code(1) and code(0)));
addr(1) := ((code(3) and code(2) and code(1) and code(0)) or (not code(3) and not code(2) and code(1) and code(0)) or (not code(3) and code(2) and not code(0)) or (code(3) and not code(2) and not code(0)));
addr(2) := not ((code(3) and code(2)) or (code(2) and code(0)) or (code(3) and code(1) and code(0)));
addr(3) := ((not code(3) and code(2) and code(1) and code(0)) or (not code(3) and code(2) and not code(1) and not code(0)) or (code(3) and not code(2) and not code(0)));
addr(4) := not ((code(2) and not code(1) and code(0)) or (code(3) and not code(2) and not code(0)));
addr(5) := ((code(2) and not code(1) and code(0)) or (code(3) and not code(2) and not code(0)) or (code(3) and not code(2) and code(1)));
addr(6) := '1';
addr(7) := '0';
when x"4" =>
-- 0100 mmmm 0000 0110 => 01001000 LDS.L @Rm+, MACH
-- 0100 mmmm 0000 0111 => 00111111 LDC.L @Rm+, SR
-- 0100 mmmm 0000 1010 => 00111000 LDS Rm, MACH
-- 0100 mmmm 0000 1011 => 00111101 JSR @Rm
-- 0100 mmmm 0000 1110 => 00110101 LDC Rm, SR
-- 0100 mmmm 0001 0110 => 01001001 LDS.L @Rm+, MACL
-- 0100 mmmm 0001 0111 => 01000010 LDC.L @Rm+, GBR
-- 0100 mmmm 0001 1010 => 00111001 LDS Rm, MACL
-- 0100 mmmm 0001 1110 => 00110110 LDC, Rm, GBR
-- 0100 mmmm 0010 0110 => 01001010 LDS.L @Rm+, PR
-- 0100 mmmm 0010 0111 => 01000101 LDC.L @Rm+, VBR
-- 0100 mmmm 0010 1010 => 00111010 LDS Rm, PR
-- 0100 mmmm 0010 1011 => 00111011 JMP @Rm
-- 0100 mmmm 0010 1110 => 00110111 LDC Rm, VBR
-- 0100 nnnn 0000 0000 => 00011010 SHLL Rn
-- 0100 nnnn 0000 0001 => 00011011 SHLR Rn
-- 0100 nnnn 0000 0010 => 00110010 STS.L MACH, @-Rn
-- 0100 nnnn 0000 0011 => 00101100 STC.L SR, @-Rn
-- 0100 nnnn 0000 0100 => 00010100 ROTL Rn
-- 0100 nnnn 0000 0101 => 00010101 ROTR Rn
-- 0100 nnnn 0000 1000 => 00011100 SHLL2 Rn
-- 0100 nnnn 0000 1001 => 00011101 SHLR2 Rn
-- 0100 nnnn 0001 0000 => 00010010 DT Rn
-- 0100 nnnn 0001 0001 => 00010001 CMP/PZ Rn
-- 0100 nnnn 0001 0010 => 00110011 STS.L MACL, @-Rn
-- 0100 nnnn 0001 0011 => 00101110 STC.L GBR, @-Rn
-- 0100 nnnn 0001 0101 => 00010000 CMP/PL Rn
-- 0100 nnnn 0001 1000 => 00011110 SHLL8 Rn
-- 0100 nnnn 0001 1001 => 00011111 SHLR8 Rn
-- 0100 nnnn 0001 1011 => 00101000 TAS.B @Rn
-- 0100 nnnn 0010 0000 => 00011000 SHAL Rn
-- 0100 nnnn 0010 0001 => 00011001 SHAR Rn
-- 0100 nnnn 0010 0010 => 00110100 STS.L PR, @-Rn
-- 0100 nnnn 0010 0011 => 00110000 STC.L VBR, @-Rn
-- 0100 nnnn 0010 0100 => 00010110 ROTCL Rn
-- 0100 nnnn 0010 0101 => 00010111 ROTCR Rn
-- 0100 nnnn 0010 1000 => 00100000 SHLL16 Rn
-- 0100 nnnn 0010 1001 => 00100001 SHLR16 Rn
-- 0100 nnnn mmmm 1100 => 01110110 SHAD Rm, Rn
-- 0100 nnnn mmmm 1101 => 01110111 SHLD Rm, Rn
-- 0100 nnnn mmmm 1111 => 10000001 MAC.W @Rm+, @Rn+
addr(0) := not ((not code(7) and not code(6) and not code(5) and code(4) and not code(3) and code(2) and code(0)) or (not code(7) and not code(6) and not code(5) and not code(2) and not code(1) and not code(0)) or (not code(7) and not code(6) and not code(4) and not code(3) and not code(0)) or (not code(7) and not code(6) and not code(4) and not code(2) and not code(0)) or (not code(7) and not code(6) and not code(5) and code(4) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(4) and not code(3) and not code(2) and code(1)) or (not code(7) and not code(6) and not code(5) and code(4) and code(3) and code(2) and code(1) and not code(0)) or (code(3) and code(2) and not code(1) and not code(0)));
addr(1) := not ((not code(7) and not code(6) and not code(5) and code(4) and not code(3) and not code(1) and code(0)) or (not code(7) and not code(6) and not code(5) and code(3) and not code(2) and code(1)) or (not code(7) and not code(6) and code(5) and not code(4) and not code(3) and not code(2)) or (not code(7) and not code(6) and code(5) and not code(4) and not code(3) and code(1) and code(0)) or (not code(7) and not code(6) and not code(5) and not code(3) and code(2) and code(1) and not code(0)) or (code(3) and code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(4) and code(3) and not code(2) and not code(1)) or (not code(7) and not code(6) and not code(5) and not code(4) and not code(3) and code(2) and not code(1)) or (not code(7) and not code(6) and not code(4) and not code(3) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(5) and not code(4) and code(3) and code(1) and not code(0)));
addr(2) := ((not code(7) and not code(6) and not code(4) and not code(3) and code(2) and not code(1)) or (not code(7) and not code(6) and not code(5) and code(3) and not code(2) and not code(1)) or (not code(7) and not code(6) and not code(5) and not code(3) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and code(5) and not code(4) and not code(3) and not code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(5) and code(3) and code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(4) and code(3) and code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(4) and not code(3) and code(2) and code(0)) or (code(3) and code(2) and not code(1)) or (not code(7) and not code(6) and not code(5) and not code(4) and code(3) and not code(2) and code(0)));
addr(3) := ((not code(7) and not code(6) and not code(4) and not code(3) and not code(2) and not code(1)) or (not code(7) and not code(6) and not code(5) and code(3) and not code(2)) or (not code(7) and not code(6) and not code(5) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(4) and code(3) and not code(2) and code(1)) or (not code(7) and not code(6) and not code(5) and not code(3) and code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(4) and not code(3) and code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(5) and not code(4) and not code(3) and code(1) and code(0)));
addr(4) := not ((not code(7) and not code(6) and code(5) and not code(4) and code(3) and not code(2) and not code(1)) or (not code(7) and not code(6) and not code(5) and code(4) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(5) and not code(3) and not code(2) and code(1) and code(0)) or (not code(7) and not code(6) and code(5) and not code(4) and not code(3) and code(2) and code(1)) or (code(3) and code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(5) and not code(3) and code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(5) and code(4) and not code(3) and code(1) and code(0)));
addr(5) := not ((not code(7) and not code(6) and not code(5) and not code(2) and not code(1)) or (not code(7) and not code(6) and not code(4) and not code(3) and not code(1)) or (not code(7) and not code(6) and code(5) and not code(4) and not code(3) and code(2)) or (code(3) and code(2) and code(1) and code(0)) or (not code(7) and not code(6) and not code(5) and not code(3) and code(2) and code(1) and not code(0)) or (not code(7) and not code(6) and not code(5) and code(4) and not code(3) and code(2) and code(0)));
addr(6) := ((not code(7) and not code(6) and not code(5) and code(4) and not code(3) and code(2) and code(1)) or (not code(7) and not code(6) and code(5) and not code(4) and not code(3) and code(2) and code(1)) or (code(3) and code(2) and not code(1)) or (not code(7) and not code(6) and not code(5) and not code(3) and code(2) and code(1) and not code(0)));
addr(7) := ((code(3) and code(2) and code(1) and code(0)));
when x"5" =>
-- 0101 nnnn mmmm dddd => 10010111 MOV.L @(disp, Rm), Rn
addr := x"97";
when x"6" =>
-- 0110 nnnn mmmm 0000 => 01111011 MOV.B @Rm, Rn
-- 0110 nnnn mmmm 0001 => 01111100 MOV.W @Rm, Rn
-- 0110 nnnn mmmm 0010 => 01111101 MOV.L @Rm, Rn
-- 0110 nnnn mmmm 0011 => 01100110 MOV Rm, Rn
-- 0110 nnnn mmmm 0100 => 10000011 MOV.B @Rm+, Rn
-- 0110 nnnn mmmm 0101 => 10000101 MOV.W @Rm+, Rn
-- 0110 nnnn mmmm 0110 => 10000111 MOV.L @Rm+, Rn
-- 0110 nnnn mmmm 0111 => 01101100 NOT Rm, Rn
-- 0110 nnnn mmmm 1000 => 01110001 SWAP.B Rm, Rn
-- 0110 nnnn mmmm 1001 => 01110010 SWAP.W Rm, Rn
-- 0110 nnnn mmmm 1010 => 01101011 NEGC Rm, Rn
-- 0110 nnnn mmmm 1011 => 01101010 NEG Rm, Rn
-- 0110 nnnn mmmm 1100 => 01100100 EXTU.B Rm, Rn
-- 0110 nnnn mmmm 1101 => 01100101 EXTU.W Rm, Rn
-- 0110 nnnn mmmm 1110 => 01100010 EXTS.B Rm, Rn
-- 0110 nnnn mmmm 1111 => 01100011 EXTS.W Rm, Rn
addr(0) := not ((code(3) and code(2) and not code(0)) or (not code(2) and code(0)) or (not code(3) and code(1) and code(0)));
addr(1) := not ((not code(3) and code(2) and code(0)) or (code(3) and not code(1) and not code(0)) or (not code(3) and not code(1) and code(0)) or (not code(3) and not code(2) and code(1) and not code(0)) or (code(3) and code(2) and not code(1)));
addr(2) := not ((code(3) and code(1)) or (code(3) and not code(2)) or (not code(3) and not code(1) and not code(0)));
addr(3) := ((code(3) and not code(2) and code(1)) or (not code(3) and code(2) and code(1) and code(0)) or (not code(3) and not code(2) and not code(1)) or (not code(3) and not code(2) and not code(0)));
addr(4) := ((not code(2) and not code(1)) or (not code(3) and not code(2) and not code(0)));
addr(5) := not ((not code(3) and code(2) and not code(1)) or (not code(3) and code(2) and not code(0)));
addr(6) := not ((not code(3) and code(2) and not code(1)) or (not code(3) and code(2) and not code(0)));
addr(7) := ((not code(3) and code(2) and not code(1)) or (not code(3) and code(2) and not code(0)));
when x"7" =>
-- 0111 nnnn iiii iiii => 11000111 ADD #imm, Rn
addr := x"c7";
when x"8" =>
-- 1000 0000 nnnn dddd => 10010100 MOV.B R0, @(disp, Rn)
-- 1000 0001 nnnn dddd => 10010101 MOV.W R0, @(disp, Rn)
-- 1000 0100 mmmm dddd => 10010010 MOV.B @(disp, Rm), R0
-- 1000 0101 mmmm dddd => 10010011 MOV.W @(disp, Rm), R0
-- 1000 1000 iiii iiii => 10111100 CMP /EQ #imm, R0
-- 1000 1001 dddd dddd => 10100100 BT label
-- 1000 1011 dddd dddd => 10011111 BF label
-- 1000 1101 dddd dddd => 10100111 BT /S label
-- 1000 1111 dddd dddd => 10100010 BF /S label
addr(0) := not ((not code(11) and not code(9) and not code(8)) or (code(11) and code(10) and code(9) and code(8)) or (code(11) and not code(10) and not code(9)));
addr(1) := not ((not code(10) and not code(9)));
addr(2) := not ((not code(11) and code(10) and not code(9)) or (code(11) and code(10) and code(9) and code(8)));
addr(3) := ((code(11) and not code(10) and code(9) and code(8)) or (code(11) and not code(10) and not code(9) and not code(8)));
addr(4) := not ((code(11) and code(10) and code(8)) or (code(11) and not code(9) and code(8)));
addr(5) := not ((not code(11) and not code(9)) or (code(11) and not code(10) and code(9) and code(8)));
addr(6) := '0';
addr(7) := '1';
when x"9" =>
-- 1001 nnnn dddd dddd => 10101101 MOV.W @(disp, PC), Rn
addr := x"ad";
when x"a" =>
-- 1010 dddd dddd dddd => 10101001 BRA label
addr := x"a9";
when x"b" =>
-- 1011 dddd dddd dddd => 10101011 BSR label
addr := x"ab";
when x"c" =>
-- 1100 0000 dddd dddd => 10011000 MOV.B R0, @(disp, GBR)
-- 1100 0001 dddd dddd => 10011001 MOV.W R0, @(disp, GBR)
-- 1100 0010 dddd dddd => 10011010 MOV.L R0, @(disp, GBR)
-- 1100 0011 iiii iiii => 11000000 TRAPA #imm
-- 1100 0100 dddd dddd => 10011011 MOV.B @(disp, GBR), R0
-- 1100 0101 dddd dddd => 10011100 MOV.W @(disp, GBR), R0
-- 1100 0110 dddd dddd => 10011101 MOV.L @(disp, GBR), R0
-- 1100 0111 dddd dddd => 10011110 MOVA @(disp, PC), R0
-- 1100 1000 iiii iiii => 10111110 TST #imm, R0
-- 1100 1001 iiii iiii => 10111011 AND #imm, R0
-- 1100 1010 iiii iiii => 10111111 XOR #imm, R0
-- 1100 1011 iiii iiii => 10111101 OR #imm, R0
-- 1100 1100 iiii iiii => 10110101 TST.B #imm, @(R0, GBR)
-- 1100 1101 iiii iiii => 10101111 AND.B #imm, @(R0, GBR)
-- 1100 1110 iiii iiii => 10111000 XOR.B #imm, @(R0, GBR)
-- 1100 1111 iiii iiii => 10110010 OR.B #imm, @(R0, GBR)
addr(0) := not ((not code(11) and code(10) and code(8)) or (code(11) and code(10) and code(9)) or (not code(10) and not code(9) and not code(8)) or (not code(11) and not code(10) and code(9)));
addr(1) := not ((not code(11) and not code(10) and not code(9)) or (not code(11) and not code(9) and code(8)) or (code(10) and code(9) and not code(8)) or (code(11) and code(10) and not code(8)) or (not code(10) and code(9) and code(8)));
addr(2) := not ((not code(11) and not code(10)) or (not code(11) and not code(9) and not code(8)) or (code(11) and code(10) and code(9)) or (not code(10) and not code(9) and code(8)));
addr(3) := not ((code(11) and code(10) and code(9) and code(8)) or (code(11) and code(10) and not code(9) and not code(8)) or (not code(11) and not code(10) and code(9) and code(8)));
addr(4) := not ((code(11) and code(10) and not code(9) and code(8)) or (not code(11) and not code(10) and code(9) and code(8)));
addr(5) := not (not code(11));
addr(6) := ((not code(11) and not code(10) and code(9) and code(8)));
addr(7) := '1';
when x"d" =>
-- 1101 nnnn dddd dddd => 10101110 MOV.L @(disp, PC), Rn
addr := x"ae";
when x"e" =>
-- 1110 nnnn iiii iiii => 11001000 MOV #imm, Rn
addr := x"c8";
when others =>
addr := x"ff";
end case;
return addr;
end;
function check_illegal_delay_slot (code : std_logic_vector(15 downto 0)) return std_logic is
begin
-- Check for instructions that assign to PC:
-- RTE, RTS, JMP @Rm, JSR @Rm, BRAF Rm, BSRF Rm, BF label, BF /S label, BT label, BT /S label, BRA label, BSR label, TRAPA #imm
if ((code(15 downto 12) = "0000" and code(3 downto 2) = "00" and code(0) = '1') or (code(15 downto 14) = "10" and code(12 downto 11) = "01" and code(8) = '1') or code(15 downto 13) = "101" or (code(15) = '1' and code(13 downto 8) = "000011") or (code(15) = '0' and code(13 downto 12) = "00" and code(4 downto 0) = "01011")) then
return '1';
else
return '0';
end if;
end;
function check_illegal_instruction (code : std_logic_vector(15 downto 0)) return std_logic is
begin
-- TODO: Improve detection of illegal instructions
if code(15 downto 8) = x"ff" then
return '1';
else
return '0';
end if;
end;
end;

191
decode_core.vhd Normal file
View File

@ -0,0 +1,191 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.decode_pack.all;
use work.cpu2j0_pack.all;
entity decode_core is
generic (
decode_type : cpu_decode_type_t := REVERSE;
reset_vector : decode_core_reg_t := DEC_CORE_RESET);
port (
clk : in std_logic;
delay_jump : in std_logic;
dispatch : in std_logic;
event_ack_0 : in std_logic;
event_i : in cpu_event_i_t;
ex : in pipeline_ex_t;
ex_stall : in pipeline_ex_stall_t;
ibit : in std_logic_vector(3 downto 0);
id : in pipeline_id_t;
if_dr : in std_logic_vector(15 downto 0);
if_stall : in std_logic;
ilevel_cap : in std_logic;
illegal_delay_slot : in std_logic;
illegal_instr : in std_logic;
mac_busy : in std_logic;
mac_stall_sense : in std_logic;
maskint_next : in std_logic;
p : in pipeline_t;
rst : in std_logic;
slot : in std_logic;
t_bcc : in std_logic;
debug : in std_logic;
enter_debug : in std_logic;
event_ack : out std_logic;
if_issue : out std_logic;
ifadsel : out std_logic;
ilevel : out std_logic_vector(3 downto 0);
incpc : out std_logic;
op : out operation_t;
next_id_stall : out std_logic
);
end;
architecture arch of decode_core is
signal mac_stall : std_logic;
signal reg_conf : std_logic;
signal next_op : operation_t;
signal instr_state_sel : std_logic;
signal next_id_stall_a : std_logic;
signal maskint : std_logic;
signal delay_slot : std_logic;
signal this_c : decode_core_reg_t;
signal this_r : decode_core_reg_t := reset_vector;
function system_op (code : std_logic_vector(15 downto 0); instr : system_instr_t)
return operation_t is
variable op : operation_t;
begin
op.plane := SYSTEM_INSTR;
op.code := code;
if decode_type = MICROCODE then
-- Microcode-based decoder requires an address into the ROM that is different
-- for each system instruction
op.addr := system_instr_rom_addrs(instr);
else
op.addr := x"00";
end if;
return op;
end;
function system_op (instr : system_instr_t)
return operation_t is
variable cd : std_logic_vector(15 downto 0);
begin
cd := x"0" & system_instr_codes(instr) & x"00";
return system_op(cd, instr);
end;
function system_op (event : cpu_event_i_t)
return operation_t is
variable code : std_logic_vector(15 downto 0);
begin
code := x"0" & system_event_codes(event.cmd) & event.vec;
return system_op(code, system_event_instrs(event.cmd));
end;
function normal_op (instr : std_logic_vector(15 downto 0))
return operation_t is
variable op : operation_t;
begin
op.plane := NORMAL_INSTR;
op.code := instr;
if decode_type = MICROCODE then
-- Microcode-based decoder requires a first stage decode from the instruction
-- to the address in the ROM where the microcode starts for the instruction
op.addr := predecode_rom_addr(instr);
else
op.addr := x"00";
end if;
return op;
end;
begin
decode_core : process(this_r,slot,next_id_stall_a,ilevel_cap,dispatch,maskint_next,delay_jump,event_i,next_op)
variable this : decode_core_reg_t;
begin
this := this_r;
if slot = '1' then
this.maskint := maskint_next;
if ilevel_cap = '1' then
this.ilevel := event_i.lvl;
end if;
if this.id_stall = '0' and this.instr_seq_zero = '1' then
this.op := next_op;
end if;
this.id_stall := next_id_stall_a;
if next_id_stall_a = '0' then
this.delay_slot := delay_jump;
this.instr_seq_zero := dispatch;
this.op.addr := std_logic_vector(unsigned(this.op.addr) + 1);
end if;
end if;
this_c <= this;
end process;
decode_core_r0 : process(clk, rst)
begin
if rst='1' then
this_r <= reset_vector;
elsif clk='1' and clk'event then
this_r <= this_c;
end if;
end process;
maskint <= this_r.maskint;
delay_slot <= this_r.delay_slot;
ilevel <= this_r.ilevel;
mac_stall <= mac_stall_sense and (p.wb1.mac_busy or p.wb2.mac_busy or
p.wb3.mac_busy or p.ex1.mac_busy or mac_busy);
-- Next ID STALL
next_id_stall_a <= reg_conf or if_stall or mac_stall;
next_id_stall <= next_id_stall_a;
incpc <= id.incpc and not(next_id_stall_a);
ifadsel <= id.ifadsel;
if_issue <= id.if_issue and not(reg_conf) and not(mac_stall);
-- Detect Exception Events
next_op <=
system_op(event_i)
-- Interrupts, (address) errors, reset and break
when delay_slot = '0' and event_i.en = '1' and (
( maskint = '0' and event_i.cmd = INTERRUPT and ( ibit < event_i.lvl or event_i.msk = '1' ) ) or
( event_i.cmd = ERROR or event_i.cmd = RESET_CPU or event_i.cmd = BREAK ) ) else
-- Slot Illegal Instruction
system_op(SLOT_ILLEGAL)
when delay_slot = '1' and (illegal_delay_slot or illegal_instr) = '1' else
-- General Illegal Instruction
system_op(GENERAL_ILLEGAL)
when illegal_instr = '1' else
-- Break Instruction
system_op(BREAK)
when delay_slot = '0' and enter_debug = '1' else
-- Normal instruction
normal_op(if_dr);
event_ack <= '1' when slot = '1' and (event_ack_0 = '1' or (event_i.en = '1' and event_i.cmd = BREAK and debug = '1') ) else '0';
op <= this_r.op when this_r.id_stall = '1' or this_r.instr_seq_zero = '0'
else next_op;
-- Detect register conflict
reg_conf <=
'1' when
-- W bus write to register
(p.wb1_stall.wrreg_w = '1' and
((ex.xbus_sel = SEL_REG and ex.regnum_x = p.wb1.regnum_w) or
(ex.ybus_sel = SEL_REG and ex.regnum_y = p.wb1.regnum_w) or
(ex_stall.wrreg_z = '1' and ex.regnum_z = p.wb1.regnum_w) or
-- write to R0
(ex.aluiny_sel = SEL_R0 and p.wb1.regnum_w = "00000")))
else '0';
end;

287
decode_pkg.vhd Normal file
View File

@ -0,0 +1,287 @@
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
-- This file is generated. Changing this file directly is probably
-- not what you want to do. Any changes will be overwritten next time
-- the generator is run.
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
library ieee;
use ieee.std_logic_1164.all;
use work.cpu2j0_components_pack.all;
use work.mult_pkg.all;
use work.cpu2j0_pack.all;
package decode_pack is
type aluinx_sel_t is (SEL_XBUS, SEL_FC, SEL_ROTCL, SEL_ZERO);
type aluiny_sel_t is (SEL_YBUS, SEL_IMM, SEL_R0);
type cpu_decode_type_t is (SIMPLE, REVERSE, MICROCODE);
type immval_t is (IMM_ZERO, IMM_P1, IMM_P2, IMM_P4, IMM_P8, IMM_P16, IMM_N16, IMM_N8, IMM_N2, IMM_N1, IMM_U_4_0, IMM_U_4_1, IMM_U_4_2, IMM_U_8_0, IMM_U_8_1, IMM_U_8_2, IMM_S_8_1, IMM_S_12_1, IMM_S_8_0);
type instruction_plane_t is (NORMAL_INSTR, SYSTEM_INSTR);
type mac_busy_t is (NOT_BUSY, EX_NOT_STALL, WB_NOT_STALL, EX_BUSY, WB_BUSY);
type macin1_sel_t is (SEL_XBUS, SEL_ZBUS, SEL_WBUS);
type macin2_sel_t is (SEL_YBUS, SEL_ZBUS, SEL_WBUS);
type mem_addr_sel_t is (SEL_XBUS, SEL_YBUS, SEL_ZBUS);
type mem_wdata_sel_t is (SEL_ZBUS, SEL_YBUS);
type reg_sel_t is (SEL_R0, SEL_R15, SEL_RA, SEL_RB);
type sr_sel_t is (SEL_PREV, SEL_WBUS, SEL_ZBUS, SEL_DIV0U, SEL_ARITH, SEL_LOGIC, SEL_INT_MASK, SEL_SET_T);
type t_sel_t is (SEL_CLEAR, SEL_SET, SEL_SHIFT, SEL_CARRY);
type xbus_sel_t is (SEL_IMM, SEL_REG, SEL_PC);
type ybus_sel_t is (SEL_IMM, SEL_REG, SEL_MACH, SEL_MACL, SEL_PC, SEL_SR);
type zbus_sel_t is (SEL_ARITH, SEL_LOGIC, SEL_SHIFT, SEL_MANIP, SEL_YBUS, SEL_WBUS);
type operation_t is
record
plane : instruction_plane_t;
code : std_logic_vector(15 downto 0);
addr : std_logic_vector(7 downto 0);
end record;
type alu_ctrl_t is
record
manip : alumanip_t;
inx_sel : aluinx_sel_t;
iny_sel : aluiny_sel_t;
end record;
type arith_ctrl_t is
record
func : arith_func_t;
ci_en : std_logic;
sr : arith_sr_func_t;
end record;
type buses_ctrl_t is
record
x_sel : xbus_sel_t;
y_sel : ybus_sel_t;
z_sel : zbus_sel_t;
imm_val : std_logic_vector(31 downto 0);
end record;
type func_ctrl_t is
record
alu : alu_ctrl_t;
shift : shiftfunc_t;
arith : arith_ctrl_t;
logic_func : logic_func_t;
logic_sr : logic_sr_func_t;
end record;
type instr_ctrl_t is
record
issue : std_logic;
addr_sel : std_logic;
end record;
type mac_ctrl_t is
record
com1 : std_logic;
wrmach : std_logic;
wrmacl : std_logic;
s_latch : std_logic;
sel1 : macin1_sel_t;
sel2 : macin2_sel_t;
com2 : mult_state_t;
end record;
type mem_ctrl_t is
record
issue : std_logic;
wr : std_logic;
lock : std_logic;
size : mem_size_t;
addr_sel : mem_addr_sel_t;
wdata_sel : mem_wdata_sel_t;
end record;
type pc_ctrl_t is
record
wr_z : std_logic;
wrpr : std_logic;
inc : std_logic;
end record;
type reg_ctrl_t is
record
num_x : regnum_t;
num_y : regnum_t;
num_z : regnum_t;
num_w : regnum_t;
wr_z : std_logic;
wr_w : std_logic;
end record;
type sr_ctrl_t is
record
sel : sr_sel_t;
t : t_sel_t;
ilevel : std_logic_vector(3 downto 0);
end record;
type pipeline_ex_stall_t is
record
wrpc_z : std_logic;
wrsr_z : std_logic;
ma_issue : std_logic;
wrpr_pc : std_logic;
zbus_sel : zbus_sel_t;
sr_sel : sr_sel_t;
t_sel : t_sel_t;
mem_addr_sel : mem_addr_sel_t;
mem_wdata_sel : mem_wdata_sel_t;
wrreg_z : std_logic;
wrmach, wrmacl : std_logic;
shiftfunc : shiftfunc_t;
mulcom1 : std_logic;
mulcom2 : mult_state_t;
macsel1 : macin1_sel_t;
macsel2 : macin2_sel_t;
end record;
type pipeline_ex_t is
record
imm_val : std_logic_vector(31 downto 0);
xbus_sel : xbus_sel_t;
ybus_sel : ybus_sel_t;
regnum_z, regnum_x, regnum_y : regnum_t;
alumanip : alumanip_t;
aluinx_sel : aluinx_sel_t;
aluiny_sel : aluiny_sel_t;
arith_func : arith_func_t;
arith_ci_en : std_logic;
arith_sr_func : arith_sr_func_t;
logic_func : logic_func_t;
logic_sr_func : logic_sr_func_t;
mac_busy : std_logic;
ma_wr : std_logic;
mem_lock : std_logic;
mem_size : mem_size_t;
end record;
type pipeline_id_t is
record
incpc : std_logic;
if_issue : std_logic;
ifadsel : std_logic;
end record;
type pipeline_wb_stall_t is
record
mulcom1 : std_logic;
wrmach, wrmacl : std_logic;
wrreg_w, wrsr_w : std_logic;
macsel1 : macin1_sel_t;
macsel2 : macin2_sel_t;
mulcom2 : mult_state_t;
end record;
type pipeline_wb_t is
record
regnum_w : regnum_t;
mac_busy : std_logic;
end record;
type pipeline_t is
record
ex1 : pipeline_ex_t;
ex1_stall : pipeline_ex_stall_t;
wb1 : pipeline_wb_t;
wb2 : pipeline_wb_t;
wb3 : pipeline_wb_t;
wb1_stall : pipeline_wb_stall_t;
wb2_stall : pipeline_wb_stall_t;
wb3_stall : pipeline_wb_stall_t;
end record;
component decode
port (
clk : in std_logic;
enter_debug : in std_logic;
event_i : in cpu_event_i_t;
ibit : in std_logic_vector(3 downto 0);
if_dr : in std_logic_vector(15 downto 0);
if_stall : in std_logic;
illegal_delay_slot : in std_logic;
illegal_instr : in std_logic;
mac_busy : in std_logic;
mask_int : in std_logic;
rst : in std_logic;
slot : in std_logic;
t_bcc : in std_logic;
buses : out buses_ctrl_t;
debug : out std_logic;
event_ack : out std_logic;
func : out func_ctrl_t;
instr : out instr_ctrl_t;
mac : out mac_ctrl_t;
mem : out mem_ctrl_t;
pc : out pc_ctrl_t;
reg : out reg_ctrl_t;
slp : out std_logic;
sr : out sr_ctrl_t
);
end component;
component decode_core
port (
clk : in std_logic;
debug : in std_logic;
delay_jump : in std_logic;
dispatch : in std_logic;
enter_debug : in std_logic;
event_ack_0 : in std_logic;
event_i : in cpu_event_i_t;
ex : in pipeline_ex_t;
ex_stall : in pipeline_ex_stall_t;
ibit : in std_logic_vector(3 downto 0);
id : in pipeline_id_t;
if_dr : in std_logic_vector(15 downto 0);
if_stall : in std_logic;
ilevel_cap : in std_logic;
illegal_delay_slot : in std_logic;
illegal_instr : in std_logic;
mac_busy : in std_logic;
mac_stall_sense : in std_logic;
maskint_next : in std_logic;
p : in pipeline_t;
rst : in std_logic;
slot : in std_logic;
t_bcc : in std_logic;
event_ack : out std_logic;
if_issue : out std_logic;
ifadsel : out std_logic;
ilevel : out std_logic_vector(3 downto 0);
incpc : out std_logic;
next_id_stall : out std_logic;
op : out operation_t
);
end component;
component decode_table
port (
clk : in std_logic;
next_id_stall : in std_logic;
op : in operation_t;
t_bcc : in std_logic;
debug : out std_logic;
delay_jump : out std_logic;
dispatch : out std_logic;
event_ack_0 : out std_logic;
ex : out pipeline_ex_t;
ex_stall : out pipeline_ex_stall_t;
id : out pipeline_id_t;
ilevel_cap : out std_logic;
mac_s_latch : out std_logic;
mac_stall_sense : out std_logic;
maskint_next : out std_logic;
slp : out std_logic;
wb : out pipeline_wb_t;
wb_stall : out pipeline_wb_stall_t
);
end component;
function predecode_rom_addr (code : std_logic_vector(15 downto 0)) return std_logic_vector;
function check_illegal_delay_slot (code : std_logic_vector(15 downto 0)) return std_logic;
function check_illegal_instruction (code : std_logic_vector(15 downto 0)) return std_logic;
type decode_core_reg_t is
record
maskint : std_logic;
delay_slot : std_logic;
id_stall : std_logic;
instr_seq_zero : std_logic;
op : operation_t;
ilevel : std_logic_vector(3 downto 0);
end record;
constant DEC_CORE_RESET : decode_core_reg_t := (maskint => '0', delay_slot => '0', id_stall => '0', instr_seq_zero => '0', op => (plane => SYSTEM_INSTR, code => x"0300", addr => x"01"), ilevel => x"0");
-- Reset vector specific to the microcode ROM. Uses a different starting addr.
constant DEC_CORE_ROM_RESET : decode_core_reg_t := (maskint => '0', delay_slot => '0', id_stall => '0', instr_seq_zero => '0', op => (plane => SYSTEM_INSTR, code => x"0300", addr => x"da"), ilevel => x"0");
type system_instr_t is (BREAK, ERROR, GENERAL_ILLEGAL, INTERRUPT, RESET_CPU, SLOT_ILLEGAL);
type system_instr_addr_array is array (system_instr_t range <>) of std_logic_vector(7 downto 0);
constant system_instr_rom_addrs : system_instr_addr_array := (BREAK => x"f2", ERROR => x"e9", GENERAL_ILLEGAL => x"c9", INTERRUPT => x"e0", RESET_CPU => x"d9", SLOT_ILLEGAL => x"d1");
type system_instr_code_array is array (system_instr_t range <>) of std_logic_vector(11 downto 8);
constant system_instr_codes : system_instr_code_array := (BREAK => x"2", ERROR => x"1", GENERAL_ILLEGAL => x"7", INTERRUPT => x"0", RESET_CPU => x"3", SLOT_ILLEGAL => x"6");
type system_event_code_array is array (cpu_event_cmd_t range <>) of std_logic_vector(11 downto 8);
constant system_event_codes : system_event_code_array := (INTERRUPT => x"0", ERROR => x"1", BREAK => x"2", RESET_CPU => x"3");
type system_event_instr_array is array (cpu_event_cmd_t range <>) of system_instr_t;
constant system_event_instrs : system_event_instr_array := (INTERRUPT => INTERRUPT, ERROR => ERROR, BREAK => BREAK, RESET_CPU => RESET_CPU);
end;

37
decode_table.vhd Normal file
View File

@ -0,0 +1,37 @@
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
-- This file is generated. Changing this file directly is probably
-- not what you want to do. Any changes will be overwritten next time
-- the generator is run.
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.decode_pack.all;
use work.cpu2j0_components_pack.all;
use work.mult_pkg.all;
entity decode_table is
port (
clk : in std_logic;
next_id_stall : in std_logic;
op : in operation_t;
t_bcc : in std_logic;
debug : out std_logic;
delay_jump : out std_logic;
dispatch : out std_logic;
event_ack_0 : out std_logic;
ex : out pipeline_ex_t;
ex_stall : out pipeline_ex_stall_t;
id : out pipeline_id_t;
ilevel_cap : out std_logic;
mac_s_latch : out std_logic;
mac_stall_sense : out std_logic;
maskint_next : out std_logic;
slp : out std_logic;
wb : out pipeline_wb_t;
wb_stall : out pipeline_wb_stall_t
);
end;

649
decode_table_reverse.vhd Normal file
View File

@ -0,0 +1,649 @@
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
-- This file is generated. Changing this file directly is probably
-- not what you want to do. Any changes will be overwritten next time
-- the generator is run.
-- ******************************************************************
-- ******************************************************************
-- ******************************************************************
architecture reverse_logic of decode_table is
signal mac_busy : mac_busy_t;
signal imms_12_1 : std_logic_vector(31 downto 0);
signal imms_8_0 : std_logic_vector(31 downto 0);
signal imms_8_1 : std_logic_vector(31 downto 0);
signal cond1 : std_logic_vector(2 downto 0);
signal cond10 : std_logic_vector(1 downto 0);
signal cond11 : std_logic_vector(2 downto 0);
signal cond12 : std_logic_vector(6 downto 0);
signal cond13 : std_logic_vector(2 downto 0);
signal cond14 : std_logic_vector(4 downto 0);
signal cond15 : std_logic_vector(6 downto 0);
signal cond16 : std_logic_vector(2 downto 0);
signal cond18 : std_logic_vector(1 downto 0);
signal cond19 : std_logic_vector(1 downto 0);
signal cond20 : std_logic_vector(6 downto 0);
signal cond23 : std_logic_vector(6 downto 0);
signal cond25 : std_logic_vector(2 downto 0);
signal cond27 : std_logic_vector(1 downto 0);
signal cond3 : std_logic_vector(6 downto 0);
signal cond35 : std_logic_vector(2 downto 0);
signal cond36 : std_logic_vector(5 downto 0);
signal cond42 : std_logic_vector(17 downto 0);
signal cond44 : std_logic_vector(4 downto 0);
signal cond45 : std_logic_vector(2 downto 0);
signal cond47 : std_logic_vector(1 downto 0);
signal cond5 : std_logic_vector(1 downto 0);
signal cond50 : std_logic_vector(4 downto 0);
signal cond53 : std_logic_vector(6 downto 0);
signal cond7 : std_logic_vector(2 downto 0);
signal imp_bit_0 : std_logic;
signal imp_bit_1 : std_logic;
signal imp_bit_10 : std_logic;
signal imp_bit_100 : std_logic;
signal imp_bit_101 : std_logic;
signal imp_bit_102 : std_logic;
signal imp_bit_103 : std_logic;
signal imp_bit_104 : std_logic;
signal imp_bit_105 : std_logic;
signal imp_bit_106 : std_logic;
signal imp_bit_107 : std_logic;
signal imp_bit_108 : std_logic;
signal imp_bit_109 : std_logic;
signal imp_bit_11 : std_logic;
signal imp_bit_110 : std_logic;
signal imp_bit_111 : std_logic;
signal imp_bit_112 : std_logic;
signal imp_bit_113 : std_logic;
signal imp_bit_114 : std_logic;
signal imp_bit_115 : std_logic;
signal imp_bit_116 : std_logic;
signal imp_bit_117 : std_logic;
signal imp_bit_118 : std_logic;
signal imp_bit_119 : std_logic;
signal imp_bit_12 : std_logic;
signal imp_bit_120 : std_logic;
signal imp_bit_121 : std_logic;
signal imp_bit_122 : std_logic;
signal imp_bit_123 : std_logic;
signal imp_bit_124 : std_logic;
signal imp_bit_125 : std_logic;
signal imp_bit_126 : std_logic;
signal imp_bit_127 : std_logic;
signal imp_bit_128 : std_logic;
signal imp_bit_129 : std_logic;
signal imp_bit_13 : std_logic;
signal imp_bit_130 : std_logic;
signal imp_bit_131 : std_logic;
signal imp_bit_132 : std_logic;
signal imp_bit_133 : std_logic;
signal imp_bit_134 : std_logic;
signal imp_bit_135 : std_logic;
signal imp_bit_136 : std_logic;
signal imp_bit_137 : std_logic;
signal imp_bit_138 : std_logic;
signal imp_bit_139 : std_logic;
signal imp_bit_14 : std_logic;
signal imp_bit_140 : std_logic;
signal imp_bit_141 : std_logic;
signal imp_bit_142 : std_logic;
signal imp_bit_143 : std_logic;
signal imp_bit_144 : std_logic;
signal imp_bit_145 : std_logic;
signal imp_bit_146 : std_logic;
signal imp_bit_147 : std_logic;
signal imp_bit_148 : std_logic;
signal imp_bit_149 : std_logic;
signal imp_bit_15 : std_logic;
signal imp_bit_150 : std_logic;
signal imp_bit_151 : std_logic;
signal imp_bit_152 : std_logic;
signal imp_bit_153 : std_logic;
signal imp_bit_154 : std_logic;
signal imp_bit_155 : std_logic;
signal imp_bit_156 : std_logic;
signal imp_bit_157 : std_logic;
signal imp_bit_158 : std_logic;
signal imp_bit_159 : std_logic;
signal imp_bit_16 : std_logic;
signal imp_bit_160 : std_logic;
signal imp_bit_161 : std_logic;
signal imp_bit_162 : std_logic;
signal imp_bit_17 : std_logic;
signal imp_bit_18 : std_logic;
signal imp_bit_19 : std_logic;
signal imp_bit_2 : std_logic;
signal imp_bit_20 : std_logic;
signal imp_bit_21 : std_logic;
signal imp_bit_22 : std_logic;
signal imp_bit_23 : std_logic;
signal imp_bit_24 : std_logic;
signal imp_bit_25 : std_logic;
signal imp_bit_26 : std_logic;
signal imp_bit_27 : std_logic;
signal imp_bit_28 : std_logic;
signal imp_bit_29 : std_logic;
signal imp_bit_3 : std_logic;
signal imp_bit_30 : std_logic;
signal imp_bit_31 : std_logic;
signal imp_bit_32 : std_logic;
signal imp_bit_33 : std_logic;
signal imp_bit_34 : std_logic;
signal imp_bit_35 : std_logic;
signal imp_bit_36 : std_logic;
signal imp_bit_37 : std_logic;
signal imp_bit_38 : std_logic;
signal imp_bit_39 : std_logic;
signal imp_bit_4 : std_logic;
signal imp_bit_40 : std_logic;
signal imp_bit_41 : std_logic;
signal imp_bit_42 : std_logic;
signal imp_bit_43 : std_logic;
signal imp_bit_44 : std_logic;
signal imp_bit_45 : std_logic;
signal imp_bit_46 : std_logic;
signal imp_bit_47 : std_logic;
signal imp_bit_48 : std_logic;
signal imp_bit_49 : std_logic;
signal imp_bit_5 : std_logic;
signal imp_bit_50 : std_logic;
signal imp_bit_51 : std_logic;
signal imp_bit_52 : std_logic;
signal imp_bit_53 : std_logic;
signal imp_bit_54 : std_logic;
signal imp_bit_55 : std_logic;
signal imp_bit_56 : std_logic;
signal imp_bit_57 : std_logic;
signal imp_bit_58 : std_logic;
signal imp_bit_59 : std_logic;
signal imp_bit_6 : std_logic;
signal imp_bit_60 : std_logic;
signal imp_bit_61 : std_logic;
signal imp_bit_62 : std_logic;
signal imp_bit_63 : std_logic;
signal imp_bit_64 : std_logic;
signal imp_bit_65 : std_logic;
signal imp_bit_66 : std_logic;
signal imp_bit_67 : std_logic;
signal imp_bit_68 : std_logic;
signal imp_bit_69 : std_logic;
signal imp_bit_7 : std_logic;
signal imp_bit_70 : std_logic;
signal imp_bit_71 : std_logic;
signal imp_bit_72 : std_logic;
signal imp_bit_73 : std_logic;
signal imp_bit_74 : std_logic;
signal imp_bit_75 : std_logic;
signal imp_bit_76 : std_logic;
signal imp_bit_77 : std_logic;
signal imp_bit_78 : std_logic;
signal imp_bit_79 : std_logic;
signal imp_bit_8 : std_logic;
signal imp_bit_80 : std_logic;
signal imp_bit_81 : std_logic;
signal imp_bit_82 : std_logic;
signal imp_bit_83 : std_logic;
signal imp_bit_84 : std_logic;
signal imp_bit_85 : std_logic;
signal imp_bit_86 : std_logic;
signal imp_bit_87 : std_logic;
signal imp_bit_88 : std_logic;
signal imp_bit_89 : std_logic;
signal imp_bit_9 : std_logic;
signal imp_bit_90 : std_logic;
signal imp_bit_91 : std_logic;
signal imp_bit_92 : std_logic;
signal imp_bit_93 : std_logic;
signal imp_bit_94 : std_logic;
signal imp_bit_95 : std_logic;
signal imp_bit_96 : std_logic;
signal imp_bit_97 : std_logic;
signal imp_bit_98 : std_logic;
signal imp_bit_99 : std_logic;
signal p : std_logic_vector(0 downto 0);
begin
-- Sign extend parts of opcode
process(op)
begin
-- Sign extend 8 right-most bits
for i in 8 to 31 loop
imms_8_0(i) <= op.code(7);
end loop;
imms_8_0(7 downto 0) <= op.code(7 downto 0);
-- Sign extend 8 right-most bits shifted by 1
for i in 9 to 31 loop
imms_8_1(i) <= op.code(7);
end loop;
imms_8_1(8 downto 1) <= op.code(7 downto 0);
imms_8_1(0) <= '0';
-- Sign extend 12 right-most bits shifted by 1
for i in 13 to 31 loop
imms_12_1(i) <= op.code(11);
end loop;
imms_12_1(12 downto 1) <= op.code(11 downto 0);
imms_12_1(0) <= '0';
end process;
-- Mac busy muxes
with mac_busy select
ex.mac_busy <=
not next_id_stall when EX_NOT_STALL,
'1' when EX_BUSY,
'0' when others;
with mac_busy select
wb.mac_busy <=
not next_id_stall when WB_NOT_STALL,
'1' when WB_BUSY,
'0' when others;
p <= "0" when op.plane = NORMAL_INSTR else "1";
imp_bit_0 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(8)));
imp_bit_1 <= (p(0) and (not op.code(10) and not op.code(9)) and (not op.addr(3) and not op.addr(2) and not op.addr(1) and op.addr(0)));
imp_bit_2 <= ((not op.addr(3) and op.addr(2) and not op.addr(1) and not op.addr(0)) and p(0) and (not op.code(10) and not op.code(9)));
imp_bit_3 <= (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and not op.code(0)));
imp_bit_4 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_5 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(0)));
imp_bit_6 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(2) and not op.code(1) and op.code(0)));
imp_bit_7 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(0)));
imp_bit_8 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3)));
imp_bit_9 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(2)));
imp_bit_10 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10)));
imp_bit_11 <= (not p(0) and not op.addr(1) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_12 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_13 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1)));
imp_bit_14 <= ((op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_15 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_16 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_17 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(0)));
imp_bit_18 <= (not p(0) and (op.code(15) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9)));
imp_bit_19 <= (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(0)));
imp_bit_20 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1)));
imp_bit_21 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_22 <= (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1)));
imp_bit_23 <= (not p(0) and not op.addr(1) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10)));
imp_bit_24 <= ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10)));
imp_bit_25 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10)));
imp_bit_26 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1)));
imp_bit_27 <= (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_28 <= (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_29 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_30 <= (p(0) and (not op.addr(1) and op.addr(0)) and (not op.code(10) and op.code(9) and not op.code(8)));
imp_bit_31 <= (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_32 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_33 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and op.code(2) and op.code(1) and not op.code(0)));
imp_bit_34 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_35 <= (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_36 <= (op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_37 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_38 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(1)));
imp_bit_39 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_40 <= (not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_41 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(1) and op.code(0)));
imp_bit_42 <= ((not op.addr(2) and op.addr(1) and not op.addr(0)) and p(0) and (not op.code(10) and op.code(9) and op.code(8)));
imp_bit_43 <= (not p(0) and not op.addr(1) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_44 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(0)));
imp_bit_45 <= (not p(0) and (op.code(15) and op.code(14) and op.code(13) and not op.code(12)));
imp_bit_46 <= ((not op.addr(2) and op.addr(1) and op.addr(0)) and p(0) and (not op.code(10) and op.code(9) and op.code(8)));
imp_bit_47 <= ((op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_48 <= (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_49 <= (not p(0) and not op.addr(1) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_50 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_51 <= (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_52 <= (not p(0) and op.addr(1) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_53 <= (not op.addr(0) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(9) and op.code(8)));
imp_bit_54 <= (not op.addr(0) and p(0) and (op.code(9) and not op.code(8)));
imp_bit_55 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and not op.code(1) and op.code(0)));
imp_bit_56 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and op.code(2) and not op.code(1) and not op.code(0)));
imp_bit_57 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_58 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_59 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_60 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and op.code(10) and op.code(9) and op.code(8)));
imp_bit_61 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and op.code(1)));
imp_bit_62 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(2) and not op.code(0)));
imp_bit_63 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(1)));
imp_bit_64 <= (not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and op.code(12)));
imp_bit_65 <= ((op.addr(2) and not op.addr(1) and not op.addr(0)) and p(0) and (not op.code(10) and op.code(9) and op.code(8)));
imp_bit_66 <= ((op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_67 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_68 <= (not p(0) and not op.addr(1) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_69 <= (op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_70 <= (not op.addr(0) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and not op.code(9) and op.code(8)));
imp_bit_71 <= (not p(0) and (op.code(15) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and not op.code(9) and not op.code(8)));
imp_bit_72 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(2) and not op.code(1)));
imp_bit_73 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and op.code(12)));
imp_bit_74 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and op.code(12)));
imp_bit_75 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and op.code(12)));
imp_bit_76 <= (p(0) and (not op.code(10) and op.code(9) and op.code(8)) and (op.addr(2) and not op.addr(1) and op.addr(0)));
imp_bit_77 <= ((not op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_78 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_79 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and op.code(9) and op.code(8)));
imp_bit_80 <= (not p(0) and not op.addr(1) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_81 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_82 <= (not p(0) and not op.addr(1) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8)));
imp_bit_83 <= (not p(0) and (op.code(15) and not op.code(14) and op.code(13) and op.code(12)) and not op.addr(0));
imp_bit_84 <= ((not op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_85 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_86 <= ((op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_87 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and not op.code(9) and op.code(8)));
imp_bit_88 <= (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_89 <= (not p(0) and not op.addr(2) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8)));
imp_bit_90 <= (p(0) and (op.code(9) and op.code(8)) and not op.addr(2));
imp_bit_91 <= (not op.addr(0) and p(0) and (op.code(10) and op.code(9)));
imp_bit_92 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_93 <= ((not op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_94 <= (not p(0) and (op.code(15) and not op.code(13) and op.code(12)));
imp_bit_95 <= ((not op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0)));
imp_bit_96 <= (p(0) and (op.code(10) and op.code(9)) and not op.addr(2));
imp_bit_97 <= (not p(0) and (not op.code(15) and not op.code(13) and op.code(12)));
imp_bit_98 <= (not p(0) and (not op.addr(2) and not op.addr(1)) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8)));
imp_bit_99 <= (p(0) and (not op.code(10) and not op.code(9)) and not op.addr(3));
imp_bit_100 <= ((not op.addr(2) and op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8)));
imp_bit_101 <= (not op.addr(0) and not p(0) and (op.code(15) and not op.code(14) and op.code(13)));
imp_bit_102 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and op.code(9)));
imp_bit_103 <= (not p(0) and (op.code(15) and not op.code(14) and op.code(13)) and op.addr(0));
imp_bit_104 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_105 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(8)));
imp_bit_106 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and op.code(8)));
imp_bit_107 <= ((op.addr(2) and not op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8)));
imp_bit_108 <= (p(0) and (not op.addr(2) and op.addr(1) and not op.addr(0)) and (op.code(10) and op.code(9)));
imp_bit_109 <= ((not op.addr(3) and op.addr(0)) and p(0) and (not op.code(10) and not op.code(9)));
imp_bit_110 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and not op.code(0)));
imp_bit_111 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_112 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and op.code(3) and op.code(1) and not op.code(0)));
imp_bit_113 <= (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and op.code(10) and not op.code(8)));
imp_bit_114 <= ((not op.addr(2) and not op.addr(1) and not op.addr(0)) and p(0) and (op.code(10) and op.code(9)));
imp_bit_115 <= (p(0) and (not op.addr(2) and op.addr(1) and op.addr(0)) and (op.code(10) and op.code(9)));
imp_bit_116 <= (p(0) and (not op.code(10) and not op.code(9)) and (not op.addr(3) and not op.addr(2)));
imp_bit_117 <= (not op.addr(0) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(8)));
imp_bit_118 <= (not op.addr(0) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(9)));
imp_bit_119 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(3) and op.code(1) and not op.code(0)));
imp_bit_120 <= (p(0) and (not op.addr(2) and not op.addr(1) and op.addr(0)) and (op.code(10) and op.code(9)));
imp_bit_121 <= (not p(0) and op.addr(1) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_122 <= (op.addr(0) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(8)));
imp_bit_123 <= (not p(0) and not op.addr(1) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(9)));
imp_bit_124 <= (not op.addr(0) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(8)));
imp_bit_125 <= (p(0) and not op.addr(1) and op.code(9));
imp_bit_126 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and op.code(1) and not op.code(0)));
imp_bit_127 <= (p(0) and (not op.addr(3) and not op.addr(2) and op.addr(1)) and (not op.code(10) and not op.code(9)));
imp_bit_128 <= ((op.addr(2) and not op.addr(1) and op.addr(0)) and p(0) and (op.code(10) and op.code(9)));
imp_bit_129 <= ((not op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and op.code(8)));
imp_bit_130 <= ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(9)));
imp_bit_131 <= (not p(0) and not op.addr(1) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_132 <= (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_133 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_134 <= (not p(0) and not op.addr(1) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(8)));
imp_bit_135 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_136 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and op.code(0)));
imp_bit_137 <= (not p(0) and (op.code(15) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9)));
imp_bit_138 <= ((op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_139 <= ((not op.addr(1) and op.addr(0)) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and op.code(8)));
imp_bit_140 <= ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(8)));
imp_bit_141 <= (op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_142 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_143 <= (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_144 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and op.code(2) and op.code(1) and not op.code(0)));
imp_bit_145 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0)));
imp_bit_146 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(3) and not op.code(2) and not op.code(1)));
imp_bit_147 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(3) and op.code(1) and not op.code(0)));
imp_bit_148 <= (not p(0) and (op.code(15) and not op.code(13) and not op.code(12) and not op.code(11) and op.code(10) and not op.code(9)));
imp_bit_149 <= (p(0) and (not op.addr(3) and op.addr(2) and op.addr(0)) and (not op.code(10) and not op.code(9)));
imp_bit_150 <= ((op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_151 <= ((not op.addr(1) and op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(9)));
imp_bit_152 <= (not p(0) and not op.addr(1) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_153 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and not op.code(0)));
imp_bit_154 <= ((not op.addr(3) and not op.addr(2) and not op.addr(1) and not op.addr(0)) and p(0) and (not op.code(10) and not op.code(9)));
imp_bit_155 <= (p(0) and (not op.code(10) and not op.code(9)) and (not op.addr(3) and op.addr(2) and op.addr(1) and not op.addr(0)));
imp_bit_156 <= ((not op.addr(1) and op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(8)));
imp_bit_157 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and not op.code(0)));
imp_bit_158 <= (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_159 <= (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
imp_bit_160 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and op.code(2) and op.code(1) and not op.code(0)));
imp_bit_161 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and op.code(1)));
imp_bit_162 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1)));
ex.arith_func <= SUB when (imp_bit_55 or imp_bit_39 or imp_bit_34 or imp_bit_29 or imp_bit_61 or imp_bit_161 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(3) and not op.code(2) and not op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(2) and op.code(1))) or imp_bit_22 or imp_bit_19 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1))) or imp_bit_98 or imp_bit_120 or imp_bit_108 or (p(0) and (not op.addr(3) and not op.addr(2) and not op.addr(0)) and (not op.code(10) and not op.code(9))) or imp_bit_149 or imp_bit_30 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and not op.code(2) and not op.code(0))) or imp_bit_127 or imp_bit_5 or (p(0) and (not op.addr(2) and not op.addr(1)) and (op.code(10) and op.code(9) and op.code(8)))) = '1' else ADD;
cond1 <= imp_bit_56 & imp_bit_14 & (imp_bit_60 or imp_bit_73 or imp_bit_1);
with cond1 select
ex.aluinx_sel <=
SEL_ROTCL when "100",
SEL_ZERO when "010",
SEL_FC when "001",
SEL_XBUS when others;
wb_stall.wrmach <= imp_bit_153;
cond3 <= (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1) and not op.code(0))) & (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and not op.code(0))) & imp_bit_14;
with cond3 select
ex.alumanip <=
EXTEND_SWORD when "1000000",
SWAP_WORD when "0100000",
EXTEND_UBYTE when "0010000",
EXTRACT when "0001000",
EXTEND_UWORD when "0000100",
EXTEND_SBYTE when "0000010",
SET_BIT_7 when "0000001",
SWAP_BYTE when others;
ilevel_cap <= imp_bit_154;
cond5 <= (imp_bit_72 or imp_bit_62) & (imp_bit_131 or imp_bit_39 or imp_bit_133 or imp_bit_126 or imp_bit_29 or imp_bit_84 or imp_bit_77 or imp_bit_3 or imp_bit_63 or imp_bit_44 or imp_bit_80 or imp_bit_57 or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(0))) or imp_bit_18 or imp_bit_97 or imp_bit_0 or imp_bit_24 or imp_bit_98 or (p(0) and (not op.addr(2) and not op.addr(1)) and (op.code(10) and op.code(9))) or ((not op.addr(2) and not op.addr(0)) and p(0) and (op.code(10) and op.code(9))) or imp_bit_46 or imp_bit_116 or imp_bit_109 or imp_bit_30);
with cond5 select
ex.aluiny_sel <=
SEL_R0 when "10",
SEL_IMM when "01",
SEL_YBUS when others;
mac_stall_sense <= (imp_bit_110 or (not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or imp_bit_126 or imp_bit_6 or imp_bit_58 or imp_bit_162);
cond7 <= imp_bit_53 & imp_bit_70 & (imp_bit_131 or imp_bit_27 or imp_bit_152 or imp_bit_28 or imp_bit_11 or imp_bit_142 or imp_bit_133 or imp_bit_49 or imp_bit_43 or imp_bit_157 or imp_bit_48 or imp_bit_68 or imp_bit_51 or imp_bit_80 or imp_bit_81 or imp_bit_20 or imp_bit_17 or imp_bit_101 or imp_bit_23 or imp_bit_89 or ((not op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or (p(0) and not op.addr(1) and (op.code(10) and op.code(9))) or imp_bit_96 or imp_bit_90 or ((not op.addr(1) and not op.addr(0)) and p(0) and op.code(9)) or imp_bit_116 or (p(0) and (not op.addr(3) and not op.addr(1)) and (not op.code(10) and not op.code(9))) or ((not op.addr(3) and not op.addr(0)) and p(0) and (not op.code(10) and not op.code(9))) or (p(0) and not op.addr(1) and (op.code(9) and not op.code(8))));
with cond7 select
id.if_issue <=
t_bcc when "100",
not t_bcc when "010",
'0' when "001",
'1' when others;
ex_stall.wrmach <= (imp_bit_110 or imp_bit_135);
ex.arith_ci_en <= (imp_bit_147 or imp_bit_37);
cond10 <= (imp_bit_31 or imp_bit_60 or imp_bit_129 or imp_bit_117 or imp_bit_101 or imp_bit_94 or imp_bit_114 or imp_bit_154 or imp_bit_30) & ((not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(3) and not op.code(2) and not op.code(1))) or imp_bit_121 or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(3) and not op.code(2) and op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_136 or imp_bit_111 or imp_bit_104 or (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_119 or imp_bit_112 or (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_66 or imp_bit_47 or (op.addr(0) and not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_85 or imp_bit_8 or imp_bit_41 or imp_bit_9 or ((op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0))) or imp_bit_139 or ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and op.code(8))) or imp_bit_122 or imp_bit_103 or ((not op.addr(1) and op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and not op.code(9) and not op.code(8))) or (not p(0) and (not op.addr(2) and op.addr(1)) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or (not p(0) and (op.addr(2) and not op.addr(1)) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or imp_bit_45 or (p(0) and (op.code(10) and op.code(9)) and (op.addr(1) and op.addr(0))) or (p(0) and (op.code(10) and op.code(9)) and op.addr(2)) or (p(0) and (not op.code(10) and op.code(9) and op.code(8)) and (not op.addr(2) and not op.addr(1))) or (p(0) and (not op.code(10) and op.code(9)) and not op.addr(0)) or imp_bit_155 or (p(0) and (not op.code(10) and not op.code(9)) and (op.addr(3) and not op.addr(2) and not op.addr(1) and not op.addr(0))) or ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or (p(0) and (not op.code(10) and op.code(9) and not op.code(8)) and op.addr(1)));
with cond10 select
ex.xbus_sel <=
SEL_PC when "10",
SEL_IMM when "01",
SEL_REG when others;
cond11 <= (imp_bit_87 or imp_bit_70) & (imp_bit_79 or imp_bit_53) & (imp_bit_138 or imp_bit_132 or imp_bit_32 or imp_bit_31 or imp_bit_101 or imp_bit_107 or imp_bit_114 or imp_bit_128 or imp_bit_65 or imp_bit_154 or imp_bit_155 or imp_bit_30);
with cond11 select
ex_stall.wrpc_z <=
t_bcc when "100",
not t_bcc when "010",
'1' when "001",
'0' when others;
cond12 <= imp_bit_46 & imp_bit_25 & imp_bit_157 & (imp_bit_148 or imp_bit_113) & imp_bit_15 & imp_bit_16 & imp_bit_21;
with cond12 select
wb.regnum_w <=
"01111" when "1000000",
"10100" when "0100000",
"10010" when "0010000",
"00000" when "0001000",
"10011" when "0000100",
"10001" when "0000010",
"10000" when "0000001",
'0' & op.code(11 downto 8) when others;
cond13 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and op.code(2) and not op.code(1))) & (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and op.code(2) and not op.code(1))) & ((not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1) and not op.code(0))));
with cond13 select
ex_stall.shiftfunc <=
ROTC when "100",
ROTATE when "010",
ARITH when "001",
LOGIC when others;
cond14 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(3) and op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and not op.code(0))) & imp_bit_58 & (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and op.code(1) and op.code(0)));
with cond14 select
ex_stall.mulcom2 <=
DMULUL when "10000",
DMULSL when "01000",
MULUW when "00100",
MULL when "00010",
MULSW when "00001",
NOP when others;
cond15 <= imp_bit_2 & (imp_bit_46 or imp_bit_127) & (imp_bit_69 or imp_bit_10 or imp_bit_71) & (imp_bit_110 or imp_bit_24 or imp_bit_76) & ((not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9))) or imp_bit_0 or imp_bit_134 or imp_bit_25 or imp_bit_123) & (imp_bit_131 or imp_bit_98 or imp_bit_120 or imp_bit_108 or ((not op.addr(3) and not op.addr(1) and op.addr(0)) and p(0) and (not op.code(10) and not op.code(9))) or imp_bit_149) & (imp_bit_95 or imp_bit_88 or (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1))) or (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(0))) or imp_bit_13 or imp_bit_7 or (not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and op.code(12))));
with cond15 select
ex.regnum_x <=
"10001" when "1000000",
"10011" when "0100000",
"00000" when "0010000",
"10100" when "0001000",
"10000" when "0000100",
"01111" when "0000010",
'0' & op.code(7 downto 4) when "0000001",
'0' & op.code(11 downto 8) when others;
cond16 <= (imp_bit_79 or imp_bit_53) & (imp_bit_87 or imp_bit_70) & (imp_bit_131 or imp_bit_27 or imp_bit_152 or imp_bit_28 or imp_bit_11 or imp_bit_142 or imp_bit_133 or imp_bit_49 or imp_bit_43 or imp_bit_157 or imp_bit_48 or imp_bit_68 or imp_bit_51 or imp_bit_80 or imp_bit_81 or imp_bit_20 or imp_bit_17 or imp_bit_139 or imp_bit_101 or imp_bit_23 or imp_bit_89 or imp_bit_82 or imp_bit_125 or imp_bit_91 or imp_bit_96 or imp_bit_90 or imp_bit_99 or imp_bit_54);
with cond16 select
dispatch <=
t_bcc when "100",
not t_bcc when "010",
'0' when "001",
'1' when others;
ex_stall.mulcom1 <= (imp_bit_6 or imp_bit_58 or imp_bit_162);
cond18 <= imp_bit_88 & imp_bit_95;
with cond18 select
wb_stall.mulcom2 <=
MACW when "10",
MACL when "01",
NOP when others;
cond19 <= ((not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) or imp_bit_57 or (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(2) and not op.code(1) and op.code(0))) or (not p(0) and (op.code(15) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9) and op.code(8))) or imp_bit_64 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(1) and op.code(0)))) & (imp_bit_4 or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) or (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(2) and not op.code(1) and not op.code(0))) or (not p(0) and (op.code(15) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9) and not op.code(8))) or imp_bit_124 or imp_bit_25 or imp_bit_118 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(1) and not op.code(0))));
with cond19 select
ex.mem_size <=
WORD when "10",
BYTE when "01",
LONG when others;
cond20 <= (imp_bit_110 or imp_bit_76) & (imp_bit_143 or imp_bit_12) & (imp_bit_137 or imp_bit_105 or imp_bit_134 or imp_bit_25 or imp_bit_123) & (imp_bit_132 or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0)))) & ((not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_100 or imp_bit_115) & (imp_bit_119 or imp_bit_112 or imp_bit_31 or imp_bit_85) & (imp_bit_14 or imp_bit_86 or imp_bit_140 or imp_bit_130);
with cond20 select
ex.regnum_y <=
"10100" when "1000000",
"10000" when "0100000",
"00000" when "0010000",
"10010" when "0001000",
"10001" when "0000100",
'0' & op.code(11 downto 8) when "0000010",
"10011" when "0000001",
'0' & op.code(7 downto 4) when others;
event_ack_0 <= (((not op.addr(2) and not op.addr(1) and op.addr(0)) and p(0) and (not op.code(10) and op.code(9) and op.code(8))) or imp_bit_154);
wb_stall.mulcom1 <= (imp_bit_92 or imp_bit_81);
cond23 <= (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and op.code(2) and op.code(1) and not op.code(0))) & ((not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and op.code(2) and op.code(1) and not op.code(0))) or imp_bit_76) & (imp_bit_60 or imp_bit_106 or imp_bit_102) & (imp_bit_95 or imp_bit_88 or imp_bit_20 or imp_bit_17) & ((not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or imp_bit_158 or imp_bit_159 or imp_bit_83) & (imp_bit_131 or imp_bit_98 or imp_bit_120 or imp_bit_108 or imp_bit_149) & (imp_bit_85 or imp_bit_156 or imp_bit_151 or imp_bit_42 or ((not op.addr(3) and not op.addr(2) and op.addr(0)) and p(0) and (not op.code(10) and not op.code(9))) or imp_bit_127);
with cond23 select
ex.regnum_z <=
"10000" when "1000000",
"10001" when "0100000",
"00000" when "0010000",
'0' & op.code(7 downto 4) when "0001000",
"10010" when "0000100",
"01111" when "0000010",
"10011" when "0000001",
'0' & op.code(11 downto 8) when others;
ex_stall.mem_wdata_sel <= SEL_ZBUS when (imp_bit_14 or imp_bit_140 or imp_bit_130) = '1' else SEL_YBUS;
cond25 <= imp_bit_33 & (imp_bit_95 or imp_bit_88) & (imp_bit_6 or imp_bit_58 or imp_bit_162);
with cond25 select
mac_busy <=
WB_NOT_STALL when "100",
WB_BUSY when "010",
EX_NOT_STALL when "001",
NOT_BUSY when others;
slp <= ((not op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0)));
cond27 <= imp_bit_86 & (imp_bit_131 or imp_bit_50 or imp_bit_34 or imp_bit_126 or imp_bit_29 or imp_bit_78 or imp_bit_67 or imp_bit_157 or imp_bit_93 or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(1))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(0))) or imp_bit_80 or imp_bit_57 or imp_bit_22 or imp_bit_19 or imp_bit_72 or imp_bit_62 or imp_bit_18 or (not p(0) and (not op.code(13) and op.code(12))) or imp_bit_0 or imp_bit_124 or imp_bit_25 or imp_bit_118 or imp_bit_98 or ((not op.addr(2) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or ((not op.addr(2) and op.addr(0)) and p(0) and (op.code(10) and op.code(9))) or (p(0) and (not op.addr(2) and op.addr(1)) and (op.code(10) and op.code(9))) or (p(0) and (not op.addr(2) and op.addr(1)) and (op.code(9) and op.code(8))) or imp_bit_127 or imp_bit_2 or imp_bit_63 or imp_bit_44);
with cond27 select
ex_stall.ma_issue <=
t_bcc when "10",
'1' when "01",
'0' when others;
ex.ma_wr <= (imp_bit_14 or imp_bit_39 or imp_bit_34 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or imp_bit_29 or imp_bit_86 or imp_bit_63 or imp_bit_44 or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1))) or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(0))) or imp_bit_137 or imp_bit_74 or imp_bit_105 or imp_bit_140 or imp_bit_130 or imp_bit_98 or imp_bit_120 or imp_bit_108 or imp_bit_127);
id.ifadsel <= (imp_bit_150 or imp_bit_141 or imp_bit_35 or imp_bit_36 or imp_bit_139 or imp_bit_122 or imp_bit_103 or ((op.addr(2) and not op.addr(1) and op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or ((op.addr(2) and op.addr(1) and not op.addr(0)) and p(0) and (op.code(10) and op.code(9))) or imp_bit_76 or ((not op.addr(3) and op.addr(2) and op.addr(1) and op.addr(0)) and p(0) and (not op.code(10) and not op.code(9))) or ((op.addr(1) and not op.addr(0)) and p(0) and (not op.code(10) and op.code(9) and not op.code(8))));
ex_stall.wrsr_z <= imp_bit_144;
wb_stall.macsel1 <= SEL_WBUS when (imp_bit_153 or imp_bit_92 or imp_bit_81) = '1' else SEL_XBUS;
wb_stall.wrsr_w <= (((not op.addr(1) and op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or ((not op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and op.code(2) and op.code(1) and op.code(0))));
ex_stall.wrmacl <= (imp_bit_110 or imp_bit_145);
wb_stall.macsel2 <= SEL_WBUS when (imp_bit_160 or imp_bit_95 or imp_bit_88) = '1' else SEL_YBUS;
cond35 <= imp_bit_38 & (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) & (imp_bit_147 or imp_bit_37);
with cond35 select
ex_stall.t_sel <=
SEL_SHIFT when "100",
SEL_SET when "010",
SEL_CARRY when "001",
SEL_CLEAR when others;
cond36 <= ((not op.addr(3) and op.addr(2) and not op.addr(1) and op.addr(0)) and p(0) and (not op.code(10) and not op.code(9) and not op.code(8))) & imp_bit_144 & (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) & ((not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) or imp_bit_38 or imp_bit_147 or imp_bit_37) & ((not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(1) and not op.code(0))) or ((op.addr(1) and not op.addr(0)) and not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and not op.code(9) and not op.code(8))) or imp_bit_71) & (imp_bit_55 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and not op.code(2) and not op.code(1))) or imp_bit_14 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(1) and op.code(0))) or imp_bit_61 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and op.code(2) and not op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(3) and op.code(2) and op.code(1) and op.code(0))));
with cond36 select
ex_stall.sr_sel <=
SEL_INT_MASK when "100000",
SEL_ZBUS when "010000",
SEL_DIV0U when "001000",
SEL_SET_T when "000100",
SEL_LOGIC when "000010",
SEL_ARITH when "000001",
SEL_PREV when others;
mac_s_latch <= (imp_bit_95 or imp_bit_88);
wb_stall.wrreg_w <= (imp_bit_15 or imp_bit_21 or imp_bit_16 or imp_bit_157 or imp_bit_93 or (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(1))) or (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(0))) or imp_bit_22 or imp_bit_19 or imp_bit_13 or imp_bit_7 or imp_bit_148 or (not p(0) and (op.code(14) and not op.code(13) and op.code(12))) or imp_bit_113 or imp_bit_94 or imp_bit_25 or imp_bit_46);
ex.logic_sr_func <= BYTE_EQ when (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1) and not op.code(0))) = '1' else ZERO;
ex_stall.wrreg_z <= (imp_bit_131 or (not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) or imp_bit_38 or imp_bit_146 or imp_bit_111 or imp_bit_39 or imp_bit_34 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(2) and op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and op.code(1) and not op.code(0))) or (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_84 or imp_bit_77 or imp_bit_3 or (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(3) and op.code(1))) or imp_bit_85 or imp_bit_8 or imp_bit_41 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(3) and not op.code(0))) or imp_bit_26 or imp_bit_80 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(12) and op.code(3) and op.code(2) and op.code(0))) or imp_bit_20 or imp_bit_17 or imp_bit_5 or imp_bit_60 or imp_bit_83 or imp_bit_156 or imp_bit_151 or imp_bit_106 or imp_bit_102 or imp_bit_98 or imp_bit_75 or imp_bit_45 or imp_bit_120 or imp_bit_108 or ((not op.addr(2) and op.addr(1) and not op.addr(0)) and p(0) and (op.code(9) and op.code(8))) or imp_bit_76 or imp_bit_109 or imp_bit_127 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and not op.code(2) and not op.code(0))) or imp_bit_40 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(2) and not op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(2) and not op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(3) and op.code(2) and not op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and op.code(1))));
id.incpc <= not ((op.addr(0) and not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_121 or imp_bit_152 or imp_bit_28 or imp_bit_11 or imp_bit_50 or imp_bit_34 or imp_bit_35 or imp_bit_49 or imp_bit_43 or imp_bit_157 or imp_bit_36 or imp_bit_68 or imp_bit_51 or imp_bit_80 or imp_bit_81 or imp_bit_20 or imp_bit_17 or imp_bit_139 or imp_bit_122 or imp_bit_103 or imp_bit_23 or imp_bit_89 or imp_bit_82 or imp_bit_125 or imp_bit_91 or imp_bit_96 or imp_bit_90 or imp_bit_99 or imp_bit_54);
cond42 <= imp_bit_97 & imp_bit_101 & (not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9) and not op.code(8))) & (not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9) and op.code(8))) & (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) & ((not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9) and op.code(8))) or imp_bit_64) & ((not p(0) and (op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and not op.code(9) and not op.code(8))) or imp_bit_75 or imp_bit_45) & (imp_bit_129 or imp_bit_117) & ((not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(9) and not op.code(8))) or imp_bit_24 or imp_bit_10) & ((not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) or imp_bit_136 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1) and not op.code(0)))) & ((not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and not op.code(1) and not op.code(0))) or imp_bit_57 or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and not op.code(1) and op.code(0))) or (p(0) and (not op.addr(2) and not op.addr(1) and not op.addr(0)) and (op.code(10) and op.code(9) and op.code(8))) or imp_bit_154 or imp_bit_30) & ((not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and op.code(9) and not op.code(8))) or (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and op.code(10) and op.code(9))) or imp_bit_73 or imp_bit_100 or imp_bit_115 or imp_bit_42 or imp_bit_2) & (imp_bit_55 or imp_bit_32 or imp_bit_161 or imp_bit_59 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(1))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2) and not op.code(0))) or (p(0) and (not op.addr(2) and not op.addr(1) and not op.addr(0)) and (op.code(10) and op.code(9) and not op.code(8))) or imp_bit_1);
with cond42 select
ex.imm_val <=
"00000000000000000000000000" & op.code(3 downto 0) & "00" when "100000000000000000",
imms_12_1 when "010000000000000000",
x"0000000" & op.code(3 downto 0) when "001000000000000000",
"000000000000000000000000000" & op.code(3 downto 0) & "0" when "000100000000000000",
x"ffffffff" when "000010000000000000",
x"fffffffe" when "000001000000000000",
x"fffffff8" when "000000100000000000",
x"00000008" when "000000010000000000",
x"fffffff0" when "000000001000000000",
x"00000010" when "000000000100000000",
"00000000000000000000000" & op.code(7 downto 0) & "0" when "000000000010000000",
imms_8_0 when "000000000001000000",
imms_8_1 when "000000000000100000",
x"000000" & op.code(7 downto 0) when "000000000000010000",
x"00000001" when "000000000000001000",
x"00000002" when "000000000000000100",
"0000000000000000000000" & op.code(7 downto 0) & "00" when "000000000000000010",
x"00000000" when "000000000000000001",
x"00000004" when others;
debug <= ((not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and not op.code(9) and not op.code(8) and not op.code(7) and not op.code(6) and op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_30);
cond44 <= (imp_bit_14 or (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and op.code(2))) or (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(1))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1) and op.code(0)))) & (imp_bit_38 or imp_bit_146 or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(2) and not op.code(1))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(3) and op.code(2) and not op.code(1)))) & (imp_bit_138 or imp_bit_107 or imp_bit_128 or imp_bit_65 or imp_bit_155) & (imp_bit_132 or imp_bit_111 or imp_bit_104 or imp_bit_119 or imp_bit_112 or imp_bit_85 or (not p(0) and (not op.code(15) and op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and not op.code(2))) or imp_bit_45 or imp_bit_42) & (imp_bit_110 or imp_bit_136 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and op.code(0))) or imp_bit_59 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and op.code(1))) or imp_bit_140 or imp_bit_130 or imp_bit_106 or imp_bit_102 or imp_bit_76);
with cond44 select
ex_stall.zbus_sel <=
SEL_MANIP when "10000",
SEL_SHIFT when "01000",
SEL_WBUS when "00100",
SEL_YBUS when "00010",
SEL_LOGIC when "00001",
SEL_ARITH when others;
cond45 <= imp_bit_59 & ((not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and op.code(9) and op.code(8))) or (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and op.code(9) and op.code(8)))) & (imp_bit_136 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and op.code(3) and not op.code(2) and not op.code(1))) or ((op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and op.code(10) and not op.code(9))) or (not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and op.code(11) and not op.code(10) and not op.code(9))));
with cond45 select
ex.logic_func <=
LOGIC_NOT when "100",
LOGIC_OR when "010",
LOGIC_AND when "001",
LOGIC_XOR when others;
delay_jump <= (imp_bit_150 or imp_bit_141 or imp_bit_35 or imp_bit_36 or imp_bit_122 or imp_bit_103);
cond47 <= (imp_bit_140 or imp_bit_130) & (imp_bit_131 or imp_bit_4 or imp_bit_78 or imp_bit_67 or imp_bit_33 or imp_bit_157 or imp_bit_69 or imp_bit_80 or imp_bit_57);
with cond47 select
ex_stall.mem_addr_sel <=
SEL_YBUS when "10",
SEL_XBUS when "01",
SEL_ZBUS when others;
ex_stall.macsel1 <= SEL_ZBUS when (imp_bit_110 or imp_bit_135) = '1' else SEL_XBUS;
ex_stall.macsel2 <= SEL_ZBUS when (imp_bit_110 or imp_bit_145) = '1' else SEL_YBUS;
cond50 <= (((not op.addr(2) and not op.addr(1) and op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or imp_bit_108 or ((not op.addr(3) and not op.addr(2) and op.addr(1) and op.addr(0)) and p(0) and (not op.code(10) and not op.code(9)))) & ((not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0)))) & ((not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0)))) & (imp_bit_136 or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) or (not op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or ((not op.addr(2) and not op.addr(1) and not op.addr(0)) and not p(0) and (op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(11) and not op.code(10) and op.code(9) and op.code(8))) or imp_bit_120 or (p(0) and (not op.addr(3) and not op.addr(2) and op.addr(1) and not op.addr(0)) and (not op.code(10) and not op.code(9)))) & (imp_bit_110 or imp_bit_132 or imp_bit_143 or imp_bit_40 or imp_bit_14 or imp_bit_12 or (not op.addr(0) and not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and op.code(5) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or imp_bit_119 or imp_bit_112 or imp_bit_31 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(1))) or imp_bit_51 or imp_bit_52 or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(2))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and op.code(3))) or (not p(0) and (not op.code(15) and not op.code(14) and not op.code(12) and not op.code(3) and op.code(2))) or imp_bit_26 or imp_bit_137 or imp_bit_74 or imp_bit_105 or imp_bit_134 or imp_bit_124 or imp_bit_25 or imp_bit_123 or imp_bit_118 or imp_bit_100 or imp_bit_115 or imp_bit_76 or imp_bit_9 or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and op.code(2) and op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and op.code(13) and not op.code(12) and not op.code(2) and not op.code(1))));
with cond50 select
ex.ybus_sel <=
SEL_PC when "10000",
SEL_MACH when "01000",
SEL_MACL when "00100",
SEL_SR when "00010",
SEL_REG when "00001",
SEL_IMM when others;
ex.mem_lock <= (imp_bit_11 or imp_bit_4 or imp_bit_69 or imp_bit_52);
ex_stall.wrpr_pc <= (imp_bit_158 or imp_bit_159 or imp_bit_83);
cond53 <= (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and op.code(3) and op.code(1) and op.code(0))) & (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and not op.code(0))) & (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and op.code(2) and op.code(1) and not op.code(0))) & (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and not op.code(12) and not op.code(3) and op.code(2) and op.code(1) and op.code(0))) & imp_bit_56 & ((not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and op.code(2) and not op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and op.code(2) and op.code(1) and op.code(0)))) & ((not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(4) and not op.code(3) and not op.code(2) and not op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and not op.code(14) and op.code(13) and op.code(12) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))));
with cond53 select
ex.arith_sr_func <=
OVERUNDERFLOW when "1000000",
UGRTER_EQ when "0100000",
UGRTER when "0010000",
DIV0S when "0001000",
DIV1 when "0000100",
SGRTER when "0000010",
SGRTER_EQ when "0000001",
ZERO when others;
wb_stall.wrmacl <= imp_bit_160;
maskint_next <= ((not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(2) and op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(2) and op.code(1) and not op.code(0))) or (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or (op.addr(0) and not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and not op.code(3) and not op.code(2) and op.code(1) and op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(5) and op.code(1) and not op.code(0))) or (not p(0) and (not op.code(15) and op.code(14) and not op.code(13) and not op.code(12) and not op.code(7) and not op.code(6) and not op.code(4) and op.code(1) and not op.code(0))) or imp_bit_66 or imp_bit_47);
end;

7
ghdl.sh Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh
ghdl -a cpu2j0_pkg.vhd components_pkg.vhd mult_pkg.vhd decode_pkg.vhd decode_body.vhd datapath_pkg.vhd cpu.vhd decode.vhd decode_core.vhd decode_table.vhd decode_table_reverse.vhd datapath.vhd register_file.vhd mult.vhd
ghdl -a data_bus_pkg.vhd monitor_pkg.vhd asymmetric_ram.vhd bus_monitor.vhd timeout_cnt.vhd cpu_sram.vhd cpu_pure_tb.vhh
ghdl -e cpu_pure_tb

40
monitor_pkg.vhd Normal file
View File

@ -0,0 +1,40 @@
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use work.cpu2j0_pack.all;
package monitor_pkg is
type timeout_t is record
cnt : integer range 0 to 10;
end record;
type cnt_reg_t is record
a : std_logic;
cnt : integer range 0 to 10;
end record;
constant CNT_REG_RESET : cnt_reg_t := ('0',0);
component timeout_cnt
port(
clk : in std_logic;
rst : in std_logic;
enable : in std_logic;
ack : in std_logic;
timeout : out timeout_t;
fault : out std_logic
);
end component;
component bus_monitor
generic ( memblock : string := "IF");
port (
clk : in std_logic;
rst : in std_logic;
cpu_bus_o : in cpu_data_o_t;
cpu_bus_i : in cpu_data_i_t
);
end component;
end package;

174
mult.vhd Normal file
View File

@ -0,0 +1,174 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.mult_pkg.all;
entity mult is port (
clk : in std_logic;
rst : in std_logic;
slot : in std_logic;
a : in mult_i_t;
y : out mult_o_t);
end mult;
architecture stru of mult is
signal this_c : mult_reg_t;
signal this_r : mult_reg_t := MULT_RESET;
begin
mult : process(this_r, slot, a)
variable this : mult_reg_t;
variable aa : std_logic_vector(31 downto 0);
variable ah : std_logic_vector(30 downto 0);
variable bh : std_logic_vector(15 downto 0);
variable abh2 : std_logic_vector(32 downto 0);
variable p2 : std_logic_vector(31 downto 0);
variable p3 : std_logic_vector(31 downto 0);
variable sgn : std_logic_vector(31 downto 0);
variable pm : std_logic_vector(47 downto 0);
variable c : std_logic_vector(63 downto 0);
variable acc : std_logic_vector(63 downto 0);
variable region: std_logic_vector(2 downto 0);
variable sat : std_logic;
variable code : mult_codeline_t;
begin
this := this_r;
code := MULT_CODE(this.state);
y.busy <= code.busy; -- FIXME: warning : combinatorial output
-- operand intermediates, multiplier and input mux, lower 31bits of A and upper/lower 16bits of B
aa := this.m1;
if code.sela = MB then aa := this.mb; end if;
ah := aa(30 downto 0);
if code.size = B16 then ah(30 downto 15) := (others => '0'); end if;
bh := this.m2(15 downto 0);
if code.size = B16 then bh(15) := '0';
elsif code.shift = '1' then bh := '0' & this.m2(30 downto 16); end if;
-- partial product adder input mux
if code.size = B16 then abh2 := '0' & x"0000" & (aa(15) and this.m2(15)) & this.abh(29 downto 15);
elsif this.shift = '0' then abh2 := '0' & this.abh(46 downto 15);
else abh2 := '0' & (aa(31) and this.m2(31)) & this.abh(45 downto 15); end if;
-- partial products adders
p2 := (others => '0');
if aa(31) = '1' and code.shift = '1' then p2 := '0' & this.m2(30 downto 0); end if;
if aa(15) = '1' and code.size = B16 then p2 := x"0000" & '0' & this.m2(14 downto 0); end if;
p3 := (others => '0');
if this.m2(31) = '1' and code.shift = '1' then p3 := '0' & aa(30 downto 0); end if;
if this.m2(15) = '1' and code.size = B16 then p3 := x"0000" & '0' & aa(14 downto 0); end if;
if code.sign = 1 then sgn := (others => '1'); else sgn := (others => '0'); end if;
pm := std_logic_vector(unsigned(abh2) + unsigned(sgn(0) & (this.p23 xor sgn)) + code.sign) & this.abh(14 downto 0);
this.p23 := std_logic_vector(unsigned(p2) + unsigned(p3));
if this.shift = '0' then
if pm(47) = '1' and code.size = B16 then c := x"ffff" & pm;
else c := x"0000" & pm; end if;
else c := pm & x"0000";
end if;
-- accumulator
acc := std_logic_vector(unsigned(c) + unsigned((this.mach and to_slv(code.use_h, 32)) & this.macl));
-- saturate
sat := '1'; region := (others => '0');
case this.result_op is
when IDENTITY => sat := '0';
when SATURATE64 =>
if acc(63) = '0' and acc(62 downto 47) /= x"0000" then region(0) := '1';
elsif acc(63) = '1' and acc(62 downto 47) /= x"ffff" then region(0) := '1'; end if;
region(2 downto 1) := this.mach(31) & acc(63);
if c(63) = '0' then
case region is
when "001" | "010" | "011" | "101" => acc := P48MAX;
when "111" => acc := N48MAX;
when others => sat := '0';
end case;
else
case region is
when "001" => acc := P48MAX;
when "011" | "100" | "101" | "111" => acc := N48MAX;
when others => sat := '0';
end case;
end if;
when SATURATE32 =>
region := this.macl(31) & acc(31) & '0';
if c(31) = '0' then
case (region) is
when "010" => acc := P32MAX;
when others => sat := '0';
end case;
else
case (region) is
when "100" => acc := N32MAX;
when others => sat := '0';
end case;
end if;
end case;
-- multiplier
this.abh := std_logic_vector(unsigned(ah) * unsigned(bh));
-- load the internal registers from the CPU
if slot = '1' then
if a.command /= NOP then
this.m2 := a.in2;
if a.command = MACL or a.command = MACW then this.mb := this.m1; end if;
end if;
if a.wr_m1 = '1' then this.m1 := a.in1; end if;
end if;
if slot = '1' and a.wr_mach = '1' then this.mach := a.in1;
elsif slot = '1' and (a.command = DMULSL or a.command = DMULUL) then this.mach := x"00000000";
elsif this.state = MACWS1 and sat = '1' then this.mach := this.mach or x"00000001";
elsif code.mach_en = '1' then this.mach := acc(63 downto 32);
end if;
if slot = '1' and a.wr_macl = '1' then this.macl := a.in2;
elsif slot = '1' and a.command /= NOP and a.command /= MACL and a.command /= MACW then this.macl := x"00000000";
elsif code.macl_en = '1' then this.macl := acc(31 downto 0);
end if;
-- delayed versions of the control signals to delay for p23 pipeline register
this.state := code.state;
this.shift := code.shift;
-- load the command from the CPU
if code.busy = '0' and slot = '1' then
this.result_op := IDENTITY;
this.state := a.command;
if a.command = MACL then
if a.s = '1' then this.result_op := SATURATE64; end if;
elsif a.command = MACW then -- override start state, MACWS and MACW set different busy and mach_en values
if a.s = '1' then this.result_op := SATURATE32; this.state := MACWS; end if;
end if;
end if;
this_c <= this;
end process;
mult_r0 : process(clk, rst)
begin
if rst='1' then
this_r <= MULT_RESET;
elsif clk='1' and clk'event then
this_r <= this_c;
end if;
end process;
-- drive the outputs
y.mach <= this_r.mach;
y.macl <= this_r.macl;
end stru;

115
mult_pkg.vhd Normal file
View File

@ -0,0 +1,115 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package mult_pkg is
type mult_state_t is (NOP, DMULSL, DMULSL1, DMULSL2, DMULUL, DMULUL1, DMULUL2, MACL, MACL1, MACL2, MACW, MACW1, MACWS, MACWS1, MULL, MULL1, MULL2, MULSW, MULSW1, MULUW, MULUW1);
type mult_result_op_t is (IDENTITY, SATURATE32, SATURATE64);
type mult_sela_t is ( M1, MB );
type mult_size_t is ( B16, B32 );
constant P48MAX : std_logic_vector(63 downto 0) := x"00007fffffffffff";
constant N48MAX : std_logic_vector(63 downto 0) := x"ffff800000000000";
constant P32MAX : std_logic_vector(63 downto 0) := x"000000007fffffff";
constant N32MAX : std_logic_vector(63 downto 0) := x"ffffffff80000000";
type mult_codeline_t is record
state : mult_state_t;
busy : std_logic;
sela : mult_sela_t;
shift : std_logic;
sign : integer range 0 to 1;
size : mult_size_t;
mach_en : std_logic;
macl_en : std_logic;
use_h : std_logic;
end record;
type mult_microcode_t is array (mult_state_t) of mult_codeline_t;
constant MULT_CODE : mult_microcode_t := (
-- state busy sela shft sign size h_en l_en use_h
( NOP, '0', M1, '0', 0, B16, '0', '0', '1' ), -- NOP
( DMULSL1, '1', M1, '0', 1, B32, '0', '0', '1' ), -- DMULSL
( DMULSL2, '1', M1, '1', 1, B32, '1', '1', '1' ), -- DMULSL1
( NOP, '0', M1, '1', 1, B32, '1', '1', '1' ), -- DMULSL2
( DMULUL1, '1', M1, '0', 0, B32, '0', '0', '1' ), -- DMULUL
( DMULUL2, '1', M1, '1', 0, B32, '1', '1', '1' ), -- DMULUL1
( NOP, '0', M1, '1', 0, B32, '1', '1', '1' ), -- DMULUL2
( MACL1, '1', MB, '0', 1, B32, '0', '0', '1' ), -- MACL
( MACL2, '1', MB, '1', 1, B32, '1', '1', '1' ), -- MACL1
( NOP, '0', MB, '1', 1, B32, '1', '1', '1' ), -- MACL2
( MACW1, '1', M1, '0', 1, B16, '0', '0', '1' ), -- MACW
( NOP, '0', M1, '0', 1, B16, '1', '1', '1' ), -- MACW1
( MACWS1, '1', M1, '0', 1, B16, '0', '0', '0' ), -- MACWS
( NOP, '0', M1, '0', 1, B16, '0', '1', '0' ), -- MACWS1
( MULL1, '1', M1, '0', 1, B32, '0', '0', '0' ), -- MULL
( MULL2, '1', M1, '1', 1, B32, '0', '1', '0' ), -- MULL1
( NOP, '0', M1, '1', 1, B32, '0', '1', '0' ), -- MULL2
( MULSW1, '1', M1, '0', 1, B16, '0', '0', '0' ), -- MULSW
( NOP, '0', M1, '0', 1, B16, '0', '1', '0' ), -- MULSW1
( MULUW1, '1', M1, '0', 0, B16, '0', '0', '0' ), -- MULUW
( NOP, '0', M1, '0', 0, B16, '0', '1', '0' ) -- MULUW1
);
type mult_i_t is record
wr_m1 : std_logic;
command : mult_state_t;
s : std_logic;
wr_mach : std_logic;
wr_macl : std_logic;
in1 : std_logic_vector(31 downto 0);
in2 : std_logic_vector(31 downto 0);
end record;
type mult_o_t is record
mach : std_logic_vector(31 downto 0);
macl : std_logic_vector(31 downto 0);
busy : std_logic;
end record;
type mult_reg_t is record
state : mult_state_t;
result_op : mult_result_op_t;
m1, m2, mb : std_logic_vector(31 downto 0);
p23 : std_logic_vector(31 downto 0);
mach, macl : std_logic_vector(31 downto 0);
shift : std_logic;
abh : std_logic_vector(46 downto 0);
end record;
constant MULT_RESET : mult_reg_t := (state => NOP,
result_op => IDENTITY,
m1 => (others => '0'),
m2 => (others => '0'),
mb => (others => '0'),
p23 => (others => '0'),
mach => (others => '0'),
macl => (others => '0'),
shift => '0',
abh => (others => '0')
);
component mult is
port (
clk : in std_logic;
rst : in std_logic;
slot : in std_logic;
a : in mult_i_t;
y : out mult_o_t);
end component mult;
function to_slv(b : std_logic; s : integer) return std_logic_vector;
end package;
package body mult_pkg is
function to_slv(b : std_logic; s : integer) return std_logic_vector is
variable r : std_logic_vector(s-1 downto 0);
begin
r := (others => b);
return r;
end function to_slv;
end package body;

7
nvc.sh Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh
nvc -a cpu2j0_pkg.vhd components_pkg.vhd mult_pkg.vhd decode_pkg.vhd decode_body.vhd datapath_pkg.vhd cpu.vhd decode.vhd decode_core.vhd decode_table.vhd decode_table_reverse.vhd datapath.vhd register_file.vhd mult.vhd
nvc -a data_bus_pkg.vhd monitor_pkg.vhd asymmetric_ram.vhd bus_monitor.vhd timeout_cnt.vhd cpu_sram.vhd cpu_pure_tb.vhh
nvc -e -V cpu_pure_tb

BIN
ram.img Normal file

Binary file not shown.

170
register_file.vhd Normal file
View File

@ -0,0 +1,170 @@
-- A Register File with 2 write ports and 2 read ports built out of
-- 2 RAM blocks with 1 read and 1 independant write port. Register 0
-- also has independant ouput. 32 regs x 32 bits by default, one write clock.
--
-- Both write ports actually write to the same RAM blocks by delaying EX stage
-- writes to the WB stage and assuming that the decoder will never schedule
-- register writes for both Z and W busses in same ID stage.
--
-- To delay EX stage writes, a pipeline of 2 pending writes is kept. To service
-- a read, either the data in the EX pipeline or the current WB write value
-- may be returned instead of the data in the RAM block. Servicing reads from
-- the current WB write value implements W bus forwarding.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity register_file is
generic (
ADDR_WIDTH : integer;
NUM_REGS : integer;
REG_WIDTH : integer);
port (
clk : in std_logic;
rst : in std_logic;
ce : in std_logic;
addr_ra : in std_logic_vector(ADDR_WIDTH-1 downto 0);
dout_a : out std_logic_vector(REG_WIDTH-1 downto 0);
addr_rb : in std_logic_vector(ADDR_WIDTH-1 downto 0);
dout_b : out std_logic_vector(REG_WIDTH-1 downto 0);
dout_0 : out std_logic_vector(REG_WIDTH-1 downto 0);
we_wb : in std_logic;
w_addr_wb : in std_logic_vector(ADDR_WIDTH-1 downto 0);
din_wb : in std_logic_vector(REG_WIDTH-1 downto 0);
we_ex : in std_logic;
w_addr_ex : in std_logic_vector(ADDR_WIDTH-1 downto 0);
din_ex : in std_logic_vector(REG_WIDTH-1 downto 0);
-- wr_data_o exposes the data about to be written to the
-- register memories
wr_data_o : out std_logic_vector(REG_WIDTH-1 downto 0)
);
subtype addr_t is std_logic_vector(ADDR_WIDTH-1 downto 0);
subtype data_t is std_logic_vector(REG_WIDTH-1 downto 0);
type reg_pipe_t is
record
en : std_logic;
data : data_t;
addr : addr_t;
end record;
type ex_pipeline_t is array(0 to 2) of reg_pipe_t;
function pipe_matches(pipe : reg_pipe_t; addr : addr_t)
return boolean is
begin
return pipe.en = '1' and pipe.addr = addr;
end;
function read_with_forwarding(addr : addr_t; bank_data : data_t;
wb_pipe : reg_pipe_t;
ex_pipes : ex_pipeline_t)
return std_logic_vector is
begin
-- The goal here is to read the most recent value for a register.
-- (I believe the order of the wb_pipe and ex_pipes(1) checks doesn't
-- matter and can be reversed because they cannot both be writing to the
-- same register. Register conflict detection prevents that.)
-- forward from W bus writes occuring this cycle
if (pipe_matches(wb_pipe, addr)) then
return wb_pipe.data;
-- ex_pipes(1) and ex_pipes(2) are "already written" values that should be
-- returned before the bank data. Check ex_pipes(1) first as it is the more
-- recent write.
elsif (pipe_matches(ex_pipes(1), addr)) then
return ex_pipes(1).data;
elsif (pipe_matches(ex_pipes(2), addr)) then
return ex_pipes(2).data;
else
-- no matching pending writes in the pipeline, return bank data
return bank_data;
end if;
end;
function to_reg_index(addr : addr_t)
return integer is
variable ret : integer range 0 to 31;
begin
ret := to_integer(unsigned(addr));
if ret >= NUM_REGS then
report "Register out of range";
ret := 0;
end if;
return ret;
end;
end register_file;
architecture two_bank of register_file is
constant ZERO_ADDR : addr_t := (others => '0');
type ram_type is array(0 to NUM_REGS - 1) of data_t;
signal bank_a, bank_b : ram_type;
signal reg0 : data_t;
signal ex_pipes : ex_pipeline_t;
signal wb_pipe : reg_pipe_t;
begin
wb_pipe.en <= we_wb;
wb_pipe.addr <= w_addr_wb;
wb_pipe.data <= din_wb;
ex_pipes(0).en <= we_ex;
ex_pipes(0).addr <= w_addr_ex;
ex_pipes(0).data <= din_ex;
dout_a <= read_with_forwarding(addr_ra, bank_a(to_reg_index(addr_ra)), wb_pipe, ex_pipes);
dout_b <= read_with_forwarding(addr_rb, bank_b(to_reg_index(addr_rb)), wb_pipe, ex_pipes);
dout_0 <= read_with_forwarding(ZERO_ADDR, reg0, wb_pipe, ex_pipes);
process (clk, rst, ce, wb_pipe, ex_pipes)
variable addr : integer;
variable data : data_t;
begin
if rst = '1' then
addr := 0;
data := (others => '0');
wr_data_o <= (others => '0');
reg0 <= (others => '0');
ex_pipes(1) <= (
en => '0',
data => (others => '0'),
addr => (others => '0'));
ex_pipes(2) <= (
en => '0',
data => (others => '0'),
addr => (others => '0'));
elsif (rising_edge(clk) and ce = '1') then
-- the decoder should never schedule a write to a register for both Z and
-- W bus at the same time
assert (wb_pipe.en and ex_pipes(2).en) = '0'
report "Write clash detected" severity warning;
addr := to_reg_index(wb_pipe.addr);
data := wb_pipe.data;
if (ex_pipes(2).en = '1') then
addr := to_reg_index(ex_pipes(2).addr);
data := ex_pipes(2).data;
end if;
wr_data_o <= (others => '0');
if ((wb_pipe.en or ex_pipes(2).en) = '1') then
wr_data_o <= data;
bank_a(addr) <= data;
bank_b(addr) <= data;
if (addr = 0) then
reg0 <= data;
end if;
end if;
ex_pipes(2) <= ex_pipes(1);
ex_pipes(1) <= ex_pipes(0);
end if;
end process;
end architecture;

63
timeout_cnt.vhd Normal file
View File

@ -0,0 +1,63 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.monitor_pkg.all;
entity timeout_cnt is
generic ( timeout_cc : integer := 3); -- clock cycles timeout
port(
clk : in std_logic;
rst : in std_logic;
enable : in std_logic;
ack : in std_logic;
timeout : out timeout_t;
fault : out std_logic
);
end timeout_cnt;
architecture structure of timeout_cnt is
signal this_c : cnt_reg_t;
signal this_r : cnt_reg_t := CNT_REG_RESET;
begin
counter : process(this_r,enable,ack)
variable this : cnt_reg_t;
begin
this := this_r;
if (enable = '1') then
if (ack = '1') then
this.cnt := 0;
else
if (this.cnt /= timeout_cc) then
this.cnt := this.cnt + 1; -- start counting
end if;
end if;
else
this.cnt := 0;
end if;
this_c <= this;
end process;
counter_r0 : process(clk, rst)
begin
if rst = '1' then
this_r <= CNT_REG_RESET;
elsif clk = '1' and clk'event then
this_r <= this_c;
end if;
end process;
--timeout <= '1' when (this.cnt = timeout_cc) else '0';
timeout.cnt <= this_r.cnt;
fault <= '1' when (this_r.cnt = timeout_cc) else '0';
end structure;

1
verific Normal file
View File

@ -0,0 +1 @@
verific -vhdl93 cpu2j0_pkg.vhd components_pkg.vhd mult_pkg.vhd decode_pkg.vhd decode_body.vhd datapath_pkg.vhd cpu.vhd decode.vhd decode_core.vhd decode_table.vhd decode_table_reverse.vhd datapath.vhd register_file.vhd mult.vhd