diff --git a/core.vhdl b/core.vhdl index 092df6d..4a83d69 100644 --- a/core.vhdl +++ b/core.vhdl @@ -11,7 +11,8 @@ entity core is SIM : boolean := false; DISABLE_FLATTEN : boolean := false; EX1_BYPASS : boolean := true; - ALT_RESET_ADDRESS : std_ulogic_vector(63 downto 0) := (others => '0') + ALT_RESET_ADDRESS : std_ulogic_vector(63 downto 0) := (others => '0'); + LOG_LENGTH : natural := 512 ); port ( clk : in std_ulogic; @@ -372,6 +373,9 @@ begin log_data(139 downto 135) <= "00000"; debug_0: entity work.core_debug + generic map ( + LOG_LENGTH => LOG_LENGTH + ) port map ( clk => clk, rst => rst_dbg, diff --git a/core_debug.vhdl b/core_debug.vhdl index 31e4ab8..9efaa7c 100644 --- a/core_debug.vhdl +++ b/core_debug.vhdl @@ -9,7 +9,7 @@ use work.common.all; entity core_debug is generic ( -- Length of log buffer - LOG_LENGTH : positive := 2048 + LOG_LENGTH : natural := 512 ); port ( clk : in std_logic; @@ -92,6 +92,8 @@ architecture behave of core_debug is constant DBG_CORE_LOG_ADDR : std_ulogic_vector(3 downto 0) := "0110"; constant DBG_CORE_LOG_DATA : std_ulogic_vector(3 downto 0) := "0111"; + constant LOG_INDEX_BITS : natural := log2(LOG_LENGTH); + -- Some internal wires signal stat_reg : std_ulogic_vector(63 downto 0); @@ -104,38 +106,12 @@ architecture behave of core_debug is signal do_gspr_rd : std_ulogic; signal gspr_index : gspr_index_t; - -- Logging RAM - constant LOG_INDEX_BITS : natural := log2(LOG_LENGTH); - subtype log_ptr_t is unsigned(LOG_INDEX_BITS - 1 downto 0); - type log_array_t is array(0 to LOG_LENGTH - 1) of std_ulogic_vector(255 downto 0); - signal log_array : log_array_t; - signal log_rd_ptr : log_ptr_t; - signal log_wr_ptr : log_ptr_t; - signal log_toggle : std_ulogic; - signal log_wr_enable : std_ulogic; - signal log_rd_ptr_latched : log_ptr_t; - signal log_rd : std_ulogic_vector(255 downto 0); - signal log_dmi_addr : std_ulogic_vector(31 downto 0); - signal log_dmi_data : std_ulogic_vector(63 downto 0); + signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0'); + signal log_dmi_data : std_ulogic_vector(63 downto 0) := (others => '0'); signal do_dmi_log_rd : std_ulogic; - signal log_dmi_reading : std_ulogic; - signal log_dmi_read_done : std_ulogic; signal dmi_read_log_data : std_ulogic; signal dmi_read_log_data_1 : std_ulogic; - function select_dword(data : std_ulogic_vector(255 downto 0); - addr : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is - variable firstbit : integer; - begin - firstbit := to_integer(unsigned(addr(1 downto 0))) * 64; - return data(firstbit + 63 downto firstbit); - end; - - attribute ram_style : string; - attribute ram_style of log_array : signal is "block"; - attribute ram_decomp : string; - attribute ram_decomp of log_array : signal is "power"; - begin -- Single cycle register accesses on DMI except for GSPR data dmi_ack <= dmi_req when dmi_addr /= DBG_CORE_GSPR_DATA @@ -241,50 +217,86 @@ begin icache_rst <= do_icreset; terminated_out <= terminated; - -- Use MSB of read addresses to stop the logging - log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31)); - - log_ram: process(clk) - begin - if rising_edge(clk) then - if log_wr_enable = '1' then - log_array(to_integer(log_wr_ptr)) <= log_data; - end if; - log_rd <= log_array(to_integer(log_rd_ptr_latched)); - end if; - end process; - + -- Logging RAM + maybe_log: if LOG_LENGTH > 0 generate + subtype log_ptr_t is unsigned(LOG_INDEX_BITS - 1 downto 0); + type log_array_t is array(0 to LOG_LENGTH - 1) of std_ulogic_vector(255 downto 0); + signal log_array : log_array_t; + signal log_rd_ptr : log_ptr_t; + signal log_wr_ptr : log_ptr_t; + signal log_toggle : std_ulogic; + signal log_wr_enable : std_ulogic; + signal log_rd_ptr_latched : log_ptr_t; + signal log_rd : std_ulogic_vector(255 downto 0); + signal log_dmi_reading : std_ulogic; + signal log_dmi_read_done : std_ulogic; + + function select_dword(data : std_ulogic_vector(255 downto 0); + addr : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is + variable firstbit : integer; + begin + firstbit := to_integer(unsigned(addr(1 downto 0))) * 64; + return data(firstbit + 63 downto firstbit); + end; + + attribute ram_style : string; + attribute ram_style of log_array : signal is "block"; + attribute ram_decomp : string; + attribute ram_decomp of log_array : signal is "power"; - log_buffer: process(clk) - variable b : integer; - variable data : std_ulogic_vector(255 downto 0); begin - if rising_edge(clk) then - if rst = '1' then - log_wr_ptr <= (others => '0'); - log_toggle <= '0'; - elsif log_wr_enable = '1' then - if log_wr_ptr = to_unsigned(LOG_LENGTH - 1, LOG_INDEX_BITS) then - log_toggle <= not log_toggle; + -- Use MSB of read addresses to stop the logging + log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31)); + + log_ram: process(clk) + begin + if rising_edge(clk) then + if log_wr_enable = '1' then + log_array(to_integer(log_wr_ptr)) <= log_data; end if; - log_wr_ptr <= log_wr_ptr + 1; - end if; - if do_dmi_log_rd = '1' then - log_rd_ptr_latched <= unsigned(log_dmi_addr(LOG_INDEX_BITS + 1 downto 2)); - else - log_rd_ptr_latched <= unsigned(log_read_addr(LOG_INDEX_BITS + 1 downto 2)); + log_rd <= log_array(to_integer(log_rd_ptr_latched)); end if; - if log_dmi_read_done = '1' then - log_dmi_data <= select_dword(log_rd, log_dmi_addr); - else - log_read_data <= select_dword(log_rd, log_read_addr); + end process; + + + log_buffer: process(clk) + variable b : integer; + variable data : std_ulogic_vector(255 downto 0); + begin + if rising_edge(clk) then + if rst = '1' then + log_wr_ptr <= (others => '0'); + log_toggle <= '0'; + elsif log_wr_enable = '1' then + if log_wr_ptr = to_unsigned(LOG_LENGTH - 1, LOG_INDEX_BITS) then + log_toggle <= not log_toggle; + end if; + log_wr_ptr <= log_wr_ptr + 1; + end if; + if do_dmi_log_rd = '1' then + log_rd_ptr_latched <= unsigned(log_dmi_addr(LOG_INDEX_BITS + 1 downto 2)); + else + log_rd_ptr_latched <= unsigned(log_read_addr(LOG_INDEX_BITS + 1 downto 2)); + end if; + if log_dmi_read_done = '1' then + log_dmi_data <= select_dword(log_rd, log_dmi_addr); + else + log_read_data <= select_dword(log_rd, log_read_addr); + end if; + log_dmi_read_done <= log_dmi_reading; + log_dmi_reading <= do_dmi_log_rd; end if; - log_dmi_read_done <= log_dmi_reading; - log_dmi_reading <= do_dmi_log_rd; - end if; - end process; - log_write_addr(LOG_INDEX_BITS - 1 downto 0) <= std_ulogic_vector(log_wr_ptr); - log_write_addr(LOG_INDEX_BITS) <= '1'; - log_write_addr(31 downto LOG_INDEX_BITS + 1) <= (others => '0'); + end process; + log_write_addr(LOG_INDEX_BITS - 1 downto 0) <= std_ulogic_vector(log_wr_ptr); + log_write_addr(LOG_INDEX_BITS) <= '1'; + log_write_addr(31 downto LOG_INDEX_BITS + 1) <= (others => '0'); + end generate; + + no_log: if LOG_LENGTH = 0 generate + begin + log_read_data <= (others => '0'); + log_write_addr <= x"00000001"; + end generate; + end behave; diff --git a/fpga/top-arty.vhdl b/fpga/top-arty.vhdl index b13ed34..44b59c3 100644 --- a/fpga/top-arty.vhdl +++ b/fpga/top-arty.vhdl @@ -20,7 +20,8 @@ entity toplevel is SCLK_STARTUPE2 : boolean := false; SPI_FLASH_OFFSET : integer := 4194304; SPI_FLASH_DEF_CKDV : natural := 1; - SPI_FLASH_DEF_QUAD : boolean := true + SPI_FLASH_DEF_QUAD : boolean := true; + LOG_LENGTH : natural := 512 ); port( ext_clk : in std_ulogic; @@ -139,7 +140,8 @@ begin SPI_FLASH_DLINES => 4, SPI_FLASH_OFFSET => SPI_FLASH_OFFSET, SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV, - SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD + SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD, + LOG_LENGTH => LOG_LENGTH ) port map ( -- System signals diff --git a/microwatt.core b/microwatt.core index 7d86cc2..85710be 100644 --- a/microwatt.core +++ b/microwatt.core @@ -110,6 +110,7 @@ targets: - clk_input - clk_frequency - disable_flatten_core + - log_length=2048 tools: vivado: {part : xc7a100tcsg324-1} toplevel : toplevel @@ -124,6 +125,7 @@ targets: - clk_frequency - disable_flatten_core - spi_flash_offset=10485760 + - log_length=2048 tools: vivado: {part : xc7a200tsbg484-1} toplevel : toplevel @@ -138,6 +140,7 @@ targets: - disable_flatten_core - no_bram - spi_flash_offset=10485760 + - log_length=2048 generate: [dram_nexys_video] tools: vivado: {part : xc7a200tsbg484-1} @@ -153,6 +156,7 @@ targets: - clk_frequency - disable_flatten_core - spi_flash_offset=3145728 + - log_length=512 tools: vivado: {part : xc7a35ticsg324-1L} toplevel : toplevel @@ -167,6 +171,7 @@ targets: - disable_flatten_core - no_bram - spi_flash_offset=3145728 + - log_length=512 generate: [dram_arty] tools: vivado: {part : xc7a35ticsg324-1L} @@ -182,6 +187,7 @@ targets: - clk_frequency - disable_flatten_core - spi_flash_offset=4194304 + - log_length=2048 tools: vivado: {part : xc7a100ticsg324-1L} toplevel : toplevel @@ -196,6 +202,7 @@ targets: - disable_flatten_core - no_bram - spi_flash_offset=4194304 + - log_length=2048 generate: [dram_arty] tools: vivado: {part : xc7a100ticsg324-1L} @@ -211,6 +218,7 @@ targets: - clk_input=12000000 - clk_frequency - disable_flatten_core + - log_length=512 tools: vivado: {part : xc7a35tcpg236-1} toplevel : toplevel @@ -281,3 +289,8 @@ parameters: datatype : int description : Offset (in bytes) in the SPI flash of the code payload to run paramtype : generic + + log_length: + datatype : int + description : Length of the core log buffer in entries (32 bytes each) + paramtype : generic diff --git a/soc.vhdl b/soc.vhdl index 7c8e825..8c2fbfb 100644 --- a/soc.vhdl +++ b/soc.vhdl @@ -41,7 +41,8 @@ entity soc is SPI_FLASH_DLINES : positive := 1; SPI_FLASH_OFFSET : integer := 0; SPI_FLASH_DEF_CKDV : natural := 2; - SPI_FLASH_DEF_QUAD : boolean := false + SPI_FLASH_DEF_QUAD : boolean := false; + LOG_LENGTH : natural := 512 ); port( rst : in std_ulogic; @@ -186,7 +187,8 @@ begin generic map( SIM => SIM, DISABLE_FLATTEN => DISABLE_FLATTEN_CORE, - ALT_RESET_ADDRESS => (23 downto 0 => '0', others => '1') + ALT_RESET_ADDRESS => (23 downto 0 => '0', others => '1'), + LOG_LENGTH => LOG_LENGTH ) port map( clk => system_clk,