From 6db626d24547b96bce576c8c3fdf2790c7d6c7ce Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 4 Aug 2022 15:17:25 +1000 Subject: [PATCH] icache: Log 36 bits of instruction rather than 32 This expands the field in the log buffer that stores the instruction fetched from the icache to 36 bits, so that we get the insn_code and illegal instruction indication. To do this, we reclaim 3 unused bits from execute1's portion and one other unused bit (previously just set to 0 in core.vhdl). This also alters the trigger behaviour to stop after one quarter of the log buffer has been filled with samples after the trigger, or 256 entries, whichever is less. This is to ensure that the trigger event doesn't get overwritten when the log buffer is small. This updates fmt_log to the new log format. Valid instructions are printed as a decimal insn_code value followed by the bottom 26 bits of the instruction. Illegal instructions are printed as "ill" followed by the full 32 bits of the instruction. Signed-off-by: Paul Mackerras --- core.vhdl | 10 +++++----- core_debug.vhdl | 3 ++- execute1.vhdl | 5 ++--- icache.vhdl | 9 ++++++--- scripts/fmt_log/fmt_log.c | 27 +++++++++++++++------------ 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/core.vhdl b/core.vhdl index 0624000..d7036f1 100644 --- a/core.vhdl +++ b/core.vhdl @@ -267,7 +267,7 @@ begin wishbone_in => wishbone_insn_in, wb_snoop_in => wb_snoop_in, events => icache_events, - log_out => log_data(96 downto 43) + log_out => log_data(100 downto 43) ); icache_stall_in <= decode1_busy; @@ -288,7 +288,7 @@ begin d_out => decode1_to_decode2, f_out => decode1_to_fetch1, r_out => decode1_to_register_file, - log_out => log_data(109 downto 97) + log_out => log_data(113 downto 101) ); decode1_stall_in <= decode2_stall_out; @@ -320,7 +320,7 @@ begin writeback_bypass => writeback_bypass, dbg_spr_req => dbg_spr_req, dbg_spr_addr => dbg_spr_addr, - log_out => log_data(119 downto 110) + log_out => log_data(123 downto 114) ); decode2_busy_in <= ex1_busy_out; @@ -399,7 +399,7 @@ begin dbg_spr_data => dbg_spr_data, sim_dump => sim_ex_dump, sim_dump_done => sim_cr_dump, - log_out => log_data(134 downto 120), + log_out => log_data(135 downto 124), log_rd_addr => log_rd_addr, log_rd_data => log_rd_data, log_wr_addr => log_wr_addr @@ -501,7 +501,7 @@ begin ); log_data(150) <= '0'; - log_data(139 downto 135) <= "00000"; + log_data(139 downto 136) <= "0000"; debug_0: entity work.core_debug generic map ( diff --git a/core_debug.vhdl b/core_debug.vhdl index c9c3f40..592cf85 100644 --- a/core_debug.vhdl +++ b/core_debug.vhdl @@ -175,7 +175,8 @@ begin gspr_index <= (others => '0'); else if do_log_trigger = '1' or log_trigger_delay /= 0 then - if log_trigger_delay = 255 then + if log_trigger_delay = 255 or + (LOG_LENGTH < 1024 and log_trigger_delay = LOG_LENGTH / 4) then log_dmi_trigger(1) <= '1'; log_trigger_delay <= 0; else diff --git a/execute1.vhdl b/execute1.vhdl index 024f5c2..92da2ee 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -65,7 +65,7 @@ entity execute1 is sim_dump : in std_ulogic; sim_dump_done : out std_ulogic; - log_out : out std_ulogic_vector(14 downto 0); + log_out : out std_ulogic_vector(11 downto 0); log_rd_addr : out std_ulogic_vector(31 downto 0); log_rd_data : in std_ulogic_vector(63 downto 0); log_wr_addr : in std_ulogic_vector(31 downto 0) @@ -1802,7 +1802,7 @@ begin end generate; e1_log: if LOG_LENGTH > 0 generate - signal log_data : std_ulogic_vector(14 downto 0); + signal log_data : std_ulogic_vector(11 downto 0); begin ex1_log : process(clk) begin @@ -1812,7 +1812,6 @@ begin exception_log & irq_valid_log & interrupt_in.intr & - "000" & ex2.e.write_enable & ex2.e.valid & (ex2.e.redirect or ex2.e.interrupt) & diff --git a/icache.vhdl b/icache.vhdl index 63de229..58e2b5c 100644 --- a/icache.vhdl +++ b/icache.vhdl @@ -71,7 +71,7 @@ entity icache is wb_snoop_in : in wishbone_master_out := wishbone_master_out_init; events : out IcacheEventType; - log_out : out std_ulogic_vector(53 downto 0) + log_out : out std_ulogic_vector(57 downto 0) ); end entity icache; @@ -244,6 +244,8 @@ architecture rtl of icache is signal snoop_index : index_t; signal snoop_hits : cache_way_valids_t; + signal log_insn : std_ulogic_vector(35 downto 0); + -- Return the cache line index (tag index) for an address function get_index(addr: std_ulogic_vector) return index_t is begin @@ -623,6 +625,7 @@ begin end if; i_out.insn <= insn(31 downto 0); i_out.icode <= icode; + log_insn <= cache_wr_data(35 downto 0); i_out.valid <= r.hit_valid; i_out.nia <= r.hit_nia; i_out.stop_mark <= r.hit_smark; @@ -872,7 +875,7 @@ begin icache_log: if LOG_LENGTH > 0 generate -- Output data to logger - signal log_data : std_ulogic_vector(53 downto 0); + signal log_data : std_ulogic_vector(57 downto 0); begin data_log: process(clk) variable lway: way_t; @@ -885,7 +888,7 @@ begin wstate := '1'; end if; log_data <= i_out.valid & - i_out.insn & + log_insn & wishbone_in.ack & r.wb.adr(2 downto 0) & r.wb.stb & r.wb.cyc & diff --git a/scripts/fmt_log/fmt_log.c b/scripts/fmt_log/fmt_log.c index 09d41ad..e92ecba 100644 --- a/scripts/fmt_log/fmt_log.c +++ b/scripts/fmt_log/fmt_log.c @@ -22,7 +22,7 @@ struct log_entry { u64 ic_wb_adr: 3; u64 ic_wb_ack: 1; - u64 ic_insn: 32; + u64 ic_insn: 36; u64 ic_valid: 1; u64 d1_valid: 1; u64 d1_unit: 2; @@ -39,9 +39,8 @@ struct log_entry { u64 e1_stall_out: 1; u64 e1_redirect: 1; u64 e1_valid: 1; - u64 e1_write_enable: 1; - u64 e1_unused: 3; + u64 e1_write_enable: 1; u64 e1_irq_state: 1; u64 e1_irq: 1; u64 e1_exception: 1; @@ -49,7 +48,7 @@ struct log_entry { u64 e1_msr_ir: 1; u64 e1_msr_pr: 1; u64 e1_msr_ee: 1; - u64 pad1: 5; + u64 pad1: 4; u64 ls_state: 3; u64 ls_dw_done: 1; u64 ls_min_done: 1; @@ -134,9 +133,9 @@ int main(int ac, char **av) full_nia[log.nia_lo & 0xf] = (log.nia_hi? 0xc000000000000000: 0) | (log.nia_lo << 2); if (lineno % 20 == 1) { - printf(" fetch1 NIA icache decode1 decode2 execute1 loadstore dcache CR GSPR\n"); - printf(" ---------------- TAHW S -WB-- pN --insn-- pN un op pN byp FR IIE MSR WC SD MM CE SRTO DE -WB-- c ms reg val\n"); - printf(" LdMy t csnSa IA IA it IA abc le srx EPID em tw rd mx tAwp vr csnSa 0 k\n"); + printf(" fetch1 NIA icache decode1 decode2 execute1 loadstore dcache CR GSPR\n"); + printf(" ---------------- TAHW S -WB-- pN ic --insn-- pN un op pN byp FR IIE MSR WC SD MM CE SRTO DE -WB-- c ms reg val\n"); + printf(" LdMy t csnSa IA IA it IA abc le srx EPID em tw rd mx tAwp vr csnSa 0 k\n"); } printf("%4ld %c0000%.11llx %c ", lineno, (log.nia_hi? 'c': '0'), @@ -154,12 +153,16 @@ int main(int ac, char **av) FLAG(ic_wb_stall, 'S'), FLAG(ic_wb_ack, 'a'), PNIA(ic_part_nia)); - if (log.ic_valid) - printf("%.8x", log.ic_insn); - else if (log.ic_fetch_failed) - printf("!!!!!!!!"); + if (log.ic_valid) { + if (log.ic_insn & (1ul << 35)) + printf("ill %.8lx", log.ic_insn & 0xfffffffful); + else + printf("%3lu x%.7lx", (long)(log.ic_insn >> 26), + (unsigned long)(log.ic_insn & 0x3ffffff)); + } else if (log.ic_fetch_failed) + printf(" !!!!!!!!"); else - printf("--------"); + printf("--- --------"); printf(" %c%c %.2llx ", FLAG(ic_valid, '>'), FLAG(d2_stall_out, '|'),