Initial import of microwatt
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>pull/4/head
commit
5a29cb4699
@ -0,0 +1,8 @@
|
||||
*.o
|
||||
*~
|
||||
*.cf
|
||||
*.s
|
||||
core_tb
|
||||
fetch_tb
|
||||
loadstore_tb
|
||||
simple_ram_behavioural_tb
|
@ -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 @@
|
||||
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 @@
|
||||
# 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 @@
|
||||
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 @@
|
||||
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 @@
|
||||
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 @@
|
||||
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 @@
|
||||
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 @@
|
||||
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 @@
|
||||
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
|
||||
(others => '0');
|
||||
|
||||
r_out.read3_reg <= insn_rs when d.decode.input_reg_c = RS else
|
||||
(others => '0');
|
||||
|
||||
decode2_1: process(all)
|
||||
variable mul_a : std_ulogic_vector(63 downto 0);
|
||||
variable mul_b : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
e_out <= Decode2ToExecute1Init;
|
||||
l_out <= Decode2ToLoadStore1Init;
|
||||
m_out <= Decode2ToMultiplyInit;
|
||||
|
||||
mul_a := (others => '0');
|
||||
mul_b := (others => '0');
|
||||
|
||||
e_out.nia <= d.nia;
|
||||
l_out.nia <= d.nia;
|
||||
m_out.nia <= d.nia;
|
||||
|
||||
--e_out.input_cr <= d.decode.input_cr;
|
||||
--m_out.input_cr <= d.decode.input_cr;
|
||||
--e_out.output_cr <= d.decode.output_cr;
|
||||
|
||||
e_out.cr <= c_in.read_cr_data;
|
||||
|
||||
e_out.input_carry <= d.decode.input_carry;
|
||||
e_out.output_carry <= d.decode.output_carry;
|
||||
|
||||
if d.decode.lr then
|
||||
e_out.lr <= insn_lk;
|
||||
end if;
|
||||
|
||||
-- XXX This is getting too complicated. Use variables and assign to each unit later
|
||||
|
||||
case d.decode.unit is
|
||||
when ALU =>
|
||||
e_out.insn_type <= d.decode.insn_type;
|
||||
e_out.valid <= d.valid;
|
||||
when LDST =>
|
||||
l_out.valid <= d.valid;
|
||||
when MUL =>
|
||||
m_out.insn_type <= d.decode.insn_type;
|
||||
m_out.valid <= d.valid;
|
||||
when NONE =>
|
||||
e_out.insn_type <= OP_ILLEGAL;
|
||||
e_out.valid <= d.valid;
|
||||
end case;
|
||||
|
||||
-- required for bypassing
|
||||
case d.decode.input_reg_a is
|
||||
when RA =>
|
||||
e_out.read_reg1 <= insn_ra;
|
||||
l_out.update_reg <= insn_ra;
|
||||
when RA_OR_ZERO =>
|
||||
e_out.read_reg1 <= insn_ra;
|
||||
l_out.update_reg <= insn_ra;
|
||||
when RS =>
|
||||
e_out.read_reg1 <= insn_rs;
|
||||
when NONE =>
|
||||
e_out.read_reg1 <= (others => '0');
|
||||
l_out.update_reg <= (others => '0');
|
||||
end case;
|
||||
|
||||
-- required for bypassing
|
||||
case d.decode.input_reg_b is
|
||||
when RB =>
|
||||
e_out.read_reg2 <= insn_rb;
|
||||
when RS =>
|
||||
e_out.read_reg2 <= insn_rs;
|
||||
when others =>
|
||||
e_out.read_reg2 <= (others => '0');
|
||||
end case;
|
||||
|
||||
-- required for bypassing
|
||||
--case d.decode.input_reg_c is
|
||||
--when RS =>
|
||||
--e_out.read_reg3 <= insn_rs;
|
||||
--when NONE =>
|
||||
--e_out.read_reg3 <= (others => '0');
|
||||
--end case;
|
||||
|
||||
case d.decode.input_reg_a is
|
||||
when RA =>
|
||||
e_out.read_data1 <= r_in.read1_data;
|
||||
mul_a := r_in.read1_data;
|
||||
l_out.addr1 <= r_in.read1_data;
|
||||
when RA_OR_ZERO =>
|
||||
e_out.read_data1 <= ra_or_zero(r_in.read1_data, insn_ra);
|
||||
l_out.addr1 <= ra_or_zero(r_in.read1_data, insn_ra);
|
||||
when RS =>
|
||||
e_out.read_data1 <= r_in.read1_data;
|
||||
when NONE =>
|
||||
e_out.read_data1 <= (others => '0');
|
||||
mul_a := (others => '0');
|
||||
end case;
|
||||
|
||||
case d.decode.input_reg_b is
|
||||
when RB =>
|
||||
e_out.read_data2 <= r_in.read2_data;
|
||||
mul_b := r_in.read2_data;
|
||||
l_out.addr2 <= r_in.read2_data;
|
||||
when RS =>
|
||||
e_out.read_data2 <= r_in.read2_data;
|
||||
when CONST_UI =>
|
||||
e_out.read_data2 <= std_ulogic_vector(resize(unsigned(insn_ui), 64));
|
||||
when CONST_SI =>
|
||||
e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_si), 64));
|
||||
l_out.addr2 <= std_ulogic_vector(resize(signed(insn_si), 64));
|
||||
mul_b := std_ulogic_vector(resize(signed(insn_si), 64));
|
||||
when CONST_SI_HI =>
|
||||
e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_si) & x"0000", 64));
|
||||
when CONST_UI_HI =>
|
||||
e_out.read_data2 <= std_ulogic_vector(resize(unsigned(insn_si) & x"0000", 64));
|
||||
when CONST_LI =>
|
||||
e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_li) & "00", 64));
|
||||
when CONST_BD =>
|
||||
e_out.read_data2 <= std_ulogic_vector(resize(signed(insn_bd) & "00", 64));
|
||||
when CONST_DS =>
|
||||
l_out.addr2 <= std_ulogic_vector(resize(signed(insn_ds) & "00", 64));
|
||||
when NONE =>
|
||||
e_out.read_data2 <= (others => '0');
|
||||
l_out.addr2 <= (others => '0');
|
||||
mul_b := (others => '0');
|
||||
end case;
|
||||
|
||||
case d.decode.input_reg_c is
|
||||
when RS =>
|
||||
l_out.data <= r_in.read3_data;
|
||||
when NONE =>
|
||||
l_out.data <= (others => '0');
|
||||
end case;
|
||||
|
||||
if d.decode.mul_32bit = '1' then
|
||||
if d.decode.mul_signed = '1' then
|
||||
m_out.data1 <= (others => mul_a(31));
|
||||
m_out.data1(31 downto 0) <= mul_a(31 downto 0);
|
||||
m_out.data2 <= (others => mul_b(31));
|
||||
m_out.data2(31 downto 0) <= mul_b(31 downto 0);
|
||||
else
|
||||
m_out.data1 <= '0' & x"00000000" & mul_a(31 downto 0);
|
||||
m_out.data2 <= '0' & x"00000000" & mul_b(31 downto 0);
|
||||
end if;
|
||||
else
|
||||
if d.decode.mul_signed = '1' then
|
||||
m_out.data1 <= mul_a(63) & mul_a;
|
||||
m_out.data2 <= mul_b(63) & mul_b;
|
||||
else
|
||||
m_out.data1 <= '0' & mul_a;
|
||||
m_out.data2 <= '0' & mul_b;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
case d.decode.const_a is
|
||||
when SH =>
|
||||
e_out.const1(insn_sh'range) <= insn_sh;
|
||||
when SH32 =>
|
||||
e_out.const1(insn_sh32'range) <= insn_sh32;
|
||||
when FXM =>
|
||||
e_out.const1(insn_fxm'range) <= insn_fxm;
|
||||
when BO =>
|
||||
e_out.const1(insn_bo'range)<= insn_bo;
|
||||
when BF =>
|
||||
e_out.const1(insn_bf'range)<= insn_bf;
|
||||
when TOO =>
|
||||
e_out.const1(insn_to'range)<= insn_to;
|
||||
when BC =>
|
||||
e_out.const1(insn_bc'range)<= insn_bc;
|
||||
when NONE =>
|
||||
e_out.const1 <= (others => '0');
|
||||
end case;
|
||||
|
||||
case d.decode.const_b is
|
||||
when MB =>
|
||||
e_out.const2(insn_mb'range) <= insn_mb;
|
||||
when ME =>
|
||||
e_out.const2(insn_me'range) <= insn_me;
|
||||
when MB32 =>
|
||||
e_out.const2(insn_mb32'range) <= insn_mb32;
|
||||
when BI =>
|
||||
e_out.const2(insn_bi'range) <= insn_bi;
|
||||
when L =>
|
||||
e_out.const2(0) <= insn_l;
|
||||
when NONE =>
|
||||
e_out.const2 <= (others => '0');
|
||||
end case;
|
||||
|
||||
case d.decode.const_c is
|
||||
when ME32 =>
|
||||
e_out.const3(insn_me32'range) <= insn_me32;
|
||||
when BH =>
|
||||
e_out.const3(insn_bh'range) <= insn_bh;
|
||||
when NONE =>
|
||||
e_out.const3 <= (others => '0');
|
||||
end case;
|
||||
|
||||
case d.decode.output_reg_a is
|
||||
when RT =>
|
||||
e_out.write_reg <= insn_rt;
|
||||
l_out.write_reg <= insn_rt;
|
||||
m_out.write_reg <= insn_rt;
|
||||
when RA =>
|
||||
e_out.write_reg <= insn_ra;
|
||||
l_out.write_reg <= insn_ra;
|
||||
when NONE =>
|
||||
e_out.write_reg <= (others => '0');
|
||||
l_out.write_reg <= (others => '0');
|
||||
m_out.write_reg <= (others => '0');
|
||||
end case;
|
||||
|
||||
case d.decode.rc is
|
||||
when RC =>
|
||||
e_out.rc <= insn_rc;
|
||||
m_out.rc <= insn_rc;
|
||||
when ONE =>
|
||||
e_out.rc <= '1';
|
||||
m_out.rc <= '1';
|
||||
when NONE =>
|
||||
e_out.rc <= '0';
|
||||
m_out.rc <= '0';
|
||||
end case;
|
||||
|
||||
-- load/store specific signals
|
||||
if d.decode.insn_type = OP_LOAD then
|
||||
l_out.load <= '1';
|
||||
else
|
||||
l_out.load <= '0';
|
||||
end if;
|
||||
|
||||
case d.decode.length is
|
||||
when is1B =>
|
||||
l_out.length <= "0001";
|
||||
when is2B =>
|
||||
l_out.length <= "0010";
|
||||
when is4B =>
|
||||
l_out.length <= "0100";
|
||||
when is8B =>
|
||||
l_out.length <= "1000";
|
||||
when NONE =>
|
||||
l_out.length <= "0000";
|
||||
end case;
|
||||
|
||||
l_out.byte_reverse <= d.decode.byte_reverse;
|
||||
l_out.sign_extend <= d.decode.sign_extend;
|
||||
l_out.update <= d.decode.update;
|
||||
end process;
|
||||
end architecture behaviour;
|
@ -0,0 +1,140 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package decode_types is
|
||||
type ppc_insn_t is (PPC_ILLEGAL, PPC_ADD, PPC_ADDC, PPC_ADDE,
|
||||
PPC_ADDEX, PPC_ADDI, PPC_ADDIC, PPC_ADDIC_RC, PPC_ADDIS,
|
||||
PPC_ADDME, PPC_ADDPCIS, PPC_ADDZE, PPC_AND, PPC_ANDC,
|
||||
PPC_ANDI_RC, PPC_ANDIS_RC, PPC_ATTN, PPC_B, PPC_BA, PPC_BC,
|
||||
PPC_BCA, PPC_BCCTR, PPC_BCLA, PPC_BCLR, PPC_BCTAR, PPC_BPERM,
|
||||
PPC_CMP, PPC_CMPB, PPC_CMPEQB, PPC_CMPI, PPC_CMPL, PPC_CMPLI,
|
||||
PPC_CMPRB, PPC_CNTLZD, PPC_CNTLZW, PPC_CNTTZD, PPC_CNTTZW,
|
||||
PPC_CRAND, PPC_CRANDC, PPC_CREQV, PPC_CRNAND, PPC_CRNOR,
|
||||
PPC_CROR, PPC_CRORC, PPC_CRXOR, PPC_DARN, PPC_DCBF, PPC_DCBST,
|
||||
PPC_DCBT, PPC_DCBTST, PPC_DCBZ, PPC_DIVD, PPC_DIVDE,
|
||||
PPC_DIVDEU, PPC_DIVDU, PPC_DIVW, PPC_DIVWE, PPC_DIVWEU,
|
||||
PPC_DIVWU, PPC_EQV, PPC_EXTSB, PPC_EXTSH, PPC_EXTSW,
|
||||
PPC_EXTSWSLI, PPC_ICBI, PPC_ICBT, PPC_ISEL, PPC_ISYNC,
|
||||
PPC_LBARX, PPC_LBZ, PPC_LBZU, PPC_LBZUX, PPC_LBZX, PPC_LD,
|
||||
PPC_LDARX, PPC_LDBRX, PPC_LDU, PPC_LDUX, PPC_LDX, PPC_LHA,
|
||||
PPC_LHARX, PPC_LHAU, PPC_LHAUX, PPC_LHAX, PPC_LHBRX, PPC_LHZ,
|
||||
PPC_LHZU, PPC_LHZUX, PPC_LHZX, PPC_LWA, PPC_LWARX, PPC_LWAUX,
|
||||
PPC_LWAX, PPC_LWBRX, PPC_LWZ, PPC_LWZU, PPC_LWZUX, PPC_LWZX,
|
||||
PPC_MADDHD, PPC_MADDHDU, PPC_MADDLD, PPC_MCRF, PPC_MCRXR,
|
||||
PPC_MCRXRX, PPC_MFCR, PPC_MFOCRF, PPC_MFSPR, PPC_MFTB,
|
||||
PPC_MODSD, PPC_MODSW, PPC_MODUD, PPC_MODUW, PPC_MTCRF,
|
||||
PPC_MFCTR, PPC_MTCTR, PPC_MFLR, PPC_MTLR, PPC_MTOCRF,
|
||||
PPC_MTSPR, PPC_MULHD, PPC_MULHDU, PPC_MULHW, PPC_MULHWU,
|
||||
PPC_MULLD, PPC_MULLI, PPC_MULLW, PPC_NAND, PPC_NEG, PPC_NOR,
|
||||
PPC_OR, PPC_ORC, PPC_ORI, PPC_ORIS, PPC_POPCNTB, PPC_POPCNTD,
|
||||
PPC_POPCNTW, PPC_PRTYD, PPC_PRTYW, PPC_RLDCL, PPC_RLDCR,
|
||||
PPC_RLDIC, PPC_RLDICL, PPC_RLDICR, PPC_RLDIMI, PPC_RLWIMI,
|
||||
PPC_RLWINM, PPC_RLWNM, PPC_SETB, PPC_SLD, PPC_SLW, PPC_SRAD,
|
||||
PPC_SRADI, PPC_SRAW, PPC_SRAWI, PPC_SRD, PPC_SRW, PPC_STB,
|
||||
PPC_STBCX, PPC_STBU, PPC_STBUX, PPC_STBX, PPC_STD, PPC_STDBRX,
|
||||
PPC_STDCX, PPC_STDU, PPC_STDUX, PPC_STDX, PPC_STH, PPC_STHBRX,
|
||||
PPC_STHCX, PPC_STHU, PPC_STHUX, PPC_STHX, PPC_STW, PPC_STWBRX,
|
||||
PPC_STWCX, PPC_STWU, PPC_STWUX, PPC_STWX, PPC_SUBF, PPC_SUBFC,
|
||||
PPC_SUBFE, PPC_SUBFIC, PPC_SUBFME, PPC_SUBFZE, PPC_SYNC, PPC_TD,
|
||||
PPC_TDI, PPC_TW, PPC_TWI, PPC_XOR, PPC_XORI, PPC_XORIS,
|
||||
PPC_SIM_READ, PPC_SIM_POLL, PPC_SIM_WRITE, PPC_SIM_CONFIG);
|
||||
|
||||
type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, OP_ADDC, OP_ADDEX, OP_ADDME,
|
||||
OP_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BA, OP_BC,
|
||||
OP_BCA, OP_BCCTR, OP_BCLA, OP_BCLR, OP_BCTAR, OP_BPERM, OP_CMP,
|
||||
OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB,
|
||||
OP_CNTLZD, OP_CNTLZW, OP_CNTTZD, OP_CNTTZW, OP_CRAND,
|
||||
OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC,
|
||||
OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,
|
||||
OP_DCBZ, OP_DIVD, OP_DIVDE, OP_DIVDEU, OP_DIVDU, OP_DIVW,
|
||||
OP_DIVWE, OP_DIVWEU, OP_DIVWU, OP_EQV, OP_EXTSB, OP_EXTSH,
|
||||
OP_EXTSW, OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC,
|
||||
OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF,
|
||||
OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFCTR, OP_MFLR,
|
||||
OP_MFTB, OP_MFSPR, OP_MODSD, OP_MODSW, OP_MODUD, OP_MODUW,
|
||||
OP_MTCRF, OP_MTOCRF, OP_MTCTR, OP_MTLR, OP_MTSPR, OP_MUL_L64,
|
||||
OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR,
|
||||
OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD,
|
||||
OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR,
|
||||
OP_RLDIMI, OP_RLWIMI, OP_RLWINM, OP_RLWNM, OP_SETB, OP_SLD,
|
||||
OP_SLW, OP_SRAD, OP_SRADI, OP_SRAW, OP_SRAWI, OP_SRD, OP_SRW,
|
||||
OP_SUBF, OP_SUBFC, OP_SUBFME, OP_SYNC, OP_TD, OP_TDI, OP_TW,
|
||||
OP_TWI, OP_XOR, OP_SIM_READ, OP_SIM_POLL, OP_SIM_WRITE,
|
||||
OP_SIM_CONFIG);
|
||||
|
||||
type input_reg_a_t is (NONE, RA, RA_OR_ZERO, RS);
|
||||
type input_reg_b_t is (NONE, RB, RS, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS);
|
||||
type input_reg_c_t is (NONE, RS);
|
||||
type output_reg_a_t is (NONE, RT, RA);
|
||||
type constant_a_t is (NONE, SH, SH32, FXM, BO, BF, TOO, BC);
|
||||
type constant_b_t is (NONE, MB, ME, MB32, BI, L);
|
||||
type constant_c_t is (NONE, ME32, BH);
|
||||
type rc_t is (NONE, ONE, RC);
|
||||
|
||||
constant SH_OFFSET : integer := 0;
|
||||
constant MB_OFFSET : integer := 1;
|
||||
constant ME_OFFSET : integer := 1;
|
||||
constant SH32_OFFSET : integer := 0;
|
||||
constant MB32_OFFSET : integer := 1;
|
||||
constant ME32_OFFSET : integer := 2;
|
||||
|
||||
constant FXM_OFFSET : integer := 0;
|
||||
|
||||
constant BO_OFFSET : integer := 0;
|
||||
constant BI_OFFSET : integer := 1;
|
||||
constant BH_OFFSET : integer := 2;
|
||||
|
||||
constant BF_OFFSET : integer := 0;
|
||||
constant L_OFFSET : integer := 1;
|
||||
|
||||
constant TOO_OFFSET : integer := 0;
|
||||
|
||||
type unit_t is (NONE, ALU, LDST, MUL);
|
||||
type length_t is (NONE, is1B, is2B, is4B, is8B);
|
||||
|
||||
type decode_rom_t is record
|
||||
unit : unit_t;
|
||||
insn_type : insn_type_t;
|
||||
input_reg_a : input_reg_a_t;
|
||||
input_reg_b : input_reg_b_t;
|
||||
input_reg_c : input_reg_c_t;
|
||||
output_reg_a : output_reg_a_t;
|
||||
|
||||
const_a : constant_a_t;
|
||||
const_b : constant_b_t;
|
||||
const_c : constant_c_t;
|
||||
|
||||
input_cr : std_ulogic;
|
||||
output_cr : std_ulogic;
|
||||
|
||||
input_carry : std_ulogic;
|
||||
output_carry : std_ulogic;
|
||||
|
||||
-- load/store signals
|
||||
length : length_t;
|
||||
byte_reverse : std_ulogic;
|
||||
sign_extend : std_ulogic;
|
||||
update : std_ulogic;
|
||||
reserve : std_ulogic;
|
||||
|
||||
-- multiplier signals
|
||||
mul_32bit : std_ulogic;
|
||||
mul_signed : std_ulogic;
|
||||
|
||||
rc : rc_t;
|
||||
lr : std_ulogic;
|
||||
end record;
|
||||
constant decode_rom_init : decode_rom_t := (unit => NONE,
|
||||
insn_type => OP_ILLEGAL, input_reg_a => NONE,
|
||||
input_reg_b => NONE, input_reg_c => NONE,
|
||||
output_reg_a => NONE, const_a => NONE, const_b => NONE,
|
||||
const_c => NONE, input_cr => '0', output_cr => '0',
|
||||
input_carry => '0', output_carry => '0',
|
||||
length => NONE, byte_reverse => '0', sign_extend => '0',
|
||||
update => '0', reserve => '0', mul_32bit => '0',
|
||||
mul_signed => '0', rc => NONE, lr => '0');
|
||||
|
||||
end decode_types;
|
||||
|
||||
package body decode_types is
|
||||
end decode_types;
|
@ -0,0 +1,360 @@
|
||||
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;
|
||||
use work.crhelpers.all;
|
||||
use work.ppc_fx_insns.all;
|
||||
use work.sim_console.all;
|
||||
|
||||
entity execute1 is
|
||||
generic (
|
||||
SIM : boolean := false
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
|
||||
e_in : in Decode2ToExecute1Type;
|
||||
f_out : out Execute1ToFetch1Type;
|
||||
e_out : out Execute1ToExecute2Type;
|
||||
|
||||
terminate_out : out std_ulogic
|
||||
);
|
||||
end entity execute1;
|
||||
|
||||
architecture behaviour of execute1 is
|
||||
signal e: Decode2ToExecute1Type := Decode2ToExecute1Init;
|
||||
signal ctrl: ctrl_t := (carry => '0', others => (others => '0'));
|
||||
signal ctrl_tmp: ctrl_t := (carry => '0', others => (others => '0'));
|
||||
begin
|
||||
execute1_0: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
e <= e_in;
|
||||
ctrl <= ctrl_tmp;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
execute1_1: process(all)
|
||||
variable result : std_ulogic_vector(63 downto 0);
|
||||
variable result_with_carry : std_ulogic_vector(64 downto 0);
|
||||
variable result_en : integer;
|
||||
variable crnum : integer;
|
||||
begin
|
||||
result := (others => '0');
|
||||
result_with_carry := (others => '0');
|
||||
result_en := 0;
|
||||
|
||||
e_out <= Execute1ToExecute2Init;
|
||||
f_out <= Execute1ToFetch1TypeInit;
|
||||
ctrl_tmp <= ctrl;
|
||||
-- FIXME: run at 512MHz not core freq
|
||||
ctrl_tmp.tb <= std_ulogic_vector(unsigned(ctrl.tb) + 1);
|
||||
|
||||
terminate_out <= '0';
|
||||
|
||||
if e.valid = '1' then
|
||||
e_out.valid <= '1';
|
||||
e_out.write_reg <= e.write_reg;
|
||||
|
||||
report "execute " & to_hstring(e.nia);
|
||||
|
||||
case_0: case e.insn_type is
|
||||
|
||||
when OP_ILLEGAL =>
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
when OP_NOP =>
|
||||
-- Do nothing
|
||||
when OP_ADD =>
|
||||
result := ppc_add(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_ADDC =>
|
||||
result_with_carry := ppc_adde(e.read_data1, e.read_data2, ctrl.carry and e.input_carry);
|
||||
result := result_with_carry(63 downto 0);
|
||||
ctrl_tmp.carry <= result_with_carry(64) and e.output_carry;
|
||||
result_en := 1;
|
||||
when OP_AND =>
|
||||
result := ppc_and(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_ANDC =>
|
||||
result := ppc_andc(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_B =>
|
||||
f_out.redirect <= '1';
|
||||
f_out.redirect_nia <= std_ulogic_vector(signed(e.nia) + signed(e.read_data2));
|
||||
when OP_BC =>
|
||||
if e.const1(4-2) = '0' then
|
||||
ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
|
||||
end if;
|
||||
if ppc_bc_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr, ctrl.ctr) = 1 then
|
||||
f_out.redirect <= '1';
|
||||
f_out.redirect_nia <= std_ulogic_vector(signed(e.nia) + signed(e.read_data2));
|
||||
end if;
|
||||
when OP_BCLR =>
|
||||
if e.const1(4-2) = '0' then
|
||||
ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
|
||||
end if;
|
||||
if ppc_bc_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr, ctrl.ctr) = 1 then
|
||||
f_out.redirect <= '1';
|
||||
f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00";
|
||||
end if;
|
||||
when OP_BCCTR =>
|
||||
if ppc_bcctr_taken(e.const1(4 downto 0), e.const2(4 downto 0), e.cr) = 1 then
|
||||
f_out.redirect <= '1';
|
||||
f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00";
|
||||
end if;
|
||||
when OP_CMPB =>
|
||||
result := ppc_cmpb(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_CMP =>
|
||||
e_out.write_cr_enable <= '1';
|
||||
crnum := to_integer(unsigned(e.const1(2 downto 0)));
|
||||
e_out.write_cr_mask <= num_to_fxm(crnum);
|
||||
e_out.write_cr_data <= (others => '0');
|
||||
e_out.write_cr_data((4*(7-crnum)+3) downto (4*(7-crnum))) <= ppc_cmp(e.const2(0), e.read_data1, e.read_data2);
|
||||
when OP_CMPL =>
|
||||
e_out.write_cr_enable <= '1';
|
||||
crnum := to_integer(unsigned(e.const1(2 downto 0)));
|
||||
e_out.write_cr_mask <= num_to_fxm(crnum);
|
||||
e_out.write_cr_data <= (others => '0');
|
||||
e_out.write_cr_data((4*(7-crnum)+3) downto (4*(7-crnum))) <= ppc_cmpl(e.const2(0), e.read_data1, e.read_data2);
|
||||
when OP_CNTLZW =>
|
||||
result := ppc_cntlzw(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_CNTTZW =>
|
||||
result := ppc_cnttzw(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_CNTLZD =>
|
||||
result := ppc_cntlzd(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_CNTTZD =>
|
||||
result := ppc_cnttzd(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_EXTSB =>
|
||||
result := ppc_extsb(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_EXTSH =>
|
||||
result := ppc_extsh(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_EXTSW =>
|
||||
result := ppc_extsw(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_EQV =>
|
||||
result := ppc_eqv(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_ISEL =>
|
||||
crnum := to_integer(unsigned(e.const1));
|
||||
if e.cr(31-crnum) = '1' then
|
||||
result := e.read_data1;
|
||||
else
|
||||
result := e.read_data2;
|
||||
end if;
|
||||
result_en := 1;
|
||||
when OP_MFCTR =>
|
||||
result := ctrl.ctr;
|
||||
result_en := 1;
|
||||
when OP_MFLR =>
|
||||
result := ctrl.lr;
|
||||
result_en := 1;
|
||||
when OP_MFTB =>
|
||||
result := ctrl.tb;
|
||||
result_en := 1;
|
||||
when OP_MTCTR =>
|
||||
ctrl_tmp.ctr <= e.read_data1;
|
||||
when OP_MTLR =>
|
||||
ctrl_tmp.lr <= e.read_data1;
|
||||
when OP_MFCR =>
|
||||
result := x"00000000" & e.cr;
|
||||
result_en := 1;
|
||||
when OP_MFOCRF =>
|
||||
crnum := fxm_to_num(e.const1(7 downto 0));
|
||||
result := (others => '0');
|
||||
result((4*(7-crnum)+3) downto (4*(7-crnum))) := e.cr((4*(7-crnum)+3) downto (4*(7-crnum)));
|
||||
result_en := 1;
|
||||
when OP_MTCRF =>
|
||||
e_out.write_cr_enable <= '1';
|
||||
e_out.write_cr_mask <= e.const1(7 downto 0);
|
||||
e_out.write_cr_data <= e.read_data1(31 downto 0);
|
||||
when OP_MTOCRF =>
|
||||
e_out.write_cr_enable <= '1';
|
||||
-- We require one hot priority encoding here
|
||||
crnum := fxm_to_num(e.const1(7 downto 0));
|
||||
e_out.write_cr_mask <= num_to_fxm(crnum);
|
||||
e_out.write_cr_data <= e.read_data1(31 downto 0);
|
||||
when OP_NAND =>
|
||||
result := ppc_nand(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_NEG =>
|
||||
result := ppc_neg(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_NOR =>
|
||||
result := ppc_nor(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_OR =>
|
||||
result := ppc_or(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_ORC =>
|
||||
result := ppc_orc(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_POPCNTB =>
|
||||
result := ppc_popcntb(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_POPCNTW =>
|
||||
result := ppc_popcntw(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_POPCNTD =>
|
||||
result := ppc_popcntd(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_PRTYD =>
|
||||
result := ppc_prtyd(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_PRTYW =>
|
||||
result := ppc_prtyw(e.read_data1);
|
||||
result_en := 1;
|
||||
when OP_RLDCL =>
|
||||
result := ppc_rldcl(e.read_data1, e.read_data2, e.const2(5 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLDCR =>
|
||||
result := ppc_rldcr(e.read_data1, e.read_data2, e.const2(5 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLDICL =>
|
||||
result := ppc_rldicl(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLDICR =>
|
||||
result := ppc_rldicr(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLWNM =>
|
||||
result := ppc_rlwnm(e.read_data1, e.read_data2, e.const2(4 downto 0), e.const3(4 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLWINM =>
|
||||
result := ppc_rlwinm(e.read_data1, e.const1(4 downto 0), e.const2(4 downto 0), e.const3(4 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLDIC =>
|
||||
result := ppc_rldic(e.read_data1, e.const1(5 downto 0), e.const2(5 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLDIMI =>
|
||||
result := ppc_rldimi(e.read_data1, e.read_data2, e.const1(5 downto 0), e.const2(5 downto 0));
|
||||
result_en := 1;
|
||||
when OP_RLWIMI =>
|
||||
result := ppc_rlwimi(e.read_data1, e.read_data2, e.const1(4 downto 0), e.const2(4 downto 0), e.const3(4 downto 0));
|
||||
result_en := 1;
|
||||
when OP_SLD =>
|
||||
result := ppc_sld(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_SLW =>
|
||||
result := ppc_slw(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_SRAW =>
|
||||
result_with_carry := ppc_sraw(e.read_data1, e.read_data2);
|
||||
result := result_with_carry(63 downto 0);
|
||||
ctrl_tmp.carry <= result_with_carry(64);
|
||||
result_en := 1;
|
||||
when OP_SRAWI =>
|
||||
result_with_carry := ppc_srawi(e.read_data1, e.const1(5 downto 0));
|
||||
result := result_with_carry(63 downto 0);
|
||||
ctrl_tmp.carry <= result_with_carry(64);
|
||||
result_en := 1;
|
||||
when OP_SRAD =>
|
||||
result_with_carry := ppc_srad(e.read_data1, e.read_data2);
|
||||
result := result_with_carry(63 downto 0);
|
||||
ctrl_tmp.carry <= result_with_carry(64);
|
||||
result_en := 1;
|
||||
when OP_SRADI =>
|
||||
result_with_carry := ppc_sradi(e.read_data1, e.const1(5 downto 0));
|
||||
result := result_with_carry(63 downto 0);
|
||||
ctrl_tmp.carry <= result_with_carry(64);
|
||||
result_en := 1;
|
||||
when OP_SUBF =>
|
||||
result := ppc_subf(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
when OP_SUBFC =>
|
||||
result_with_carry := ppc_subfe(e.read_data1, e.read_data2, ctrl.carry or not(e.input_carry));
|
||||
result := result_with_carry(63 downto 0);
|
||||
ctrl_tmp.carry <= result_with_carry(64) and e.output_carry;
|
||||
result_en := 1;
|
||||
when OP_XOR =>
|
||||
result := ppc_xor(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
|
||||
-- sim console
|
||||
when OP_SIM_READ =>
|
||||
if SIM = true then
|
||||
sim_console_read(result);
|
||||
result_en := 1;
|
||||
else
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
end if;
|
||||
when OP_SIM_POLL =>
|
||||
if SIM = true then
|
||||
sim_console_poll(result);
|
||||
result_en := 1;
|
||||
else
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
end if;
|
||||
when OP_SIM_WRITE =>
|
||||
if SIM = true then
|
||||
sim_console_write(e.read_data1);
|
||||
else
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
end if;
|
||||
when OP_SIM_CONFIG =>
|
||||
if SIM = true then
|
||||
result := x"0000000000000001";
|
||||
else
|
||||
result := x"0000000000000000";
|
||||
end if;
|
||||
result_en := 1;
|
||||
|
||||
when OP_TDI =>
|
||||
-- Keep our test cases happy for now, ignore trap instructions
|
||||
report "OP_TDI FIXME";
|
||||
|
||||
when OP_DIVDU =>
|
||||
if SIM = true then
|
||||
result := ppc_divdu(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
else
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
end if;
|
||||
when OP_DIVD =>
|
||||
if SIM = true then
|
||||
result := ppc_divd(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
else
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
end if;
|
||||
when OP_DIVWU =>
|
||||
if SIM = true then
|
||||
result := ppc_divwu(e.read_data1, e.read_data2);
|
||||
result_en := 1;
|
||||
|
||||
else
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
end if;
|
||||
when others =>
|
||||
terminate_out <= '1';
|
||||
report "illegal";
|
||||
end case;
|
||||
|
||||
if e.lr = '1' then
|
||||
ctrl_tmp.lr <= std_ulogic_vector(unsigned(e.nia) + 4);
|
||||
end if;
|
||||
|
||||
if result_en = 1 then
|
||||
e_out.write_data <= result;
|
||||
e_out.write_enable <= '1';
|
||||
e_out.rc <= e.rc;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end architecture behaviour;
|
@ -0,0 +1,48 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.crhelpers.all;
|
||||
use work.ppc_fx_insns.all;
|
||||
|
||||
-- 2 cycle ALU
|
||||
-- We handle rc form instructions here
|
||||
|
||||
entity execute2 is
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
|
||||
e_in : in Execute1ToExecute2Type;
|
||||
e_out : out Execute2ToWritebackType
|
||||
);
|
||||
end execute2;
|
||||
|
||||
architecture behave of execute2 is
|
||||
signal e: Execute1ToExecute2Type;
|
||||
begin
|
||||
execute2_0: process(clk)
|
||||
begin
|
||||
if (rising_edge(clk)) then
|
||||
e <= e_in;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
execute2_1: process(all)
|
||||
begin
|
||||
e_out.valid <= e.valid;
|
||||
e_out.write_enable <= e.write_enable;
|
||||
e_out.write_reg <= e.write_reg;
|
||||
e_out.write_data <= e.write_data;
|
||||
e_out.write_cr_enable <= e.write_cr_enable;
|
||||
e_out.write_cr_mask <= e.write_cr_mask;
|
||||
e_out.write_cr_data <= e.write_cr_data;
|
||||
|
||||
if e.valid = '1' and e.rc = '1' then
|
||||
e_out.write_cr_enable <= '1';
|
||||
e_out.write_cr_mask <= num_to_fxm(0);
|
||||
e_out.write_cr_data <= ppc_cmpi('1', e.write_data, x"0000") & x"0000000";
|
||||
end if;
|
||||
end process;
|
||||
end;
|
@ -0,0 +1,78 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
|
||||
entity fetch1 is
|
||||
generic(
|
||||
RESET_ADDRESS : std_logic_vector(63 downto 0)
|
||||
);
|
||||
port(
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
|
||||
-- Control inputs:
|
||||
fetch_one_in : in std_ulogic;
|
||||
|
||||
-- redirect from execution unit
|
||||
e_in : in Execute1ToFetch1Type;
|
||||
|
||||
-- fetch data out
|
||||
f_out : out Fetch1ToFetch2Type
|
||||
);
|
||||
end entity fetch1;
|
||||
|
||||
architecture behaviour of fetch1 is
|
||||
type reg_type is record
|
||||
pc : std_ulogic_vector(63 downto 0);
|
||||
fetch_one : std_ulogic;
|
||||
end record;
|
||||
|
||||
signal r : reg_type;
|
||||
signal rin : reg_type;
|
||||
begin
|
||||
regs : process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
r <= rin;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
comb : process(all)
|
||||
variable v : reg_type;
|
||||
variable fetch_valid : std_ulogic;
|
||||
variable fetch_nia : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
v := r;
|
||||
|
||||
fetch_valid := '0';
|
||||
fetch_nia := (others => '0');
|
||||
|
||||
v.fetch_one := v.fetch_one or fetch_one_in;
|
||||
|
||||
if e_in.redirect = '1' then
|
||||
v.pc := e_in.redirect_nia;
|
||||
end if;
|
||||
|
||||
if v.fetch_one = '1' then
|
||||
fetch_nia := v.pc;
|
||||
fetch_valid := '1';
|
||||
v.pc := std_logic_vector(unsigned(v.pc) + 4);
|
||||
|
||||
v.fetch_one := '0';
|
||||
end if;
|
||||
|
||||
if rst = '1' then
|
||||
v.pc := RESET_ADDRESS;
|
||||
v.fetch_one := '0';
|
||||
end if;
|
||||
|
||||
rin <= v;
|
||||
|
||||
f_out.valid <= fetch_valid;
|
||||
f_out.nia <= fetch_nia;
|
||||
end process;
|
||||
|
||||
end architecture behaviour;
|
@ -0,0 +1,70 @@
|
||||
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 fetch2 is
|
||||
port(
|
||||
clk : in std_ulogic;
|
||||
|
||||
-- instruction memory interface
|
||||
wishbone_in : in wishbone_slave_out;
|
||||
wishbone_out : out wishbone_master_out;
|
||||
|
||||
f_in : in Fetch1ToFetch2Type;
|
||||
|
||||
f_out : out Fetch2ToDecode1Type
|
||||
);
|
||||
end entity fetch2;
|
||||
|
||||
architecture behaviour of fetch2 is
|
||||
type reg_type is record
|
||||
valid : std_ulogic;
|
||||
nia : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
signal f : Fetch1ToFetch2Type;
|
||||
signal wishbone: wishbone_slave_out;
|
||||
signal r : reg_type := (valid => '0', nia => (others => '0'));
|
||||
signal rin : reg_type := (valid => '0', nia => (others => '0'));
|
||||
begin
|
||||
regs : process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
wishbone <= wishbone_in;
|
||||
f <= f_in;
|
||||
r <= rin;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
comb : process(all)
|
||||
variable v : reg_type;
|
||||
begin
|
||||
v := r;
|
||||
|
||||
if f.valid = '1' then
|
||||
v.valid := '1';
|
||||
v.nia := f.nia;
|
||||
end if;
|
||||
|
||||
if v.valid = '1' and wishbone.ack = '1' then
|
||||
v.valid := '0';
|
||||
end if;
|
||||
|
||||
rin <= v;
|
||||
|
||||
wishbone_out.adr <= v.nia(63 downto 3) & "000";
|
||||
wishbone_out.dat <= (others => '0');
|
||||
wishbone_out.cyc <= v.valid;
|
||||
wishbone_out.stb <= v.valid;
|
||||
wishbone_out.sel <= "00001111" when v.nia(2) = '0' else "11110000";
|
||||
wishbone_out.we <= '0';
|
||||
|
||||
f_out.valid <= wishbone.ack;
|
||||
f_out.nia <= v.nia;
|
||||
f_out.insn <= wishbone.dat(31 downto 0) when v.nia(2) = '0' else wishbone.dat(63 downto 32);
|
||||
end process;
|
||||
end architecture behaviour;
|
@ -0,0 +1,12 @@
|
||||
Copyright (c) Kristian Klomsten Skordal
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -0,0 +1,10 @@
|
||||
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports clk]
|
||||
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk]
|
||||
|
||||
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS15} [get_ports reset_n]
|
||||
|
||||
set_property -dict {PACKAGE_PIN AA19 IOSTANDARD LVCMOS33} [get_ports uart0_txd]
|
||||
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports uart0_rxd]
|
||||
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property CFGBVS VCCO [current_design]
|
@ -0,0 +1,91 @@
|
||||
-- The Potato Processor - A simple processor for FPGAs
|
||||
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
--! @brief A generic FIFO module.
|
||||
--! Adopted from the FIFO module in <https://github.com/skordal/smallthings>.
|
||||
entity pp_fifo is
|
||||
generic(
|
||||
DEPTH : natural := 64;
|
||||
WIDTH : natural := 32
|
||||
);
|
||||
port(
|
||||
-- Control lines:
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
-- Status lines:
|
||||
full : out std_logic;
|
||||
empty : out std_logic;
|
||||
|
||||
-- Data in:
|
||||
data_in : in std_logic_vector(WIDTH - 1 downto 0);
|
||||
data_out : out std_logic_vector(WIDTH - 1 downto 0);
|
||||
push, pop : in std_logic
|
||||
);
|
||||
end entity pp_fifo;
|
||||
|
||||
architecture behaviour of pp_fifo is
|
||||
|
||||
type memory_array is array(0 to DEPTH - 1) of std_logic_vector(WIDTH - 1 downto 0);
|
||||
shared variable memory : memory_array := (others => (others => '0'));
|
||||
|
||||
subtype index_type is integer range 0 to DEPTH - 1;
|
||||
signal top, bottom : index_type;
|
||||
|
||||
type fifo_op is (FIFO_POP, FIFO_PUSH);
|
||||
signal prev_op : fifo_op := FIFO_POP;
|
||||
|
||||
begin
|
||||
|
||||
empty <= '1' when top = bottom and prev_op = FIFO_POP else '0';
|
||||
full <= '1' when top = bottom and prev_op = FIFO_PUSH else '0';
|
||||
|
||||
read: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
bottom <= 0;
|
||||
else
|
||||
if pop = '1' then
|
||||
data_out <= memory(bottom);
|
||||
bottom <= (bottom + 1) mod DEPTH;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process read;
|
||||
|
||||
write: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
top <= 0;
|
||||
else
|
||||
if push = '1' then
|
||||
memory(top) := data_in;
|
||||
top <= (top + 1) mod DEPTH;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process write;
|
||||
|
||||
set_prev_op: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
prev_op <= FIFO_POP;
|
||||
else
|
||||
if push = '1' and pop = '1' then
|
||||
prev_op <= FIFO_POP;
|
||||
elsif push = '1' then
|
||||
prev_op <= FIFO_PUSH;
|
||||
elsif pop = '1' then
|
||||
prev_op <= FIFO_POP;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process set_prev_op;
|
||||
|
||||
end architecture behaviour;
|
@ -0,0 +1,106 @@
|
||||
-- The Potato Processor - A simple processor for FPGAs
|
||||
-- (c) Kristian Klomsten Skordal 2014 - 2015 <kristian.skordal@wafflemail.net>
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
use work.pp_utilities.all;
|
||||
|
||||
--! @brief Simple memory module for use in Wishbone-based systems.
|
||||
entity pp_soc_memory is
|
||||
generic(
|
||||
MEMORY_SIZE : natural := 4096 --! Memory size in bytes.
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
-- Wishbone interface:
|
||||
wb_adr_in : in std_logic_vector(log2(MEMORY_SIZE) - 1 downto 0);
|
||||
wb_dat_in : in std_logic_vector(63 downto 0);
|
||||
wb_dat_out : out std_logic_vector(63 downto 0);
|
||||
wb_cyc_in : in std_logic;
|
||||
wb_stb_in : in std_logic;
|
||||
wb_sel_in : in std_logic_vector( 7 downto 0);
|
||||
wb_we_in : in std_logic;
|
||||
wb_ack_out : out std_logic
|
||||
);
|
||||
end entity pp_soc_memory;
|
||||
|
||||
architecture behaviour of pp_soc_memory is
|
||||
type ram_t is array(0 to (MEMORY_SIZE / 8) - 1) of std_logic_vector(63 downto 0);
|
||||
|
||||
impure function init_ram(name : STRING) return ram_t is
|
||||
file ram_file : text open read_mode is name;
|
||||
variable ram_line : line;
|
||||
variable temp_word : std_logic_vector(63 downto 0);
|
||||
variable temp_ram : ram_t := (others => (others => '0'));
|
||||
begin
|
||||
for i in 0 to (MEMORY_SIZE/8)-1 loop
|
||||
exit when endfile(ram_file);
|
||||
readline(ram_file, ram_line);
|
||||
hread(ram_line, temp_word);
|
||||
temp_ram(i) := temp_word;
|
||||
end loop;
|
||||
|
||||
return temp_ram;
|
||||
end function;
|
||||
|
||||
signal memory : ram_t := init_ram("firmware.hex");
|
||||
|
||||
attribute ram_style : string;
|
||||
attribute ram_style of memory : signal is "block";
|
||||
|
||||
attribute ram_decomp : string;
|
||||
attribute ram_decomp of memory : signal is "power";
|
||||
|
||||
type state_type is (IDLE, ACK);
|
||||
signal state : state_type;
|
||||
|
||||
signal read_ack : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
wb_ack_out <= read_ack and wb_stb_in;
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
read_ack <= '0';
|
||||
state <= IDLE;
|
||||
else
|
||||
if wb_cyc_in = '1' then
|
||||
case state is
|
||||
when IDLE =>
|
||||
if wb_stb_in = '1' and wb_we_in = '1' then
|
||||
for i in 0 to 7 loop
|
||||
if wb_sel_in(i) = '1' then
|
||||
memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3))))(((i + 1) * 8) - 1 downto i * 8)
|
||||
<= wb_dat_in(((i + 1) * 8) - 1 downto i * 8);
|
||||
end if;
|
||||
end loop;
|
||||
read_ack <= '1';
|
||||
state <= ACK;
|
||||
elsif wb_stb_in = '1' then
|
||||
wb_dat_out <= memory(to_integer(unsigned(wb_adr_in(wb_adr_in'left downto 3))));
|
||||
read_ack <= '1';
|
||||
state <= ACK;
|
||||
end if;
|
||||
when ACK =>
|
||||
if wb_stb_in = '0' then
|
||||
read_ack <= '0';
|
||||
state <= IDLE;
|
||||
end if;
|
||||
end case;
|
||||
else
|
||||
state <= IDLE;
|
||||
read_ack <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process clk;
|
||||
|
||||
end architecture behaviour;
|
@ -0,0 +1,69 @@
|
||||
-- The Potato Processor - A simple processor for FPGAs
|
||||
-- (c) Kristian Klomsten Skordal 2018 <kristian.skordal@wafflemail.net>
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use work.pp_utilities.all;
|
||||
|
||||
--! @brief System reset unit.
|
||||
--! Because most resets in the processor core are synchronous, at least one
|
||||
--! clock pulse has to be given to the processor while the reset signal is
|
||||
--! asserted. However, if the clock generator is being reset at the same time,
|
||||
--! the system clock might not run during reset, preventing the processor from
|
||||
--! properly resetting.
|
||||
entity pp_soc_reset is
|
||||
generic(
|
||||
RESET_CYCLE_COUNT : natural := 20000000
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
|
||||
reset_n : in std_logic;
|
||||
reset_out : out std_logic;
|
||||
|
||||
system_clk : in std_logic;
|
||||
system_clk_locked : in std_logic
|
||||
);
|
||||
end entity pp_soc_reset;
|
||||
|
||||
architecture behaviour of pp_soc_reset is
|
||||
|
||||
subtype counter_type is natural range 0 to RESET_CYCLE_COUNT;
|
||||
signal counter : counter_type;
|
||||
|
||||
signal fast_reset : std_logic := '0';
|
||||
signal slow_reset : std_logic := '1';
|
||||
begin
|
||||
|
||||
reset_out <= slow_reset;
|
||||
|
||||
-- process(clk)
|
||||
-- begin
|
||||
-- if rising_edge(clk) then
|
||||
-- if reset_n = '0' then
|
||||
-- fast_reset <= '1';
|
||||
-- elsif system_clk_locked = '1' then
|
||||
-- if fast_reset = '1' and slow_reset = '1' then
|
||||
-- fast_reset <= '0';
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end process;
|
||||
|
||||
process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
if reset_n = '0' then
|
||||
slow_reset <= '1';
|
||||
counter <= RESET_CYCLE_COUNT;
|
||||
else
|
||||
if counter = 0 then
|
||||
slow_reset <= '0';
|
||||
else
|
||||
counter <= counter - 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture behaviour;
|
@ -0,0 +1,384 @@
|
||||
-- The Potato Processor - A simple processor for FPGAs
|
||||
-- (c) Kristian Klomsten Skordal 2014 - 2016 <kristian.skordal@wafflemail.net>
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
--! @brief Simple UART module.
|
||||
--! The following registers are defined:
|
||||
--! |--------------------|--------------------------------------------|
|
||||
--! | Address | Description |
|
||||
--! |--------------------|--------------------------------------------|
|
||||
--! | 0x00 | Transmit register (write-only) |
|
||||
--! | 0x08 | Receive register (read-only) |
|
||||
--! | 0x10 | Status register (read-only) |
|
||||
--! | 0x18 | Sample clock divisor register (read/write) |
|
||||
--! | 0x20 | Interrupt enable register (read/write) |
|
||||
--! |--------------------|--------------------------------------------|
|
||||
--!
|
||||
--! The status register contains the following bits:
|
||||
--! - Bit 0: receive buffer empty
|
||||
--! - Bit 1: transmit buffer empty
|
||||
--! - Bit 2: receive buffer full
|
||||
--! - Bit 3: transmit buffer full
|
||||
--!
|
||||
--! The sample clock divisor should be set according to the formula:
|
||||
--! sample_clk = (f_clk / (baudrate * 16)) - 1
|
||||
--!
|
||||
--! If the sample clock divisor register is set to 0, the sample clock
|
||||
--! is stopped.
|
||||
--!
|
||||
--! Interrupts are enabled by setting the corresponding bit in the interrupt
|
||||
--! enable register. The following bits are available:
|
||||
--! - Bit 0: data received (receive buffer not empty)
|
||||
--! - Bit 1: ready to send data (transmit buffer empty)
|
||||
entity pp_soc_uart is
|
||||
generic(
|
||||
FIFO_DEPTH : natural := 64 --! Depth of the input and output FIFOs.
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
-- UART ports:
|
||||
txd : out std_logic;
|
||||
rxd : in std_logic;
|
||||
|
||||
-- Interrupt signal:
|
||||
irq : out std_logic;
|
||||
|
||||
-- Wishbone ports:
|
||||
wb_adr_in : in std_logic_vector(11 downto 0);
|
||||
wb_dat_in : in std_logic_vector( 7 downto 0);
|
||||
wb_dat_out : out std_logic_vector( 7 downto 0);
|
||||
wb_we_in : in std_logic;
|
||||
wb_cyc_in : in std_logic;
|
||||
wb_stb_in : in std_logic;
|
||||
wb_ack_out : out std_logic
|
||||
);
|
||||
end entity pp_soc_uart;
|
||||
|
||||
architecture behaviour of pp_soc_uart is
|
||||
|
||||
subtype bitnumber is natural range 0 to 7; --! Type representing the index of a bit.
|
||||
|
||||
-- UART sample clock signals:
|
||||
signal sample_clk : std_logic;
|
||||
signal sample_clk_divisor : std_logic_vector(7 downto 0);
|
||||
signal sample_clk_counter : std_logic_vector(sample_clk_divisor'range);
|
||||
|
||||
-- UART receive process signals:
|
||||
type rx_state_type is (IDLE, RECEIVE, STARTBIT, STOPBIT);
|
||||
signal rx_state : rx_state_type;
|
||||
signal rx_byte : std_logic_vector(7 downto 0);
|
||||
signal rx_current_bit : bitnumber;
|
||||
|
||||
subtype rx_sample_counter_type is natural range 0 to 15;
|
||||
signal rx_sample_counter : rx_sample_counter_type;
|
||||
signal rx_sample_value : rx_sample_counter_type;
|
||||
|
||||
subtype rx_sample_delay_type is natural range 0 to 7;
|
||||
signal rx_sample_delay : rx_sample_delay_type;
|
||||
|
||||
-- UART transmit process signals:
|
||||
type tx_state_type is (IDLE, TRANSMIT, STOPBIT);
|
||||
signal tx_state : tx_state_type;
|
||||
signal tx_byte : std_logic_vector(7 downto 0);
|
||||
signal tx_current_bit : bitnumber;
|
||||
|
||||
-- UART transmit clock:
|
||||
subtype uart_tx_counter_type is natural range 0 to 15;
|
||||
signal uart_tx_counter : uart_tx_counter_type := 0;
|
||||
signal uart_tx_clk : std_logic;
|
||||
|
||||
-- Buffer signals:
|
||||
signal send_buffer_full, send_buffer_empty : std_logic;
|
||||
signal recv_buffer_full, recv_buffer_empty : std_logic;
|
||||
signal send_buffer_input, send_buffer_output : std_logic_vector(7 downto 0);
|
||||
signal recv_buffer_input, recv_buffer_output : std_logic_vector(7 downto 0);
|
||||
signal send_buffer_push, send_buffer_pop : std_logic := '0';
|
||||
signal recv_buffer_push, recv_buffer_pop : std_logic := '0';
|
||||
|
||||
-- IRQ enable signals:
|
||||
signal irq_recv_enable, irq_tx_ready_enable : std_logic := '0';
|
||||
|
||||
-- Wishbone signals:
|
||||
type wb_state_type is (IDLE, WRITE_ACK, READ_ACK);
|
||||
signal wb_state : wb_state_type;
|
||||
|
||||
signal wb_ack : std_logic; --! Wishbone acknowledge signal
|
||||
|
||||
begin
|
||||
|
||||
irq <= (irq_recv_enable and (not recv_buffer_empty))
|
||||
or (irq_tx_ready_enable and send_buffer_empty);
|
||||
|
||||
---------- UART receive ----------
|
||||
|
||||
recv_buffer_input <= rx_byte;
|
||||
|
||||
uart_receive: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
rx_state <= IDLE;
|
||||
recv_buffer_push <= '0';
|
||||
else
|
||||
case rx_state is
|
||||
when IDLE =>
|
||||
if recv_buffer_push = '1' then
|
||||
recv_buffer_push <= '0';
|
||||
end if;
|
||||
|
||||
if sample_clk = '1' and rxd = '0' then
|
||||
rx_sample_value <= rx_sample_counter;
|
||||
rx_sample_delay <= 0;
|
||||
rx_current_bit <= 0;
|
||||
rx_state <= STARTBIT;
|
||||
end if;
|
||||
when STARTBIT =>
|
||||
if sample_clk = '1' then
|
||||
if rx_sample_delay = 7 then
|
||||
rx_state <= RECEIVE;
|
||||
rx_sample_value <= rx_sample_counter;
|
||||
rx_sample_delay <= 0;
|
||||
else
|
||||
rx_sample_delay <= rx_sample_delay + 1;
|
||||
end if;
|
||||
end if;
|
||||
when RECEIVE =>
|
||||
if sample_clk = '1' and rx_sample_counter = rx_sample_value then
|
||||
if rx_current_bit /= 7 then
|
||||
rx_byte(rx_current_bit) <= rxd;
|
||||
rx_current_bit <= rx_current_bit + 1;
|
||||
else
|
||||
rx_byte(rx_current_bit) <= rxd;
|
||||
rx_state <= STOPBIT;
|
||||
end if;
|
||||
end if;
|
||||
when STOPBIT =>
|
||||
if sample_clk = '1' and rx_sample_counter = rx_sample_value then
|
||||
rx_state <= IDLE;
|
||||
|
||||
if recv_buffer_full = '0' then
|
||||
recv_buffer_push <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process uart_receive;
|
||||
|
||||
sample_counter: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
rx_sample_counter <= 0;
|
||||
elsif sample_clk = '1' then
|
||||
if rx_sample_counter = 15 then
|
||||
rx_sample_counter <= 0;
|
||||
else
|
||||
rx_sample_counter <= rx_sample_counter + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process sample_counter;
|
||||
|
||||
---------- UART transmit ----------
|
||||
|
||||
tx_byte <= send_buffer_output;
|
||||
|
||||
uart_transmit: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
txd <= '1';
|
||||
tx_state <= IDLE;
|
||||
send_buffer_pop <= '0';
|
||||
tx_current_bit <= 0;
|
||||
else
|
||||
case tx_state is
|
||||
when IDLE =>
|
||||
if send_buffer_empty = '0' and uart_tx_clk = '1' then
|
||||
txd <= '0';
|
||||
send_buffer_pop <= '1';
|
||||
tx_current_bit <= 0;
|
||||
tx_state <= TRANSMIT;
|
||||
elsif uart_tx_clk = '1' then
|
||||
txd <= '1';
|
||||
end if;
|
||||
when TRANSMIT =>
|
||||
if send_buffer_pop = '1' then
|
||||
send_buffer_pop <= '0';
|
||||
elsif uart_tx_clk = '1' and tx_current_bit = 7 then
|
||||
txd <= tx_byte(tx_current_bit);
|
||||
tx_state <= STOPBIT;
|
||||
elsif uart_tx_clk = '1' then
|
||||
txd <= tx_byte(tx_current_bit);
|
||||
tx_current_bit <= tx_current_bit + 1;
|
||||
end if;
|
||||
when STOPBIT =>
|
||||
if uart_tx_clk = '1' then
|
||||
txd <= '1';
|
||||
tx_state <= IDLE;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process uart_transmit;
|
||||
|
||||
uart_tx_clock_generator: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
uart_tx_counter <= 0;
|
||||
uart_tx_clk <= '0';
|
||||
else
|
||||
if sample_clk = '1' then
|
||||
if uart_tx_counter = 15 then
|
||||
uart_tx_counter <= 0;
|
||||
uart_tx_clk <= '1';
|
||||
else
|
||||
uart_tx_counter <= uart_tx_counter + 1;
|
||||
uart_tx_clk <= '0';
|
||||
end if;
|
||||
else
|
||||
uart_tx_clk <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process uart_tx_clock_generator;
|
||||
|
||||
---------- Sample clock generator ----------
|
||||
|
||||
sample_clock_generator: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
sample_clk_counter <= (others => '0');
|
||||
sample_clk <= '0';
|
||||
else
|
||||
if sample_clk_divisor /= x"00" then
|
||||
if sample_clk_counter = sample_clk_divisor then
|
||||
sample_clk_counter <= (others => '0');
|
||||
sample_clk <= '1';
|
||||
else
|
||||
sample_clk_counter <= std_logic_vector(unsigned(sample_clk_counter) + 1);
|
||||
sample_clk <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process sample_clock_generator;
|
||||
|
||||
---------- Data Buffers ----------
|
||||
|
||||
send_buffer: entity work.pp_fifo
|
||||
generic map(
|
||||
DEPTH => FIFO_DEPTH,
|
||||
WIDTH => 8
|
||||
) port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
full => send_buffer_full,
|
||||
empty => send_buffer_empty,
|
||||
data_in => send_buffer_input,
|
||||
data_out => send_buffer_output,
|
||||
push => send_buffer_push,
|
||||
pop => send_buffer_pop
|
||||
);
|
||||
|
||||
recv_buffer: entity work.pp_fifo
|
||||
generic map(
|
||||
DEPTH => FIFO_DEPTH,
|
||||
WIDTH => 8
|
||||
) port map(
|
||||
clk => clk,
|
||||
reset => reset,
|
||||
full => recv_buffer_full,
|
||||
empty => recv_buffer_empty,
|
||||
data_in => recv_buffer_input,
|
||||
data_out => recv_buffer_output,
|
||||
push => recv_buffer_push,
|
||||
pop => recv_buffer_pop
|
||||
);
|
||||
|
||||
---------- Wishbone Interface ----------
|
||||
|
||||
wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in;
|
||||
|
||||
wishbone: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if reset = '1' then
|
||||
wb_ack <= '0';
|
||||
wb_state <= IDLE;
|
||||
send_buffer_push <= '0';
|
||||
recv_buffer_pop <= '0';
|
||||
sample_clk_divisor <= (others => '0');
|
||||
irq_recv_enable <= '0';
|
||||
irq_tx_ready_enable <= '0';
|
||||
else
|
||||
case wb_state is
|
||||
when IDLE =>
|
||||
if wb_cyc_in = '1' and wb_stb_in = '1' then
|
||||
if wb_we_in = '1' then -- Write to register
|
||||
if wb_adr_in = x"000" then
|
||||
send_buffer_input <= wb_dat_in;
|
||||
send_buffer_push <= '1';
|
||||
elsif wb_adr_in = x"018" then
|
||||
sample_clk_divisor <= wb_dat_in;
|
||||
elsif wb_adr_in = x"020" then
|
||||
irq_recv_enable <= wb_dat_in(0);
|
||||
irq_tx_ready_enable <= wb_dat_in(1);
|
||||
end if;
|
||||
|
||||
-- Invalid writes are acked and ignored.
|
||||
|
||||
wb_ack <= '1';
|
||||
wb_state <= WRITE_ACK;
|
||||
else -- Read from register
|
||||
if wb_adr_in = x"008" then
|
||||
recv_buffer_pop <= '1';
|
||||
elsif wb_adr_in = x"010" then
|
||||
wb_dat_out <= x"0" & send_buffer_full & recv_buffer_full & send_buffer_empty & recv_buffer_empty;
|
||||
wb_ack <= '1';
|
||||
elsif wb_adr_in = x"018" then
|
||||
wb_dat_out <= sample_clk_divisor;
|
||||
wb_ack <= '1';
|
||||
elsif wb_adr_in = x"020" then
|
||||
wb_dat_out <= (0 => irq_recv_enable, 1 => irq_tx_ready_enable, others => '0');
|
||||
wb_ack <= '1';
|
||||
else
|
||||
wb_dat_out <= (others => '0');
|
||||
wb_ack <= '1';
|
||||
end if;
|
||||
wb_state <= READ_ACK;
|
||||
end if;
|
||||
end if;
|
||||
when WRITE_ACK =>
|
||||
send_buffer_push <= '0';
|
||||
|
||||
if wb_stb_in = '0' then
|
||||
wb_ack <= '0';
|
||||
wb_state <= IDLE;
|
||||
end if;
|
||||
when READ_ACK =>
|
||||
if recv_buffer_pop = '1' then
|
||||
recv_buffer_pop <= '0';
|
||||
else
|
||||
wb_dat_out <= recv_buffer_output;
|
||||
wb_ack <= '1';
|
||||
end if;
|
||||
|
||||
if wb_stb_in = '0' then
|
||||
wb_ack <= '0';
|
||||
wb_state <= IDLE;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process wishbone;
|
||||
|
||||
end architecture behaviour;
|
@ -0,0 +1,90 @@
|
||||
-- The Potato Processor - A simple processor for FPGAs
|
||||
-- (c) Kristian Klomsten Skordal 2014 <kristian.skordal@wafflemail.net>
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package pp_utilities is
|
||||
|
||||
--! Converts a boolean to an std_logic.
|
||||
function to_std_logic(input : in boolean) return std_logic;
|
||||
|
||||
-- Checks if a number is 2^n:
|
||||
function is_pow2(input : in natural) return boolean;
|
||||
|
||||
--! Calculates log2 with integers.
|
||||
function log2(input : in natural) return natural;
|
||||
|
||||
-- Gets the value of the sel signals to the wishbone interconnect for the specified
|
||||
-- operand size and address.
|
||||
function wb_get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector)
|
||||
return std_logic_vector;
|
||||
|
||||
end package pp_utilities;
|
||||
|
||||
package body pp_utilities is
|
||||
|
||||
function to_std_logic(input : in boolean) return std_logic is
|
||||
begin
|
||||
if input then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end function to_std_logic;
|
||||
|
||||
function is_pow2(input : in natural) return boolean is
|
||||
variable c : natural := 1;
|
||||
begin
|
||||
for i in 0 to 31 loop
|
||||
if input = c then
|
||||
return true;
|
||||
end if;
|
||||
|
||||
c := c * 2;
|
||||
end loop;
|
||||
|
||||
return false;
|
||||
end function is_pow2;
|
||||
|
||||
function log2(input : in natural) return natural is
|
||||
variable retval : natural := 0;
|
||||
variable temp : natural := input;
|
||||
begin
|
||||
while temp > 1 loop
|
||||
retval := retval + 1;
|
||||
temp := temp / 2;
|
||||
end loop;
|
||||
|
||||
return retval;
|
||||
end function log2;
|
||||
|
||||
function wb_get_data_sel(size : in std_logic_vector(1 downto 0); address : in std_logic_vector)
|
||||
return std_logic_vector is
|
||||
begin
|
||||
case size is
|
||||
when b"01" =>
|
||||
case address(1 downto 0) is
|
||||
when b"00" =>
|
||||
return b"0001";
|
||||
when b"01" =>
|
||||
return b"0010";
|
||||
when b"10" =>
|
||||
return b"0100";
|
||||
when b"11" =>
|
||||
return b"1000";
|
||||
when others =>
|
||||
return b"0001";
|
||||
end case;
|
||||
when b"10" =>
|
||||
if address(1) = '0' then
|
||||
return b"0011";
|
||||
else
|
||||
return b"1100";
|
||||
end if;
|
||||
when others =>
|
||||
return b"1111";
|
||||
end case;
|
||||
end function wb_get_data_sel;
|
||||
|
||||
end package body pp_utilities;
|
@ -0,0 +1,213 @@
|
||||
-- The Potato Processor - SoC design for the Arty FPGA board
|
||||
-- (c) Kristian Klomsten Skordal 2016 <kristian.skordal@wafflemail.net>
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
-- 0x00000000: Main memory (1 MB)
|
||||
-- 0xc0002000: UART0 (for host communication)
|
||||
entity toplevel is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
reset_n : in std_logic;
|
||||
|
||||
-- UART0 signals:
|
||||
uart0_txd : out std_logic;
|
||||
uart0_rxd : in std_logic
|
||||
);
|
||||
end entity toplevel;
|
||||
|
||||
architecture behaviour of toplevel is
|
||||
|
||||
-- Reset signals:
|
||||
signal reset : std_logic;
|
||||
|
||||
-- Internal clock signals:
|
||||
signal system_clk : std_logic;
|
||||
signal timer_clk : std_logic;
|
||||
signal system_clk_locked : std_logic;
|
||||
|
||||
-- wishbone signals:
|
||||
signal wishbone_proc_out: wishbone_master_out;
|
||||
signal wishbone_proc_in: wishbone_slave_out;
|
||||
|
||||
-- Processor signals:
|
||||
signal processor_adr_out : std_logic_vector(63 downto 0);
|
||||
signal processor_sel_out : std_logic_vector(7 downto 0);
|
||||
signal processor_cyc_out : std_logic;
|
||||
signal processor_stb_out : std_logic;
|
||||
signal processor_we_out : std_logic;
|
||||
signal processor_dat_out : std_logic_vector(63 downto 0);
|
||||
signal processor_dat_in : std_logic_vector(63 downto 0);
|
||||
signal processor_ack_in : std_logic;
|
||||
|
||||
-- UART0 signals:
|
||||
signal uart0_adr_in : std_logic_vector(11 downto 0);
|
||||
signal uart0_dat_in : std_logic_vector( 7 downto 0);
|
||||
signal uart0_dat_out : std_logic_vector( 7 downto 0);
|
||||
signal uart0_cyc_in : std_logic;
|
||||
signal uart0_stb_in : std_logic;
|
||||
signal uart0_we_in : std_logic;
|
||||
signal uart0_ack_out : std_logic;
|
||||
|
||||
-- Main memory signals:
|
||||
signal main_memory_adr_in : std_logic_vector(19 downto 0);
|
||||
signal main_memory_dat_in : std_logic_vector(63 downto 0);
|
||||
signal main_memory_dat_out : std_logic_vector(63 downto 0);
|
||||
signal main_memory_cyc_in : std_logic;
|
||||
signal main_memory_stb_in : std_logic;
|
||||
signal main_memory_sel_in : std_logic_vector(7 downto 0);
|
||||
signal main_memory_we_in : std_logic;
|
||||
signal main_memory_ack_out : std_logic;
|
||||
|
||||
-- Selected peripheral on the interconnect:
|
||||
type intercon_peripheral_type is (
|
||||
PERIPHERAL_UART0, PERIPHERAL_MAIN_MEMORY, PERIPHERAL_ERROR,
|
||||
PERIPHERAL_NONE);
|
||||
signal intercon_peripheral : intercon_peripheral_type := PERIPHERAL_NONE;
|
||||
|
||||
-- Interconnect address decoder state:
|
||||
signal intercon_busy : boolean := false;
|
||||
|
||||
-- disable for now
|
||||
signal gpio_pins : std_logic_vector(11 downto 0);
|
||||
signal uart1_txd : std_logic;
|
||||
signal uart1_rxd : std_logic;
|
||||
begin
|
||||
|
||||
address_decoder: process(system_clk)
|
||||
begin
|
||||
if rising_edge(system_clk) then
|
||||
if reset = '1' then
|
||||
intercon_peripheral <= PERIPHERAL_NONE;
|
||||
intercon_busy <= false;
|
||||
else
|
||||
if not intercon_busy then
|
||||
if processor_cyc_out = '1' then
|
||||
intercon_busy <= true;
|
||||
|
||||
if processor_adr_out(31 downto 24) = x"00" then -- Main memory space
|
||||
intercon_peripheral <= PERIPHERAL_MAIN_MEMORY;
|
||||
elsif processor_adr_out(31 downto 24) = x"c0" then -- Peripheral memory space
|
||||
case processor_adr_out(15 downto 12) is
|
||||
when x"2" =>
|
||||
intercon_peripheral <= PERIPHERAL_UART0;
|
||||
when others => -- Invalid address - delegated to the error peripheral
|
||||
intercon_peripheral <= PERIPHERAL_ERROR;
|
||||
end case;
|
||||
else
|
||||
intercon_peripheral <= PERIPHERAL_ERROR;
|
||||
end if;
|
||||
else
|
||||
intercon_peripheral <= PERIPHERAL_NONE;
|
||||
end if;
|
||||
else
|
||||
if processor_cyc_out = '0' then
|
||||
intercon_busy <= false;
|
||||
intercon_peripheral <= PERIPHERAL_NONE;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process address_decoder;
|
||||
|
||||
processor_intercon: process(all)
|
||||
begin
|
||||
case intercon_peripheral is
|
||||
when PERIPHERAL_UART0 =>
|
||||
processor_ack_in <= uart0_ack_out;
|
||||
processor_dat_in <= x"00000000000000" & uart0_dat_out;
|
||||
when PERIPHERAL_MAIN_MEMORY =>
|
||||
processor_ack_in <= main_memory_ack_out;
|
||||
processor_dat_in <= main_memory_dat_out;
|
||||
when PERIPHERAL_NONE =>
|
||||
processor_ack_in <= '0';
|
||||
processor_dat_in <= (others => '0');
|
||||
when others =>
|
||||
processor_ack_in <= '0';
|
||||
processor_dat_in <= (others => '0');
|
||||
end case;
|
||||
end process processor_intercon;
|
||||
|
||||
reset_controller: entity work.pp_soc_reset
|
||||
port map(
|
||||
clk => system_clk,
|
||||
reset_n => reset_n,
|
||||
reset_out => reset,
|
||||
system_clk => system_clk,
|
||||
system_clk_locked => system_clk_locked
|
||||
);
|
||||
|
||||
clkgen: entity work.clock_generator
|
||||
port map(
|
||||
clk => clk,
|
||||
resetn => reset_n,
|
||||
system_clk => system_clk,
|
||||
locked => system_clk_locked
|
||||
);
|
||||
|
||||
processor: entity work.core
|
||||
port map(
|
||||
clk => system_clk,
|
||||
rst => reset,
|
||||
|
||||
wishbone_out => wishbone_proc_out,
|
||||
wishbone_in => wishbone_proc_in
|
||||
);
|
||||
processor_adr_out <= wishbone_proc_out.adr;
|
||||
processor_dat_out <= wishbone_proc_out.dat;
|
||||
processor_sel_out <= wishbone_proc_out.sel;
|
||||
processor_cyc_out <= wishbone_proc_out.cyc;
|
||||
processor_stb_out <= wishbone_proc_out.stb;
|
||||
processor_we_out <= wishbone_proc_out.we;
|
||||
wishbone_proc_in.dat <= processor_dat_in;
|
||||
wishbone_proc_in.ack <= processor_ack_in;
|
||||
|
||||
uart0: entity work.pp_soc_uart
|
||||
generic map(
|
||||
FIFO_DEPTH => 32
|
||||
) port map(
|
||||
clk => system_clk,
|
||||
reset => reset,
|
||||
txd => uart0_txd,
|
||||
rxd => uart0_rxd,
|
||||
wb_adr_in => uart0_adr_in,
|
||||
wb_dat_in => uart0_dat_in,
|
||||
wb_dat_out => uart0_dat_out,
|
||||
wb_cyc_in => uart0_cyc_in,
|
||||
wb_stb_in => uart0_stb_in,
|
||||
wb_we_in => uart0_we_in,
|
||||
wb_ack_out => uart0_ack_out
|
||||
);
|
||||
uart0_adr_in <= processor_adr_out(uart0_adr_in'range);
|
||||
uart0_dat_in <= processor_dat_out(7 downto 0);
|
||||
uart0_we_in <= processor_we_out;
|
||||
uart0_cyc_in <= processor_cyc_out when intercon_peripheral = PERIPHERAL_UART0 else '0';
|
||||
uart0_stb_in <= processor_stb_out when intercon_peripheral = PERIPHERAL_UART0 else '0';
|
||||
|
||||
main_memory: entity work.pp_soc_memory
|
||||
generic map(
|
||||
MEMORY_SIZE => 1048576
|
||||
) port map(
|
||||
clk => system_clk,
|
||||
reset => reset,
|
||||
wb_adr_in => main_memory_adr_in,
|
||||
wb_dat_in => main_memory_dat_in,
|
||||
wb_dat_out => main_memory_dat_out,
|
||||
wb_cyc_in => main_memory_cyc_in,
|
||||
wb_stb_in => main_memory_stb_in,
|
||||
wb_sel_in => main_memory_sel_in,
|
||||
wb_we_in => main_memory_we_in,
|
||||
wb_ack_out => main_memory_ack_out
|
||||
);
|
||||
main_memory_adr_in <= processor_adr_out(main_memory_adr_in'range);
|
||||
main_memory_dat_in <= processor_dat_out;
|
||||
main_memory_we_in <= processor_we_out;
|
||||
main_memory_sel_in <= processor_sel_out;
|
||||
main_memory_cyc_in <= processor_cyc_out when intercon_peripheral = PERIPHERAL_MAIN_MEMORY else '0';
|
||||
main_memory_stb_in <= processor_stb_out when intercon_peripheral = PERIPHERAL_MAIN_MEMORY else '0';
|
||||
|
||||
end architecture behaviour;
|
@ -0,0 +1,38 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.glibc_random_helpers.all;
|
||||
|
||||
package glibc_random is
|
||||
function pseudorand(a: integer) return std_ulogic_vector;
|
||||
function pseudorand1 return std_ulogic;
|
||||
end package glibc_random;
|
||||
|
||||
package body glibc_random is
|
||||
function pseudorand(a: integer) return std_ulogic_vector is
|
||||
variable tmp1, tmp2, tmp3, tmp4: std_ulogic_vector(31 downto 0);
|
||||
variable ret: std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
tmp1 := std_ulogic_vector(to_unsigned(random, 32));
|
||||
tmp2 := std_ulogic_vector(to_unsigned(random, 32));
|
||||
if a <= 32 then
|
||||
ret := tmp1 & tmp2;
|
||||
else
|
||||
tmp3 := std_ulogic_vector(to_unsigned(random, 32));
|
||||
tmp4 := std_ulogic_vector(to_unsigned(random, 32));
|
||||
|
||||
ret := tmp1(15 downto 0) & tmp2(15 downto 0) & tmp3(15 downto 0) & tmp4(15 downto 0);
|
||||
end if;
|
||||
|
||||
return ret((a-1) downto 0);
|
||||
end;
|
||||
|
||||
function pseudorand1 return std_ulogic is
|
||||
variable tmp: std_ulogic_vector(31 downto 0);
|
||||
begin
|
||||
tmp := std_ulogic_vector(to_unsigned(random, 32));
|
||||
return tmp(0);
|
||||
end;
|
||||
end package body glibc_random;
|
@ -0,0 +1,19 @@
|
||||
package glibc_random_helpers is
|
||||
procedure srand (v : integer);
|
||||
attribute foreign of srand : procedure is "VHPIDIRECT srand";
|
||||
|
||||
function random return integer;
|
||||
attribute foreign of random : function is "VHPIDIRECT random";
|
||||
end glibc_random_helpers;
|
||||
|
||||
package body glibc_random_helpers is
|
||||
procedure srand (v : integer) is
|
||||
begin
|
||||
assert false severity failure;
|
||||
end srand;
|
||||
|
||||
function random return integer is
|
||||
begin
|
||||
assert false severity failure;
|
||||
end random;
|
||||
end glibc_random_helpers;
|
@ -0,0 +1,209 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
|
||||
package helpers is
|
||||
function fls_32 (val: std_ulogic_vector(31 downto 0)) return integer;
|
||||
function ffs_32 (val: std_ulogic_vector(31 downto 0)) return integer;
|
||||
|
||||
function fls_64 (val: std_ulogic_vector(63 downto 0)) return integer;
|
||||
function ffs_64 (val: std_ulogic_vector(63 downto 0)) return integer;
|
||||
|
||||
function popcnt8(val: std_ulogic_vector(7 downto 0)) return std_ulogic_vector;
|
||||
function popcnt32(val: std_ulogic_vector(31 downto 0)) return std_ulogic_vector;
|
||||
function popcnt64(val: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function cmp_one_byte(a, b: std_ulogic_vector(7 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_signed_compare(a, b: signed(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_unsigned_compare(a, b: unsigned(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ra_or_zero(ra: std_ulogic_vector(63 downto 0); reg: std_ulogic_vector(4 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function byte_reverse(val: std_ulogic_vector(63 downto 0); size: integer) return std_ulogic_vector;
|
||||
|
||||
function sign_extend(val: std_ulogic_vector(63 downto 0); size: natural) return std_ulogic_vector;
|
||||
end package helpers;
|
||||
|
||||
package body helpers is
|
||||
function fls_32 (val: std_ulogic_vector(31 downto 0)) return integer is
|
||||
variable ret: integer;
|
||||
begin
|
||||
ret := 32;
|
||||
for i in val'range loop
|
||||
if val(i) = '1' then
|
||||
ret := 31 - i;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ffs_32 (val: std_ulogic_vector(31 downto 0)) return integer is
|
||||
variable ret: integer;
|
||||
begin
|
||||
ret := 32;
|
||||
for i in val'reverse_range loop
|
||||
if val(i) = '1' then
|
||||
ret := i;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function fls_64 (val: std_ulogic_vector(63 downto 0)) return integer is
|
||||
variable ret: integer;
|
||||
begin
|
||||
ret := 64;
|
||||
for i in val'range loop
|
||||
if val(i) = '1' then
|
||||
ret := 63 - i;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ffs_64 (val: std_ulogic_vector(63 downto 0)) return integer is
|
||||
variable ret: integer;
|
||||
begin
|
||||
ret := 64;
|
||||
for i in val'reverse_range loop
|
||||
if val(i) = '1' then
|
||||
ret := i;
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function popcnt8(val: std_ulogic_vector(7 downto 0)) return std_ulogic_vector is
|
||||
variable ret: unsigned(3 downto 0) := (others => '0');
|
||||
begin
|
||||
for i in val'range loop
|
||||
ret := ret + ("000" & val(i));
|
||||
end loop;
|
||||
|
||||
return std_ulogic_vector(resize(ret, val'length));
|
||||
end;
|
||||
|
||||
function popcnt32(val: std_ulogic_vector(31 downto 0)) return std_ulogic_vector is
|
||||
variable ret: unsigned(5 downto 0) := (others => '0');
|
||||
begin
|
||||
for i in val'range loop
|
||||
ret := ret + ("00000" & val(i));
|
||||
end loop;
|
||||
|
||||
return std_ulogic_vector(resize(ret, val'length));
|
||||
end;
|
||||
|
||||
function popcnt64(val: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable ret: unsigned(6 downto 0) := (others => '0');
|
||||
begin
|
||||
for i in val'range loop
|
||||
ret := ret + ("000000" & val(i));
|
||||
end loop;
|
||||
|
||||
return std_ulogic_vector(resize(ret, val'length));
|
||||
end;
|
||||
|
||||
function cmp_one_byte(a, b: std_ulogic_vector(7 downto 0)) return std_ulogic_vector is
|
||||
variable ret: std_ulogic_vector(7 downto 0);
|
||||
begin
|
||||
if a = b then
|
||||
ret := x"ff";
|
||||
else
|
||||
ret := x"00";
|
||||
end if;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ppc_signed_compare(a, b: signed(63 downto 0)) return std_ulogic_vector is
|
||||
variable ret: std_ulogic_vector(3 downto 0);
|
||||
begin
|
||||
if a < b then
|
||||
ret := "1000";
|
||||
elsif a > b then
|
||||
ret := "0100";
|
||||
else
|
||||
ret := "0010";
|
||||
end if;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ppc_unsigned_compare(a, b: unsigned(63 downto 0)) return std_ulogic_vector is
|
||||
variable ret: std_ulogic_vector(3 downto 0);
|
||||
begin
|
||||
if a < b then
|
||||
ret := "1000";
|
||||
elsif a > b then
|
||||
ret := "0100";
|
||||
else
|
||||
ret := "0010";
|
||||
end if;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ra_or_zero(ra: std_ulogic_vector(63 downto 0); reg: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
if to_integer(unsigned(reg)) = 0 then
|
||||
return x"0000000000000000";
|
||||
else
|
||||
return ra;
|
||||
end if;
|
||||
end;
|
||||
|
||||
function byte_reverse(val: std_ulogic_vector(63 downto 0); size: integer) return std_ulogic_vector is
|
||||
variable ret : std_ulogic_vector(63 downto 0) := (others => '0');
|
||||
begin
|
||||
-- Vivado doesn't support non constant vector slices, so we have to code
|
||||
-- each of these.
|
||||
case_0: case size is
|
||||
when 2 =>
|
||||
for_2 : for k in 0 to 1 loop
|
||||
ret(((8*k)+7) downto (8*k)) := val((8*(1-k)+7) downto (8*(1-k)));
|
||||
end loop;
|
||||
when 4 =>
|
||||
for_4 : for k in 0 to 3 loop
|
||||
ret(((8*k)+7) downto (8*k)) := val((8*(3-k)+7) downto (8*(3-k)));
|
||||
end loop;
|
||||
when 8 =>
|
||||
for_8 : for k in 0 to 7 loop
|
||||
ret(((8*k)+7) downto (8*k)) := val((8*(7-k)+7) downto (8*(7-k)));
|
||||
end loop;
|
||||
when others =>
|
||||
report "bad byte reverse length " & integer'image(size) severity failure;
|
||||
end case;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function sign_extend(val: std_ulogic_vector(63 downto 0); size: natural) return std_ulogic_vector is
|
||||
variable ret : signed(63 downto 0) := (others => '0');
|
||||
variable upper : integer := 0;
|
||||
begin
|
||||
case_0: case size is
|
||||
when 2 =>
|
||||
upper := 15;
|
||||
when 4 =>
|
||||
upper := 31;
|
||||
when 8 =>
|
||||
upper := 63;
|
||||
when others =>
|
||||
report "bad byte reverse length " & integer'image(size) severity failure;
|
||||
end case;
|
||||
|
||||
ret := resize(signed(val(upper downto 0)), 64);
|
||||
return std_ulogic_vector(ret);
|
||||
end;
|
||||
end package body helpers;
|
@ -0,0 +1,55 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
|
||||
-- 2 cycle LSU
|
||||
-- We calculate the address in the first cycle
|
||||
|
||||
entity loadstore1 is
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
|
||||
l_in : in Decode2ToLoadstore1Type;
|
||||
l_out : out Loadstore1ToLoadstore2Type
|
||||
);
|
||||
end loadstore1;
|
||||
|
||||
architecture behave of loadstore1 is
|
||||
signal l : Decode2ToLoadstore1Type;
|
||||
signal lsu_sum : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
-- Calculate the address in the first cycle
|
||||
lsu_sum <= std_ulogic_vector(unsigned(l.addr1) + unsigned(l.addr2)) when l.valid = '1' else (others => '0');
|
||||
|
||||
loadstore1_0: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
l <= l_in;
|
||||
|
||||
if l_in.valid = '1' then
|
||||
report "execute " & to_hstring(l_in.nia);
|
||||
report "loadstore1 " & to_hstring(l_in.addr1) & " " & to_hstring(l_in.addr2);
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
loadstore1_1: process(all)
|
||||
begin
|
||||
l_out.valid <= l.valid;
|
||||
l_out.load <= l.load;
|
||||
l_out.data <= l.data;
|
||||
l_out.write_reg <= l.write_reg;
|
||||
l_out.length <= l.length;
|
||||
l_out.byte_reverse <= l.byte_reverse;
|
||||
l_out.sign_extend <= l.sign_extend;
|
||||
l_out.update <= l.update;
|
||||
l_out.update_reg <= l.update_reg;
|
||||
|
||||
l_out.addr <= lsu_sum;
|
||||
end process;
|
||||
end;
|
@ -0,0 +1,151 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.helpers.all;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
-- 2 cycle LSU
|
||||
-- In this cycle we read or write any data and do sign extension and update if required.
|
||||
|
||||
entity loadstore2 is
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
|
||||
l_in : in Loadstore1ToLoadstore2Type;
|
||||
w_out : out Loadstore2ToWritebackType;
|
||||
|
||||
m_in : in wishbone_slave_out;
|
||||
m_out : out wishbone_master_out
|
||||
);
|
||||
end loadstore2;
|
||||
|
||||
architecture behave of loadstore2 is
|
||||
signal l_saved : Loadstore1ToLoadstore2Type;
|
||||
signal w_tmp : Loadstore2ToWritebackType;
|
||||
signal m_tmp : wishbone_master_out;
|
||||
|
||||
type state_t is (IDLE, WAITING_FOR_READ_ACK, WAITING_FOR_WRITE_ACK);
|
||||
signal state : state_t := IDLE;
|
||||
|
||||
function length_to_sel(length : in std_logic_vector(3 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
case length is
|
||||
when "0001" =>
|
||||
return "00000001";
|
||||
when "0010" =>
|
||||
return "00000011";
|
||||
when "0100" =>
|
||||
return "00001111";
|
||||
when "1000" =>
|
||||
return "11111111";
|
||||
when others =>
|
||||
return "00000000";
|
||||
end case;
|
||||
end function length_to_sel;
|
||||
|
||||
function wishbone_data_shift(address : in std_ulogic_vector(63 downto 0)) return natural is
|
||||
begin
|
||||
return to_integer(unsigned(address(2 downto 0))) * 8;
|
||||
end function wishbone_data_shift;
|
||||
|
||||
function wishbone_data_sel(size : in std_logic_vector(3 downto 0); address : in std_logic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(shift_left(unsigned(length_to_sel(size)), to_integer(unsigned(address(2 downto 0)))));
|
||||
end function wishbone_data_sel;
|
||||
begin
|
||||
w_out <= w_tmp;
|
||||
m_out <= m_tmp;
|
||||
|
||||
loadstore2_0: process(clk)
|
||||
variable tmp : std_ulogic_vector(63 downto 0);
|
||||
variable data : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
tmp := (others => '0');
|
||||
data := (others => '0');
|
||||
|
||||
w_tmp <= Loadstore2ToWritebackInit;
|
||||
|
||||
l_saved <= l_saved;
|
||||
|
||||
case_0: case state is
|
||||
when IDLE =>
|
||||
if l_in.valid = '1' then
|
||||
m_tmp <= wishbone_master_out_init;
|
||||
|
||||
m_tmp.sel <= wishbone_data_sel(l_in.length, l_in.addr);
|
||||
m_tmp.adr <= l_in.addr(63 downto 3) & "000";
|
||||
m_tmp.cyc <= '1';
|
||||
m_tmp.stb <= '1';
|
||||
|
||||
if l_in.load = '1' then
|
||||
m_tmp.we <= '0';
|
||||
|
||||
l_saved <= l_in;
|
||||
state <= WAITING_FOR_READ_ACK;
|
||||
else
|
||||
m_tmp.we <= '1';
|
||||
|
||||
w_tmp.valid <= '1';
|
||||
|
||||
data := l_in.data;
|
||||
if l_in.byte_reverse = '1' then
|
||||
data := byte_reverse(data, to_integer(unsigned(l_in.length)));
|
||||
end if;
|
||||
|
||||
m_tmp.dat <= std_logic_vector(shift_left(unsigned(data), wishbone_data_shift(l_in.addr)));
|
||||
|
||||
assert l_in.sign_extend = '0' report "sign extension doesn't make sense for stores" severity failure;
|
||||
|
||||
if l_in.update = '1' then
|
||||
w_tmp.write_enable <= '1';
|
||||
w_tmp.write_reg <= l_in.update_reg;
|
||||
w_tmp.write_data <= l_in.addr;
|
||||
end if;
|
||||
|
||||
state <= WAITING_FOR_WRITE_ACK;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when WAITING_FOR_READ_ACK =>
|
||||
if m_in.ack = '1' then
|
||||
tmp := std_logic_vector(shift_right(unsigned(m_in.dat), wishbone_data_shift(l_saved.addr)));
|
||||
data((to_integer(unsigned(l_saved.length))*8-1) downto 0) := tmp((to_integer(unsigned(l_saved.length))*8-1) downto 0);
|
||||
|
||||
if l_saved.sign_extend = '1' then
|
||||
data := sign_extend(data, to_integer(unsigned(l_saved.length)));
|
||||
end if;
|
||||
|
||||
if l_saved.byte_reverse = '1' then
|
||||
data := byte_reverse(data, to_integer(unsigned(l_saved.length)));
|
||||
end if;
|
||||
|
||||
w_tmp.write_data <= data;
|
||||
|
||||
-- write data to register file
|
||||
w_tmp.valid <= '1';
|
||||
w_tmp.write_enable <= '1';
|
||||
w_tmp.write_reg <= l_saved.write_reg;
|
||||
|
||||
if l_saved.update = '1' then
|
||||
w_tmp.write_enable2 <= '1';
|
||||
w_tmp.write_reg2 <= l_saved.update_reg;
|
||||
w_tmp.write_data2 <= l_saved.addr;
|
||||
end if;
|
||||
|
||||
m_tmp <= wishbone_master_out_init;
|
||||
state <= IDLE;
|
||||
end if;
|
||||
|
||||
when WAITING_FOR_WRITE_ACK =>
|
||||
if m_in.ack = '1' then
|
||||
m_tmp <= wishbone_master_out_init;
|
||||
state <= IDLE;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
end;
|
@ -0,0 +1,104 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.decode_types.all;
|
||||
use work.ppc_fx_insns.all;
|
||||
use work.crhelpers.all;
|
||||
|
||||
entity multiply is
|
||||
generic (
|
||||
PIPELINE_DEPTH : integer := 6
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
|
||||
m_in : in Decode2ToMultiplyType;
|
||||
m_out : out MultiplyToWritebackType
|
||||
);
|
||||
end entity multiply;
|
||||
|
||||
architecture behaviour of multiply is
|
||||
signal m: Decode2ToMultiplyType;
|
||||
|
||||
type multiply_pipeline_stage is record
|
||||
valid : std_ulogic;
|
||||
insn_type : insn_type_t;
|
||||
data : signed(129 downto 0);
|
||||
write_reg : std_ulogic_vector(4 downto 0);
|
||||
rc : std_ulogic;
|
||||
end record;
|
||||
constant MultiplyPipelineStageInit : multiply_pipeline_stage := (valid => '0', insn_type => OP_ILLEGAL, rc => '0', data => (others => '0'), others => (others => '0'));
|
||||
|
||||
type multiply_pipeline_type is array(0 to PIPELINE_DEPTH-1) of multiply_pipeline_stage;
|
||||
constant MultiplyPipelineInit : multiply_pipeline_type := (others => MultiplyPipelineStageInit);
|
||||
|
||||
type reg_type is record
|
||||
multiply_pipeline : multiply_pipeline_type;
|
||||
end record;
|
||||
|
||||
signal r, rin : reg_type := (multiply_pipeline => MultiplyPipelineInit);
|
||||
begin
|
||||
multiply_0: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
m <= m_in;
|
||||
r <= rin;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
multiply_1: process(all)
|
||||
variable v : reg_type;
|
||||
variable d : std_ulogic_vector(129 downto 0);
|
||||
variable d2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
v := r;
|
||||
|
||||
m_out <= MultiplyToWritebackInit;
|
||||
|
||||
if m.valid then
|
||||
v.multiply_pipeline(0).valid := '1';
|
||||
v.multiply_pipeline(0).insn_type := m.insn_type;
|
||||
v.multiply_pipeline(0).data := signed(m.data1) * signed(m.data2);
|
||||
v.multiply_pipeline(0).write_reg := m.write_reg;
|
||||
v.multiply_pipeline(0).rc := m.rc;
|
||||
else
|
||||
v.multiply_pipeline(0).valid := '0';
|
||||
end if;
|
||||
|
||||
loop_0: for i in 0 to PIPELINE_DEPTH-2 loop
|
||||
v.multiply_pipeline(i+1) := r.multiply_pipeline(i);
|
||||
end loop;
|
||||
|
||||
if v.multiply_pipeline(PIPELINE_DEPTH-1).valid then
|
||||
d := std_ulogic_vector(v.multiply_pipeline(PIPELINE_DEPTH-1).data);
|
||||
|
||||
case_0: case v.multiply_pipeline(PIPELINE_DEPTH-1).insn_type is
|
||||
when OP_MUL_L64 =>
|
||||
d2 := d(63 downto 0);
|
||||
when OP_MUL_H32 =>
|
||||
d2 := d(63 downto 32) & d(63 downto 32);
|
||||
when OP_MUL_H64 =>
|
||||
d2 := d(127 downto 64);
|
||||
when others =>
|
||||
report "Illegal insn type in multiplier";
|
||||
d2 := (others => '0');
|
||||
end case;
|
||||
|
||||
m_out.valid <= '1';
|
||||
m_out.write_reg_enable <= '1';
|
||||
m_out.write_reg_nr <= v.multiply_pipeline(PIPELINE_DEPTH-1).write_reg;
|
||||
m_out.write_reg_data <= d2;
|
||||
|
||||
if v.multiply_pipeline(PIPELINE_DEPTH-1).rc = '1' then
|
||||
m_out.write_cr_enable <= '1';
|
||||
m_out.write_cr_mask <= num_to_fxm(0);
|
||||
m_out.write_cr_data <= ppc_cmpi('1', d2, x"0000") & x"0000000";
|
||||
end if;
|
||||
end if;
|
||||
|
||||
rin <= v;
|
||||
end process;
|
||||
end architecture behaviour;
|
@ -0,0 +1,263 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.glibc_random.all;
|
||||
use work.ppc_fx_insns.all;
|
||||
|
||||
entity multiply_tb is
|
||||
end multiply_tb;
|
||||
|
||||
architecture behave of multiply_tb is
|
||||
signal clk : std_ulogic;
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
constant pipeline_depth: integer := 6;
|
||||
|
||||
signal m1 : DecodeToMultiplyType;
|
||||
signal m2 : MultiplyToWritebackType;
|
||||
begin
|
||||
multiply_0: entity work.multiply
|
||||
generic map (PIPELINE_DEPTH => pipeline_depth)
|
||||
port map (clk => clk, m_in => m1, m_out => m2);
|
||||
|
||||
clk_process: process
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
|
||||
stim_process: process
|
||||
variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
|
||||
variable si: std_ulogic_vector(15 downto 0);
|
||||
begin
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= LOWER_64;
|
||||
m1.nia <= (others => '0');
|
||||
m1.write_reg <= "10001";
|
||||
m1.data1 <= '0' & x"0000000000001000";
|
||||
m1.data2 <= '0' & x"0000000000001111";
|
||||
m1.rc <= '0';
|
||||
|
||||
wait for clk_period;
|
||||
assert m2.valid = '0';
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period;
|
||||
assert m2.valid = '0';
|
||||
|
||||
wait for clk_period;
|
||||
assert m2.valid = '0';
|
||||
|
||||
wait for clk_period;
|
||||
assert m2.valid = '1';
|
||||
assert m2.write_enable = '1';
|
||||
assert m2.write_reg = "10001";
|
||||
assert m2.write_data = x"0000000001111000";
|
||||
assert m2.write_cr_enable = '0';
|
||||
|
||||
wait for clk_period;
|
||||
assert m2.valid = '0';
|
||||
|
||||
m1.valid <= '1';
|
||||
m1.rc <= '1';
|
||||
|
||||
wait for clk_period;
|
||||
assert m2.valid = '0';
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
assert m2.valid = '1';
|
||||
assert m2.write_enable = '1';
|
||||
assert m2.write_reg = "10001";
|
||||
assert m2.write_data = x"0000000001111000";
|
||||
assert m2.write_cr_enable = '1';
|
||||
assert m2.cr = x"4";
|
||||
|
||||
-- test mulld
|
||||
mulld_loop : for i in 0 to 1000 loop
|
||||
ra := pseudorand(ra'length);
|
||||
rb := pseudorand(rb'length);
|
||||
|
||||
behave_rt := ppc_mulld(ra, rb);
|
||||
|
||||
m1.data1 <= '0' & ra;
|
||||
m1.data2 <= '0' & rb;
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= LOWER_64;
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
|
||||
assert m2.valid = '1';
|
||||
|
||||
assert to_hstring(behave_rt) = to_hstring(m2.write_data)
|
||||
report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_data);
|
||||
end loop;
|
||||
|
||||
-- test mulhdu
|
||||
mulhdu_loop : for i in 0 to 1000 loop
|
||||
ra := pseudorand(ra'length);
|
||||
rb := pseudorand(rb'length);
|
||||
|
||||
behave_rt := ppc_mulhdu(ra, rb);
|
||||
|
||||
m1.data1 <= '0' & ra;
|
||||
m1.data2 <= '0' & rb;
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= UPPER_64;
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
|
||||
assert m2.valid = '1';
|
||||
|
||||
assert to_hstring(behave_rt) = to_hstring(m2.write_data)
|
||||
report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_data);
|
||||
end loop;
|
||||
|
||||
-- test mulhd
|
||||
mulhd_loop : for i in 0 to 1000 loop
|
||||
ra := pseudorand(ra'length);
|
||||
rb := pseudorand(rb'length);
|
||||
|
||||
behave_rt := ppc_mulhd(ra, rb);
|
||||
|
||||
m1.data1 <= ra(63) & ra;
|
||||
m1.data2 <= rb(63) & rb;
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= UPPER_64;
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
|
||||
assert m2.valid = '1';
|
||||
|
||||
assert to_hstring(behave_rt) = to_hstring(m2.write_data)
|
||||
report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_data);
|
||||
end loop;
|
||||
|
||||
-- test mullw
|
||||
mullw_loop : for i in 0 to 1000 loop
|
||||
ra := pseudorand(ra'length);
|
||||
rb := pseudorand(rb'length);
|
||||
|
||||
behave_rt := ppc_mullw(ra, rb);
|
||||
|
||||
m1.data1 <= (others => ra(31));
|
||||
m1.data1(31 downto 0) <= ra(31 downto 0);
|
||||
m1.data2 <= (others => rb(31));
|
||||
m1.data2(31 downto 0) <= rb(31 downto 0);
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= LOWER_64;
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
|
||||
assert m2.valid = '1';
|
||||
|
||||
assert to_hstring(behave_rt) = to_hstring(m2.write_data)
|
||||
report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_data);
|
||||
end loop;
|
||||
|
||||
-- test mulhw
|
||||
mulhw_loop : for i in 0 to 1000 loop
|
||||
ra := pseudorand(ra'length);
|
||||
rb := pseudorand(rb'length);
|
||||
|
||||
behave_rt := ppc_mulhw(ra, rb);
|
||||
|
||||
m1.data1 <= (others => ra(31));
|
||||
m1.data1(31 downto 0) <= ra(31 downto 0);
|
||||
m1.data2 <= (others => rb(31));
|
||||
m1.data2(31 downto 0) <= rb(31 downto 0);
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= UPPER_32;
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
|
||||
assert m2.valid = '1';
|
||||
|
||||
assert to_hstring(behave_rt) = to_hstring(m2.write_data)
|
||||
report "bad mulhw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_data);
|
||||
end loop;
|
||||
|
||||
-- test mulhwu
|
||||
mulhwu_loop : for i in 0 to 1000 loop
|
||||
ra := pseudorand(ra'length);
|
||||
rb := pseudorand(rb'length);
|
||||
|
||||
behave_rt := ppc_mulhwu(ra, rb);
|
||||
|
||||
m1.data1 <= (others => '0');
|
||||
m1.data1(31 downto 0) <= ra(31 downto 0);
|
||||
m1.data2 <= (others => '0');
|
||||
m1.data2(31 downto 0) <= rb(31 downto 0);
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= UPPER_32;
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
|
||||
assert m2.valid = '1';
|
||||
|
||||
assert to_hstring(behave_rt) = to_hstring(m2.write_data)
|
||||
report "bad mulhwu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_data);
|
||||
end loop;
|
||||
|
||||
-- test mulli
|
||||
mulli_loop : for i in 0 to 1000 loop
|
||||
ra := pseudorand(ra'length);
|
||||
si := pseudorand(si'length);
|
||||
|
||||
behave_rt := ppc_mulli(ra, si);
|
||||
|
||||
m1.data1 <= ra(63) & ra;
|
||||
m1.data2 <= (others => si(15));
|
||||
m1.data2(15 downto 0) <= si;
|
||||
m1.valid <= '1';
|
||||
m1.mul_type <= LOWER_64;
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
m1.valid <= '0';
|
||||
|
||||
wait for clk_period * (pipeline_depth-1);
|
||||
|
||||
assert m2.valid = '1';
|
||||
|
||||
assert to_hstring(behave_rt) = to_hstring(m2.write_data)
|
||||
report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_data);
|
||||
end loop;
|
||||
|
||||
assert false report "end of test" severity failure;
|
||||
wait;
|
||||
end process;
|
||||
end behave;
|
@ -0,0 +1,749 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.helpers.all;
|
||||
|
||||
package ppc_fx_insns is
|
||||
function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector;
|
||||
function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector;
|
||||
function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector;
|
||||
|
||||
function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector;
|
||||
function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector;
|
||||
function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
|
||||
|
||||
function ppc_b (nia: std_ulogic_vector(63 downto 0); bd: std_ulogic_vector(23 downto 0)) return std_ulogic_vector;
|
||||
function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return integer;
|
||||
function ppc_bcctr_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0)) return integer;
|
||||
end package ppc_fx_insns;
|
||||
|
||||
package body ppc_fx_insns is
|
||||
function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(signed(ra) + signed(si));
|
||||
end;
|
||||
|
||||
function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_logic_vector(resize(unsigned(ra), 65) + unsigned(resize(signed(si), 64)));
|
||||
end;
|
||||
|
||||
function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is
|
||||
begin
|
||||
return std_logic_vector(resize(unsigned(ra), 65) + resize(unsigned(rb), 65) + carry);
|
||||
end;
|
||||
|
||||
function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_logic_vector(unsigned(resize(signed(si), 64)) + resize(unsigned(not(ra)), 65) + 1);
|
||||
end;
|
||||
|
||||
function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + 1);
|
||||
end;
|
||||
|
||||
function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is
|
||||
begin
|
||||
return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + carry);
|
||||
end;
|
||||
|
||||
function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is
|
||||
begin
|
||||
return std_logic_vector(resize(unsigned(ra), 65) + carry);
|
||||
end;
|
||||
|
||||
function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(signed(ra) + shift_left(resize(signed(si), 32), 16));
|
||||
end;
|
||||
|
||||
function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(signed(ra) + signed(rb));
|
||||
end;
|
||||
|
||||
function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(signed(rb) - signed(ra));
|
||||
end;
|
||||
|
||||
function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(-signed(ra));
|
||||
end;
|
||||
|
||||
function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs and std_ulogic_vector(resize(unsigned(ui), 64));
|
||||
end;
|
||||
|
||||
function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs and std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16));
|
||||
end;
|
||||
|
||||
function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs or std_ulogic_vector(resize(unsigned(ui), 64));
|
||||
end;
|
||||
|
||||
function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs or std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16));
|
||||
end;
|
||||
|
||||
function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs xor std_ulogic_vector(resize(unsigned(ui), 64));
|
||||
end;
|
||||
|
||||
function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs xor std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16));
|
||||
end;
|
||||
|
||||
function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs and rb;
|
||||
end;
|
||||
|
||||
function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs xor rb;
|
||||
end;
|
||||
|
||||
function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs nand rb;
|
||||
end;
|
||||
|
||||
function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs or rb;
|
||||
end;
|
||||
|
||||
function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs nor rb;
|
||||
end;
|
||||
|
||||
function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs and not(rb);
|
||||
end;
|
||||
|
||||
function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return not(rs xor rb);
|
||||
end;
|
||||
|
||||
function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return rs or not(rb);
|
||||
end;
|
||||
|
||||
function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(resize(signed(rs(7 downto 0)), rs'length));
|
||||
end;
|
||||
|
||||
function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(resize(signed(rs(15 downto 0)), rs'length));
|
||||
end;
|
||||
|
||||
function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(resize(signed(rs(31 downto 0)), rs'length));
|
||||
end;
|
||||
|
||||
function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(to_unsigned(fls_32(rs(31 downto 0)), rs'length));
|
||||
end;
|
||||
|
||||
function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(to_unsigned(ffs_32(rs(31 downto 0)), rs'length));
|
||||
end;
|
||||
|
||||
function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(to_unsigned(fls_64(rs), rs'length));
|
||||
end;
|
||||
|
||||
function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(to_unsigned(ffs_64(rs), rs'length));
|
||||
end;
|
||||
|
||||
function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable ret: std_ulogic_vector (rs'range);
|
||||
variable hi: integer;
|
||||
variable lo: integer;
|
||||
begin
|
||||
ret := (others => '0');
|
||||
|
||||
for i in 1 to 8 loop
|
||||
hi := (8*i)-1;
|
||||
lo := 8*(i-1);
|
||||
ret(hi downto lo) := popcnt8(rs(hi downto lo));
|
||||
end loop;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable ret: std_ulogic_vector (rs'range);
|
||||
variable hi: integer;
|
||||
variable lo: integer;
|
||||
begin
|
||||
ret := (others => '0');
|
||||
|
||||
for i in 1 to 2 loop
|
||||
hi := (32*i)-1;
|
||||
lo := 32*(i-1);
|
||||
ret(hi downto lo) := popcnt32(rs(hi downto lo));
|
||||
end loop;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return popcnt64(rs);
|
||||
end;
|
||||
|
||||
function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp : std_ulogic;
|
||||
variable ret : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
ret := (others => '0');
|
||||
|
||||
tmp := '0';
|
||||
for i in 0 to 7 loop
|
||||
tmp := tmp xor rs(i*8);
|
||||
end loop;
|
||||
|
||||
ret(0) := tmp;
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp : std_ulogic;
|
||||
variable ret : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
ret := (others => '0');
|
||||
|
||||
tmp := '0';
|
||||
for i in 0 to 3 loop
|
||||
tmp := tmp xor rs(i*8);
|
||||
end loop;
|
||||
ret(0) := tmp;
|
||||
|
||||
tmp := '0';
|
||||
for i in 4 to 7 loop
|
||||
tmp := tmp xor rs(i*8);
|
||||
end loop;
|
||||
ret(32) := tmp;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is
|
||||
variable hi, lo : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
hi := 31 - to_integer(unsigned(mb));
|
||||
lo := 31 - to_integer(unsigned(me));
|
||||
tmp1 := rs(31 downto 0) & rs(31 downto 0);
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh))));
|
||||
tmp2 := (others => '0');
|
||||
if hi < lo then
|
||||
-- Mask wraps around
|
||||
tmp2(63 downto lo) := tmp1(63 downto lo);
|
||||
tmp2(hi downto 0) := tmp1(hi downto 0);
|
||||
else
|
||||
tmp2(hi downto lo) := tmp1(hi downto lo);
|
||||
end if;
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is
|
||||
variable hi, lo : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
variable n : integer;
|
||||
begin
|
||||
hi := 31 - to_integer(unsigned(mb));
|
||||
lo := 31 - to_integer(unsigned(me));
|
||||
n := to_integer(unsigned(rb(4 downto 0)));
|
||||
tmp1 := rs(31 downto 0) & rs(31 downto 0);
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), n));
|
||||
tmp2 := (others => '0');
|
||||
if hi < lo then
|
||||
-- Mask wraps around
|
||||
tmp2(63 downto lo) := tmp1(63 downto lo);
|
||||
tmp2(hi downto 0) := tmp1(hi downto 0);
|
||||
else
|
||||
tmp2(hi downto lo) := tmp1(hi downto lo);
|
||||
end if;
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is
|
||||
variable hi, lo : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
hi := 31 - to_integer(unsigned(mb));
|
||||
lo := 31 - to_integer(unsigned(me));
|
||||
tmp1 := rs(31 downto 0) & rs(31 downto 0);
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh))));
|
||||
tmp2 := ra;
|
||||
if hi < lo then
|
||||
-- Mask wraps around
|
||||
tmp2(63 downto lo) := tmp1(63 downto lo);
|
||||
tmp2(hi downto 0) := tmp1(hi downto 0);
|
||||
else
|
||||
tmp2(hi downto lo) := tmp1(hi downto lo);
|
||||
end if;
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable hi : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
hi := 63-to_integer(unsigned(mb));
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
|
||||
tmp2 := (others => '0');
|
||||
tmp2(hi downto 0) := tmp1(hi downto 0);
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable lo : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
lo := 63-to_integer(unsigned(me));
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
|
||||
tmp2 := (others => '0');
|
||||
tmp2(63 downto lo) := tmp1(63 downto lo);
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable hi, lo : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
hi := 63-to_integer(unsigned(mb));
|
||||
lo := to_integer(unsigned(sh));
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
|
||||
tmp2 := (others => '0');
|
||||
if hi < lo then
|
||||
-- Mask wraps around
|
||||
tmp2(63 downto lo) := tmp1(63 downto lo);
|
||||
tmp2(hi downto 0) := tmp1(hi downto 0);
|
||||
else
|
||||
tmp2(hi downto lo) := tmp1(hi downto lo);
|
||||
end if;
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable hi : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
hi := 63-to_integer(unsigned(mb));
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
|
||||
tmp2 := (others => '0');
|
||||
tmp2(hi downto 0) := tmp1(hi downto 0);
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable lo : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(63 downto 0);
|
||||
begin
|
||||
lo := 63-to_integer(unsigned(me));
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
|
||||
tmp2 := (others => '0');
|
||||
tmp2(63 downto lo) := tmp1(63 downto lo);
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable hi, lo : integer;
|
||||
variable tmp1, tmp2 : std_ulogic_vector(rs'range);
|
||||
begin
|
||||
hi := 63-to_integer(unsigned(mb));
|
||||
lo := to_integer(unsigned(sh));
|
||||
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), lo));
|
||||
tmp2 := ra;
|
||||
if hi < lo then
|
||||
-- Mask wraps around
|
||||
tmp2(63 downto lo) := tmp1(63 downto lo);
|
||||
tmp2(hi downto 0) := tmp1(hi downto 0);
|
||||
else
|
||||
tmp2(hi downto lo) := tmp1(hi downto lo);
|
||||
end if;
|
||||
return tmp2;
|
||||
end;
|
||||
|
||||
function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable n : integer;
|
||||
variable tmp : unsigned(31 downto 0);
|
||||
begin
|
||||
n := to_integer(unsigned(rb(5 downto 0)));
|
||||
tmp := shift_left(unsigned(rs(31 downto 0)), n);
|
||||
|
||||
return (63 downto 32 => '0') & std_ulogic_vector(tmp);
|
||||
end;
|
||||
|
||||
function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable n : integer;
|
||||
variable tmp : unsigned(31 downto 0);
|
||||
begin
|
||||
n := to_integer(unsigned(rb(5 downto 0)));
|
||||
tmp := shift_right(unsigned(rs(31 downto 0)), n);
|
||||
|
||||
return (63 downto 32 => '0') & std_ulogic_vector(tmp);
|
||||
end;
|
||||
|
||||
function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable n : integer;
|
||||
variable tmp : signed(31 downto 0);
|
||||
variable carry: std_ulogic;
|
||||
begin
|
||||
n := to_integer(unsigned(sh));
|
||||
tmp := shift_right(signed(rs(31 downto 0)), n);
|
||||
-- what about n = 0?
|
||||
carry := or rs(n-1 downto 0) and rs(31);
|
||||
|
||||
return carry & std_ulogic_vector(resize(tmp, rs'length));
|
||||
end;
|
||||
|
||||
function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable n : natural;
|
||||
variable tmp : signed(31 downto 0);
|
||||
variable carry: std_ulogic;
|
||||
begin
|
||||
n := to_integer(unsigned(rb(5 downto 0)));
|
||||
tmp := shift_right(signed(rs(31 downto 0)), n);
|
||||
-- what about n = 0?
|
||||
carry := or rs(n-1 downto 0) and rs(31);
|
||||
|
||||
return carry & std_ulogic_vector(resize(tmp, rs'length));
|
||||
end;
|
||||
|
||||
function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable n : integer;
|
||||
begin
|
||||
n := to_integer(unsigned(rb(6 downto 0)));
|
||||
return std_ulogic_vector(shift_left(unsigned(rs), n));
|
||||
end;
|
||||
|
||||
function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable n : integer;
|
||||
begin
|
||||
n := to_integer(unsigned(rb(6 downto 0)));
|
||||
return std_ulogic_vector(shift_right(unsigned(rs), n));
|
||||
end;
|
||||
|
||||
function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
|
||||
variable n : integer;
|
||||
variable carry: std_ulogic;
|
||||
begin
|
||||
n := to_integer(unsigned(sh));
|
||||
-- what about n = 0?
|
||||
carry := or rs(n-1 downto 0) and rs(63);
|
||||
|
||||
return carry & std_ulogic_vector(shift_right(signed(rs), n));
|
||||
end;
|
||||
|
||||
function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable n : integer;
|
||||
variable carry: std_ulogic;
|
||||
begin
|
||||
n := to_integer(unsigned(rb(6 downto 0)));
|
||||
-- what about n = 0?
|
||||
carry := or rs(n-1 downto 0) and rs(63);
|
||||
|
||||
return carry & std_ulogic_vector(shift_right(signed(rs), n));
|
||||
end;
|
||||
|
||||
-- Not sure how to better communicate the top 64 bits of the result is unused
|
||||
function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: signed(127 downto 0);
|
||||
begin
|
||||
tmp := signed(ra) * signed(rb);
|
||||
return std_ulogic_vector(tmp(63 downto 0));
|
||||
end;
|
||||
|
||||
-- Not sure how to better communicate the top 64 bits of the result is unused
|
||||
function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: signed(127 downto 0);
|
||||
begin
|
||||
tmp := signed(ra) * signed(rb);
|
||||
return std_ulogic_vector(tmp(127 downto 64));
|
||||
end;
|
||||
|
||||
-- Not sure how to better communicate the top 64 bits of the result is unused
|
||||
function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: unsigned(127 downto 0);
|
||||
begin
|
||||
tmp := unsigned(ra) * unsigned(rb);
|
||||
return std_ulogic_vector(tmp(127 downto 64));
|
||||
end;
|
||||
|
||||
-- Not sure how to better communicate the top 16 bits of the result is unused
|
||||
function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: signed(79 downto 0);
|
||||
begin
|
||||
tmp := signed(ra) * signed(si);
|
||||
return std_ulogic_vector(tmp(63 downto 0));
|
||||
end;
|
||||
|
||||
function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(signed(ra(31 downto 0)) * signed(rb(31 downto 0)));
|
||||
end;
|
||||
|
||||
function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: signed(63 downto 0);
|
||||
begin
|
||||
tmp := signed(ra(31 downto 0)) * signed(rb(31 downto 0));
|
||||
return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32));
|
||||
end;
|
||||
|
||||
function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: unsigned(63 downto 0);
|
||||
begin
|
||||
tmp := unsigned(ra(31 downto 0)) * unsigned(rb(31 downto 0));
|
||||
return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32));
|
||||
end;
|
||||
|
||||
function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: signed(ra'range);
|
||||
begin
|
||||
tmp := signed(ra);
|
||||
if l = '0' then
|
||||
tmp := resize(signed(ra(31 downto 0)), tmp'length);
|
||||
end if;
|
||||
|
||||
return ppc_signed_compare(tmp, resize(signed(si), tmp'length));
|
||||
end;
|
||||
|
||||
function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmpa, tmpb: signed(ra'range);
|
||||
begin
|
||||
tmpa := signed(ra);
|
||||
tmpb := signed(rb);
|
||||
if l = '0' then
|
||||
tmpa := resize(signed(ra(31 downto 0)), ra'length);
|
||||
tmpb := resize(signed(rb(31 downto 0)), ra'length);
|
||||
end if;
|
||||
|
||||
return ppc_signed_compare(tmpa, tmpb);
|
||||
end;
|
||||
|
||||
function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: unsigned(ra'range);
|
||||
begin
|
||||
tmp := unsigned(ra);
|
||||
if l = '0' then
|
||||
tmp := resize(unsigned(ra(31 downto 0)), tmp'length);
|
||||
end if;
|
||||
|
||||
return ppc_unsigned_compare(tmp, resize(unsigned(si), tmp'length));
|
||||
end;
|
||||
|
||||
function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmpa, tmpb: unsigned(ra'range);
|
||||
begin
|
||||
tmpa := unsigned(ra);
|
||||
tmpb := unsigned(rb);
|
||||
if l = '0' then
|
||||
tmpa := resize(unsigned(ra(31 downto 0)), ra'length);
|
||||
tmpb := resize(unsigned(rb(31 downto 0)), ra'length);
|
||||
end if;
|
||||
|
||||
return ppc_unsigned_compare(tmpa, tmpb);
|
||||
end;
|
||||
|
||||
function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable ret: std_ulogic_vector (rs'range);
|
||||
variable hi: integer;
|
||||
variable lo: integer;
|
||||
begin
|
||||
for i in 1 to 8 loop
|
||||
hi := (8*i)-1;
|
||||
lo := 8*(i-1);
|
||||
ret(hi downto lo) := cmp_one_byte(rs(hi downto lo), rb(hi downto lo));
|
||||
end loop;
|
||||
|
||||
return ret;
|
||||
end;
|
||||
|
||||
-- Not synthesizable
|
||||
function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: signed(31 downto 0);
|
||||
begin
|
||||
tmp := signed(ra(31 downto 0)) / signed(rb(31 downto 0));
|
||||
|
||||
return (63 downto 32 => '0') & std_ulogic_vector(tmp);
|
||||
end;
|
||||
|
||||
function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: unsigned(63 downto 0) := (others => '0');
|
||||
begin
|
||||
if unsigned(rb) /= 0 then
|
||||
tmp := unsigned(ra) / unsigned(rb);
|
||||
end if;
|
||||
|
||||
return std_ulogic_vector(tmp);
|
||||
end;
|
||||
|
||||
function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: signed(63 downto 0) := (others => '0');
|
||||
begin
|
||||
if signed(rb) /= 0 then
|
||||
tmp := signed(ra) / signed(rb);
|
||||
end if;
|
||||
|
||||
return std_ulogic_vector(tmp);
|
||||
end;
|
||||
|
||||
function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
|
||||
variable tmp: unsigned(31 downto 0) := (others => '0');
|
||||
begin
|
||||
if unsigned(rb(31 downto 0)) /= 0 then
|
||||
tmp := unsigned(ra(31 downto 0)) / unsigned(rb(31 downto 0));
|
||||
end if;
|
||||
|
||||
return std_ulogic_vector(resize(tmp, ra'length));
|
||||
end;
|
||||
|
||||
function ppc_b (nia: std_ulogic_vector(63 downto 0); bd: std_ulogic_vector(23 downto 0)) return std_ulogic_vector is
|
||||
begin
|
||||
return std_ulogic_vector(signed(nia) + signed(bd & "00"));
|
||||
end;
|
||||
|
||||
function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return integer is
|
||||
variable crfield: integer;
|
||||
variable crbit_match: std_ulogic;
|
||||
variable ctr_not_zero: std_ulogic;
|
||||
variable ctr_ok: std_ulogic;
|
||||
variable cond_ok: std_ulogic;
|
||||
variable ret: integer;
|
||||
begin
|
||||
crfield := to_integer(unsigned(bi));
|
||||
-- BE bit numbering
|
||||
crbit_match := '1' when cr(31-crfield) = bo(4-1) else '0';
|
||||
-- We check this before it is decremented
|
||||
ctr_not_zero := '1' when ctr /= x"0000000000000001" else '0';
|
||||
ctr_ok := bo(4-2) or (ctr_not_zero xor bo(4-3));
|
||||
cond_ok := bo(4-0) or crbit_match;
|
||||
if ctr_ok = '1' and cond_ok = '1' then
|
||||
ret := 1;
|
||||
else
|
||||
ret := 0;
|
||||
end if;
|
||||
return ret;
|
||||
end;
|
||||
|
||||
function ppc_bcctr_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0)) return integer is
|
||||
variable crfield: integer;
|
||||
variable crbit_match: std_ulogic;
|
||||
variable cond_ok: std_ulogic;
|
||||
variable ret: integer;
|
||||
begin
|
||||
crfield := to_integer(unsigned(bi));
|
||||
-- BE bit numbering
|
||||
crbit_match := '1' when cr(31-crfield) = bo(4-1) else '0';
|
||||
cond_ok := bo(4-0) or crbit_match;
|
||||
if cond_ok = '1' then
|
||||
ret := 1;
|
||||
else
|
||||
ret := 0;
|
||||
end if;
|
||||
return ret;
|
||||
end;
|
||||
end package body ppc_fx_insns;
|
@ -0,0 +1,68 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
|
||||
entity register_file is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
|
||||
d_in : in Decode2ToRegisterFileType;
|
||||
d_out : out RegisterFileToDecode2Type;
|
||||
|
||||
w_in : in WritebackToRegisterFileType;
|
||||
|
||||
-- debug
|
||||
registers_out : out regfile
|
||||
);
|
||||
end entity register_file;
|
||||
|
||||
architecture behaviour of register_file is
|
||||
signal registers : regfile := (others => (others => '0'));
|
||||
begin
|
||||
-- synchronous writes
|
||||
register_write_0: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if w_in.write_enable = '1' then
|
||||
assert not(is_x(w_in.write_data)) and not(is_x(w_in.write_reg)) severity failure;
|
||||
report "Writing " & to_hstring(w_in.write_data) & " to " & to_hstring(w_in.write_reg);
|
||||
registers(to_integer(unsigned(w_in.write_reg))) <= w_in.write_data;
|
||||
end if;
|
||||
if w_in.write_enable2 = '1' then
|
||||
assert not(is_x(w_in.write_data2)) and not(is_x(w_in.write_reg2)) severity failure;
|
||||
report "Writing " & to_hstring(w_in.write_data2) & " to " & to_hstring(w_in.write_reg2);
|
||||
registers(to_integer(unsigned(w_in.write_reg2))) <= w_in.write_data2;
|
||||
end if;
|
||||
end if;
|
||||
end process register_write_0;
|
||||
|
||||
-- asynchronous reads
|
||||
register_read_0: process(all)
|
||||
begin
|
||||
report "read " & to_hstring(d_in.read1_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read1_reg))));
|
||||
report "read " & to_hstring(d_in.read2_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read2_reg))));
|
||||
report "read " & to_hstring(d_in.read3_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read3_reg))));
|
||||
d_out.read1_data <= registers(to_integer(unsigned(d_in.read1_reg)));
|
||||
d_out.read2_data <= registers(to_integer(unsigned(d_in.read2_reg)));
|
||||
d_out.read3_data <= registers(to_integer(unsigned(d_in.read3_reg)));
|
||||
|
||||
-- Forward any written data
|
||||
--if w_in.write_enable = '1' then
|
||||
--if d_in.read1_reg = w_in.write_reg then
|
||||
--d_out.read1_data <= w_in.write_data;
|
||||
--end if;
|
||||
--if d_in.read2_reg = w_in.write_reg then
|
||||
--d_out.read2_data <= w_in.write_data;
|
||||
--end if;
|
||||
--if d_in.read3_reg = w_in.write_reg then
|
||||
--d_out.read3_data <= w_in.write_data;
|
||||
--end if;
|
||||
--end if;
|
||||
end process register_read_0;
|
||||
|
||||
-- debug
|
||||
registers_out <= registers;
|
||||
end architecture behaviour;
|
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Create makefile dependencies for VHDL files, looking for "use work" and
|
||||
# "entity work" declarations
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
work = re.compile('use work\.([^.]+)\.')
|
||||
entity = re.compile('entity work\.(.*)')
|
||||
|
||||
for filename in sys.argv[1:]:
|
||||
with open(filename, 'r') as f:
|
||||
(basename, suffix) = filename.split('.')
|
||||
print('%s.o:' % basename, end='')
|
||||
|
||||
for line in f:
|
||||
m = work.search(line)
|
||||
if m:
|
||||
print(' %s.o' % m.group(1), end='')
|
||||
|
||||
m = entity.search(line)
|
||||
if m:
|
||||
print(' %s.o' % m.group(1), end='')
|
||||
print()
|
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import re
|
||||
import fileinput
|
||||
|
||||
r = re.compile("REG ([0-9A-F]+)");
|
||||
|
||||
regs = list()
|
||||
|
||||
for line in fileinput.input():
|
||||
m = r.search(line)
|
||||
if m:
|
||||
regs.append(int(m.group(1), 16))
|
||||
#print("%016X"% int(m.group(1), 16))
|
||||
|
||||
print("%x" % hash(tuple(regs)))
|
@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: run_test.sh <test>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TEST=$1
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
|
||||
function finish {
|
||||
rm -rf "$TMPDIR"
|
||||
}
|
||||
|
||||
trap finish EXIT
|
||||
|
||||
MICROWATT_DIR=$PWD
|
||||
|
||||
Y=$(${MICROWATT_DIR}/scripts/hash.py tests/${TEST}.out)
|
||||
|
||||
cd $TMPDIR
|
||||
|
||||
cp ${MICROWATT_DIR}/tests/${TEST}.bin simple_ram_behavioural.bin
|
||||
|
||||
X=$( ${MICROWATT_DIR}/core_tb | ${MICROWATT_DIR}/scripts/hash.py )
|
||||
|
||||
if [ $X == $Y ]; then
|
||||
echo "$TEST PASS"
|
||||
else
|
||||
echo "$TEST FAIL ********"
|
||||
exit 1
|
||||
fi
|
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import tempfile
|
||||
import os
|
||||
from shutil import copyfile
|
||||
import subprocess
|
||||
from pexpect import fdpexpect
|
||||
import sys
|
||||
import signal
|
||||
|
||||
tempdir = tempfile.TemporaryDirectory()
|
||||
cwd = os.getcwd()
|
||||
os.chdir(tempdir.name)
|
||||
|
||||
copyfile(os.path.join(cwd, 'tests/micropython.bin'),
|
||||
os.path.join(tempdir.name, 'simple_ram_behavioural.bin'))
|
||||
|
||||
cmd = [ os.path.join(cwd, './core_tb') ]
|
||||
|
||||
devNull = open(os.devnull, 'w')
|
||||
p = subprocess.Popen(cmd, stdout=devNull,
|
||||
stdin=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
exp = fdpexpect.fdspawn(p.stderr)
|
||||
exp.logfile = sys.stdout.buffer
|
||||
|
||||
exp.expect('Type "help\(\)" for more information.')
|
||||
exp.expect('>>>')
|
||||
|
||||
p.stdin.write(b'print("foo")\r\n')
|
||||
p.stdin.flush()
|
||||
|
||||
# Catch the command echoed back to the console
|
||||
exp.expect('foo', timeout=600)
|
||||
|
||||
# Now catch the output
|
||||
exp.expect('foo', timeout=600)
|
||||
exp.expect('>>>')
|
||||
|
||||
os.kill(p.pid, signal.SIGKILL)
|
@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import tempfile
|
||||
import os
|
||||
from shutil import copyfile
|
||||
import subprocess
|
||||
from pexpect import fdpexpect
|
||||
import sys
|
||||
import signal
|
||||
|
||||
tempdir = tempfile.TemporaryDirectory()
|
||||
cwd = os.getcwd()
|
||||
os.chdir(tempdir.name)
|
||||
|
||||
copyfile(os.path.join(cwd, 'tests/micropython.bin'),
|
||||
os.path.join(tempdir.name, 'simple_ram_behavioural.bin'))
|
||||
|
||||
cmd = [ os.path.join(cwd, './core_tb') ]
|
||||
|
||||
devNull = open(os.devnull, 'w')
|
||||
p = subprocess.Popen(cmd, stdout=devNull,
|
||||
stdin=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
exp = fdpexpect.fdspawn(p.stderr)
|
||||
exp.logfile = sys.stdout.buffer
|
||||
|
||||
exp.expect('Type "help\(\)" for more information.')
|
||||
exp.expect('>>>')
|
||||
|
||||
p.stdin.write(b'n2=0\r\n')
|
||||
p.stdin.write(b'n1=1\r\n')
|
||||
p.stdin.write(b'for i in range(5):\r\n')
|
||||
p.stdin.write(b' n0 = n1 + n2\r\n')
|
||||
p.stdin.write(b' print(n0)\r\n')
|
||||
p.stdin.write(b' n2 = n1\r\n')
|
||||
p.stdin.write(b' n1 = n0\r\n')
|
||||
p.stdin.write(b'\r\n')
|
||||
p.stdin.flush()
|
||||
|
||||
exp.expect('n1 = n0', timeout=600)
|
||||
exp.expect('1', timeout=600)
|
||||
exp.expect('2', timeout=600)
|
||||
exp.expect('3', timeout=600)
|
||||
exp.expect('5', timeout=600)
|
||||
exp.expect('8', timeout=600)
|
||||
exp.expect('>>>', timeout=600)
|
||||
|
||||
os.kill(p.pid, signal.SIGKILL)
|
@ -0,0 +1,30 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package sim_console is
|
||||
procedure sim_console_read (val: out std_ulogic_vector(63 downto 0));
|
||||
attribute foreign of sim_console_read : procedure is "VHPIDIRECT sim_console_read";
|
||||
|
||||
procedure sim_console_poll (val: out std_ulogic_vector(63 downto 0));
|
||||
attribute foreign of sim_console_poll : procedure is "VHPIDIRECT sim_console_poll";
|
||||
|
||||
procedure sim_console_write (val: std_ulogic_vector(63 downto 0));
|
||||
attribute foreign of sim_console_write : procedure is "VHPIDIRECT sim_console_write";
|
||||
end sim_console;
|
||||
|
||||
package body sim_console is
|
||||
procedure sim_console_read (val: out std_ulogic_vector(63 downto 0)) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end sim_console_read;
|
||||
|
||||
procedure sim_console_poll (val: out std_ulogic_vector(63 downto 0)) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end sim_console_poll;
|
||||
|
||||
procedure sim_console_write (val: std_ulogic_vector(63 downto 0)) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end sim_console_write;
|
||||
end sim_console;
|
@ -0,0 +1,136 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
|
||||
#define vhpi0 2 /* forcing 0 */
|
||||
#define vhpi1 3 /* forcing 1 */
|
||||
|
||||
static uint64_t from_std_logic_vector(unsigned char *p, unsigned long len)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
|
||||
if (len > 64) {
|
||||
fprintf(stderr, "%s: invalid length %lu\n", __func__, len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (unsigned long i = 0; i < len; i++) {
|
||||
unsigned char bit;
|
||||
|
||||
if (*p == vhpi0) {
|
||||
bit = 0;
|
||||
} else if (*p == vhpi1) {
|
||||
bit = 1;
|
||||
} else {
|
||||
fprintf(stderr, "%s: bad bit %d\n", __func__, *p);
|
||||
bit = 0;
|
||||
}
|
||||
|
||||
ret = (ret << 1) | bit;
|
||||
p++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void to_std_logic_vector(unsigned long val, unsigned char *p,
|
||||
unsigned long len)
|
||||
{
|
||||
if (len > 64) {
|
||||
fprintf(stderr, "%s: invalid length %lu\n", __func__, len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (unsigned long i = 0; i < len; i++) {
|
||||
if ((val >> (len-1-i) & 1))
|
||||
*p = vhpi1;
|
||||
else
|
||||
*p = vhpi0;
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
static struct termios oldt;
|
||||
|
||||
static void restore_termios(void)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
}
|
||||
|
||||
static void nonblocking(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
static struct termios newt;
|
||||
|
||||
tcgetattr(STDIN_FILENO, &oldt);
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~(ICANON|ECHO);
|
||||
|
||||
newt.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
||||
newt.c_oflag &= ~(OPOST);
|
||||
newt.c_cflag |= (CS8);
|
||||
newt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
|
||||
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
initialized = true;
|
||||
atexit(restore_termios);
|
||||
}
|
||||
}
|
||||
|
||||
void sim_console_read(unsigned char *__rt)
|
||||
{
|
||||
int ret;
|
||||
unsigned long val = 0;
|
||||
|
||||
nonblocking();
|
||||
|
||||
ret = read(STDIN_FILENO, &val, 1);
|
||||
if (ret != 1) {
|
||||
fprintf(stderr, "%s: read of stdin returns %d\n", __func__, ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//fprintf(stderr, "read returns %c\n", val);
|
||||
|
||||
to_std_logic_vector(val, __rt, 64);
|
||||
}
|
||||
|
||||
void sim_console_poll(unsigned char *__rt)
|
||||
{
|
||||
int ret;
|
||||
struct pollfd fdset[1];
|
||||
uint8_t val = 0;
|
||||
|
||||
nonblocking();
|
||||
|
||||
memset(fdset, 0, sizeof(fdset));
|
||||
|
||||
fdset[0].fd = STDIN_FILENO;
|
||||
fdset[0].events = POLLIN;
|
||||
|
||||
ret = poll(fdset, 1, -1);
|
||||
//fprintf(stderr, "poll returns %d\n", ret);
|
||||
|
||||
if (ret == 1)
|
||||
val = 1;
|
||||
|
||||
to_std_logic_vector(val, __rt, 64);
|
||||
}
|
||||
|
||||
void sim_console_write(unsigned char *__rs)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
val = from_std_logic_vector(__rs, 64);
|
||||
|
||||
fprintf(stderr, "%c", val);
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
use work.simple_ram_behavioural_helpers.all;
|
||||
|
||||
entity simple_ram_behavioural is
|
||||
generic (
|
||||
FILENAME : string;
|
||||
SIZE : integer
|
||||
);
|
||||
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
|
||||
wishbone_in : in wishbone_master_out;
|
||||
wishbone_out : out wishbone_slave_out
|
||||
);
|
||||
end simple_ram_behavioural;
|
||||
|
||||
architecture behave of simple_ram_behavioural is
|
||||
type wishbone_state_t is (IDLE, ACK);
|
||||
|
||||
signal state : wishbone_state_t := IDLE;
|
||||
signal ret_ack : std_ulogic := '0';
|
||||
signal identifier : integer := behavioural_initialize(filename => FILENAME, size => SIZE);
|
||||
signal reload : integer := 0;
|
||||
begin
|
||||
wishbone_process: process(clk)
|
||||
variable ret_dat: std_ulogic_vector(63 downto 0) := (others => '0');
|
||||
begin
|
||||
wishbone_out.ack <= ret_ack and wishbone_in.cyc and wishbone_in.stb;
|
||||
wishbone_out.dat <= ret_dat;
|
||||
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
state <= IDLE;
|
||||
ret_ack <= '0';
|
||||
report "MEM RST";
|
||||
else
|
||||
ret_dat := x"XXXXXXXXXXXXXXXX";
|
||||
|
||||
-- Active
|
||||
if wishbone_in.cyc = '1' then
|
||||
report "MEM CYC";
|
||||
case state is
|
||||
when IDLE =>
|
||||
report "MEM IDLE";
|
||||
if wishbone_in.stb = '1' then
|
||||
-- write
|
||||
if wishbone_in.we = '1' then
|
||||
assert not(is_x(wishbone_in.dat)) and not(is_x(wishbone_in.adr)) severity failure;
|
||||
report "RAM writing " & to_hstring(wishbone_in.dat) & " to " & to_hstring(wishbone_in.adr);
|
||||
behavioural_write(wishbone_in.dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier);
|
||||
reload <= reload + 1;
|
||||
ret_ack <= '1';
|
||||
state <= ACK;
|
||||
else
|
||||
behavioural_read(ret_dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier, reload);
|
||||
report "RAM reading from " & to_hstring(wishbone_in.adr) & " returns " & to_hstring(ret_dat);
|
||||
ret_ack <= '1';
|
||||
state <= ACK;
|
||||
end if;
|
||||
end if;
|
||||
when ACK =>
|
||||
report "MEM ACK";
|
||||
ret_ack <= '0';
|
||||
state <= IDLE;
|
||||
end case;
|
||||
else
|
||||
ret_ack <= '0';
|
||||
state <= IDLE;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end behave;
|
@ -0,0 +1,30 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package simple_ram_behavioural_helpers is
|
||||
function behavioural_initialize (filename: String; size: integer) return integer;
|
||||
attribute foreign of behavioural_initialize : function is "VHPIDIRECT behavioural_initialize";
|
||||
|
||||
procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer);
|
||||
attribute foreign of behavioural_read : procedure is "VHPIDIRECT behavioural_read";
|
||||
|
||||
procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer);
|
||||
attribute foreign of behavioural_write : procedure is "VHPIDIRECT behavioural_write";
|
||||
end simple_ram_behavioural_helpers;
|
||||
|
||||
package body simple_ram_behavioural_helpers is
|
||||
function behavioural_initialize (filename: String; size: integer) return integer is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end behavioural_initialize;
|
||||
|
||||
procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end behavioural_read;
|
||||
|
||||
procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer) is
|
||||
begin
|
||||
assert false report "VHPI" severity failure;
|
||||
end behavioural_write;
|
||||
end simple_ram_behavioural_helpers;
|
@ -0,0 +1,258 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#define ALIGN_UP(VAL, SIZE) (((VAL) + ((SIZE)-1)) & ~((SIZE)-1))
|
||||
|
||||
#define vhpi0 2 /* forcing 0 */
|
||||
#define vhpi1 3 /* forcing 1 */
|
||||
|
||||
struct int_bounds
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
char dir;
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
struct fat_pointer
|
||||
{
|
||||
void *base;
|
||||
struct int_bounds *bounds;
|
||||
};
|
||||
|
||||
static char *from_string(void *__p)
|
||||
{
|
||||
struct fat_pointer *p = __p;
|
||||
unsigned long len = p->bounds->len;
|
||||
char *m;
|
||||
|
||||
m = malloc(len+1);
|
||||
if (!m) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(m, p->base, len);
|
||||
m[len] = 0x0;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
static uint64_t from_std_logic_vector(unsigned char *p, unsigned long len)
|
||||
{
|
||||
unsigned long ret = 0;
|
||||
|
||||
if (len > 64) {
|
||||
fprintf(stderr, "%s: invalid length %lu\n", __func__, len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (unsigned long i = 0; i < len; i++) {
|
||||
unsigned char bit;
|
||||
|
||||
if (*p == vhpi0) {
|
||||
bit = 0;
|
||||
} else if (*p == vhpi1) {
|
||||
bit = 1;
|
||||
} else {
|
||||
fprintf(stderr, "%s: bad bit %d\n", __func__, *p);
|
||||
bit = 0;
|
||||
}
|
||||
|
||||
ret = (ret << 1) | bit;
|
||||
p++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void to_std_logic_vector(unsigned long val, unsigned char *p,
|
||||
unsigned long len)
|
||||
{
|
||||
if (len > 64) {
|
||||
fprintf(stderr, "%s: invalid length %lu\n", __func__, len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (unsigned long i = 0; i < len; i++) {
|
||||
if ((val >> (len-1-i) & 1))
|
||||
*p = vhpi1;
|
||||
else
|
||||
*p = vhpi0;
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_REGIONS 128
|
||||
|
||||
struct ram_behavioural {
|
||||
char *filename;
|
||||
unsigned long size;
|
||||
void *m;
|
||||
};
|
||||
|
||||
static struct ram_behavioural behavioural_regions[MAX_REGIONS];
|
||||
static unsigned long region_nr;
|
||||
|
||||
unsigned long behavioural_initialize(void *__f, unsigned long size)
|
||||
{
|
||||
struct ram_behavioural *r;
|
||||
int fd;
|
||||
struct stat buf;
|
||||
unsigned long tmp_size;
|
||||
void *mem;
|
||||
|
||||
if (region_nr == MAX_REGIONS) {
|
||||
fprintf(stderr, "%s: too many regions, bump MAX_REGIONS\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r = &behavioural_regions[region_nr];
|
||||
|
||||
r->filename = from_string(__f);
|
||||
r->size = ALIGN_UP(size, getpagesize());
|
||||
|
||||
fd = open(r->filename, O_RDWR);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "%s: could not open %s\n", __func__,
|
||||
r->filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fstat(fd, &buf)) {
|
||||
perror("fstat");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* XXX Do we need to truncate the underlying file? */
|
||||
tmp_size = ALIGN_UP(buf.st_size, getpagesize());
|
||||
|
||||
if (r->size > tmp_size) {
|
||||
void *m;
|
||||
|
||||
/*
|
||||
* We have to pad the file. Allocate the total size, then
|
||||
* create a space for the file.
|
||||
*/
|
||||
mem = mmap(NULL, r->size, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if (mem == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (tmp_size) {
|
||||
munmap(mem, tmp_size);
|
||||
|
||||
m = mmap(mem, tmp_size, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_FIXED, fd, 0);
|
||||
if (m == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (m != mem) {
|
||||
fprintf(stderr, "%s: mmap(MAP_FIXED) failed\n",
|
||||
__func__);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mem = mmap(NULL, tmp_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
|
||||
fd, 0);
|
||||
if (mem == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
behavioural_regions[region_nr].m = mem;
|
||||
return region_nr++;
|
||||
}
|
||||
|
||||
void behavioural_read(unsigned char *__val, unsigned char *__addr,
|
||||
unsigned long sel, int identifier)
|
||||
{
|
||||
struct ram_behavioural *r;
|
||||
unsigned long val = 0;
|
||||
unsigned long addr = from_std_logic_vector(__addr, 64);
|
||||
unsigned char *p;
|
||||
|
||||
if (identifier > region_nr) {
|
||||
fprintf(stderr, "%s: bad index %d\n", __func__, identifier);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r = &behavioural_regions[identifier];
|
||||
|
||||
for (unsigned long i = 0; i < 8; i++) {
|
||||
#if 0
|
||||
/* sel only used on writes */
|
||||
if (!(sel & (1UL << i)))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if ((addr + i) > r->size) {
|
||||
fprintf(stderr, "%s: bad memory access %lx %lx\n", __func__,
|
||||
addr+i, r->size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
p = (unsigned char *)(((unsigned long)r->m) + addr + i);
|
||||
val |= (((unsigned long)*p) << (i*8));
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("MEM behave %d read %016lx addr %016lx sel %02lx\n", identifier, val,
|
||||
addr, sel);
|
||||
#endif
|
||||
|
||||
to_std_logic_vector(val, __val, 64);
|
||||
}
|
||||
|
||||
void behavioural_write(unsigned char *__val, unsigned char *__addr,
|
||||
unsigned int sel, int identifier)
|
||||
{
|
||||
struct ram_behavioural *r;
|
||||
unsigned long val = from_std_logic_vector(__val, 64);
|
||||
unsigned long addr = from_std_logic_vector(__addr, 64);
|
||||
unsigned char *p;
|
||||
|
||||
if (identifier > region_nr) {
|
||||
fprintf(stderr, "%s: bad index %d\n", __func__, identifier);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r = &behavioural_regions[identifier];
|
||||
|
||||
p = (unsigned char *)(((unsigned long)r->m) + addr);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("MEM behave %d write %016lx addr %016lx sel %02x\n", identifier, val,
|
||||
addr, sel);
|
||||
#endif
|
||||
|
||||
for (unsigned long i = 0; i < 8; i++) {
|
||||
if (!(sel & (1UL << i)))
|
||||
continue;
|
||||
|
||||
if ((addr + i) > r->size) {
|
||||
fprintf(stderr, "%s: bad memory access %lx %lx\n", __func__,
|
||||
addr+i, r->size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
p = (unsigned char *)(((unsigned long)r->m) + addr + i);
|
||||
*p = (val >> (i*8)) & 0xff;
|
||||
}
|
||||
}
|
Binary file not shown.
@ -0,0 +1,233 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity simple_ram_behavioural_tb is
|
||||
end simple_ram_behavioural_tb;
|
||||
|
||||
architecture behave of simple_ram_behavioural_tb is
|
||||
signal clk : std_ulogic;
|
||||
signal rst : std_ulogic := '1';
|
||||
|
||||
constant clk_period : time := 10 ns;
|
||||
|
||||
signal w_in : wishbone_slave_out;
|
||||
signal w_out : wishbone_master_out;
|
||||
begin
|
||||
simple_ram_0: entity work.simple_ram_behavioural
|
||||
generic map ( filename => "simple_ram_behavioural_tb.bin", size => 16 )
|
||||
port map (clk => clk, rst => rst, wishbone_out => w_in, wishbone_in => w_out);
|
||||
|
||||
clock: process
|
||||
begin
|
||||
clk <= '1';
|
||||
wait for clk_period / 2;
|
||||
clk <= '0';
|
||||
wait for clk_period / 2;
|
||||
end process clock;
|
||||
|
||||
stim: process
|
||||
begin
|
||||
w_out.adr <= (others => '0');
|
||||
w_out.dat <= (others => '0');
|
||||
w_out.cyc <= '0';
|
||||
w_out.stb <= '0';
|
||||
w_out.sel <= (others => '0');
|
||||
w_out.we <= '0';
|
||||
|
||||
wait for clk_period;
|
||||
rst <= '0';
|
||||
|
||||
wait for clk_period;
|
||||
|
||||
w_out.cyc <= '1';
|
||||
|
||||
-- test various read lengths and alignments
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(7 downto 0) = x"00" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(7 downto 0) = x"01" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(7 downto 0) = x"07" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000011";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(15 downto 0) = x"0100" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000011";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(15 downto 0) = x"0201" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000011";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(15 downto 0) = x"0807" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00001111";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(31 downto 0) = x"03020100" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00001111";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(31 downto 0) = x"04030201" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00001111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(31 downto 0) = x"0A090807" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(63 downto 0) = x"0706050403020100" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000001";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(63 downto 0) = x"0807060504030201" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(63 downto 0) = x"0E0D0C0B0A090807" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
-- test various write lengths and alignments
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.we <= '1';
|
||||
w_out.dat(7 downto 0) <= x"0F";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "00000001";
|
||||
w_out.adr <= x"0000000000000000";
|
||||
w_out.we <= '0';
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat(7 downto 0) = x"0F" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.we <= '1';
|
||||
w_out.dat <= x"BADC0FFEBADC0FFE";
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
w_out.stb <= '1';
|
||||
w_out.sel <= "11111111";
|
||||
w_out.adr <= x"0000000000000007";
|
||||
w_out.we <= '0';
|
||||
assert w_in.ack = '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '1';
|
||||
assert w_in.dat = x"BADC0FFEBADC0FFE" report to_hstring(w_in.dat);
|
||||
w_out.stb <= '0';
|
||||
wait for clk_period;
|
||||
assert w_in.ack = '0';
|
||||
|
||||
assert false report "end of test" severity failure;
|
||||
wait;
|
||||
end process;
|
||||
end behave;
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FFFFFFFEA9FF0004
|
||||
REG 0000000072E50000
|
||||
REG 0000000000000000
|
||||
REG 0000000000001CAA
|
||||
REG 0000000000000040
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 000B000100000000
|
||||
REG 0000000000000000
|
||||
REG 000000000000131F
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFA9F40004
|
||||
REG 000B000100000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000040000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFF8D1AFFFF
|
||||
REG 0000000000000004
|
||||
REG 0000000028808000
|
||||
REG 000000000161E8C0
|
||||
REG 000000000000BCD9
|
||||
REG FFFFFFFFFFFFFFF1
|
||||
REG 000000000000471E
|
||||
REG 000000000000BCD9
|
||||
REG 0000000028808000
|
||||
REG 000010000000BC00
|
||||
REG 0000000000000000
|
||||
REG 0000000100000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000001CAA
|
||||
REG 0000000051010001
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 00000000290C5C65
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFC802
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF04EC
|
||||
REG FFFFFFFFDFFFFFFE
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000040
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000005800000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000020
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000080000000
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FC00000030B80F7E
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 000000000000001F
|
||||
REG 0000000000000009
|
||||
REG FFFFFFFFFFFFF03F
|
||||
REG 0000000628C6749B
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFF4
|
||||
REG 0000000000000FC0
|
||||
REG 0000000000000F80
|
||||
REG 0000000000000000
|
||||
REG 000000000000001B
|
||||
REG 000000000000AFC6
|
||||
REG 00000000CAEC001F
|
||||
REG FFFFFFFFFFFFFFE1
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000007
|
||||
REG 0000000628C67484
|
||||
REG FFFFFFF9FFF6101F
|
||||
REG 000000002300001F
|
||||
REG 0000000000000040
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 000000000000007C
|
||||
REG 000000000000001F
|
||||
REG FFFFFFF9FBC21000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFF07F
|
||||
REG 000000001CF4001F
|
||||
REG 000000000000007C
|
||||
REG 000000005FF10911
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 0000000000000042
|
||||
REG 00000000E0000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00000000001CE494
|
||||
REG 0000000000000000
|
||||
REG 0000000000000002
|
||||
REG FFFFFFFFFFFFABBB
|
||||
REG 0000000000000000
|
||||
REG 8000000000000000
|
||||
REG 0000000000000039
|
||||
REG 0000000000000000
|
||||
REG 8000000000000000
|
||||
REG 0000000100000001
|
||||
REG FFFFFFFFFFFFFFC0
|
||||
REG 0000000000000000
|
||||
REG 00FFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00FFFFFFFFFFFFFF
|
||||
REG 0000000000000040
|
||||
REG 00000000001D5A80
|
||||
REG 0000000000000000
|
||||
REG 0000000100000003
|
||||
REG 0000000000000068
|
||||
REG 0000000000000000
|
||||
REG 0100000000000033
|
||||
REG 0000000000000007
|
||||
REG 0000000085000040
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 00000000000000ED
|
||||
REG 0000000000000000
|
||||
REG 000000000000074A
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000006FE7D07
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0808000806FE7D06
|
||||
REG 0000000000000004
|
||||
REG 00000000B83A0000
|
||||
REG 0000000000001B05
|
||||
REG FFFFFFFFFFFFFFF8
|
||||
REG 0003100000000000
|
||||
REG 0000000000000000
|
||||
REG 00000100000050EA
|
||||
REG 0000000000000007
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 000002000000A1D0
|
||||
REG 0000000020000000
|
||||
REG 0000000000000007
|
||||
REG 0000000000001B05
|
||||
REG 0000000044882888
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000001B05
|
||||
REG 00000000810001E1
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FFFFFFFFFD338C3F
|
||||
REG 0000000000000000
|
||||
REG 0000000000004870
|
||||
REG 000000003FFFFFC0
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 480085E048000000
|
||||
REG FFFFFF8000001FE5
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 000000000000001A
|
||||
REG 0000000005040001
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000002820000000
|
||||
REG F58349ADEDA77E00
|
||||
REG FFFFFFFFFFFFFFF8
|
||||
REG 000000000000001A
|
||||
REG FFFFFFFFE00003FF
|
||||
REG 0000000000000020
|
||||
REG 00000000000009E4
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000008
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FC0000000505CC9F
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 000000000A080003
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FF9FFFFF21240000
|
||||
REG 000000000017EE80
|
||||
REG 00000001BFC00000
|
||||
REG 0060000000780000
|
||||
REG 0000000000000020
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFF95
|
||||
REG FFFFFFFFE0CA9244
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF408B
|
||||
REG 0000000040000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF9ED4
|
||||
REG 00000000000002FD
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFE0CA9244
|
||||
REG 0000000000000020
|
||||
REG 000000000000EA01
|
||||
REG 0000000000000000
|
||||
REG 000000000D000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFE80000
|
||||
REG 0000000000000000
|
||||
REG 000000005A108491
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 00003FFFFFFF8001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 49C2000000000082
|
||||
REG 801F100000000000
|
||||
REG FFFFFFFFFDF6D8F0
|
||||
REG 49C2000000000082
|
||||
REG 0000000000000026
|
||||
REG FFFFFFFFFFFEFFFF
|
||||
REG 801F100000000000
|
||||
REG FFFFFF00FFFFFFFF
|
||||
REG FFFFFF00FFFFFFFE
|
||||
REG FFFFFF00FFFFFFFE
|
||||
REG FFFFFFFFD56124E1
|
||||
REG FFFFFF00FFFFFFFF
|
||||
REG 0000000000008000
|
||||
REG 0000000000000026
|
||||
REG EAB09270E8409270
|
||||
REG 0000000000000000
|
||||
REG FFFFFF00FFFFFFFF
|
||||
REG 000801F1000001E8
|
||||
REG 0000000000000000
|
||||
REG FFF7FE0EFFFFFFFF
|
||||
REG 7FE0F00000000000
|
||||
REG FFFFFF00FFFFFFFE
|
||||
REG 00000000004124E1
|
||||
REG 0000000038820000
|
||||
REG 00000000004124E1
|
||||
REG 03FFFFFFFF000000
|
||||
REG 0000000000000000
|
||||
REG 0000002500000025
|
||||
REG 000000001090001E
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 0000000048200024
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000001
|
||||
REG 0000000000000002
|
||||
REG FFFFFFFF82410000
|
||||
REG 0000000000000000
|
||||
REG 00000000BA76001F
|
||||
REG 020000202A26001F
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000002
|
||||
REG 0000001F0000000A
|
||||
REG 0004C0000004C000
|
||||
REG FFFFFFFFF7FFFFFD
|
||||
REG 0000000000000001
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG BE041CE7FFFBDC6A
|
||||
REG 00000000000059A0
|
||||
REG 0000000000000006
|
||||
REG 0000000048200024
|
||||
REG 0000000000000000
|
||||
REG FFFB3FFFFFFB4000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000090400048
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 000000070000075A
|
||||
REG 0000000000000000
|
||||
REG BFFFFFFFBE000004
|
||||
REG 0000000001FFFFFB
|
||||
REG 0000000000000000
|
||||
REG FFFFFEF2FFFFA904
|
||||
REG 0200000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFB
|
||||
REG F873800000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG FFFFFFFFFFFE1CE0
|
||||
REG 0000000001FFFFFB
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 078C2C003F540004
|
||||
REG 00000000000007E8
|
||||
REG 0000000002000871
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFE000004
|
||||
REG FFFFFFF1FFFFAB02
|
||||
REG 0000000000000000
|
||||
REG 078C2C003F540004
|
||||
REG F873D3FFC1540004
|
||||
REG 00000007184E0100
|
||||
REG 4000000040000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000001
|
||||
REG 0000000108800088
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 7851A07EFFA70241
|
||||
REG 0000000000000000
|
||||
REG 0000000000004000
|
||||
REG D30FE001D310661A
|
||||
REG D3102F7BD3102F7B
|
||||
REG FFFBFFFFFFFD7FFF
|
||||
REG 87F000010000423F
|
||||
REG FFFBFFFFFFFD7E00
|
||||
REG 87F40015741BFFD1
|
||||
REG 7B81FFFF4000001F
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00000000000C110F
|
||||
REG FFFFFFFFFFFFFFCB
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF5BC0
|
||||
REG 00000000000007FF
|
||||
REG 000000147419F50E
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 87F40015741C5662
|
||||
REG 0000000000000000
|
||||
REG FFFFFFF94C438180
|
||||
REG 780BFFFEFFFD11AF
|
||||
REG 00000000FFFFBDC0
|
||||
REG 0000000000000000
|
||||
REG FFFFFFF94C438180
|
||||
REG FFFFFFF94C43C3BF
|
||||
REG 780BFFFEFFFD11AF
|
||||
REG 0000000040088004
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 000000000000001E
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000010
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000040
|
||||
REG 0000000000000000
|
||||
REG 00003FFFCE9561AE
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000007
|
||||
REG 0000001F9AA70020
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFF7FFFFFFF
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFF76D1FFF0
|
||||
REG FFFFFFFFFFFFFFF0
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 00000000892E0000
|
||||
REG 00007FFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000040088088
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 000000004C5B0000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFC00000000000
|
||||
REG FFFFFFFFFFFF8D9E
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF5E44
|
||||
REG FFFFFFFFFFFFE8C8
|
||||
REG 00000000FFFFFFFF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 3FFFFFF8FFFFFFF8
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFF5E44
|
||||
REG 000000004C5B0000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000020000000
|
||||
REG FFFFFFFFFFFFBD1F
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFF00000001
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 000000000000A1BB
|
||||
REG 000000010401FFFE
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 003AD23688890019
|
||||
REG 0000000000000040
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000040
|
||||
REG 0000000000000000
|
||||
REG 00000000972B0000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 004080C0D0C0C089
|
||||
REG 0000000000000000
|
||||
REG 0000000000000317
|
||||
REG FFC52DC9E05DFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFD1
|
||||
REG 000000000000002F
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF89A0
|
||||
REG 0000000000000000
|
||||
REG 0000000000000006
|
||||
REG 0000000000000000
|
||||
REG 0808080503040000
|
||||
REG 0808080503040000
|
||||
REG 0000000000000030
|
||||
REG 0000000000000000
|
||||
REG 0000000104005000
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 0000000000000032
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000046
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFF9DDB
|
||||
REG FFFFFFFF55B2FFBF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 000000000000C6C3
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFB9
|
||||
REG FFFFFFFFFFFF3983
|
||||
REG 0000000000000033
|
||||
REG 0000000000000000
|
||||
REG 0000023000000030
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000003
|
||||
REG 0000000000000008
|
||||
REG 7C20000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0001FFFFFFFFFF73
|
||||
REG 0000000000000002
|
||||
REG FFFFFFFFFFFFFFBF
|
||||
REG 0000000000000040
|
||||
REG 0000000000000000
|
||||
REG 00000001011E89F2
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FFFFFFFFFFFF9A6A
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFF7
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000003350
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 00000FFFFFFFF7FF
|
||||
REG 0000000000000001
|
||||
REG FFFFFFFFFFFF9A6A
|
||||
REG 0000000000000000
|
||||
REG 0000001A00000012
|
||||
REG FFFFFFFFFFF34D40
|
||||
REG 000000002F280888
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0007FF0000000000
|
||||
REG FFFFFFFFD0D7FFFF
|
||||
REG FFFFFFFFFFFFB350
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 000000000000003C
|
||||
REG 0000000000000020
|
||||
REG FFFFFFFFFFFF0000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF5F77
|
||||
REG D0D72F27D0D72F27
|
||||
REG 0000000000000001
|
||||
REG 0000002000000000
|
||||
REG 0000002000000017
|
||||
REG 0000000000000000
|
||||
REG 0000000041FA11F1
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FFFFFFFFB357FFC1
|
||||
REG 0000000000000021
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFCF
|
||||
REG 0000000000008DF8
|
||||
REG 000000007FFFF7C0
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFE1
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00000000000090D6
|
||||
REG 0000000000000001
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFE1
|
||||
REG 000000000000C4A7
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFE0
|
||||
REG 0000000048D50000
|
||||
REG 00000000000034E1
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFEAD2
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFF44A9FFDF
|
||||
REG 000000000000D120
|
||||
REG FFFFFFFFFFFFFFDF
|
||||
REG 00000000000090D5
|
||||
REG 000000000000FC00
|
||||
REG 0000000000000040
|
||||
REG 0000000040000700
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FFFFFFF8E09C556F
|
||||
REG 000000002448848E
|
||||
REG 0000000083C40000
|
||||
REG 000000000000FF00
|
||||
REG E3A0008CE810D740
|
||||
REG 0000080000000000
|
||||
REG 09200002A89AE240
|
||||
REG 8D7F3BB3449942C5
|
||||
REG 0002A5B9121A971C
|
||||
REG FC48980000189976
|
||||
REG 0002A5B9121A975C
|
||||
REG FFFFFFF8E0906D06
|
||||
REG 00000000EDDA0035
|
||||
REG FFB6FFFFEABB77ED
|
||||
REG 0000000000005F00
|
||||
REG FFFFFFFFFFFFFFFD
|
||||
REG FFFFFFFFFFFFA0DA
|
||||
REG 0000000000000035
|
||||
REG 0000010000000000
|
||||
REG 0000000000005F26
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000005F26
|
||||
REG 0000000000000000
|
||||
REG 0048FFFFFFFF8808
|
||||
REG 0000000000000020
|
||||
REG 0000000000000040
|
||||
REG E3A0008CE810C566
|
||||
REG FFFFFFFFEABAFFF6
|
||||
REG FFFFFFDFFFFFA0FA
|
||||
REG FFFFFFFFFFFFFFAA
|
||||
REG 000000004891091D
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG BFFFFC0A1FFFF7DB
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 800009200003F000
|
||||
REG 0000000000000040
|
||||
REG 000000004F7FE848
|
||||
REG FFFFFFFFE00098C3
|
||||
REG FFFFFFFF80000000
|
||||
REG 000000001FFF673D
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFE000FBAF
|
||||
REG FFFFFFFFFFFFF172
|
||||
REG 0000000000000000
|
||||
REG 00000000000FFFFE
|
||||
REG 0007FFFEFFF00002
|
||||
REG 0000000000004E91
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFE0005799
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFC0000000
|
||||
REG 000003FFE000082E
|
||||
REG 00000000FFFF7EDC
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 000000001FFF5799
|
||||
REG 0000000000000000
|
||||
REG 0000000017FD0000
|
||||
REG FFFFBF6EE007BF6E
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFF0000
|
||||
REG FFFFFFFF80000000
|
||||
REG 000000005EFFD110
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 0000000000000042
|
||||
REG FFFFFFFFFE48FFFF
|
||||
REG 00006F3900006F39
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000003FE0000
|
||||
REG 100106B000000000
|
||||
REG FFFFFFFFFFFFFE13
|
||||
REG FFFFFFFFFFFF4985
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFC19D3E63
|
||||
REG FFFFFFFFE8250000
|
||||
REG 0000000000000040
|
||||
REG FFFFFFFFFE48FFFF
|
||||
REG 0000000000008A9E
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00000000106B0000
|
||||
REG E00000000100FFFF
|
||||
REG 0000000040828478
|
||||
REG 000000007B490000
|
||||
REG 8000340000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFA8250000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG E800000000000000
|
||||
REG 0000000000008A9D
|
||||
REG 0000000117120811
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 000000000045061D
|
||||
REG FFFFFFFFC0ACFFFF
|
||||
REG 0000000000450600
|
||||
REG FFFFFFFFFFBAF9DF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000380
|
||||
REG 0000000000450600
|
||||
REG 0000000000000020
|
||||
REG FFFFFEDB201FFB60
|
||||
REG FFFFFFFFC0AD0000
|
||||
REG 0000000000000000
|
||||
REG FFFFFEDB201FFB60
|
||||
REG 0000000020040001
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0808080802040808
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG 0000000000000020
|
||||
REG 0000000000450600
|
||||
REG 0000000000000020
|
||||
REG 000000000044A8A4
|
||||
REG 0000000000000007
|
||||
REG FFFFFFFFFE056800
|
||||
REG 0000000000000000
|
||||
REG 000000007F02AE4D
|
||||
REG 0000000000000000
|
||||
REG 0000000000F811B2
|
||||
REG 0000000000000007
|
||||
REG 0080000000000000
|
||||
REG 0000000000000000
|
||||
REG 00001EE90DC27CF6
|
||||
REG 0000000040509010
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 000000002F423F42
|
||||
REG 0000000000000C00
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFF0001CA8
|
||||
REG FFFFFFFFF0007B0A
|
||||
REG 0000000000000091
|
||||
REG 0000000000000003
|
||||
REG 0FFFFFD071FABD00
|
||||
REG 0000400000000001
|
||||
REG 0000000007080603
|
||||
REG 0000000037FFFFE7
|
||||
REG 000000007A114210
|
||||
REG 000000002F083F42
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFF0007B0A
|
||||
REG 0000000000000000
|
||||
REG FFFFBFFFFFFFFFFF
|
||||
REG 00000F33111EAA2C
|
||||
REG 0000000000000040
|
||||
REG FFFFFFFFFC0000BD
|
||||
REG 00000000D0BDD7BE
|
||||
REG FFFFFFFF2F422441
|
||||
REG 000000000FFF84F5
|
||||
REG 0000000000000020
|
||||
REG 0000000000000000
|
||||
REG 0000400000000001
|
||||
REG 000000002F422842
|
||||
REG 00000000D0B22BBE
|
||||
REG 000000000E0500F5
|
||||
REG 000000009E107E84
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 01FFFFFFFFFFFFFD
|
||||
REG 0000000000005802
|
||||
REG 0000000000000200
|
||||
REG FFFFFFFFFFFF9C43
|
||||
REG FFFFFFE000FFEB94
|
||||
REG 0000001FFF00146B
|
||||
REG 0000000000000020
|
||||
REG 0000000500000005
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFDFF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFC00000000
|
||||
REG FFFFFF001E000000
|
||||
REG FFFFFFFFFFFF693C
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0200001F0000001F
|
||||
REG 0000000000000200
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FE00000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 000000FFE200734A
|
||||
REG FFFFFFFC00000000
|
||||
REG FFFFFF8000000000
|
||||
REG 00000000000096E3
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000108910888
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 480000000002D4EC
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 000FFFFFFFFFCAD8
|
||||
REG 0000000000005469
|
||||
REG EFBF28D8EFFFC305
|
||||
REG 0000008FFFFFD7D8
|
||||
REG 0000000000000020
|
||||
REG FFFFFFFFFFFFFFC6
|
||||
REG 0000009000000090
|
||||
REG 0000000000000000
|
||||
REG FFFD99E9FFFFFFEC
|
||||
REG 00013B65A93C1F74
|
||||
REG FFFD99E9FFFFFFEA
|
||||
REG 0002661600026616
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000041
|
||||
REG 0000000000000006
|
||||
REG FFFD99E9FFFFFFEB
|
||||
REG 0000000000000005
|
||||
REG 00000001FFFFF2B6
|
||||
REG FFFFFFFF99CB0000
|
||||
REG 0000000000000040
|
||||
REG 000000000000006A
|
||||
REG FFFFFFFFFFFFF2B6
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000001
|
||||
REG 0000000000000185
|
||||
REG 0000000000000000
|
||||
REG 0000000000000041
|
||||
REG B7FD99E9FFFFFF95
|
||||
REG 0000000104088088
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 0000000000009F88
|
||||
REG 0000000000000000
|
||||
REG FFFFFC6CFFFFFC6C
|
||||
REG 000779480007CC9B
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFEF290001
|
||||
REG FFFFFFFFFFFF6077
|
||||
REG FFFFFFFFBBFABFFF
|
||||
REG 0000000010D6FFFF
|
||||
REG 0000000000077948
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 000000000004F40C
|
||||
REG 0000000000000000
|
||||
REG 0007794800077948
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000080000
|
||||
REG FFFFFC6CFFFFFC6C
|
||||
REG 0000000004000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00001C6CFFFFFC6C
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFC6CFFFFFC6C
|
||||
REG 000000000004F58D
|
||||
REG FF3FFFFFFFFFFFFF
|
||||
REG 00000000480A8004
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG 5CEFF00200008022
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 043BA020AF31A4FF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00000000118007FF
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG 0000000000000001
|
||||
REG 0000000000FFB800
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFFFFFEE7FF800
|
||||
REG 0000000000000000
|
||||
REG 23100FFDFFFFD610
|
||||
REG 0000000000000000
|
||||
REG 00000000015B5000
|
||||
REG 000000002E20A000
|
||||
REG 000000000000001E
|
||||
REG 0118007FF0000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 000000000000000B
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 00000000901E1000
|
Binary file not shown.
@ -0,0 +1,32 @@
|
||||
REG FFFBFFBFFDC00001
|
||||
REG FFFFFFFFFFFFFFFE
|
||||
REG 0000000000000000
|
||||
REG FFFFF9FFC92EFFFF
|
||||
REG FFFFFFFFFF7FFFFF
|
||||
REG 4000000000000000
|
||||
REG FF85A9BEFCB8F7F7
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG FFFFF9FFE757FFFF
|
||||
REG 17C49F006F000000
|
||||
REG E481584E91000000
|
||||
REG FFFFFFFFFF7FFFFF
|
||||
REG 0000000000000040
|
||||
REG 0000000094290000
|
||||
REG E481584E91000000
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG C000000000000000
|
||||
REG 0000000000000000
|
||||
REG 007B564002400019
|
||||
REG 0000000000000000
|
||||
REG 0000000000000001
|
||||
REG FFFFFFFFFFFFFFFF
|
||||
REG FFFFFFFFFFFFFFC0
|
||||
REG 20FBF9C507C70809
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000000000000000
|
||||
REG 0000020020011FFF
|
||||
REG 0000000000000000
|
||||
REG 00000000931C889F
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue