Skip to content

Commit

Permalink
Merge pull request #378 from mikey/ux-cleanup
Browse files Browse the repository at this point in the history
Metavalue cleanup
  • Loading branch information
paulusmack authored Aug 1, 2022
2 parents 281a125 + eeac86c commit de8fd49
Show file tree
Hide file tree
Showing 32 changed files with 287 additions and 118 deletions.
35 changes: 18 additions & 17 deletions common.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -115,28 +115,29 @@ package common is

-- Some SPRs are stored in a pair of small RAMs in execute1
-- Even half:
subtype ramspr_index is natural range 0 to 7;
constant RAMSPR_SRR0 : ramspr_index := 0;
constant RAMSPR_HSRR0 : ramspr_index := 1;
constant RAMSPR_SPRG0 : ramspr_index := 2;
constant RAMSPR_SPRG2 : ramspr_index := 3;
constant RAMSPR_HSPRG0 : ramspr_index := 4;
constant RAMSPR_LR : ramspr_index := 5; -- must equal RAMSPR_CTR
constant RAMSPR_TAR : ramspr_index := 6;
subtype ramspr_index_range is natural range 0 to 7;
subtype ramspr_index is unsigned(2 downto 0);
constant RAMSPR_SRR0 : ramspr_index := to_unsigned(0,3);
constant RAMSPR_HSRR0 : ramspr_index := to_unsigned(1,3);
constant RAMSPR_SPRG0 : ramspr_index := to_unsigned(2,3);
constant RAMSPR_SPRG2 : ramspr_index := to_unsigned(3,3);
constant RAMSPR_HSPRG0 : ramspr_index := to_unsigned(4,3);
constant RAMSPR_LR : ramspr_index := to_unsigned(5,3); -- must equal RAMSPR_CTR
constant RAMSPR_TAR : ramspr_index := to_unsigned(6,3);
-- Odd half:
constant RAMSPR_SRR1 : ramspr_index := 0;
constant RAMSPR_HSRR1 : ramspr_index := 1;
constant RAMSPR_SPRG1 : ramspr_index := 2;
constant RAMSPR_SPRG3 : ramspr_index := 3;
constant RAMSPR_HSPRG1 : ramspr_index := 4;
constant RAMSPR_CTR : ramspr_index := 5; -- must equal RAMSPR_LR
constant RAMSPR_SRR1 : ramspr_index := to_unsigned(0,3);
constant RAMSPR_HSRR1 : ramspr_index := to_unsigned(1,3);
constant RAMSPR_SPRG1 : ramspr_index := to_unsigned(2,3);
constant RAMSPR_SPRG3 : ramspr_index := to_unsigned(3,3);
constant RAMSPR_HSPRG1 : ramspr_index := to_unsigned(4,3);
constant RAMSPR_CTR : ramspr_index := to_unsigned(5,3); -- must equal RAMSPR_LR

type ram_spr_info is record
index : ramspr_index;
isodd : std_ulogic;
valid : std_ulogic;
end record;
constant ram_spr_info_init: ram_spr_info := (index => 0, others => '0');
constant ram_spr_info_init: ram_spr_info := (index => to_unsigned(0,3), others => '0');

subtype spr_selector is std_ulogic_vector(2 downto 0);
type spr_id is record
Expand Down Expand Up @@ -366,8 +367,8 @@ package common is
result_sel => "000", sub_select => "000",
repeat => '0', second => '0', spr_select => spr_id_init,
spr_is_ram => '0',
ramspr_even_rdaddr => 0, ramspr_odd_rdaddr => 0, ramspr_rd_odd => '0',
ramspr_wraddr => 0, ramspr_write_even => '0', ramspr_write_odd => '0',
ramspr_even_rdaddr => (others => '0'), ramspr_odd_rdaddr => (others => '0'), ramspr_rd_odd => '0',
ramspr_wraddr => (others => '0'), ramspr_write_even => '0', ramspr_write_odd => '0',
dbg_spr_access => '0',
dec_ctr => '0',
others => (others => '0'));
Expand Down
4 changes: 2 additions & 2 deletions core_debug.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ begin
valid := '1';
sel := "000";
isram := '1';
raddr := 0;
raddr := (others => '0');
odd := '0';
case gspr_index(4 downto 0) is
when 5x"00" =>
Expand Down Expand Up @@ -304,7 +304,7 @@ begin
when others =>
valid := '0';
end case;
dbg_spr_addr <= isram & sel & std_ulogic_vector(to_unsigned(raddr, 3)) & odd;
dbg_spr_addr <= isram & sel & std_ulogic_vector(raddr) & odd;
spr_index_valid <= valid;
end if;
end process;
Expand Down
104 changes: 76 additions & 28 deletions decode1.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ architecture behaviour of decode1 is

constant illegal_inst : decode_rom_t :=
(NONE, NONE, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE);
constant x_inst : decode_rom_t :=
(NONE, NONE, OP_ILLEGAL, NONE, NONE, NONE, NONE, 'X', 'X', 'X', 'X', ZERO, 'X', NONE, 'X', 'X', 'X', 'X', 'X', 'X', NONE, 'X', 'X', NONE);

-- If we have an FPU, then it is used for integer divisions,
-- otherwise a dedicated divider in the ALU is used.
Expand Down Expand Up @@ -530,7 +532,7 @@ architecture behaviour of decode1 is
function decode_ram_spr(sprn : spr_num_t) return ram_spr_info is
variable ret : ram_spr_info;
begin
ret := (index => 0, isodd => '0', valid => '1');
ret := (index => (others => '0'), isodd => '0', valid => '1');
case sprn is
when SPR_LR =>
ret.index := RAMSPR_LR;
Expand Down Expand Up @@ -664,28 +666,41 @@ begin
br_offset := (others => '0');

majorop := unsigned(f_in.insn(31 downto 26));
v.decode := major_decode_rom_array(to_integer(majorop));

sprn := decode_spr_num(f_in.insn);
v.spr_info := map_spr(sprn);
v.ram_spr := decode_ram_spr(sprn);
if is_X(majorop) then
v.decode := x_inst;
else
v.decode := major_decode_rom_array(to_integer(majorop));
end if;

case to_integer(unsigned(majorop)) is
when 4 =>
if is_X(f_in.insn) then
v.spr_info := (sel => "XXX", others => 'X');
v.ram_spr := (index => (others => 'X'), others => 'X');
else
sprn := decode_spr_num(f_in.insn);
v.spr_info := map_spr(sprn);
v.ram_spr := decode_ram_spr(sprn);
end if;

case unsigned(majorop) is
when "000100" => -- 4
-- major opcode 4, mostly VMX/VSX stuff but also some integer ops (madd*)
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';
may_read_rb := '1';

when 23 =>
when "010111" => -- 23
-- rlwnm[.]
may_read_rb := '1';

when 31 =>
when "011111" => -- 31
-- major opcode 31, lots of things
v.decode := decode_op_31_array(to_integer(unsigned(f_in.insn(10 downto 1))));
if is_X(f_in.insn) then
v.decode := x_inst;
else
v.decode := decode_op_31_array(to_integer(unsigned(f_in.insn(10 downto 1))));
end if;
may_read_rb := '1';

if std_match(f_in.insn(10 downto 1), "01-1010011") then
Expand All @@ -705,52 +720,79 @@ begin
end if;
when others =>
end case;
-- FIXME: This is a bit fragile doing this here but sprn depends
-- on f_in.insn
if is_X(f_in.insn) then
vi.override_decode.unit := NONE;
vi.override_unit := 'X';
vi.force_single := 'X';
end if;
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 =>
when "010000" => -- 16
-- Predict backward branches as taken, forward as untaken
v.br_pred := f_in.insn(15);
br_offset := resize(signed(f_in.insn(15 downto 2)), 24);

when 18 =>
when "010010" => -- 18
-- Unconditional branches are always taken
v.br_pred := '1';
br_offset := signed(f_in.insn(25 downto 2));

when 19 =>
vi.override := not decode_op_19_valid(to_integer(unsigned(f_in.insn(5 downto 1) & f_in.insn(10 downto 6))));
when "010011" => -- 19
if is_X(f_in.insn) then
vi.override := 'X';
else
vi.override := not decode_op_19_valid(to_integer(unsigned(f_in.insn(5 downto 1) & f_in.insn(10 downto 6))));
end if;
op_19_bits := f_in.insn(5) & f_in.insn(3) & f_in.insn(2);
v.decode := decode_op_19_array(to_integer(unsigned(op_19_bits)));
if is_X(op_19_bits) then
v.decode := x_inst;
else
v.decode := decode_op_19_array(to_integer(unsigned(op_19_bits)));
end if;

when 24 =>
when "011000" => -- 24
-- ori, special-case the standard NOP
if std_match(f_in.insn, "01100000000000000000000000000000") then
report "PPC_nop";
vi.override := '1';
vi.override_decode := nop_instr;
end if;

when 30 =>
v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 1))));
when "011110" => -- 30
if is_X(f_in.insn) then
v.decode := x_inst;
else
v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 1))));
end if;
may_read_rb := f_in.insn(4);

when 52 | 53 | 54 | 55 =>
when "110100" | "110101" | "110110" | "110111" => -- 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))));
when "111010" => -- 58
if is_X(f_in.insn) then
v.decode := x_inst;
else
v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0))));
end if;

when 59 =>
when "111011" => -- 59
if HAS_FPU then
-- floating point operations, mostly single-precision
v.decode := decode_op_59_array(to_integer(unsigned(f_in.insn(5 downto 1))));
if is_X(f_in.insn) then
v.decode := x_inst;
else
v.decode := decode_op_59_array(to_integer(unsigned(f_in.insn(5 downto 1))));
end if;
if f_in.insn(5) = '0' and not std_match(f_in.insn(10 downto 1), "11-1001110") then
vi.override := '1';
end if;
Expand All @@ -760,13 +802,19 @@ begin
may_read_rb := '1';
end if;

when 62 =>
v.decode := decode_op_62_array(to_integer(unsigned(f_in.insn(1 downto 0))));
when "111110" => -- 62
if is_X(f_in.insn) then
v.decode := x_inst;
else
v.decode := decode_op_62_array(to_integer(unsigned(f_in.insn(1 downto 0))));
end if;

when 63 =>
when "111111" => -- 63
if HAS_FPU then
-- floating point operations, general and double-precision
if f_in.insn(5) = '0' then
if is_X(f_in.insn) then
v.decode := x_inst;
elsif f_in.insn(5) = '0' then
v.decode := decode_op_63l_array(to_integer(unsigned(f_in.insn(4 downto 1) & f_in.insn(10 downto 6))));
else
v.decode := decode_op_63h_array(to_integer(unsigned(f_in.insn(4 downto 1))));
Expand Down
4 changes: 2 additions & 2 deletions decode2.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,8 @@ begin

v.e.dbg_spr_access := dbg_spr_req and not v.read_rspr;
if v.e.dbg_spr_access = '1' then
v.e.ramspr_even_rdaddr := to_integer(unsigned(dbg_spr_addr(3 downto 1)));
v.e.ramspr_odd_rdaddr := to_integer(unsigned(dbg_spr_addr(3 downto 1)));
v.e.ramspr_even_rdaddr := unsigned(dbg_spr_addr(3 downto 1));
v.e.ramspr_odd_rdaddr := unsigned(dbg_spr_addr(3 downto 1));
v.e.ramspr_rd_odd := dbg_spr_addr(0);
end if;

Expand Down
38 changes: 24 additions & 14 deletions execute1.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ architecture behaviour of execute1 is
taken_branch_event => '0', br_mispredict => '0',
msr => 64x"0",
xerc => xerc_init, xerc_valid => '0',
ramspr_wraddr => 0, ramspr_odd_data => 64x"0");
ramspr_wraddr => (others => '0'), ramspr_odd_data => 64x"0");

type reg_stage2_type is record
e : Execute1ToWritebackType;
Expand Down Expand Up @@ -221,7 +221,7 @@ architecture behaviour of execute1 is
signal irq_valid_log : std_ulogic;

-- SPR-related signals
type ramspr_half_t is array(ramspr_index) of std_ulogic_vector(63 downto 0);
type ramspr_half_t is array(ramspr_index_range) of std_ulogic_vector(63 downto 0);
signal even_sprs : ramspr_half_t := (others => (others => '0'));
signal odd_sprs : ramspr_half_t := (others => (others => '0'));
signal ramspr_even : std_ulogic_vector(63 downto 0);
Expand Down Expand Up @@ -510,8 +510,16 @@ begin
variable doit : std_ulogic;
begin
-- Read address mux and async RAM reading
even_rd_data := even_sprs(e_in.ramspr_even_rdaddr);
odd_rd_data := odd_sprs(e_in.ramspr_odd_rdaddr);
if is_X(e_in.ramspr_even_rdaddr) then
even_rd_data := (others => 'X');
else
even_rd_data := even_sprs(to_integer(e_in.ramspr_even_rdaddr));
end if;
if is_X(e_in.ramspr_even_rdaddr) then
odd_rd_data := (others => 'X');
else
odd_rd_data := odd_sprs(to_integer(e_in.ramspr_odd_rdaddr));
end if;

-- Write address and data muxes
doit := ex1.e.valid and not stage2_stall and not flush_in;
Expand Down Expand Up @@ -559,13 +567,15 @@ begin
begin
if rising_edge(clk) then
if ramspr_even_wr_enab = '1' then
even_sprs(ramspr_wr_addr) <= ramspr_even_wr_data;
report "writing even spr " & integer'image(ramspr_wr_addr) & " data=" &
assert not is_X(ramspr_wr_addr) report "Writing to unknown address" severity FAILURE;
even_sprs(to_integer(ramspr_wr_addr)) <= ramspr_even_wr_data;
report "writing even spr " & integer'image(to_integer(ramspr_wr_addr)) & " data=" &
to_hstring(ramspr_even_wr_data);
end if;
if ramspr_odd_wr_enab = '1' then
odd_sprs(ramspr_wr_addr) <= ramspr_odd_wr_data;
report "writing odd spr " & integer'image(ramspr_wr_addr) & " data=" &
assert not is_X(ramspr_wr_addr) report "Writing to unknown address" severity FAILURE;
odd_sprs(to_integer(ramspr_wr_addr)) <= ramspr_odd_wr_data;
report "writing odd spr " & integer'image(to_integer(ramspr_wr_addr)) & " data=" &
to_hstring(ramspr_odd_wr_data);
end if;
end if;
Expand Down Expand Up @@ -1160,12 +1170,12 @@ begin
when OP_MFMSR =>
when OP_MFSPR =>
if e_in.spr_is_ram = '1' then
if e_in.valid = '1' then
if e_in.valid = '1' and not is_X(e_in.insn) then
report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
"=" & to_hstring(alu_result);
end if;
elsif e_in.spr_select.valid = '1' then
if e_in.valid = '1' then
if e_in.valid = '1' and not is_X(e_in.insn) then
report "MFSPR to slow SPR " & integer'image(decode_spr_num(e_in.insn));
end if;
slow_op := '1';
Expand All @@ -1182,7 +1192,7 @@ begin
else
-- mfspr from unimplemented SPRs should be a nop in
-- supervisor mode and a program interrupt for user mode
if e_in.valid = '1' then
if e_in.valid = '1' and not is_X(e_in.insn) then
report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
" invalid";
end if;
Expand Down Expand Up @@ -1219,7 +1229,7 @@ begin
end if;
end if;
when OP_MTSPR =>
if e_in.valid = '1' then
if e_in.valid = '1' and not is_X(e_in.insn) then
report "MTSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) &
"=" & to_hstring(c_in);
end if;
Expand Down Expand Up @@ -1773,8 +1783,8 @@ begin
variable xer : std_ulogic_vector(63 downto 0);
begin
if sim_dump = '1' then
report "LR " & to_hstring(even_sprs(RAMSPR_LR));
report "CTR " & to_hstring(odd_sprs(RAMSPR_CTR));
report "LR " & to_hstring(even_sprs(to_integer(RAMSPR_LR)));
report "CTR " & to_hstring(odd_sprs(to_integer(RAMSPR_CTR)));
sim_dump_done <= '1';
else
sim_dump_done <= '0';
Expand Down
11 changes: 9 additions & 2 deletions fetch1.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,22 @@ begin
raddr := unsigned(r.nia(BTC_ADDR_BITS + 1 downto 2)) +
to_unsigned(2, BTC_ADDR_BITS);
if advance_nia = '1' then
btc_rd_data <= btc_memory(to_integer(raddr));
btc_rd_valid <= btc_valids(to_integer(raddr));
if is_X(raddr) then
btc_rd_data <= (others => 'X');
btc_rd_valid <= 'X';
else
btc_rd_data <= btc_memory(to_integer(raddr));
btc_rd_valid <= btc_valids(to_integer(raddr));
end if;
end if;
if btc_wr = '1' then
assert not is_X(btc_wr_addr) report "Writing to unknown address" severity FAILURE;
btc_memory(to_integer(unsigned(btc_wr_addr))) <= btc_wr_data;
end if;
if inval_btc = '1' or rst = '1' then
btc_valids <= (others => '0');
elsif btc_wr = '1' then
assert not is_X(btc_wr_addr) report "Writing to unknown address" severity FAILURE;
btc_valids(to_integer(unsigned(btc_wr_addr))) <= '1';
end if;
end if;
Expand Down
Loading

0 comments on commit de8fd49

Please sign in to comment.