mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
decode1: Work out register addresses in decode1
This adds some relatively simple logic to decode1 to compute the GPR/FPR addresses that an instruction will access. It always computes three addresses regardless of whether the instruction will actually use all of them. The main things it computes are whether the instruction uses the RS field or the RC field for the 3rd operand, and whether the operands are FPRs or GPRs (it is possible for RS to be an FPR but RA and RB to be GPRs, as for example with stfdx). At the moment all we do with these computed register addresses is to assert that they are identical to the ones coming from decode2 one cycle later. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
parent
047be5c0c3
commit
06c13d4988
@ -276,6 +276,12 @@ package common is
|
||||
redirect_nia : std_ulogic_vector(63 downto 0);
|
||||
end record;
|
||||
|
||||
type Decode1ToRegisterFileType is record
|
||||
reg_1_addr : gspr_index_t;
|
||||
reg_2_addr : gspr_index_t;
|
||||
reg_3_addr : gspr_index_t;
|
||||
end record;
|
||||
|
||||
type bypass_data_t is record
|
||||
tag : instr_tag_t;
|
||||
data : std_ulogic_vector(63 downto 0);
|
||||
|
||||
@ -63,6 +63,7 @@ architecture behave of core is
|
||||
-- decode signals
|
||||
signal decode1_to_decode2: Decode1ToDecode2Type;
|
||||
signal decode1_to_fetch1: Decode1ToFetch1Type;
|
||||
signal decode1_to_register_file: Decode1ToRegisterFileType;
|
||||
signal decode2_to_execute1: Decode2ToExecute1Type;
|
||||
|
||||
-- register file signals
|
||||
@ -285,6 +286,7 @@ begin
|
||||
f_in => icache_to_decode1,
|
||||
d_out => decode1_to_decode2,
|
||||
f_out => decode1_to_fetch1,
|
||||
r_out => decode1_to_register_file,
|
||||
log_out => log_data(109 downto 97)
|
||||
);
|
||||
|
||||
@ -329,6 +331,8 @@ begin
|
||||
)
|
||||
port map (
|
||||
clk => clk,
|
||||
stall => decode2_stall_out,
|
||||
d1_in => decode1_to_register_file,
|
||||
d_in => decode2_to_register_file,
|
||||
d_out => register_file_to_decode2,
|
||||
w_in => writeback_to_register_file,
|
||||
|
||||
37
decode1.vhdl
37
decode1.vhdl
@ -5,6 +5,7 @@ use ieee.numeric_std.all;
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.decode_types.all;
|
||||
use work.insn_helpers.all;
|
||||
|
||||
entity decode1 is
|
||||
generic (
|
||||
@ -24,6 +25,7 @@ entity decode1 is
|
||||
f_in : in IcacheToDecode1Type;
|
||||
f_out : out Decode1ToFetch1Type;
|
||||
d_out : out Decode1ToDecode2Type;
|
||||
r_out : out Decode1ToRegisterFileType;
|
||||
log_out : out std_ulogic_vector(12 downto 0)
|
||||
);
|
||||
end entity decode1;
|
||||
@ -628,6 +630,7 @@ begin
|
||||
|
||||
decode1_1: process(all)
|
||||
variable v : Decode1ToDecode2Type;
|
||||
variable vr : Decode1ToRegisterFileType;
|
||||
variable vi : reg_internal_t;
|
||||
variable majorop : major_opcode_t;
|
||||
variable minor4op : std_ulogic_vector(10 downto 0);
|
||||
@ -636,6 +639,8 @@ begin
|
||||
variable br_target : std_ulogic_vector(61 downto 0);
|
||||
variable br_offset : signed(23 downto 0);
|
||||
variable bv : br_predictor_t;
|
||||
variable fprs, fprabc : std_ulogic;
|
||||
variable in3rc : std_ulogic;
|
||||
begin
|
||||
v := Decode1ToDecode2Init;
|
||||
vi := reg_internal_t_init;
|
||||
@ -646,6 +651,10 @@ begin
|
||||
v.stop_mark := f_in.stop_mark;
|
||||
v.big_endian := f_in.big_endian;
|
||||
|
||||
fprs := '0';
|
||||
fprabc := '0';
|
||||
in3rc := '0';
|
||||
|
||||
if f_in.valid = '1' then
|
||||
report "Decode insn " & to_hstring(f_in.insn) & " at " & to_hstring(f_in.nia);
|
||||
end if;
|
||||
@ -665,6 +674,7 @@ begin
|
||||
minor4op := f_in.insn(5 downto 0) & f_in.insn(10 downto 6);
|
||||
vi.override := not decode_op_4_valid(to_integer(unsigned(minor4op)));
|
||||
v.decode := decode_op_4_array(to_integer(unsigned(f_in.insn(5 downto 0))));
|
||||
in3rc := '1';
|
||||
|
||||
when 31 =>
|
||||
-- major opcode 31, lots of things
|
||||
@ -688,6 +698,10 @@ begin
|
||||
when others =>
|
||||
end case;
|
||||
end if;
|
||||
if HAS_FPU and std_match(f_in.insn(10 downto 1), "1----10111") then
|
||||
-- lower half of column 23 has FP loads and stores
|
||||
fprs := '1';
|
||||
end if;
|
||||
|
||||
when 16 =>
|
||||
-- Predict backward branches as taken, forward as untaken
|
||||
@ -715,6 +729,12 @@ begin
|
||||
when 30 =>
|
||||
v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 1))));
|
||||
|
||||
when 52 | 53 | 54 | 55 =>
|
||||
-- stfd[u] and stfs[u]
|
||||
if HAS_FPU then
|
||||
fprs := '1';
|
||||
end if;
|
||||
|
||||
when 58 =>
|
||||
v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0))));
|
||||
|
||||
@ -725,6 +745,9 @@ begin
|
||||
if f_in.insn(5) = '0' and not std_match(f_in.insn(10 downto 1), "11-1001110") then
|
||||
vi.override := '1';
|
||||
end if;
|
||||
in3rc := '1';
|
||||
fprabc := '1';
|
||||
fprs := '1';
|
||||
end if;
|
||||
|
||||
when 62 =>
|
||||
@ -738,11 +761,23 @@ begin
|
||||
else
|
||||
v.decode := decode_op_63h_array(to_integer(unsigned(f_in.insn(4 downto 1))));
|
||||
end if;
|
||||
in3rc := '1';
|
||||
fprabc := '1';
|
||||
fprs := '1';
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
|
||||
-- Work out GPR/FPR read addresses
|
||||
vr.reg_1_addr := fprabc & insn_ra(f_in.insn);
|
||||
vr.reg_2_addr := fprabc & insn_rb(f_in.insn);
|
||||
if in3rc = '1' then
|
||||
vr.reg_3_addr := fprabc & insn_rcreg(f_in.insn);
|
||||
else
|
||||
vr.reg_3_addr := fprs & insn_rs(f_in.insn);
|
||||
end if;
|
||||
|
||||
if f_in.fetch_failed = '1' then
|
||||
v.valid := '1';
|
||||
vi.override := '1';
|
||||
@ -788,6 +823,8 @@ begin
|
||||
f_out.redirect <= br.predict;
|
||||
f_out.redirect_nia <= br_target & "00";
|
||||
flush_out <= bv.predict or br.predict;
|
||||
|
||||
r_out <= vr;
|
||||
end process;
|
||||
|
||||
d1_log: if LOG_LENGTH > 0 generate
|
||||
|
||||
@ -14,7 +14,9 @@ entity register_file is
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
stall : in std_ulogic;
|
||||
|
||||
d1_in : in Decode1ToRegisterFileType;
|
||||
d_in : in Decode2ToRegisterFileType;
|
||||
d_out : out RegisterFileToDecode2Type;
|
||||
|
||||
@ -39,9 +41,13 @@ architecture behaviour of register_file is
|
||||
signal rd_port_b : std_ulogic_vector(63 downto 0);
|
||||
signal dbg_data : std_ulogic_vector(63 downto 0);
|
||||
signal dbg_ack : std_ulogic;
|
||||
signal addr_1_reg : gspr_index_t;
|
||||
signal addr_2_reg : gspr_index_t;
|
||||
signal addr_3_reg : gspr_index_t;
|
||||
begin
|
||||
-- synchronous writes
|
||||
register_write_0: process(clk)
|
||||
variable a_addr, b_addr, c_addr : gspr_index_t;
|
||||
variable w_addr : gspr_index_t;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
@ -56,6 +62,19 @@ begin
|
||||
assert not(is_x(w_in.write_data)) and not(is_x(w_in.write_reg)) severity failure;
|
||||
registers(to_integer(unsigned(w_addr))) <= w_in.write_data;
|
||||
end if;
|
||||
|
||||
a_addr := d1_in.reg_1_addr;
|
||||
b_addr := d1_in.reg_2_addr;
|
||||
c_addr := d1_in.reg_3_addr;
|
||||
|
||||
if stall = '0' then
|
||||
addr_1_reg <= a_addr;
|
||||
addr_2_reg <= b_addr;
|
||||
addr_3_reg <= c_addr;
|
||||
end if;
|
||||
assert (d_in.read1_enable = '0') or (d_in.read1_reg = addr_1_reg) severity failure;
|
||||
assert (d_in.read2_enable = '0') or (d_in.read2_reg = addr_2_reg) severity failure;
|
||||
assert (d_in.read3_enable = '0') or (d_in.read3_reg = addr_3_reg) severity failure;
|
||||
end if;
|
||||
end process register_write_0;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user