From 78de4fef72b900ab977275c40fd21ca080671e31 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 16 Jun 2020 11:37:25 +1000 Subject: [PATCH] Make LOG_LENGTH configurable per FPGA variant This plumbs the LOG_LENGTH parameter (which controls how many entries the core log RAM has) up to the top level so that it can be set on the fusesoc command line and have different default values on different FPGAs. It now defaults to 512 entries generally and on the Artix-7 35 parts, and 2048 on the larger Artix-7 FPGAs. It can be set to 0 if desired. Signed-off-by: Paul Mackerras --- core.vhdl | 6 +- core_debug.vhdl | 150 ++++++++++++++++++++++++--------------------- fpga/top-arty.vhdl | 6 +- microwatt.core | 13 ++++ soc.vhdl | 6 +- 5 files changed, 107 insertions(+), 74 deletions(-) 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,