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:
commit
eaad427655
88
asymmetric_ram.vhd
Normal file
88
asymmetric_ram.vhd
Normal 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
214
bus_monitor.vhd
Normal 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
504
components_pkg.vhd
Normal 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
80
cpu.vhd
Normal 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
98
cpu2j0_pkg.vhd
Normal 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
172
cpu_pure_tb.vhh
Normal 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
46
cpu_sram.vhd
Normal 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
236
data_bus_pkg.vhd
Normal 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
466
datapath.vhd
Normal 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
55
datapath_pkg.vhd
Normal 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
192
decode.vhd
Normal 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
286
decode_body.vhd
Normal 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
191
decode_core.vhd
Normal 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
287
decode_pkg.vhd
Normal 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
37
decode_table.vhd
Normal 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
649
decode_table_reverse.vhd
Normal 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
7
ghdl.sh
Normal 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
40
monitor_pkg.vhd
Normal 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
174
mult.vhd
Normal 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
115
mult_pkg.vhd
Normal 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
7
nvc.sh
Normal 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
|
||||
170
register_file.vhd
Normal file
170
register_file.vhd
Normal 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
63
timeout_cnt.vhd
Normal 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;
|
||||
Loading…
x
Reference in New Issue
Block a user