mirror of
https://github.com/j-core/j-core-ice40.git
synced 2026-01-11 23:52:49 +00:00
Separate out predecoder. (Mostly Jeff's work.)
This commit is contained in:
parent
c4ac0a6e0e
commit
11c1ba7c5a
@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use work.decode_pack.all;
|
||||
use work.cpu2j0_pack.all;
|
||||
use work.predecode_pack.all;
|
||||
|
||||
entity decode_core is
|
||||
generic (
|
||||
|
||||
@ -277,7 +277,6 @@ package decode_pack is
|
||||
wb_stall : out pipeline_wb_stall_t
|
||||
);
|
||||
end component;
|
||||
function predecode_rom_addr (code : std_logic_vector(15 downto 0)) return std_logic_vector;
|
||||
function check_illegal_delay_slot (code : std_logic_vector(15 downto 0)) return std_logic;
|
||||
function check_illegal_instruction (code : std_logic_vector(15 downto 0)) return std_logic;
|
||||
type decode_core_reg_t is
|
||||
@ -302,3 +301,73 @@ package decode_pack is
|
||||
type system_event_instr_array is array (cpu_event_cmd_t range <>) of system_instr_t;
|
||||
constant system_event_instrs : system_event_instr_array := (INT => INTERRUPT_I, ERR => ERROR_I, BREAK => BREAK_I, RST => RESET_CPU_I);
|
||||
end;
|
||||
|
||||
package body decode_pack is
|
||||
function isa_fmt (code : std_logic_vector(15 downto 0)) return isa_type_t is
|
||||
variable ret : isa_type_t := ( (others => '0'), (others => '0'), (others => '0'),
|
||||
NX, LONG,
|
||||
(others => '0'), (others => '0'), (others => '0'));
|
||||
begin
|
||||
ret.ln := code(15 downto 12);
|
||||
if (ret.ln = "0000" and code(2) = '1') or (ret.ln(3) = '0' and ret.ln(1) = '1') then
|
||||
ret.fmt := NMX;
|
||||
elsif ret.ln = "0100" and code(3 downto 2) = "11" and code (1 downto 0) /= "10" then
|
||||
ret.fmt := NM;
|
||||
elsif ret.ln = "0001" or ret.ln = "0101" then
|
||||
ret.fmt := NM4;
|
||||
elsif ret.ln = "0111" or ret.ln = "1001" or ret.ln = "1101" or ret.ln = "1110" then
|
||||
ret.fmt := N8;
|
||||
elsif ret.ln(3 downto 1) = "101" then
|
||||
ret.fmt := I12;
|
||||
elsif ret.ln = "1000" and code(11) = '0' then
|
||||
ret.fmt := NX4;
|
||||
elsif (ret.ln = "1000" and code(11) = '1') or ret.ln = "1100" then
|
||||
ret.fmt := X8;
|
||||
elsif (ret.ln = "0000" and code (3 downto 0) = "0011") or (ret.ln = "0100" and code(1) = '1') then
|
||||
ret.fmt := MX;
|
||||
end if;
|
||||
|
||||
ret.rn := code(11 downto 8);
|
||||
ret.rm := code(7 downto 4);
|
||||
if code(15 downto 10) = "100000" then ret.rm := code(11 downto 8); end if;
|
||||
if ret.fmt = MX then ret.rn := code( 7 downto 4); end if;
|
||||
|
||||
if ret.fmt = I12 then ret.imm := code(11 downto 0);
|
||||
elsif ret.fmt = N8 or ret.fmt = X8 then ret.imm := x"0" & code( 7 downto 0);
|
||||
elsif ret.fmt = NM4 or ret.fmt = NX4 then ret.imm := x"00" & code( 3 downto 0); end if;
|
||||
|
||||
|
||||
if ret.fmt = NX or ret.fmt = MX then ret.col := code( 5 downto 4);
|
||||
elsif ret.fmt = NMX then ret.col := code( 1 downto 0);
|
||||
elsif ret.fmt = NX4 or ret.fmt = X8 then ret.col := code( 9 downto 8); end if;
|
||||
|
||||
if ret.fmt = NX or ret.fmt = MX then ret.op := code( 3 downto 0);
|
||||
elsif ret.fmt = NMX then ret.op := "00" & code( 3 downto 2);
|
||||
elsif ret.fmt = NX4 or ret.fmt = X8 then ret.op := "00" & code(11 downto 10); end if;
|
||||
|
||||
if ret.col = "00" then ret.sz := BYTE;
|
||||
elsif ret.col = "01" then ret.sz := WORD; end if;
|
||||
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
function check_illegal_delay_slot (code : std_logic_vector(15 downto 0)) return std_logic is
|
||||
begin
|
||||
-- Check for instructions that assign to PC:
|
||||
-- RTE, RTS, JMP @Rm, JSR @Rm, BRAF Rm, BSRF Rm, BF label, BF /S label, BT label, BT /S label, BRA label, BSR label, TRAPA #imm
|
||||
if ((code(15 downto 12) = "0000" and code(3 downto 2) = "00" and code(0) = '1') or (code(15 downto 14) = "10" and code(12 downto 11) = "01" and code(8) = '1') or code(15 downto 13) = "101" or (code(15) = '1' and code(13 downto 8) = "000011") or (code(15) = '0' and code(13 downto 12) = "00" and code(4 downto 0) = "01011")) then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end;
|
||||
function check_illegal_instruction (code : std_logic_vector(15 downto 0)) return std_logic is
|
||||
begin
|
||||
-- TODO: Improve detection of illegal instructions
|
||||
if code(15 downto 8) = x"ff" then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end;
|
||||
end decode_pack;
|
||||
|
||||
@ -9,8 +9,8 @@ rm -f *.o *.cf *.ghw
|
||||
echo Analyze...
|
||||
|
||||
# General CPU plumbing, not architecture specific
|
||||
ghdl -a cpu2j0_pkg.vhd components_pkg.vhd mult_pkg.vhd decode_pkg.vhd datapath_pkg.vhd
|
||||
ghdl -a decode_body.vhd cpu.vhd decode.vhd decode_core.vhd decode_table.vhd datapath.vhd register_file_sync.vhd mult.vhd
|
||||
ghdl -a cpu2j0_pkg.vhd components_pkg.vhd mult_pkg.vhd decode_pkg.vhd predecode_pkg.vhd datapath_pkg.vhd
|
||||
ghdl -a cpu.vhd decode.vhd decode_core.vhd decode_table.vhd datapath.vhd register_file_sync.vhd mult.vhd
|
||||
|
||||
# Using the "staircase" version of the instruction decoder. The 2 other
|
||||
# versions started life as generated code from the same microcode spreadsheet,
|
||||
|
||||
@ -13,55 +13,14 @@ use ieee.numeric_std.all;
|
||||
use work.decode_pack.all;
|
||||
use work.cpu2j0_components_pack.all;
|
||||
use work.mult_pkg.all;
|
||||
package body decode_pack is
|
||||
|
||||
function isa_fmt (code : std_logic_vector(15 downto 0)) return isa_type_t is
|
||||
variable ret : isa_type_t := ( (others => '0'), (others => '0'), (others => '0'),
|
||||
NX, LONG,
|
||||
(others => '0'), (others => '0'), (others => '0'));
|
||||
begin
|
||||
ret.ln := code(15 downto 12);
|
||||
if (ret.ln = "0000" and code(2) = '1') or (ret.ln(3) = '0' and ret.ln(1) = '1') then
|
||||
ret.fmt := NMX;
|
||||
elsif ret.ln = "0100" and code(3 downto 2) = "11" and code (1 downto 0) /= "10" then
|
||||
ret.fmt := NM;
|
||||
elsif ret.ln = "0001" or ret.ln = "0101" then
|
||||
ret.fmt := NM4;
|
||||
elsif ret.ln = "0111" or ret.ln = "1001" or ret.ln = "1101" or ret.ln = "1110" then
|
||||
ret.fmt := N8;
|
||||
elsif ret.ln(3 downto 1) = "101" then
|
||||
ret.fmt := I12;
|
||||
elsif ret.ln = "1000" and code(11) = '0' then
|
||||
ret.fmt := NX4;
|
||||
elsif (ret.ln = "1000" and code(11) = '1') or ret.ln = "1100" then
|
||||
ret.fmt := X8;
|
||||
elsif (ret.ln = "0000" and code (3 downto 0) = "0011") or (ret.ln = "0100" and code(1) = '1') then
|
||||
ret.fmt := MX;
|
||||
end if;
|
||||
package predecode_pack is
|
||||
|
||||
ret.rn := code(11 downto 8);
|
||||
ret.rm := code(7 downto 4);
|
||||
if code(15 downto 10) = "100000" then ret.rm := code(11 downto 8); end if;
|
||||
if ret.fmt = MX then ret.rn := code( 7 downto 4); end if;
|
||||
function predecode_rom_addr (code : std_logic_vector(15 downto 0)) return std_logic_vector;
|
||||
|
||||
if ret.fmt = I12 then ret.imm := code(11 downto 0);
|
||||
elsif ret.fmt = N8 or ret.fmt = X8 then ret.imm := x"0" & code( 7 downto 0);
|
||||
elsif ret.fmt = NM4 or ret.fmt = NX4 then ret.imm := x"00" & code( 3 downto 0); end if;
|
||||
end package;
|
||||
|
||||
|
||||
if ret.fmt = NX or ret.fmt = MX then ret.col := code( 5 downto 4);
|
||||
elsif ret.fmt = NMX then ret.col := code( 1 downto 0);
|
||||
elsif ret.fmt = NX4 or ret.fmt = X8 then ret.col := code( 9 downto 8); end if;
|
||||
|
||||
if ret.fmt = NX or ret.fmt = MX then ret.op := code( 3 downto 0);
|
||||
elsif ret.fmt = NMX then ret.op := "00" & code( 3 downto 2);
|
||||
elsif ret.fmt = NX4 or ret.fmt = X8 then ret.op := "00" & code(11 downto 10); end if;
|
||||
|
||||
if ret.col = "00" then ret.sz := BYTE;
|
||||
elsif ret.col = "01" then ret.sz := WORD; end if;
|
||||
|
||||
return ret;
|
||||
end function;
|
||||
package body predecode_pack is
|
||||
|
||||
function predecode_rom_addr (code : std_logic_vector(15 downto 0)) return std_logic_vector is
|
||||
variable addr : std_logic_vector(7 downto 0);
|
||||
@ -313,23 +272,4 @@ package body decode_pack is
|
||||
end case;
|
||||
return addr;
|
||||
end;
|
||||
function check_illegal_delay_slot (code : std_logic_vector(15 downto 0)) return std_logic is
|
||||
begin
|
||||
-- Check for instructions that assign to PC:
|
||||
-- RTE, RTS, JMP @Rm, JSR @Rm, BRAF Rm, BSRF Rm, BF label, BF /S label, BT label, BT /S label, BRA label, BSR label, TRAPA #imm
|
||||
if ((code(15 downto 12) = "0000" and code(3 downto 2) = "00" and code(0) = '1') or (code(15 downto 14) = "10" and code(12 downto 11) = "01" and code(8) = '1') or code(15 downto 13) = "101" or (code(15) = '1' and code(13 downto 8) = "000011") or (code(15) = '0' and code(13 downto 12) = "00" and code(4 downto 0) = "01011")) then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end;
|
||||
function check_illegal_instruction (code : std_logic_vector(15 downto 0)) return std_logic is
|
||||
begin
|
||||
-- TODO: Improve detection of illegal instructions
|
||||
if code(15 downto 8) = x"ff" then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end;
|
||||
end;
|
||||
Loading…
x
Reference in New Issue
Block a user