Move LR, CTR and TAR out of the register file

By putting CTR on the odd side and LR and TAR on the even side, we can
read and write CTR for bdnz-style instructions in parallel with
reading LR or TAR for indirect branches and writing LR for branches
with LK=1.  Thus we don't need to double up any of these instructions,
giving a simplification in decode2.

We now have logic for printing LR and CTR at the end of a simulation
in execute1, in addition to the similar logic in register_file and
cr_file.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/379/head
Paul Mackerras 2 years ago
parent bc4d02cb0d
commit 337b104250

@ -132,12 +132,15 @@ package common is
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;
-- 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

type ram_spr_info is record
index : ramspr_index;
@ -322,7 +325,6 @@ package common is
rc: std_ulogic;
oe: std_ulogic;
invert_a: std_ulogic;
addm1 : std_ulogic;
invert_out: std_ulogic;
input_carry: carry_in_t;
output_carry: std_ulogic;
@ -350,11 +352,12 @@ package common is
ramspr_wraddr : ramspr_index;
ramspr_write_even : std_ulogic;
ramspr_write_odd : std_ulogic;
dec_ctr : std_ulogic;
end record;
constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
(valid => '0', unit => NONE, fac => NONE, insn_type => OP_ILLEGAL, instr_tag => instr_tag_init,
write_reg_enable => '0',
lr => '0', br_abs => '0', rc => '0', oe => '0', invert_a => '0', addm1 => '0',
lr => '0', br_abs => '0', rc => '0', oe => '0', invert_a => '0',
invert_out => '0', input_carry => ZERO, output_carry => '0', input_cr => '0',
output_cr => '0', output_xer => '0',
is_32bit => '0', is_signed => '0', xerc => xerc_init, reserve => '0', br_pred => '0',
@ -366,6 +369,7 @@ package common is
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',
dec_ctr => '0',
others => (others => '0'));

type MultiplyInputType is record
@ -780,25 +784,8 @@ package body common is
return to_integer(unsigned(insn(15 downto 11) & insn(20 downto 16)));
end;
function fast_spr_num(spr: spr_num_t) return gspr_index_t is
variable n : integer range 0 to 31;
-- tmp variable introduced as workaround for VCS compilation
-- simulation was failing with subtype constraint mismatch error
-- see GitHub PR #173
variable tmp : std_ulogic_vector(4 downto 0);
begin
case spr is
when SPR_LR =>
n := 0; -- N.B. decode2 relies on this specific value
when SPR_CTR =>
n := 1; -- N.B. decode2 relies on this specific value
when SPR_TAR =>
n := 13;
when others =>
n := 0;
return "0000000";
end case;
tmp := std_ulogic_vector(to_unsigned(n, 5));
return "01" & tmp;
return "0000000";
end;

function gspr_to_gpr(i: gspr_index_t) return gpr_index_t is

@ -138,6 +138,7 @@ architecture behave of core is
signal rst_dbg : std_ulogic;
signal alt_reset_d : std_ulogic;

signal sim_ex_dump: std_ulogic;
signal sim_cr_dump: std_ulogic;

-- Debug actions
@ -326,7 +327,7 @@ begin
dbg_gpr_addr => dbg_gpr_addr,
dbg_gpr_data => dbg_gpr_data,
sim_dump => terminate,
sim_dump_done => sim_cr_dump,
sim_dump_done => sim_ex_dump,
log_out => log_data(255 downto 184)
);

@ -347,6 +348,7 @@ begin

execute1_0: entity work.execute1
generic map (
SIM => SIM,
EX1_BYPASS => EX1_BYPASS,
HAS_FPU => HAS_FPU,
HAS_SHORT_MULT => HAS_SHORT_MULT,
@ -376,6 +378,8 @@ begin
dc_events => dcache_events,
ic_events => icache_events,
terminate_out => terminate,
sim_dump => sim_ex_dump,
sim_dump_done => sim_cr_dump,
log_out => log_data(134 downto 120),
log_rd_addr => log_rd_addr,
log_rd_data => log_rd_data,

@ -89,8 +89,8 @@ architecture behaviour of decode1 is
28 => (ALU, NONE, OP_AND, NONE, CONST_UI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0', NONE), -- andi.
29 => (ALU, NONE, OP_AND, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '0', NONE), -- andis.
0 => (ALU, NONE, OP_ATTN, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1', NONE), -- attn
18 => (ALU, NONE, OP_B, NONE, CONST_LI, NONE, SPR, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE), -- b
16 => (ALU, NONE, OP_BC, SPR, CONST_BD, NONE, SPR , '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE), -- bc
18 => (ALU, NONE, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE), -- b
16 => (ALU, NONE, OP_BC, NONE, CONST_BD, NONE, NONE, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE), -- bc
11 => (ALU, NONE, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0', NONE), -- cmpi
10 => (ALU, NONE, OP_CMP, RA, CONST_UI, NONE, NONE, '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- cmpli
34 => (LDST, NONE, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE), -- lbz
@ -177,7 +177,7 @@ architecture behaviour of decode1 is
-- addpcis
2#001# => (ALU, NONE, OP_ADD, CIA, CONST_DXHI4, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE),
-- bclr, bcctr, bctar
2#100# => (ALU, NONE, OP_BCREG, SPR, SPR, NONE, SPR, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE),
2#100# => (ALU, NONE, OP_BCREG, NONE, NONE, NONE, SPR, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0', NONE),
-- isync
2#111# => (ALU, NONE, OP_ISYNC, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0', NONE),
-- rfid
@ -530,6 +530,13 @@ architecture behaviour of decode1 is
begin
ret := (index => 0, isodd => '0', valid => '1');
case sprn is
when SPR_LR =>
ret.index := RAMSPR_LR;
when SPR_CTR =>
ret.index := RAMSPR_CTR;
ret.isodd := '1';
when SPR_TAR =>
ret.index := RAMSPR_TAR;
when SPR_SRR0 =>
ret.index := RAMSPR_SRR0;
when SPR_SRR1 =>
@ -683,13 +690,6 @@ begin
end if;

when 16 =>
-- CTR may be needed as input to bc
if f_in.insn(23) = '0' then
v.ispr1 := fast_spr_num(SPR_CTR);
v.ispro := fast_spr_num(SPR_CTR);
elsif f_in.insn(0) = '1' then
v.ispro := fast_spr_num(SPR_LR);
end if;
-- 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);
@ -698,37 +698,12 @@ begin
-- Unconditional branches are always taken
v.br_pred := '1';
br_offset := signed(f_in.insn(25 downto 2));
if f_in.insn(0) = '1' then
v.ispro := fast_spr_num(SPR_LR);
end if;

when 19 =>
vi.override := not decode_op_19_valid(to_integer(unsigned(f_in.insn(5 downto 1) & f_in.insn(10 downto 6))));
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)));

-- Work out ispr1/ispr2 independent of v.decode since they seem to be critical path
if f_in.insn(2) = '0' then
-- Could be OP_BCREG: bclr, bcctr, bctar
-- Branch uses CTR as condition when BO(2) is 0. This is
-- also used to indicate that CTR is modified (they go
-- together).
-- bcctr doesn't update CTR or use it in the branch condition
if f_in.insn(23) = '0' and (f_in.insn(10) = '0' or f_in.insn(6) = '1') then
v.ispr1 := fast_spr_num(SPR_CTR);
v.ispro := fast_spr_num(SPR_CTR);
elsif f_in.insn(0) = '1' then
v.ispro := fast_spr_num(SPR_LR);
end if;
if f_in.insn(10) = '0' then
v.ispr2 := fast_spr_num(SPR_LR);
elsif f_in.insn(6) = '0' then
v.ispr2 := fast_spr_num(SPR_CTR);
else
v.ispr2 := fast_spr_num(SPR_TAR);
end if;
end if;

when 24 =>
-- ori, special-case the standard NOP
if std_match(f_in.insn, "01100000000000000000000000000000") then

@ -406,6 +406,7 @@ begin
variable length : std_ulogic_vector(3 downto 0);
variable op : insn_type_t;
variable valid_in : std_ulogic;
variable decctr : std_ulogic;
begin
v := dc2;

@ -470,17 +471,45 @@ begin
end if;
op := d_in.decode.insn_type;

-- Does this instruction decrement CTR?
-- bc, bclr, bctar with BO(2) = 0 do, but not bcctr.
decctr := '0';
if d_in.insn(23) = '0' and
(op = OP_BC or
(op = OP_BCREG and not (d_in.insn(10) = '1' and d_in.insn(6) = '0'))) then
decctr := '1';
end if;
v.e.dec_ctr := decctr;

v.repeat := d_in.decode.repeat;
if d_in.decode.repeat /= NONE then
v.e.repeat := '1';
elsif v.e.lr = '1' and decoded_reg_a.reg_valid = '1' then
-- bcl/bclrl/bctarl that needs to write both CTR and LR has to be doubled
v.e.repeat := '1';
end if;

v.e.spr_select := d_in.spr_info;

if decctr = '1' then
-- read and write CTR
v.e.ramspr_odd_rdaddr := RAMSPR_CTR;
v.e.ramspr_wraddr := RAMSPR_CTR;
v.e.ramspr_write_odd := '1';
end if;
if v.e.lr = '1' then
-- write LR
v.e.ramspr_wraddr := RAMSPR_LR;
v.e.ramspr_write_even := '1';
end if;

case op is
when OP_BCREG =>
if d_in.insn(10) = '0' then
v.e.ramspr_even_rdaddr := RAMSPR_LR;
elsif d_in.insn(6) = '0' then
v.e.ramspr_odd_rdaddr := RAMSPR_CTR;
v.e.ramspr_rd_odd := '1';
else
v.e.ramspr_even_rdaddr := RAMSPR_TAR;
end if;
when OP_MFSPR =>
v.e.ramspr_even_rdaddr := d_in.ram_spr.index;
v.e.ramspr_odd_rdaddr := d_in.ram_spr.index;
@ -520,7 +549,6 @@ begin
v.e.write_reg := decoded_reg_o.reg;
v.e.write_reg_enable := decoded_reg_o.reg_valid;
v.e.invert_a := d_in.decode.invert_a;
v.e.addm1 := '0';
v.e.insn_type := op;
v.e.invert_out := d_in.decode.invert_out;
v.e.input_carry := d_in.decode.input_carry;
@ -536,14 +564,6 @@ begin
v.e.br_pred := d_in.br_pred;
v.e.result_sel := result_select(op);
v.e.sub_select := subresult_select(op);
if op = OP_BC or op = OP_BCREG then
if d_in.insn(23) = '0' and
not (d_in.decode.insn_type = OP_BCREG and d_in.insn(10) = '0') then
-- decrement CTR if BO(2) = 0 and not bcctr
v.e.addm1 := '1';
v.e.result_sel := "000"; -- select adder output
end if;
end if;
if op = OP_MFSPR then
if is_fast_spr(d_in.ispr1) = '1' then
v.e.result_sel := "000"; -- adder_result, effectively a_in
@ -562,16 +582,9 @@ begin
-- dc2.busy = 1 and dc2.e.valid = 1, thus this must be a repeated instruction.
-- Set up for the second iteration (if deferred = 1 this will all be ignored)
v.e.second := '1';
case dc2.repeat is
when DUPD =>
-- update-form loads, 2nd instruction writes RA
v.e.write_reg := dc2.e.read_reg1;
when NONE =>
-- bcl/bclrl/bctarl that needs to write both CTR and LR
v.e.write_reg(0) := '0'; -- point to LR
v.e.result_sel := "110"; -- select NIA (to go to LR)
when others =>
end case;
-- DUPD is the only possibility here:
-- update-form loads, 2nd instruction writes RA
v.e.write_reg := dc2.e.read_reg1;
end if;

-- issue control

@ -12,6 +12,7 @@ use work.ppc_fx_insns.all;

entity execute1 is
generic (
SIM : boolean := false;
EX1_BYPASS : boolean := true;
HAS_FPU : boolean := true;
HAS_SHORT_MULT : boolean := false;
@ -54,6 +55,10 @@ entity execute1 is
dc_events : in DcacheEventType;
ic_events : in IcacheEventType;

-- debug
sim_dump : in std_ulogic;
sim_dump_done : out std_ulogic;

log_out : out std_ulogic_vector(14 downto 0);
log_rd_addr : out std_ulogic_vector(31 downto 0);
log_rd_data : in std_ulogic_vector(63 downto 0);
@ -92,10 +97,12 @@ architecture behaviour of execute1 is
fp_intr : std_ulogic;
res2_sel : std_ulogic_vector(1 downto 0);
bypass_valid : std_ulogic;
ramspr_odd_data : std_ulogic_vector(63 downto 0);
end record;
constant actions_type_init : actions_type :=
(e => Execute1ToWritebackInit, se => side_effect_init,
new_msr => (others => '0'), res2_sel => "00", others => '0');
new_msr => (others => '0'), res2_sel => "00",
ramspr_odd_data => 64x"0", others => '0');

type reg_stage1_type is record
e : Execute1ToWritebackType;
@ -104,7 +111,6 @@ architecture behaviour of execute1 is
fp_exception_next : std_ulogic;
trace_next : std_ulogic;
prev_op : insn_type_t;
br_taken : std_ulogic;
oe : std_ulogic;
mul_select : std_ulogic_vector(1 downto 0);
res2_sel : std_ulogic_vector(1 downto 0);
@ -122,11 +128,12 @@ architecture behaviour of execute1 is
xerc : xer_common_t;
xerc_valid : std_ulogic;
ramspr_wraddr : ramspr_index;
ramspr_odd_data : std_ulogic_vector(63 downto 0);
end record;
constant reg_stage1_type_init : reg_stage1_type :=
(e => Execute1ToWritebackInit, se => side_effect_init,
busy => '0',
fp_exception_next => '0', trace_next => '0', prev_op => OP_ILLEGAL, br_taken => '0',
fp_exception_next => '0', trace_next => '0', prev_op => OP_ILLEGAL,
oe => '0', mul_select => "00", res2_sel => "00",
spr_select => spr_id_init, pmu_spr_num => 5x"0",
mul_in_progress => '0', mul_finish => '0', div_in_progress => '0',
@ -134,7 +141,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_wraddr => 0, ramspr_odd_data => 64x"0");

type reg_stage2_type is record
e : Execute1ToWritebackType;
@ -514,7 +521,7 @@ begin
odd_wr_data := intr_srr1(ctrl.msr, interrupt_in.srr1);
else
even_wr_data := ex1.e.write_data;
odd_wr_data := ex1.e.write_data;
odd_wr_data := ex1.ramspr_odd_data;
end if;
ramspr_wr_addr <= wr_addr;
ramspr_even_wr_data <= even_wr_data;
@ -531,7 +538,7 @@ begin
ramspr_even <= even_rd_data;
end if;
if ex1.se.ramspr_write_odd = '1' and e_in.ramspr_odd_rdaddr = ex1.ramspr_wraddr then
ramspr_odd <= ex1.e.write_data;
ramspr_odd <= ex1.ramspr_odd_data;
else
ramspr_odd <= odd_rd_data;
end if;
@ -600,7 +607,6 @@ begin
-- Data path for integer instructions (first execute stage)
execute1_dp: process(all)
variable a_inv : std_ulogic_vector(63 downto 0);
variable b_or_m1 : std_ulogic_vector(63 downto 0);
variable sum_with_carry : std_ulogic_vector(64 downto 0);
variable sign1, sign2 : std_ulogic;
variable abs1, abs2 : signed(63 downto 0);
@ -635,12 +641,7 @@ begin
else
a_inv := not a_in;
end if;
if e_in.addm1 = '0' then
b_or_m1 := b_in;
else
b_or_m1 := (others => '1');
end if;
sum_with_carry := ppc_adde(a_inv, b_or_m1,
sum_with_carry := ppc_adde(a_inv, b_in,
decode_input_carry(e_in.input_carry, xerc_in));
adder_result <= sum_with_carry(63 downto 0);
carry_32 <= sum_with_carry(32) xor a_inv(32) xor b_in(32);
@ -956,6 +957,10 @@ begin

v.se.ramspr_write_even := e_in.ramspr_write_even;
v.se.ramspr_write_odd := e_in.ramspr_write_odd;
v.ramspr_odd_data := c_in;
if e_in.dec_ctr = '1' then
v.ramspr_odd_data := std_ulogic_vector(unsigned(ramspr_odd) - 1);
end if;

-- Note the difference between v.exception and v.trap:
-- v.exception signals a condition that prevents execution of the
@ -1059,61 +1064,42 @@ begin
end if;
v.se.write_cfar := '1';
when OP_BC =>
-- read_data1 is CTR
-- If this instruction updates both CTR and LR, then it is
-- doubled; the first instruction decrements CTR and determines
-- whether the branch is taken, and the second does the
-- redirect and the LR update.
-- If CTR is being decremented, it is in ramspr_odd.
bo := insn_bo(e_in.insn);
bi := insn_bi(e_in.insn);
if e_in.second = '0' then
v.take_branch := ppc_bc_taken(bo, bi, cr_in, a_in);
else
v.take_branch := ex1.br_taken;
end if;
v.take_branch := ppc_bc_taken(bo, bi, cr_in, ramspr_odd);
if v.take_branch = '1' then
v.e.br_offset := b_in;
v.e.abs_br := insn_aa(e_in.insn);
end if;
if e_in.repeat = '0' or e_in.second = '1' then
-- Mispredicted branches cause a redirect
if v.take_branch /= e_in.br_pred then
v.e.redirect := '1';
end if;
v.direct_branch := '1';
v.e.br_last := '1';
v.e.br_taken := v.take_branch;
if ex1.msr(MSR_BE) = '1' then
v.do_trace := '1';
end if;
v.se.write_cfar := v.take_branch;
-- Mispredicted branches cause a redirect
if v.take_branch /= e_in.br_pred then
v.e.redirect := '1';
end if;
v.direct_branch := '1';
v.e.br_last := '1';
v.e.br_taken := v.take_branch;
if ex1.msr(MSR_BE) = '1' then
v.do_trace := '1';
end if;
v.se.write_cfar := v.take_branch;
when OP_BCREG =>
-- read_data1 is CTR, read_data2 is target register (CTR, LR or TAR)
-- If this instruction updates both CTR and LR, then it is
-- doubled; the first instruction decrements CTR and determines
-- whether the branch is taken, and the second does the
-- redirect and the LR update.
-- If CTR is being decremented, it is in ramspr_odd.
-- The target address is in ramspr_result (LR, CTR or TAR).
bo := insn_bo(e_in.insn);
bi := insn_bi(e_in.insn);
if e_in.second = '0' then
v.take_branch := ppc_bc_taken(bo, bi, cr_in, a_in);
else
v.take_branch := ex1.br_taken;
end if;
v.take_branch := ppc_bc_taken(bo, bi, cr_in, ramspr_odd);
if v.take_branch = '1' then
v.e.br_offset := b_in;
v.e.br_offset := ramspr_result;
v.e.abs_br := '1';
end if;
if e_in.repeat = '0' or e_in.second = '1' then
-- Indirect branches are never predicted taken
v.e.redirect := v.take_branch;
v.e.br_taken := v.take_branch;
if ex1.msr(MSR_BE) = '1' then
v.do_trace := '1';
end if;
v.se.write_cfar := v.take_branch;
-- Indirect branches are never predicted taken
v.e.redirect := v.take_branch;
v.e.br_taken := v.take_branch;
if ex1.msr(MSR_BE) = '1' then
v.do_trace := '1';
end if;
v.se.write_cfar := v.take_branch;

when OP_RFID =>
srr1 := ramspr_odd;
@ -1130,7 +1116,7 @@ begin
v.new_msr(MSR_DR) := '1';
end if;
v.se.write_msr := '1';
v.e.br_offset := ramspr_even;
v.e.br_offset := ramspr_result;
v.e.abs_br := '1';
v.e.redirect := '1';
v.se.write_cfar := '1';
@ -1343,6 +1329,7 @@ begin
v.mul_select := e_in.sub_select(1 downto 0);
v.se := side_effect_init;
v.ramspr_wraddr := e_in.ramspr_wraddr;
v.ramspr_odd_data := actions.ramspr_odd_data;
end if;

lv := Execute1ToLoadstore1Init;
@ -1430,7 +1417,6 @@ begin
v.e.valid := actions.complete;
bypass_valid := actions.bypass_valid;
v.taken_branch_event := actions.take_branch;
v.br_taken := actions.take_branch;
v.trace_next := actions.do_trace;
v.fp_exception_next := actions.fp_intr;
v.res2_sel := actions.res2_sel;
@ -1759,6 +1745,25 @@ begin
exception_log <= v.e.interrupt;
end process;

sim_dump_test: if SIM generate
dump_exregs: process(all)
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));
sim_dump_done <= '1';
else
sim_dump_done <= '0';
end if;
end process;
end generate;

-- Keep GHDL synthesis happy
sim_dump_test_synth: if not SIM generate
sim_dump_done <= '0';
end generate;

e1_log: if LOG_LENGTH > 0 generate
signal log_data : std_ulogic_vector(14 downto 0);
begin

@ -130,9 +130,6 @@ begin
loop_0: for i in 0 to 31 loop
report "GPR" & integer'image(i) & " " & to_hstring(registers(i));
end loop loop_0;

report "LR " & to_hstring(registers(to_integer(unsigned(fast_spr_num(SPR_LR)))));
report "CTR " & to_hstring(registers(to_integer(unsigned(fast_spr_num(SPR_CTR)))));
sim_dump_done <= '1';
else
sim_dump_done <= '0';

Loading…
Cancel
Save