commit
5a29cb4699
2049 changed files with 38352 additions and 0 deletions
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
*.o |
||||
*~ |
||||
*.cf |
||||
*.s |
||||
core_tb |
||||
fetch_tb |
||||
loadstore_tb |
||||
simple_ram_behavioural_tb |
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
ยฉ IBM Corp. 2019 |
||||
This softcore is licensed under and subject to the terms of the CC-BY 4.0 |
||||
license (https://creativecommons.org/licenses/by/4.0/legalcode). |
||||
Additional rights, including the right to physically implement a softcore |
||||
that is compliant with the required sections of the Power ISA |
||||
Specification, will be available at no cost via the OpenPOWER Foundation. |
||||
This README will be updated with additional information when OpenPOWER's |
||||
license is available. |
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
GHDL=ghdl |
||||
GHDLFLAGS=--std=08 |
||||
CFLAGS=-O2 |
||||
|
||||
all = core_tb simple_ram_behavioural_tb |
||||
# XXX |
||||
# loadstore_tb fetch_tb |
||||
|
||||
all: $(all) |
||||
|
||||
%.o : %.vhdl |
||||
$(GHDL) -a $(GHDLFLAGS) $< |
||||
|
||||
common.o: decode_types.o |
||||
core_tb.o: common.o wishbone_types.o core.o simple_ram_behavioural.o |
||||
core.o: common.o wishbone_types.o fetch1.o fetch2.o decode1.o decode2.o register_file.o cr_file.o execute1.o execute2.o loadstore1.o loadstore2.o multiply.o writeback.o wishbone_arbiter.o |
||||
cr_file.o: common.o |
||||
crhelpers.o: common.o |
||||
decode1.o: common.o decode_types.o |
||||
decode2.o: decode_types.o common.o helpers.o |
||||
decode_types.o: |
||||
execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o sim_console.o |
||||
execute2.o: common.o crhelpers.o ppc_fx_insns.o |
||||
fetch1.o: common.o |
||||
fetch2.o: common.o wishbone_types.o |
||||
fetch_tb.o: common.o wishbone_types.o fetch.o |
||||
glibc_random_helpers.o: |
||||
glibc_random.o: glibc_random_helpers.o |
||||
helpers.o: |
||||
loadstore1.o: common.o |
||||
loadstore2.o: common.o helpers.o wishbone_types.o |
||||
loadstore_tb.o: common.o simple_ram_types.o simple_ram.o loadstore1.o loadstore2.o |
||||
multiply_tb.o: common.o glibc_random.o ppc_fx_insns.o multiply.o |
||||
multiply.o: common.o decode_types.o ppc_fx_insns.o crhelpers.o |
||||
ppc_fx_insns.o: helpers.o |
||||
register_file.o: common.o |
||||
sim_console.o: |
||||
simple_ram_behavioural_helpers.o: |
||||
simple_ram_behavioural_tb.o: wishbone_types.o simple_ram_behavioural.o |
||||
simple_ram_behavioural.o: wishbone_types.o simple_ram_behavioural_helpers.o |
||||
wishbone_arbiter.o: wishbone_types.o |
||||
wishbone_types.o: |
||||
writeback.o: common.o |
||||
|
||||
core_tb: core_tb.o simple_ram_behavioural_helpers_c.o sim_console_c.o |
||||
$(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o -Wl,sim_console_c.o $@ |
||||
|
||||
fetch_tb: fetch_tb.o |
||||
$(GHDL) -e $(GHDLFLAGS) $@ |
||||
|
||||
loadstore_tb: loadstore_tb.o |
||||
$(GHDL) -e $(GHDLFLAGS) $@ |
||||
|
||||
simple_ram_tb: simple_ram_tb.o |
||||
$(GHDL) -e $(GHDLFLAGS) $@ |
||||
|
||||
simple_ram_behavioural_tb: simple_ram_behavioural_helpers_c.o simple_ram_behavioural_tb.o |
||||
$(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o $@ |
||||
|
||||
tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out))) |
||||
|
||||
check: $(tests) test_micropython test_micropython_long |
||||
|
||||
$(tests): core_tb |
||||
@./scripts/run_test.sh $@ |
||||
|
||||
test_micropython: |
||||
@./scripts/test_micropython.py |
||||
|
||||
test_micropython_long: |
||||
@./scripts/test_micropython_long.py |
||||
|
||||
clean: |
||||
rm -f *.o work-*cf $(all) |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
# Microwatt |
||||
|
||||
A tiny Open POWER ISA softcore written in VHDL 2008. It aims to be simple and easy |
||||
to understand. |
||||
|
||||
## Simulation |
||||
|
||||
- Build micropython. If you aren't building on a ppc64le box you |
||||
will need a cross compiler. If it isn't available on your distro |
||||
grab the powerpc64le-power8 toolchain from https://toolchains.bootlin.com |
||||
|
||||
``` |
||||
git clone https://github.com/mikey/micropython |
||||
cd micropython |
||||
git checkout powerpc |
||||
cd ports/powerpc |
||||
make -j$(nproc) |
||||
cd ../../../ |
||||
``` |
||||
|
||||
- Microwatt uses ghdl for simulation. Either install this from your |
||||
distro or build it. Next build microwatt: |
||||
|
||||
``` |
||||
git clone https://github.com/antonblanchard/microwatt |
||||
cd microwatt |
||||
make |
||||
``` |
||||
|
||||
- Link in the micropython image: |
||||
|
||||
``` |
||||
ln -s ../micropython/ports/powerpc/build/firmware.bin simple_ram_behavioural.bin |
||||
``` |
||||
|
||||
- Now run microwatt, sending debug output to /dev/null: |
||||
|
||||
``` |
||||
./core_tb > /dev/null |
||||
``` |
||||
|
||||
## Testing |
||||
|
||||
- A simple test suite containing random execution test cases and a couple of |
||||
micropython test cases can be run with: |
||||
|
||||
``` |
||||
make -j$(nproc) check |
||||
``` |
||||
|
||||
## Issues |
||||
|
||||
This is functional, but very simple. We still have quite a lot to do: |
||||
|
||||
- Need to implement a simple non pipelined divide |
||||
- There are a few instructions still to be implemented |
||||
- Need to add caches and bypassing (in progress) |
||||
- Need to add supervisor state (in progress) |
@ -0,0 +1,196 @@
@@ -0,0 +1,196 @@
|
||||
library ieee; |
||||
use ieee.std_logic_1164.all; |
||||
|
||||
library work; |
||||
use work.decode_types.all; |
||||
|
||||
package common is |
||||
type ctrl_t is record |
||||
lr: std_ulogic_vector(63 downto 0); |
||||
ctr: std_ulogic_vector(63 downto 0); |
||||
tb: std_ulogic_vector(63 downto 0); |
||||
carry: std_ulogic; |
||||
end record; |
||||
|
||||
type Fetch1ToFetch2Type is record |
||||
valid: std_ulogic; |
||||
nia: std_ulogic_vector(63 downto 0); |
||||
end record; |
||||
|
||||
type Fetch2ToDecode1Type is record |
||||
valid: std_ulogic; |
||||
nia: std_ulogic_vector(63 downto 0); |
||||
insn: std_ulogic_vector(31 downto 0); |
||||
end record; |
||||
constant Fetch2ToDecode1Init : Fetch2ToDecode1Type := (valid => '0', others => (others => '0')); |
||||
|
||||
type Decode1ToDecode2Type is record |
||||
valid: std_ulogic; |
||||
nia: std_ulogic_vector(63 downto 0); |
||||
insn: std_ulogic_vector(31 downto 0); |
||||
decode: decode_rom_t; |
||||
end record; |
||||
constant Decode1ToDecode2Init : Decode1ToDecode2Type := (valid => '0', decode => decode_rom_init, others => (others => '0')); |
||||
|
||||
type Decode2ToExecute1Type is record |
||||
valid: std_ulogic; |
||||
insn_type: insn_type_t; |
||||
nia: std_ulogic_vector(63 downto 0); |
||||
write_reg: std_ulogic_vector(4 downto 0); |
||||
read_reg1: std_ulogic_vector(4 downto 0); |
||||
read_reg2: std_ulogic_vector(4 downto 0); |
||||
read_data1: std_ulogic_vector(63 downto 0); |
||||
read_data2: std_ulogic_vector(63 downto 0); |
||||
const1: std_ulogic_vector(23 downto 0); |
||||
const2: std_ulogic_vector(6 downto 0); |
||||
const3: std_ulogic_vector(6 downto 0); |
||||
cr: std_ulogic_vector(31 downto 0); |
||||
lr: std_ulogic; |
||||
rc: std_ulogic; |
||||
input_carry: std_ulogic; |
||||
output_carry: std_ulogic; |
||||
input_cr: std_ulogic; |
||||
output_cr: std_ulogic; |
||||
input_cr_data: std_ulogic_vector(31 downto 0); |
||||
end record; |
||||
constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0')); |
||||
|
||||
type Decode2ToMultiplyType is record |
||||
valid: std_ulogic; |
||||
insn_type: insn_type_t; |
||||
nia: std_ulogic_vector(63 downto 0); |
||||
write_reg: std_ulogic_vector(4 downto 0); |
||||
data1: std_ulogic_vector(64 downto 0); |
||||
data2: std_ulogic_vector(64 downto 0); |
||||
rc: std_ulogic; |
||||
end record; |
||||
constant Decode2ToMultiplyInit : Decode2ToMultiplyType := (valid => '0', insn_type => OP_ILLEGAL, rc => '0', others => (others => '0')); |
||||
|
||||
type Decode2ToRegisterFileType is record |
||||
read1_reg : std_ulogic_vector(4 downto 0); |
||||
read2_reg : std_ulogic_vector(4 downto 0); |
||||
read3_reg : std_ulogic_vector(4 downto 0); |
||||
end record; |
||||
|
||||
type RegisterFileToDecode2Type is record |
||||
read1_data : std_ulogic_vector(63 downto 0); |
||||
read2_data : std_ulogic_vector(63 downto 0); |
||||
read3_data : std_ulogic_vector(63 downto 0); |
||||
end record; |
||||
|
||||
type Decode2ToCrFileType is record |
||||
read_cr_nr_1 : integer; |
||||
read_cr_nr_2 : integer; |
||||
end record; |
||||
|
||||
type CrFileToDecode2Type is record |
||||
read_cr_data : std_ulogic_vector(31 downto 0); |
||||
read_cr_data_1 : std_ulogic_vector(3 downto 0); |
||||
read_cr_data_2 : std_ulogic_vector(3 downto 0); |
||||
end record; |
||||
|
||||
type Execute1ToFetch1Type is record |
||||
redirect: std_ulogic; |
||||
redirect_nia: std_ulogic_vector(63 downto 0); |
||||
end record; |
||||
constant Execute1ToFetch1TypeInit : Execute1ToFetch1Type := (redirect => '0', others => (others => '0')); |
||||
|
||||
type Decode2ToLoadstore1Type is record |
||||
valid : std_ulogic; |
||||
nia: std_ulogic_vector(63 downto 0); |
||||
load : std_ulogic; -- is this a load or store |
||||
addr1 : std_ulogic_vector(63 downto 0); |
||||
addr2 : std_ulogic_vector(63 downto 0); |
||||
data : std_ulogic_vector(63 downto 0); -- data to write, unused for read |
||||
write_reg : std_ulogic_vector(4 downto 0); -- read data goes to this register |
||||
length : std_ulogic_vector(3 downto 0); |
||||
byte_reverse : std_ulogic; |
||||
sign_extend : std_ulogic; -- do we need to sign extend? |
||||
update : std_ulogic; -- is this an update instruction? |
||||
update_reg : std_ulogic_vector(4 downto 0); -- if so, the register to update |
||||
end record; |
||||
constant Decode2ToLoadstore1Init : Decode2ToLoadstore1Type := (valid => '0', load => '0', byte_reverse => '0', sign_extend => '0', update => '0', others => (others => '0')); |
||||
|
||||
type Loadstore1ToLoadstore2Type is record |
||||
valid : std_ulogic; |
||||
load : std_ulogic; |
||||
addr : std_ulogic_vector(63 downto 0); |
||||
data : std_ulogic_vector(63 downto 0); |
||||
write_reg : std_ulogic_vector(4 downto 0); |
||||
length : std_ulogic_vector(3 downto 0); |
||||
byte_reverse : std_ulogic; |
||||
sign_extend : std_ulogic; |
||||
update : std_ulogic; |
||||
update_reg : std_ulogic_vector(4 downto 0); |
||||
end record; |
||||
|
||||
type Loadstore2ToWritebackType is record |
||||
valid : std_ulogic; |
||||
write_enable: std_ulogic; |
||||
write_reg : std_ulogic_vector(4 downto 0); |
||||
write_data : std_ulogic_vector(63 downto 0); |
||||
write_enable2: std_ulogic; |
||||
write_reg2 : std_ulogic_vector(4 downto 0); |
||||
write_data2 : std_ulogic_vector(63 downto 0); |
||||
end record; |
||||
constant Loadstore2ToWritebackInit : Loadstore2ToWritebackType := (valid => '0', write_enable => '0', write_enable2 => '0', others => (others => '0')); |
||||
|
||||
type Execute1ToExecute2Type is record |
||||
valid: std_ulogic; |
||||
write_enable : std_ulogic; |
||||
write_reg: std_ulogic_vector(4 downto 0); |
||||
write_data: std_ulogic_vector(63 downto 0); |
||||
write_cr_enable : std_ulogic; |
||||
write_cr_mask : std_ulogic_vector(7 downto 0); |
||||
write_cr_data : std_ulogic_vector(31 downto 0); |
||||
rc : std_ulogic; |
||||
end record; |
||||
constant Execute1ToExecute2Init : Execute1ToExecute2Type := (valid => '0', write_enable => '0', write_cr_enable => '0', rc => '0', others => (others => '0')); |
||||
|
||||
type Execute2ToWritebackType is record |
||||
valid: std_ulogic; |
||||
write_enable : std_ulogic; |
||||
write_reg: std_ulogic_vector(4 downto 0); |
||||
write_data: std_ulogic_vector(63 downto 0); |
||||
write_cr_enable : std_ulogic; |
||||
write_cr_mask : std_ulogic_vector(7 downto 0); |
||||
write_cr_data : std_ulogic_vector(31 downto 0); |
||||
end record; |
||||
constant Execute2ToWritebackInit : Execute2ToWritebackType := (valid => '0', write_enable => '0', write_cr_enable => '0', others => (others => '0')); |
||||
|
||||
type MultiplyToWritebackType is record |
||||
valid: std_ulogic; |
||||
|
||||
write_reg_enable : std_ulogic; |
||||
write_reg_nr: std_ulogic_vector(4 downto 0); |
||||
write_reg_data: std_ulogic_vector(63 downto 0); |
||||
write_cr_enable: std_ulogic; |
||||
write_cr_mask: std_ulogic_vector(7 downto 0); |
||||
write_cr_data: std_ulogic_vector(31 downto 0); |
||||
end record; |
||||
constant MultiplyToWritebackInit : MultiplyToWritebackType := (valid => '0', write_reg_enable => '0', write_cr_enable => '0', others => (others => '0')); |
||||
|
||||
type WritebackToRegisterFileType is record |
||||
write_reg : std_ulogic_vector(4 downto 0); |
||||
write_data : std_ulogic_vector(63 downto 0); |
||||
write_enable : std_ulogic; |
||||
write_reg2 : std_ulogic_vector(4 downto 0); |
||||
write_data2 : std_ulogic_vector(63 downto 0); |
||||
write_enable2 : std_ulogic; |
||||
end record; |
||||
constant WritebackToRegisterFileInit : WritebackToRegisterFileType := (write_enable => '0', write_enable2 => '0', others => (others => '0')); |
||||
|
||||
type WritebackToCrFileType is record |
||||
write_cr_enable : std_ulogic; |
||||
write_cr_mask : std_ulogic_vector(7 downto 0); |
||||
write_cr_data : std_ulogic_vector(31 downto 0); |
||||
end record; |
||||
constant WritebackToCrFileInit : WritebackToCrFileType := (write_cr_enable => '0', others => (others => '0')); |
||||
|
||||
-- Would prefer not to expose this outside the register file, but ghdl |
||||
-- doesn't support external names |
||||
type regfile is array(0 to 32) of std_ulogic_vector(63 downto 0); |
||||
end common; |
||||
|
||||
package body common is |
||||
end common; |
@ -0,0 +1,149 @@
@@ -0,0 +1,149 @@
|
||||
library ieee; |
||||
use ieee.std_logic_1164.all; |
||||
use ieee.numeric_std.all; |
||||
|
||||
library work; |
||||
use work.common.all; |
||||
use work.wishbone_types.all; |
||||
|
||||
entity core is |
||||
generic ( |
||||
SIM : boolean := false |
||||
); |
||||
port ( |
||||
clk : in std_logic; |
||||
rst : in std_logic; |
||||
|
||||
wishbone_in : in wishbone_slave_out; |
||||
wishbone_out : out wishbone_master_out; |
||||
|
||||
-- Added for debug, ghdl doesn't support external names unfortunately |
||||
registers : out regfile; |
||||
terminate_out : out std_ulogic |
||||
); |
||||
end core; |
||||
|
||||
architecture behave of core is |
||||
-- fetch signals |
||||
signal fetch1_to_fetch2: Fetch1ToFetch2Type; |
||||
signal fetch2_to_decode1: Fetch2ToDecode1Type; |
||||
|
||||
-- decode signals |
||||
signal decode1_to_decode2: Decode1ToDecode2Type; |
||||
signal decode2_to_execute1: Decode2ToExecute1Type; |
||||
|
||||
-- register file signals |
||||
signal register_file_to_decode2: RegisterFileToDecode2Type; |
||||
signal decode2_to_register_file: Decode2ToRegisterFileType; |
||||
signal writeback_to_register_file: WritebackToRegisterFileType; |
||||
|
||||
-- CR file signals |
||||
signal decode2_to_cr_file: Decode2ToCrFileType; |
||||
signal cr_file_to_decode2: CrFileToDecode2Type; |
||||
signal writeback_to_cr_file: WritebackToCrFileType; |
||||
|
||||
-- execute signals |
||||
signal execute1_to_execute2: Execute1ToExecute2Type; |
||||
signal execute2_to_writeback: Execute2ToWritebackType; |
||||
signal execute1_to_fetch1: Execute1ToFetch1Type; |
||||
|
||||
-- load store signals |
||||
signal decode2_to_loadstore1: Decode2ToLoadstore1Type; |
||||
signal loadstore1_to_loadstore2: Loadstore1ToLoadstore2Type; |
||||
signal loadstore2_to_writeback: Loadstore2ToWritebackType; |
||||
|
||||
-- multiply signals |
||||
signal decode2_to_multiply: Decode2ToMultiplyType; |
||||
signal multiply_to_writeback: MultiplyToWritebackType; |
||||
|
||||
-- wishbone signals |
||||
signal wishbone_data_in : wishbone_slave_out; |
||||
signal wishbone_data_out : wishbone_master_out; |
||||
signal wishbone_insn_in : wishbone_slave_out; |
||||
signal wishbone_insn_out : wishbone_master_out; |
||||
|
||||
-- local signals |
||||
signal fetch_enable: std_ulogic := '0'; |
||||
signal complete: std_ulogic; |
||||
signal first_fetch: std_ulogic := '0'; |
||||
|
||||
signal terminate: std_ulogic; |
||||
begin |
||||
|
||||
terminate_out <= terminate; |
||||
|
||||
fetch1_0: entity work.fetch1 |
||||
generic map (RESET_ADDRESS => (others => '0')) |
||||
port map (clk => clk, rst => rst, fetch_one_in => fetch_enable, |
||||
e_in => execute1_to_fetch1, f_out => fetch1_to_fetch2); |
||||
|
||||
fetch2_0: entity work.fetch2 |
||||
port map (clk => clk, wishbone_in => wishbone_insn_in, |
||||
wishbone_out => wishbone_insn_out, f_in => fetch1_to_fetch2, |
||||
f_out => fetch2_to_decode1); |
||||
|
||||
decode1_0: entity work.decode1 |
||||
port map (clk => clk, f_in => fetch2_to_decode1, d_out => decode1_to_decode2); |
||||
|
||||
decode2_0: entity work.decode2 |
||||
port map (clk => clk, d_in => decode1_to_decode2, e_out => decode2_to_execute1, |
||||
l_out => decode2_to_loadstore1, m_out => decode2_to_multiply, |
||||
r_in => register_file_to_decode2, r_out => decode2_to_register_file, |
||||
c_in => cr_file_to_decode2, c_out => decode2_to_cr_file); |
||||
|
||||
register_file_0: entity work.register_file |
||||
port map (clk => clk, d_in => decode2_to_register_file, |
||||
d_out => register_file_to_decode2, w_in => writeback_to_register_file, |
||||
registers_out => registers); |
||||
|
||||
cr_file_0: entity work.cr_file |
||||
port map (clk => clk, d_in => decode2_to_cr_file, d_out => cr_file_to_decode2, |
||||
w_in => writeback_to_cr_file); |
||||
|
||||
execute1_0: entity work.execute1 |
||||
generic map (SIM => SIM) |
||||
port map (clk => clk, e_in => decode2_to_execute1, f_out => execute1_to_fetch1, |
||||
e_out => execute1_to_execute2, terminate_out => terminate); |
||||
|
||||
execute2_0: entity work.execute2 |
||||
port map (clk => clk, e_in => execute1_to_execute2, e_out => execute2_to_writeback); |
||||
|
||||
loadstore1_0: entity work.loadstore1 |
||||
port map (clk => clk, l_in => decode2_to_loadstore1, l_out => loadstore1_to_loadstore2); |
||||
|
||||
loadstore2_0: entity work.loadstore2 |
||||
port map (clk => clk, l_in => loadstore1_to_loadstore2, |
||||
w_out => loadstore2_to_writeback, m_in => wishbone_data_in, |
||||
m_out => wishbone_data_out); |
||||
|
||||
multiply_0: entity work.multiply |
||||
port map (clk => clk, m_in => decode2_to_multiply, m_out => multiply_to_writeback); |
||||
|
||||
writeback_0: entity work.writeback |
||||
port map (clk => clk, w_in => execute2_to_writeback, l_in => loadstore2_to_writeback, |
||||
m_in => multiply_to_writeback, w_out => writeback_to_register_file, |
||||
c_out => writeback_to_cr_file, complete_out => complete); |
||||
|
||||
wishbone_arbiter_0: entity work.wishbone_arbiter |
||||
port map (clk => clk, rst => rst, wb1_in => wishbone_data_out, wb1_out => wishbone_data_in, |
||||
wb2_in => wishbone_insn_out, wb2_out => wishbone_insn_in, wb_out => wishbone_out, |
||||
wb_in => wishbone_in); |
||||
|
||||
-- Only single issue until we add bypass support |
||||
single_issue_0: process(clk) |
||||
begin |
||||
if (rising_edge(clk)) then |
||||
if rst = '1' then |
||||
first_fetch <= '1'; |
||||
else |
||||
if first_fetch = '1' then |
||||
fetch_enable <= '1'; |
||||
first_fetch <= '0'; |
||||
else |
||||
fetch_enable <= complete; |
||||
end if; |
||||
end if; |
||||
end if; |
||||
end process single_issue_0; |
||||
|
||||
end behave; |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
library ieee; |
||||
use ieee.std_logic_1164.all; |
||||
|
||||
library work; |
||||
use work.common.all; |
||||
use work.wishbone_types.all; |
||||
|
||||
entity core_tb is |
||||
end core_tb; |
||||
|
||||
architecture behave of core_tb is |
||||
signal clk, rst: std_logic; |
||||
|
||||
signal wishbone_in : wishbone_slave_out; |
||||
signal wishbone_out : wishbone_master_out; |
||||
|
||||
signal registers : regfile; |
||||
signal terminate : std_ulogic; |
||||
|
||||
-- testbench signals |
||||
constant clk_period : time := 10 ns; |
||||
begin |
||||
core_0: entity work.core |
||||
generic map (SIM => true) |
||||
port map (clk => clk, rst => rst, wishbone_in => wishbone_in, |
||||
wishbone_out => wishbone_out, registers => registers, terminate_out => terminate); |
||||
|
||||
simple_ram_0: entity work.simple_ram_behavioural |
||||
generic map ( filename => "simple_ram_behavioural.bin", size => 1048576) |
||||
port map (clk => clk, rst => rst, wishbone_in => wishbone_out, wishbone_out => wishbone_in); |
||||
|
||||
clk_process: process |
||||
begin |
||||
clk <= '0'; |
||||
wait for clk_period/2; |
||||
clk <= '1'; |
||||
wait for clk_period/2; |
||||
end process; |
||||
|
||||
rst_process: process |
||||
begin |
||||
rst <= '1'; |
||||
wait for 10*clk_period; |
||||
rst <= '0'; |
||||
wait; |
||||
end process; |
||||
|
||||
dump_registers: process(all) |
||||
begin |
||||
if terminate = '1' then |
||||
loop_0: for i in 0 to 31 loop |
||||
report "REG " & to_hstring(registers(i)); |
||||
end loop loop_0; |
||||
assert false report "end of test" severity failure; |
||||
end if; |
||||
end process; |
||||
end; |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
library ieee; |
||||
use ieee.std_logic_1164.all; |
||||
use ieee.numeric_std.all; |
||||
|
||||
library work; |
||||
use work.common.all; |
||||
|
||||
entity cr_file is |
||||
port( |
||||
clk : in std_logic; |
||||
|
||||
d_in : in Decode2ToCrFileType; |
||||
d_out : out CrFileToDecode2Type; |
||||
|
||||
w_in : in WritebackToCrFileType |
||||
); |
||||
end entity cr_file; |
||||
|
||||
architecture behaviour of cr_file is |
||||
signal crs : std_ulogic_vector(31 downto 0) := (others => '0'); |
||||
begin |
||||
-- synchronous writes |
||||
cr_write_0: process(clk) |
||||
variable hi, lo : integer := 0; |
||||
begin |
||||
if rising_edge(clk) then |
||||
if w_in.write_cr_enable = '1' then |
||||
report "Writing " & to_hstring(w_in.write_cr_data) & " to CR mask " & to_hstring(w_in.write_cr_mask); |
||||
|
||||
for i in 0 to 7 loop |
||||
if w_in.write_cr_mask(i) = '1' then |
||||
lo := i*4; |
||||
hi := lo + 3; |
||||
crs(hi downto lo) <= w_in.write_cr_data(hi downto lo); |
||||
end if; |
||||
end loop; |
||||
end if; |
||||
end if; |
||||
end process cr_write_0; |
||||
|
||||
-- asynchronous reads |
||||
cr_read_0: process(all) |
||||
variable hi, lo : integer := 0; |
||||
begin |
||||
--lo := (7-d_in.read_cr_nr_1)*4; |
||||
--hi := lo + 3; |
||||
|
||||
--report "read " & integer'image(d_in.read_cr_nr_1) & " from CR " & to_hstring(crs(hi downto lo)); |
||||
--d_out.read_cr_data_1 <= crs(hi downto lo); |
||||
|
||||
-- Also return the entire CR to make mfcrf easier for now |
||||
report "read CR " & to_hstring(crs); |
||||
d_out.read_cr_data <= crs; |
||||
|
||||
-- -- Forward any written data |
||||
-- if w_in.write_cr_enable = '1' then |
||||
-- if d_in.read_cr_nr_1 = w_in.write_cr_nr then |
||||
-- d_out.read_cr_data_1 <= w_in.write_cr_data; |
||||
-- end if; |
||||
-- if d_in.read_cr_nr_2 = w_in.write_cr_nr then |
||||
-- d_out.read_cr_data_2 <= w_in.write_cr_data; |
||||
-- end if; |
||||
-- end if; |
||||
end process cr_read_0; |
||||
end architecture behaviour; |
@ -0,0 +1,134 @@
@@ -0,0 +1,134 @@
|
||||
library ieee; |
||||
use ieee.std_logic_1164.all; |
||||
|
||||
library work; |
||||
use work.common.all; |
||||
|
||||
package crhelpers is |
||||
function fxm_to_num(fxm: std_ulogic_vector(7 downto 0)) return integer; |
||||
function num_to_fxm(num: integer) return std_ulogic_vector; |
||||
--function from_crfile(cr: crfile) return std_ulogic_vector; |
||||
--function extract_one_crfield(cr: crfile; fxm: std_ulogic_vector(7 downto 0)) return std_ulogic_vector; |
||||
--function insert_multiple_crfields(cr_in: crfile; rs: std_ulogic_vector(63 downto 0); fxm: std_ulogic_vector(7 downto 0)) return crfile; |
||||
--function insert_one_crfield(cr_in: crfile; rs: std_ulogic_vector(63 downto 0); fxm: std_ulogic_vector(7 downto 0)) return crfile; |
||||
end package crhelpers; |
||||
|
||||
package body crhelpers is |
||||
|
||||
function fxm_to_num(fxm: std_ulogic_vector(7 downto 0)) return integer is |
||||
begin |
||||
-- If multiple fields are set (undefined), match existing |
||||
-- hardware by returning the first one. |
||||
for i in 0 to 7 loop |
||||
-- Big endian bit numbering |
||||
if fxm(7-i) = '1' then |
||||
return i; |
||||
end if; |
||||
end loop; |
||||
|
||||
-- If no fields are set (undefined), also match existing |
||||
-- hardware by returning cr7. |
||||
return 7; |
||||
end; |
||||
|
||||
function num_to_fxm(num: integer) return std_ulogic_vector is |
||||
begin |
||||
case num is |
||||
when 0 => |
||||
return "10000000"; |
||||
when 1 => |
||||
return "01000000"; |
||||
when 2 => |
||||
return "00100000"; |
||||
when 3 => |
||||
return "00010000"; |
||||
when 4 => |
||||
return "00001000"; |
||||
when 5 => |
||||
return "00000100"; |
||||
when 6 => |
||||
return "00000010"; |
||||
when 7 => |
||||
return "00000001"; |
||||
when others => |
||||
return "00000000"; |
||||
end case; |
||||
end; |
||||
|
||||
-- function from_crfile(cr: crfile) return std_ulogic_vector is |
||||
-- variable combined_cr : std_ulogic_vector(31 downto 0) := (others => '0'); |
||||
-- variable high, low: integer range 0 to 31 := 0; |
||||
-- begin |
||||
-- for i in 0 to cr'length-1 loop |
||||
-- low := 4*(7-i); |
||||
-- high := low+3; |
||||
-- combined_cr(high downto low) := cr(i); |
||||
-- end loop; |
||||
-- |
||||
-- return combined_cr; |
||||
-- end function; |
||||
-- |
||||
-- function extract_one_crfield(cr: crfile; fxm: std_ulogic_vector(7 downto 0)) return std_ulogic_vector is |
||||
-- variable combined_cr : std_ulogic_vector(63 downto 0) := (others => '0'); |
||||
-- variable crnum: integer range 0 to 7 := 0; |
||||
-- begin |
||||
-- crnum := fxm_to_num(fxm); |
||||
-- |
||||
-- -- Vivado doesn't support non constant vector slice |
||||
-- -- low := 4*(7-crnum); |
||||
-- -- high := low+3; |
||||
-- -- combined_cr(high downto low) := cr(crnum); |
||||
-- case_0: case crnum is |
||||
-- when 0 => |
||||
-- combined_cr(31 downto 28) := cr(0); |
||||
-- when 1 => |
||||
-- combined_cr(27 downto 24) := cr(1); |
||||
-- when 2 => |
||||
-- combined_cr(23 downto 20) := cr(2); |
||||
-- when 3 => |
||||
-- combined_cr(19 downto 16) := cr(3); |
||||
-- when 4 => |
||||
-- combined_cr(15 downto 12) := cr(4); |
||||
-- when 5 => |
||||
-- combined_cr(11 downto 8) := cr(5); |
||||
-- when 6 => |
||||
-- combined_cr(7 downto 4) := cr(6); |
||||
-- when 7 => |
||||
-- combined_cr(3 downto 0) := cr(7); |
||||
-- end case; |
||||
-- |
||||
-- return combined_cr; |
||||
-- end; |
||||
-- |
||||
-- function insert_multiple_crfields(cr_in: crfile; rs: std_ulogic_vector(63 downto 0); fxm: std_ulogic_vector(7 downto 0)) return crfile is |
||||
-- variable cr : crfile; |
||||
-- variable combined_cr : std_ulogic_vector(63 downto 0) := (others => '0'); |
||||
-- variable high, low: integer range 0 to 31 := 0; |
||||
-- begin |
||||
-- cr := cr_in; |
||||
-- |
||||
-- for i in 0 to 7 loop |
||||
-- -- BE bit numbering |
||||
-- if fxm(7-i) = '1' then |
||||
-- low := 4*(7-i); |
||||
-- high := low+3; |
||||
-- cr(i) := rs(high downto low); |
||||
-- end if; |
||||
-- end loop; |
||||
-- |
||||
-- return cr; |
||||
-- end; |
||||
-- |
||||
-- function insert_one_crfield(cr_in: crfile; rs: std_ulogic_vector(63 downto 0); fxm: std_ulogic_vector(7 downto 0)) return crfile is |
||||
-- variable cr : crfile; |
||||
-- variable crnum: integer range 0 to 7 := 0; |
||||
-- variable high, low: integer range 0 to 31 := 0; |
||||
-- begin |
||||
-- cr := cr_in; |
||||
-- crnum := fxm_to_num(fxm); |
||||
-- low := 4*(7-crnum); |
||||
-- high := low+3; |
||||
-- cr(crnum) := rs(high downto low); |
||||
-- return cr; |
||||
-- end; |
||||
end package body crhelpers; |
@ -0,0 +1,847 @@
@@ -0,0 +1,847 @@
|
||||
library ieee; |
||||
use ieee.std_logic_1164.all; |
||||
use ieee.numeric_std.all; |
||||
|
||||
library work; |
||||
use work.common.all; |
||||
use work.decode_types.all; |
||||
|
||||
entity decode1 is |
||||
port ( |
||||
clk : in std_ulogic; |
||||
|
||||
f_in : in Fetch2ToDecode1Type; |
||||
d_out : out Decode1ToDecode2Type |
||||
); |
||||
end entity decode1; |
||||
|
||||
architecture behaviour of decode1 is |
||||
signal f : Fetch2ToDecode1Type := Fetch2ToDecode1Init; |
||||
|
||||
type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t; |
||||
|
||||
-- Note: reformat with column -t -o ' ' |
||||
constant decode_rom_array : decode_rom_array_t := ( |
||||
-- unit internal in1 in2 in3 out const const const CR CR cry cry ldst ld BR sgn upd mul mul rc lk |
||||
-- op 1 2 3 in out in out len ext 32 sgn |
||||
PPC_ILLEGAL => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_ADD => (ALU, OP_ADD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_ADDC => (ALU, OP_ADDC, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_ADDE => (ALU, OP_ADDC, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
--PPC_ADDEX |
||||
PPC_ADDI => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_ADDIC => (ALU, OP_ADDC, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_ADDIC_RC => (ALU, OP_ADDC, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0'), |
||||
PPC_ADDIS => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_ADDME |
||||
--PPC_ADDPCIS |
||||
PPC_ADDZE => (ALU, OP_ADDC, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_AND => (ALU, OP_AND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_ANDC => (ALU, OP_ANDC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_ANDI_RC => (ALU, OP_AND, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0'), |
||||
PPC_ANDIS_RC => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0'), |
||||
PPC_ATTN => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_B => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), |
||||
--PPC_BA |
||||
PPC_BC => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, BO, BI, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), |
||||
--PPC_BCA |
||||
PPC_BCCTR => (ALU, OP_BCCTR, NONE, NONE, NONE, NONE, BO, BI, BH, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), |
||||
--PPC_BCLA |
||||
PPC_BCLR => (ALU, OP_BCLR, NONE, NONE, NONE, NONE, BO, BI, BH, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1'), |
||||
--PPC_BCTAR |
||||
--PPC_BPERM |
||||
PPC_CMP => (ALU, OP_CMP, RA, RB, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_CMPB => (ALU, OP_CMPB, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_CMPEQB |
||||
PPC_CMPI => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_CMPL => (ALU, OP_CMPL, RA, RB, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_CMPLI => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, BF, L, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_CMPRB |
||||
PPC_CNTLZD => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_CNTLZW => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_CNTTZD => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_CNTTZW => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
--PPC_CRAND |
||||
--PPC_CRANDC |
||||
--PPC_CREQV |
||||
--PPC_CRNAND |
||||
--PPC_CRNOR |
||||
--PPC_CROR |
||||
--PPC_CRORC |
||||
--PPC_CRXOR |
||||
--PPC_DARN |
||||
PPC_DCBF => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_DCBST => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_DCBT => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_DCBTST => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_DCBZ |
||||
PPC_DIVD => (ALU, OP_DIVD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
--PPC_DIVDE |
||||
--PPC_DIVDEU |
||||
PPC_DIVDU => (ALU, OP_DIVDU, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_DIVW => (ALU, OP_DIVW, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
--PPC_DIVWE |
||||
--PPC_DIVWEU |
||||
PPC_DIVWU => (ALU, OP_DIVWU, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_EQV => (ALU, OP_EQV, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_EXTSB => (ALU, OP_EXTSB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_EXTSH => (ALU, OP_EXTSH, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_EXTSW => (ALU, OP_EXTSW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
--PPC_EXTSWSLI |
||||
--PPC_ICBI |
||||
PPC_ICBT => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_ISEL => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_ISYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LBARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0'), |
||||
--CONST_LI matches CONST_SI, so reuse it |
||||
PPC_LBZ => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LBZU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LBZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LBZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LD => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LDARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0'), |
||||
PPC_LDBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LDU => (LDST, OP_LOAD, RA, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LDUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LDX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LHA => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LHARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0'), |
||||
PPC_LHAU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LHAUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LHAX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LHBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LHZ => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LHZU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LHZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LHZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LWA => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LWARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0'), |
||||
PPC_LWAUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LWAX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LWBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LWZ => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_LWZU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LWZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_LWZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_MADDHD |
||||
--PPC_MADDHDU |
||||
--PPC_MADDLD |
||||
--PPC_MCRF |
||||
--PPC_MCRXR |
||||
--PPC_MCRXRX |
||||
PPC_MFCR => (ALU, OP_MFCR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_MFOCRF => (ALU, OP_MFOCRF, NONE, NONE, NONE, RT, FXM, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_MFCTR => (ALU, OP_MFCTR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_MFLR => (ALU, OP_MFLR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_MFTB => (ALU, OP_MFTB, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_MTCTR => (ALU, OP_MTCTR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_MTLR => (ALU, OP_MTLR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_MFSPR |
||||
--PPC_MODSD |
||||
--PPC_MODSW |
||||
--PPC_MODUD |
||||
--PPC_MODUW |
||||
PPC_MTCRF => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_MTOCRF => (ALU, OP_MTOCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_MTSPR |
||||
PPC_MULHD => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0'), |
||||
PPC_MULHDU => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_MULHW => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0'), |
||||
PPC_MULHWU => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0'), |
||||
PPC_MULLD => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0'), |
||||
PPC_MULLI => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0'), |
||||
PPC_MULLW => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0'), |
||||
PPC_NAND => (ALU, OP_NAND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_NEG => (ALU, OP_NEG, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_NOR => (ALU, OP_NOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_OR => (ALU, OP_OR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_ORC => (ALU, OP_ORC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_ORI => (ALU, OP_OR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_ORIS => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_POPCNTB => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_POPCNTD => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_POPCNTW => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_PRTYD => (ALU, OP_PRTYD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_PRTYW => (ALU, OP_PRTYW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_RLDCL => (ALU, OP_RLDCL, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLDCR => (ALU, OP_RLDCR, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLDIC => (ALU, OP_RLDIC, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLDICL => (ALU, OP_RLDICL, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLDICR => (ALU, OP_RLDICR, RS, NONE, NONE, RA, SH, ME, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLDIMI => (ALU, OP_RLDIMI, RA, RS, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLWIMI => (ALU, OP_RLWIMI, RA, RS, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLWINM => (ALU, OP_RLWINM, RS, NONE, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_RLWNM => (ALU, OP_RLWNM, RS, RB, NONE, RA, NONE, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
--PPC_SETB |
||||
PPC_SLD => (ALU, OP_SLD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SLW => (ALU, OP_SLW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SRAD => (ALU, OP_SRAD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SRADI => (ALU, OP_SRADI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SRAW => (ALU, OP_SRAW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SRAWI => (ALU, OP_SRAWI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SRD => (ALU, OP_SRD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SRW => (ALU, OP_SRW, RS, RB, RS, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_STB => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_STBCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0'), |
||||
PPC_STBU => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0'), |
||||
PPC_STBUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0'), |
||||
PPC_STBX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_STD => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STDBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STDCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0'), |
||||
PPC_STDU => (LDST, OP_STORE, RA, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_STDUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_STDX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STH => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STHBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STHCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0'), |
||||
PPC_STHU => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_STHUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_STHX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STW => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STWBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_STWCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0'), |
||||
PPC_STWU => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_STWUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0'), |
||||
PPC_STWX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_SUBF => (ALU, OP_SUBF, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SUBFC => (ALU, OP_SUBFC, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SUBFE => (ALU, OP_SUBFC, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SUBFIC => (ALU, OP_SUBFC, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_SUBFME |
||||
PPC_SUBFZE => (ALU, OP_SUBFC, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_SYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_TD |
||||
PPC_TDI => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
--PPC_TW |
||||
--PPC_TWI |
||||
PPC_XOR => (ALU, OP_XOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0'), |
||||
PPC_XORI => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_XORIS => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_SIM_READ => (ALU, OP_SIM_READ, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_SIM_POLL => (ALU, OP_SIM_POLL, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_SIM_WRITE => (ALU, OP_SIM_WRITE, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
PPC_SIM_CONFIG => (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0'), |
||||
|
||||
others => decode_rom_init |
||||
); |
||||
|
||||
begin |
||||
decode1_0: process(clk) |
||||
begin |
||||
if rising_edge(clk) then |
||||
f <= f_in; |
||||
end if; |
||||
end process; |
||||
|
||||
decode1_1: process(all) |
||||
variable ppc_insn: ppc_insn_t; |
||||
begin |
||||
d_out <= Decode1ToDecode2Init; |
||||
ppc_insn := PPC_ILLEGAL; |
||||
|
||||
d_out.valid <= f.valid; |
||||
|
||||
if f.valid then |
||||
d_out.nia <= f.nia; |
||||
d_out.insn <= f.insn; |
||||
|
||||
report "Decode insn " & to_hstring(f.insn); |
||||
if std_match(f.insn, "011111---------------0100001010-") then |
||||
report "PPC_add"; |
||||
ppc_insn := PPC_ADD; |
||||
elsif std_match(f.insn, "011111---------------0000001010-") then |
||||
report "PPC_addc"; |
||||
ppc_insn := PPC_ADDC; |
||||
elsif std_match(f.insn, "011111---------------0010001010-") then |
||||
report "PPC_adde"; |
||||
ppc_insn := PPC_ADDE; |
||||
elsif std_match(f.insn, "011111---------------0010101010-") then |
||||
report "PPC_addex"; |
||||
ppc_insn := PPC_ADDEX; |
||||
elsif std_match(f.insn, "001110--------------------------") then |
||||
report "PPC_addi"; |
||||
ppc_insn := PPC_ADDI; |
||||
elsif std_match(f.insn, "001100--------------------------") then |
||||
report "PPC_addic"; |
||||
ppc_insn := PPC_ADDIC; |
||||
elsif std_match(f.insn, "001101--------------------------") then |
||||
report "PPC_addic."; |
||||
ppc_insn := PPC_ADDIC_RC; |
||||
elsif std_match(f.insn, "001111--------------------------") then |
||||
report "PPC_addis"; |
||||
ppc_insn := PPC_ADDIS; |
||||
elsif std_match(f.insn, "011111---------------0011101010-") then |
||||
report "PPC_addme"; |
||||
ppc_insn := PPC_ADDME; |
||||
elsif std_match(f.insn, "010011--------------------00010-") then |
||||
report "PPC_addpcis"; |
||||
ppc_insn := PPC_ADDPCIS; |
||||
elsif std_match(f.insn, "011111---------------0011001010-") then |
||||
report "PPC_addze"; |
||||
ppc_insn := PPC_ADDZE; |
||||
elsif std_match(f.insn, "011111---------------0000011100-") then |
||||
report "PPC_and"; |
||||
ppc_insn := PPC_AND; |
||||
elsif std_match(f.insn, "011111---------------0000111100-") then |
||||
report "PPC_andc"; |
||||
ppc_insn := PPC_ANDC; |
||||
elsif std_match(f.insn, "011100--------------------------") then |
||||
report "PPC_andi."; |
||||
ppc_insn := PPC_ANDI_RC; |
||||
elsif std_match(f.insn, "011101--------------------------") then |
||||
report "PPC_andis."; |
||||
ppc_insn := PPC_ANDIS_RC; |
||||
elsif std_match(f.insn, "000000---------------0100000000-") then |
||||
report "PPC_attn"; |
||||
ppc_insn := PPC_ATTN; |
||||
elsif std_match(f.insn, "010010------------------------0-") then |
||||
report "PPC_b"; |
||||
ppc_insn := PPC_B; |
||||
elsif std_match(f.insn, "010010------------------------1-") then |
||||
report "PPC_ba"; |
||||
ppc_insn := PPC_BA; |
||||
elsif std_match(f.insn, "010000------------------------0-") then |
||||
report "PPC_bc"; |
||||
ppc_insn := PPC_BC; |
||||
elsif std_match(f.insn, "010000------------------------10") then |
||||
report "PPC_bca"; |
||||
ppc_insn := PPC_BCA; |
||||
elsif std_match(f.insn, "010011---------------1000010000-") then |
||||
report "PPC_bcctr"; |
||||
ppc_insn := PPC_BCCTR; |
||||
elsif std_match(f.insn, "010000------------------------11") then |
||||
report "PPC_bcla"; |
||||
ppc_insn := PPC_BCLA; |
||||
elsif std_match(f.insn, "010011---------------0000010000-") then |
||||
report "PPC_bclr"; |
||||
ppc_insn := PPC_BCLR; |
||||
elsif std_match(f.insn, "010011---------------1000110000-") then |
||||
report "PPC_bctar"; |
||||
ppc_insn := PPC_BCTAR; |
||||
elsif std_match(f.insn, "011111---------------0011111100-") then |
||||
report "PPC_bperm"; |
||||
ppc_insn := PPC_BPERM; |
||||
elsif std_match(f.insn, "011111---------------0000000000-") then |
||||
report "PPC_cmp"; |
||||
ppc_insn := PPC_CMP; |
||||
elsif std_match(f.insn, "011111---------------0111111100-") then |
||||
report "PPC_cmpb"; |
||||
ppc_insn := PPC_CMPB; |
||||
elsif std_match(f.insn, "011111---------------0011100000-") then |
||||
report "PPC_cmpeqb"; |
||||
ppc_insn := PPC_CMPEQB; |
||||
elsif std_match(f.insn, "001011--------------------------") then |
||||
report "PPC_cmpi"; |
||||
ppc_insn := PPC_CMPI; |
||||
elsif std_match(f.insn, "011111---------------0000100000-") then |
||||
report "PPC_cmpl"; |
||||
ppc_insn := PPC_CMPL; |
||||
elsif std_match(f.insn, "001010--------------------------") then |
||||
report "PPC_cmpli"; |
||||
ppc_insn := PPC_CMPLI; |
||||
elsif std_match(f.insn, "011111---------------0011000000-") then |
||||
report "PPC_cmprb"; |
||||
ppc_insn := PPC_CMPRB; |
||||
elsif std_match(f.insn, "011111---------------0000111010-") then |
||||
report "PPC_cntlzd"; |
||||
ppc_insn := PPC_CNTLZD; |
||||
elsif std_match(f.insn, "011111---------------0000011010-") then |
||||
report "PPC_cntlzw"; |
||||
ppc_insn := PPC_CNTLZW; |
||||
elsif std_match(f.insn, "011111---------------1000111010-") then |
||||
report "PPC_cnttzd"; |
||||
ppc_insn := PPC_CNTTZD; |
||||
elsif std_match(f.insn, "011111---------------1000011010-") then |
||||
report "PPC_cnttzw"; |
||||
ppc_insn := PPC_CNTTZW; |
||||
elsif std_match(f.insn, "010011---------------0100000001-") then |
||||
report "PPC_crand"; |
||||
ppc_insn := PPC_CRAND; |
||||
elsif std_match(f.insn, "010011---------------0010000001-") then |
||||
report "PPC_crandc"; |
||||
ppc_insn := PPC_CRANDC; |
||||
elsif std_match(f.insn, "010011---------------0100100001-") then |
||||
report "PPC_creqv"; |
||||
ppc_insn := PPC_CREQV; |
||||
elsif std_match(f.insn, "010011---------------0011100001-") then |
||||
report "PPC_crnand"; |
||||
ppc_insn := PPC_CRNAND; |
||||
elsif std_match(f.insn, "010011---------------0000100001-") then |
||||
report "PPC_crnor"; |
||||
ppc_insn := PPC_CRNOR; |
||||
elsif std_match(f.insn, "010011---------------0111000001-") then |
||||
report "PPC_cror"; |
||||
ppc_insn := PPC_CROR; |
||||
elsif std_match(f.insn, "010011---------------0110100001-") then |
||||
report "PPC_crorc"; |
||||
ppc_insn := PPC_CRORC; |
||||
elsif std_match(f.insn, "010011---------------0011000001-") then |
||||
report "PPC_crxor"; |
||||
ppc_insn := PPC_CRXOR; |
||||
elsif std_match(f.insn, "011111---------------1011110011-") then |
||||
report "PPC_darn"; |
||||
ppc_insn := PPC_DARN; |
||||
elsif std_match(f.insn, "011111---------------0001010110-") then |
||||
report "PPC_dcbf"; |
||||
ppc_insn := PPC_DCBF; |
||||
elsif std_match(f.insn, "011111---------------0000110110-") then |
||||
report "PPC_dcbst"; |
||||
ppc_insn := PPC_DCBST; |
||||
elsif std_match(f.insn, "011111---------------0100010110-") then |
||||
report "PPC_dcbt"; |
||||
ppc_insn := PPC_DCBT; |
||||
elsif std_match(f.insn, "011111---------------0011110110-") then |
||||
report "PPC_dcbtst"; |
||||
ppc_insn := PPC_DCBTST; |
||||
elsif std_match(f.insn, "011111---------------1111110110-") then |
||||
report "PPC_dcbz"; |
||||
ppc_insn := PPC_DCBZ; |
||||
elsif std_match(f.insn, "011111---------------0111101001-") then |
||||
report "PPC_divd"; |
||||
ppc_insn := PPC_DIVD; |
||||
elsif std_match(f.insn, "011111---------------0110101001-") then |
||||
report "PPC_divde"; |
||||
ppc_insn := PPC_DIVDE; |
||||
elsif std_match(f.insn, "011111---------------0110001001-") then |
||||
report "PPC_divdeu"; |
||||
ppc_insn := PPC_DIVDEU; |
||||
elsif std_match(f.insn, "011111---------------0111001001-") then |
||||
report "PPC_divdu"; |
||||
ppc_insn := PPC_DIVDU; |
||||
elsif std_match(f.insn, "011111---------------0111101011-") then |
||||
report "PPC_divw"; |
||||
ppc_insn := PPC_DIVW; |
||||
elsif std_match(f.insn, "011111---------------0110101011-") then |
||||
report "PPC_divwe"; |
||||
ppc_insn := PPC_DIVWE; |
||||
elsif std_match(f.insn, "011111---------------0110001011-") then |
||||
report "PPC_divweu"; |
||||
ppc_insn := PPC_DIVWEU; |
||||
elsif std_match(f.insn, "011111---------------0111001011-") then |
||||
report "PPC_divwu"; |
||||
ppc_insn := PPC_DIVWU; |
||||
elsif std_match(f.insn, "011111---------------0100011100-") then |
||||
report "PPC_eqv"; |
||||
ppc_insn := PPC_EQV; |
||||
elsif std_match(f.insn, "011111---------------1110111010-") then |
||||
report "PPC_extsb"; |
||||
ppc_insn := PPC_EXTSB; |
||||
elsif std_match(f.insn, "011111---------------1110011010-") then |
||||
report "PPC_extsh"; |
||||
ppc_insn := PPC_EXTSH; |
||||
elsif std_match(f.insn, "011111---------------1111011010-") then |
||||
report "PPC_extsw"; |
||||
ppc_insn := PPC_EXTSW; |
||||
elsif std_match(f.insn, "011111---------------110111101--") then |
||||
report "PPC_extswsli"; |
||||
ppc_insn := PPC_EXTSWSLI; |
||||
elsif std_match(f.insn, "011111---------------1111010110-") then |
||||
report "PPC_icbi"; |
||||
ppc_insn := PPC_ICBI; |
||||
elsif std_match(f.insn, "011111---------------0000010110-") then |
||||
report "PPC_icbt"; |
||||
ppc_insn := PPC_ICBT; |
||||
elsif std_match(f.insn, "011111--------------------01111-") then |
||||
report "PPC_isel"; |
||||
ppc_insn := PPC_ISEL; |
||||
elsif std_match(f.insn, "010011---------------0010010110-") then |
||||
report "PPC_isync"; |
||||
ppc_insn := PPC_ISYNC; |
||||
elsif std_match(f.insn, "011111---------------0000110100-") then |
||||
report "PPC_lbarx"; |
||||
ppc_insn := PPC_LBARX; |
||||
elsif std_match(f.insn, "100010--------------------------") then |
||||
report "PPC_lbz"; |
||||
ppc_insn := PPC_LBZ; |
||||
elsif std_match(f.insn, "100011--------------------------") then |
||||
report "PPC_lbzu"; |
||||
ppc_insn := PPC_LBZU; |
||||
elsif std_match(f.insn, "011111---------------0001110111-") then |
||||
report "PPC_lbzux"; |
||||
ppc_insn := PPC_LBZUX; |
||||
elsif std_match(f.insn, "011111---------------0001010111-") then |
||||
report "PPC_lbzx"; |
||||
ppc_insn := PPC_LBZX; |
||||
elsif std_match(f.insn, "111010------------------------00") then |
||||
report "PPC_ld"; |
||||
ppc_insn := PPC_LD; |
||||
elsif std_match(f.insn, "011111---------------0001010100-") then |
||||
report "PPC_ldarx"; |
||||
ppc_insn := PPC_LDARX; |
||||
elsif std_match(f.insn, "011111---------------1000010100-") then |
||||
report "PPC_ldbrx"; |
||||
ppc_insn := PPC_LDBRX; |
||||
elsif std_match(f.insn, "111010------------------------01") then |
||||
report "PPC_ldu"; |
||||
ppc_insn := PPC_LDU; |
||||
elsif std_match(f.insn, "011111---------------0000110101-") then |
||||
report "PPC_ldux"; |
||||
ppc_insn := PPC_LDUX; |
||||
elsif std_match(f.insn, "011111---------------0000010101-") then |
||||
report "PPC_ldx"; |
||||
ppc_insn := PPC_LDX; |
||||
elsif std_match(f.insn, "101010--------------------------") then |
||||
report "PPC_lha"; |
||||
ppc_insn := PPC_LHA; |
||||
elsif std_match(f.insn, "011111---------------0001110100-") then |
||||
report "PPC_lharx"; |
||||
ppc_insn := PPC_LHARX; |
||||
elsif std_match(f.insn, "101011--------------------------") then |
||||
report "PPC_lhau"; |
||||
ppc_insn := PPC_LHAU; |
||||
elsif std_match(f.insn, "011111---------------0101110111-") then |
||||
report "PPC_lhaux"; |
||||
ppc_insn := PPC_LHAUX; |
||||
elsif std_match(f.insn, "011111---------------0101010111-") then |
||||
report "PPC_lhax"; |
||||
ppc_insn := PPC_LHAX; |
||||
elsif std_match(f.insn, "011111---------------1100010110-") then |
||||
report "PPC_lhbrx"; |
||||
ppc_insn := PPC_LHBRX; |
||||
elsif std_match(f.insn, "101000--------------------------") then |
||||
report "PPC_lhz"; |
||||
ppc_insn := PPC_LHZ; |
||||
elsif std_match(f.insn, "101001--------------------------") then |
||||
report "PPC_lhzu"; |
||||
ppc_insn := PPC_LHZU; |
||||
elsif std_match(f.insn, "011111---------------0100110111-") then |
||||
report "PPC_lhzux"; |
||||
ppc_insn := PPC_LHZUX; |
||||
elsif std_match(f.insn, "011111---------------0100010111-") then |
||||
report "PPC_lhzx"; |
||||
ppc_insn := PPC_LHZX; |
||||
elsif std_match(f.insn, "111010------------------------10") then |
||||
report "PPC_lwa"; |
||||
ppc_insn := PPC_LWA; |
||||
elsif std_match(f.insn, "011111---------------0000010100-") then |
||||
report "PPC_lwarx"; |
||||
ppc_insn := PPC_LWARX; |
||||
elsif std_match(f.insn, "011111---------------0101110101-") then |
||||
report "PPC_lwaux"; |
||||
ppc_insn := PPC_LWAUX; |
||||
elsif std_match(f.insn, "011111---------------0101010101-") then |
||||
report "PPC_lwax"; |
||||
ppc_insn := PPC_LWAX; |
||||
elsif std_match(f.insn, "011111---------------1000010110-") then |
||||
report "PPC_lwbrx"; |
||||
ppc_insn := PPC_LWBRX; |
||||
elsif std_match(f.insn, "100000--------------------------") then |
||||
report "PPC_lwz"; |
||||
ppc_insn := PPC_LWZ; |
||||
elsif std_match(f.insn, "100001--------------------------") then |
||||
report "PPC_lwzu"; |
||||
ppc_insn := PPC_LWZU; |
||||
elsif std_match(f.insn, "011111---------------0000110111-") then |
||||
report "PPC_lwzux"; |
||||
ppc_insn := PPC_LWZUX; |
||||
elsif std_match(f.insn, "011111---------------0000010111-") then |
||||
report "PPC_lwzx"; |
||||
ppc_insn := PPC_LWZX; |
||||
elsif std_match(f.insn, "000100--------------------110000") then |
||||
report "PPC_maddhd"; |
||||
ppc_insn := PPC_MADDHD; |
||||
elsif std_match(f.insn, "000100--------------------110001") then |
||||
report "PPC_maddhdu"; |
||||
ppc_insn := PPC_MADDHDU; |
||||
elsif std_match(f.insn, "000100--------------------110011") then |
||||
report "PPC_maddld"; |
||||
ppc_insn := PPC_MADDLD; |
||||
elsif std_match(f.insn, "010011---------------0000000000-") then |
||||
report "PPC_mcrf"; |
||||
ppc_insn := PPC_MCRF; |
||||
elsif std_match(f.insn, "011111---------------1000000000-") then |
||||
report "PPC_mcrxr"; |
||||
ppc_insn := PPC_MCRXR; |
||||
elsif std_match(f.insn, "011111---------------1001000000-") then |
||||
report "PPC_mcrxrx"; |
||||
ppc_insn := PPC_MCRXRX; |
||||
elsif std_match(f.insn, "011111-----0---------0000010011-") then |
||||
report "PPC_mfcr"; |
||||
ppc_insn := PPC_MFCR; |
||||
elsif std_match(f.insn, "011111-----1---------0000010011-") then |
||||
report "PPC_mfocrf"; |
||||
ppc_insn := PPC_MFOCRF; |
||||
-- Specific MF/MT SPR encodings first |
||||
elsif std_match(f.insn, "011111-----01001000000101010011-") then |
||||
report "PPC_mfctr"; |
||||
ppc_insn := PPC_MFCTR; |
||||
elsif std_match(f.insn, "011111-----01000000000101010011-") then |
||||
report "PPC_mflr"; |
||||
ppc_insn := PPC_MFLR; |
||||
elsif std_match(f.insn, "011111-----01100010000101010011-") then |
||||
report "PPC_mftb"; |
||||
ppc_insn := PPC_MFTB; |
||||
elsif std_match(f.insn, "011111-----01001000000111010011-") then |
||||
report "PPC_mtctr"; |
||||
ppc_insn := PPC_MTCTR; |
||||
elsif std_match(f.insn, "011111-----01000000000111010011-") then |
||||
report "PPC_mtlr"; |
||||
ppc_insn := PPC_MTLR; |
||||
elsif std_match(f.insn, "011111---------------0101010011-") then |
||||
report "PPC_mfspr"; |
||||
ppc_insn := PPC_MFSPR; |
||||
elsif std_match(f.insn, "011111---------------1100001001-") then |
||||
report "PPC_modsd"; |
||||
ppc_insn := PPC_MODSD; |
||||
elsif std_match(f.insn, "011111---------------1100001011-") then |
||||
report "PPC_modsw"; |
||||
ppc_insn := PPC_MODSW; |
||||
elsif std_match(f.insn, "011111---------------0100001001-") then |
||||
report "PPC_modud"; |
||||
ppc_insn := PPC_MODUD; |
||||
elsif std_match(f.insn, "011111---------------0100001011-") then |
||||
report "PPC_moduw"; |
||||
ppc_insn := PPC_MODUW; |
||||
elsif std_match(f.insn, "011111-----0---------0010010000-") then |
||||
report "PPC_mtcrf"; |
||||
ppc_insn := PPC_MTCRF; |
||||
elsif std_match(f.insn, "011111-----1---------0010010000-") then |
||||
report "PPC_mtocrf"; |
||||
ppc_insn := PPC_MTOCRF; |
||||
elsif std_match(f.insn, "011111---------------0111010011-") then |
||||
report "PPC_mtspr"; |
||||
ppc_insn := PPC_MTSPR; |
||||
elsif std_match(f.insn, "011111----------------001001001-") then |
||||
report "PPC_mulhd"; |
||||
ppc_insn := PPC_MULHD; |
||||
elsif std_match(f.insn, "011111----------------000001001-") then |
||||
report "PPC_mulhdu"; |
||||
ppc_insn := PPC_MULHDU; |
||||
elsif std_match(f.insn, "011111----------------001001011-") then |
||||
report "PPC_mulhw"; |
||||
ppc_insn := PPC_MULHW; |
||||
elsif std_match(f.insn, "011111----------------000001011-") then |
||||
report "PPC_mulhwu"; |
||||
ppc_insn := PPC_MULHWU; |
||||
elsif std_match(f.insn, "011111---------------0011101001-") then |
||||
report "PPC_mulld"; |
||||
ppc_insn := PPC_MULLD; |
||||
elsif std_match(f.insn, "000111--------------------------") then |
||||
report "PPC_mulli"; |
||||
ppc_insn := PPC_MULLI; |
||||
elsif std_match(f.insn, "011111---------------0011101011-") then |
||||
report "PPC_mullw"; |
||||
ppc_insn := PPC_MULLW; |
||||
elsif std_match(f.insn, "011111---------------0111011100-") then |
||||
report "PPC_nand"; |
||||
ppc_insn := PPC_NAND; |
||||
elsif std_match(f.insn, "011111---------------0001101000-") then |
||||
report "PPC_neg"; |
||||
ppc_insn := PPC_NEG; |
||||
elsif std_match(f.insn, "011111---------------0001111100-") then |
||||
report "PPC_nor"; |
||||
ppc_insn := PPC_NOR; |
||||
elsif std_match(f.insn, "011111---------------0110111100-") then |
||||
report "PPC_or"; |
||||
ppc_insn := PPC_OR; |
||||
elsif std_match(f.insn, "011111---------------0110011100-") then |
||||
report "PPC_orc"; |
||||
ppc_insn := PPC_ORC; |
||||
elsif std_match(f.insn, "011000--------------------------") then |
||||
report "PPC_ori"; |
||||
ppc_insn := PPC_ORI; |
||||
elsif std_match(f.insn, "011001--------------------------") then |
||||
report "PPC_oris"; |
||||
ppc_insn := PPC_ORIS; |
||||
elsif std_match(f.insn, "011111---------------0001111010-") then |
||||
report "PPC_popcntb"; |
||||
ppc_insn := PPC_POPCNTB; |
||||
elsif std_match(f.insn, "011111---------------0111111010-") then |
||||
report "PPC_popcntd"; |
||||
ppc_insn := PPC_POPCNTD; |
||||
elsif std_match(f.insn, "011111---------------0101111010-") then |
||||
report "PPC_popcntw"; |
||||
ppc_insn := PPC_POPCNTW; |
||||
elsif std_match(f.insn, "011111---------------0010111010-") then |
||||
report "PPC_prtyd"; |
||||
ppc_insn := PPC_PRTYD; |
||||
elsif std_match(f.insn, "011111---------------0010011010-") then |
||||
report "PPC_prtyw"; |
||||
ppc_insn := PPC_PRTYW; |
||||
elsif std_match(f.insn, "011110---------------------1000-") then |
||||
report "PPC_rldcl"; |
||||
ppc_insn := PPC_RLDCL; |
||||
elsif std_match(f.insn, "011110---------------------1001-") then |
||||
report "PPC_rldcr"; |
||||
ppc_insn := PPC_RLDCR; |
||||
elsif std_match(f.insn, "011110---------------------010--") then |
||||
report "PPC_rldic"; |
||||
ppc_insn := PPC_RLDIC; |
||||
elsif std_match(f.insn, "011110---------------------000--") then |
||||
report "PPC_rldicl"; |
||||
ppc_insn := PPC_RLDICL; |
||||
elsif std_match(f.insn, "011110---------------------001--") then |
||||
report "PPC_rldicr"; |
||||
ppc_insn := PPC_RLDICR; |
||||
elsif std_match(f.insn, "011110---------------------011--") then |
||||
report "PPC_rldimi"; |
||||
ppc_insn := PPC_RLDIMI; |
||||
elsif std_match(f.insn, "010100--------------------------") then |
||||
report "PPC_rlwimi"; |
||||
ppc_insn := PPC_RLWIMI; |
||||
elsif std_match(f.insn, "010101--------------------------") then |
||||
report "PPC_rlwinm"; |
||||
ppc_insn := PPC_RLWINM; |
||||
elsif std_match(f.insn, "010111--------------------------") then |
||||
report "PPC_rlwnm"; |
||||
ppc_insn := PPC_RLWNM; |
||||
elsif std_match(f.insn, "011111---------------0010000000-") then |
||||
report "PPC_setb"; |
||||
ppc_insn := PPC_SETB; |
||||
elsif std_match(f.insn, "011111---------------0000011011-") then |
||||
report "PPC_sld"; |
||||
ppc_insn := PPC_SLD; |
||||
elsif std_match(f.insn, "011111---------------0000011000-") then |
||||
report "PPC_slw"; |
||||
ppc_insn := PPC_SLW; |
||||
elsif std_match(f.insn, "011111---------------1100011010-") then |
||||
report "PPC_srad"; |
||||
ppc_insn := PPC_SRAD; |
||||
elsif std_match(f.insn, "011111---------------110011101--") then |
||||
report "PPC_sradi"; |
||||
ppc_insn := PPC_SRADI; |
||||
elsif std_match(f.insn, "011111---------------1100011000-") then |
||||
report "PPC_sraw"; |
||||
ppc_insn := PPC_SRAW; |
||||
elsif std_match(f.insn, "011111---------------1100111000-") then |
||||
report "PPC_srawi"; |
||||
ppc_insn := PPC_SRAWI; |
||||
elsif std_match(f.insn, "011111---------------1000011011-") then |
||||
report "PPC_srd"; |
||||
ppc_insn := PPC_SRD; |
||||
elsif std_match(f.insn, "011111---------------1000011000-") then |
||||
report "PPC_srw"; |
||||
ppc_insn := PPC_SRW; |
||||
elsif std_match(f.insn, "100110--------------------------") then |
||||
report "PPC_stb"; |
||||
ppc_insn := PPC_STB; |
||||
elsif std_match(f.insn, "011111---------------1010110110-") then |
||||
report "PPC_stbcx"; |
||||
ppc_insn := PPC_STBCX; |
||||
elsif std_match(f.insn, "100111--------------------------") then |
||||
report "PPC_stbu"; |
||||
ppc_insn := PPC_STBU; |
||||
elsif std_match(f.insn, "011111---------------0011110111-") then |
||||
report "PPC_stbux"; |
||||
ppc_insn := PPC_STBUX; |
||||
elsif std_match(f.insn, "011111---------------0011010111-") then |
||||
report "PPC_stbx"; |
||||
ppc_insn := PPC_STBX; |
||||
elsif std_match(f.insn, "111110------------------------00") then |
||||
report "PPC_std"; |
||||
ppc_insn := PPC_STD; |
||||
elsif std_match(f.insn, "011111---------------1010010100-") then |
||||
report "PPC_stdbrx"; |
||||
ppc_insn := PPC_STDBRX; |
||||
elsif std_match(f.insn, "011111---------------0011010110-") then |
||||
report "PPC_stdcx"; |
||||
ppc_insn := PPC_STDCX; |
||||
elsif std_match(f.insn, "111110------------------------01") then |
||||
report "PPC_stdu"; |
||||
ppc_insn := PPC_STDU; |
||||
elsif std_match(f.insn, "011111---------------0010110101-") then |
||||
report "PPC_stdux"; |
||||
ppc_insn := PPC_STDUX; |
||||
elsif std_match(f.insn, "011111---------------0010010101-") then |
||||
report "PPC_stdx"; |
||||
ppc_insn := PPC_STDX; |
||||
elsif std_match(f.insn, "101100--------------------------") then |
||||
report "PPC_sth"; |
||||
ppc_insn := PPC_STH; |
||||
elsif std_match(f.insn, "011111---------------1110010110-") then |
||||
report "PPC_sthbrx"; |
||||
ppc_insn := PPC_STHBRX; |
||||
elsif std_match(f.insn, "011111---------------1011010110-") then |
||||
report "PPC_sthcx"; |
||||
ppc_insn := PPC_STHCX; |
||||
elsif std_match(f.insn, "101101--------------------------") then |
||||
report "PPC_sthu"; |
||||
ppc_insn := PPC_STHU; |
||||
elsif std_match(f.insn, "011111---------------0110110111-") then |
||||
report "PPC_sthux"; |
||||
ppc_insn := PPC_STHUX; |
||||
elsif std_match(f.insn, "011111---------------0110010111-") then |
||||
report "PPC_sthx"; |
||||
ppc_insn := PPC_STHX; |
||||
elsif std_match(f.insn, "100100--------------------------") then |
||||
report "PPC_stw"; |
||||
ppc_insn := PPC_STW; |
||||
elsif std_match(f.insn, "011111---------------1010010110-") then |
||||
report "PPC_stwbrx"; |
||||
ppc_insn := PPC_STWBRX; |
||||
elsif std_match(f.insn, "011111---------------0010010110-") then |
||||
report "PPC_stwcx"; |
||||
ppc_insn := PPC_STWCX; |
||||
elsif std_match(f.insn, "100101--------------------------") then |
||||
report "PPC_stwu"; |
||||
ppc_insn := PPC_STWU; |
||||
elsif std_match(f.insn, "011111---------------0010110111-") then |
||||
report "PPC_stwux"; |
||||
ppc_insn := PPC_STWUX; |
||||
elsif std_match(f.insn, "011111---------------0010010111-") then |
||||
report "PPC_stwx"; |
||||
ppc_insn := PPC_STWX; |
||||
elsif std_match(f.insn, "011111---------------0000101000-") then |
||||
report "PPC_subf"; |
||||
ppc_insn := PPC_SUBF; |
||||
elsif std_match(f.insn, "011111---------------0000001000-") then |
||||
report "PPC_subfc"; |
||||
ppc_insn := PPC_SUBFC; |
||||
elsif std_match(f.insn, "011111---------------0010001000-") then |
||||
report "PPC_subfe"; |
||||
ppc_insn := PPC_SUBFE; |
||||
elsif std_match(f.insn, "001000--------------------------") then |
||||
report "PPC_subfic"; |
||||
ppc_insn := PPC_SUBFIC; |
||||
elsif std_match(f.insn, "011111---------------0011101000-") then |
||||
report "PPC_subfme"; |
||||
ppc_insn := PPC_SUBFME; |
||||
elsif std_match(f.insn, "011111---------------0011001000-") then |
||||
report "PPC_subfze"; |
||||
ppc_insn := PPC_SUBFZE; |
||||
elsif std_match(f.insn, "011111---------------1001010110-") then |
||||
report "PPC_sync"; |
||||
ppc_insn := PPC_SYNC; |
||||
elsif std_match(f.insn, "011111---------------0001000100-") then |
||||
report "PPC_td"; |
||||
ppc_insn := PPC_TD; |
||||
elsif std_match(f.insn, "000010--------------------------") then |
||||
report "PPC_tdi"; |
||||
ppc_insn := PPC_TDI; |
||||
elsif std_match(f.insn, "011111---------------0000000100-") then |
||||
report "PPC_tw"; |
||||
ppc_insn := PPC_TW; |
||||
elsif std_match(f.insn, "000011--------------------------") then |
||||
report "PPC_twi"; |
||||
ppc_insn := PPC_TWI; |
||||
elsif std_match(f.insn, "011111---------------0100111100-") then |
||||
report "PPC_xor"; |
||||
ppc_insn := PPC_XOR; |
||||
elsif std_match(f.insn, "011010--------------------------") then |
||||
report "PPC_xori"; |
||||
ppc_insn := PPC_XORI; |
||||
elsif std_match(f.insn, "011011--------------------------") then |
||||
report "PPC_xoris"; |
||||
ppc_insn := PPC_XORIS; |
||||
elsif std_match(f.insn, "000001---------------0000000000-") then |
||||
report "PPC_SIM_READ"; |
||||
ppc_insn := PPC_SIM_READ; |
||||
elsif std_match(f.insn, "000001---------------0000000001-") then |
||||
report "PPC_SIM_POLL"; |
||||
ppc_insn := PPC_SIM_POLL; |
||||
elsif std_match(f.insn, "000001---------------0000000010-") then |
||||
report "PPC_SIM_WRITE"; |
||||
ppc_insn := PPC_SIM_WRITE; |
||||
elsif std_match(f.insn, "000001---------------0000000011-") then |
||||
report "PPC_SIM_CONFIG"; |
||||
ppc_insn := PPC_SIM_CONFIG; |
||||
else |
||||
report "PPC_illegal"; |
||||
ppc_insn := PPC_ILLEGAL; |
||||
end if; |
||||
|
||||
d_out.decode <= decode_rom_array(ppc_insn); |
||||
end if; |
||||
end process; |
||||
end architecture behaviour; |
@ -0,0 +1,324 @@
@@ -0,0 +1,324 @@
|
||||
library ieee; |
||||
use ieee.std_logic_1164.all; |
||||
use ieee.numeric_std.all; |
||||
|
||||
library work; |
||||
use work.decode_types.all; |
||||
use work.common.all; |
||||
use work.helpers.all; |
||||
|
||||
entity decode2 is |
||||
port ( |
||||
clk : in std_ulogic; |
||||
|
||||
d_in : in Decode1ToDecode2Type; |
||||
|
||||
e_out : out Decode2ToExecute1Type; |
||||
m_out : out Decode2ToMultiplyType; |
||||
l_out : out Decode2ToLoadstore1Type; |
||||
|
||||
r_in : in RegisterFileToDecode2Type; |
||||
r_out : out Decode2ToRegisterFileType; |
||||
|
||||
c_in : in CrFileToDecode2Type; |
||||
c_out : out Decode2ToCrFileType |
||||
); |
||||
end entity decode2; |
||||
|
||||
architecture behaviour of decode2 is |
||||
signal d : Decode1ToDecode2Type; |
||||
|
||||
alias insn_rs : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); |
||||
alias insn_rt : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); |
||||
alias insn_ra : std_ulogic_vector(4 downto 0) is d.insn(20 downto 16); |
||||
alias insn_rb : std_ulogic_vector(4 downto 0) is d.insn(15 downto 11); |
||||
alias insn_si : std_ulogic_vector(15 downto 0) is d.insn(15 downto 0); |
||||
alias insn_ui : std_ulogic_vector(15 downto 0) is d.insn(15 downto 0); |
||||
alias insn_l : std_ulogic is d.insn(21); |
||||
alias insn_sh32 : std_ulogic_vector(4 downto 0) is d.insn(15 downto 11); |
||||
alias insn_mb32 : std_ulogic_vector(4 downto 0) is d.insn(10 downto 6); |
||||
alias insn_me32 : std_ulogic_vector(4 downto 0) is d.insn(5 downto 1); |
||||
alias insn_li : std_ulogic_vector(23 downto 0) is d.insn(25 downto 2); |
||||
alias insn_lk : std_ulogic is d.insn(0); |
||||
alias insn_rc : std_ulogic is d.insn(0); |
||||
alias insn_bd : std_ulogic_vector(13 downto 0) is d.insn(15 downto 2); |
||||
alias insn_bf : std_ulogic_vector(2 downto 0) is d.insn(25 downto 23); |
||||
alias insn_fxm : std_ulogic_vector(7 downto 0) is d.insn(19 downto 12); |
||||
alias insn_bo : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); |
||||
alias insn_bi : std_ulogic_vector(4 downto 0) is d.insn(20 downto 16); |
||||
alias insn_bh : std_ulogic_vector(1 downto 0) is d.insn(12 downto 11); |
||||
alias insn_d : std_ulogic_vector(15 downto 0) is d.insn(15 downto 0); |
||||
alias insn_ds : std_ulogic_vector(13 downto 0) is d.insn(15 downto 2); |
||||
alias insn_to : std_ulogic_vector(4 downto 0) is d.insn(25 downto 21); |
||||
alias insn_bc : std_ulogic_vector(4 downto 0) is d.insn(10 downto 6); |
||||
|
||||
-- can't use an alias for these |
||||
signal insn_sh : std_ulogic_vector(5 downto 0); |
||||
signal insn_me : std_ulogic_vector(5 downto 0); |
||||
signal insn_mb : std_ulogic_vector(5 downto 0); |
||||
begin |
||||
insn_sh <= d.insn(1) & d.insn(15 downto 11); |
||||
insn_me <= d.insn(5) & d.insn(10 downto 6); |
||||
insn_mb <= d.insn(5) & d.insn(10 downto 6); |
||||
|
||||
decode2_0: process(clk) |
||||
begin |
||||
if rising_edge(clk) then |
||||
d <= d_in; |
||||
end if; |
||||
end process; |
||||
|
||||
r_out.read1_reg <= insn_ra when (d.decode.input_reg_a = RA) else |
||||
insn_ra when d.decode.input_reg_a = RA_OR_ZERO else |
||||
insn_rs when d.decode.input_reg_a = RS else |
||||
(others => '0'); |
||||
|
||||
r_out.read2_reg <= insn_rb when d.decode.input_reg_b = RB else |
||||
insn_rs when d.decode.input_reg_b = RS else |
||||