Make LOG_LENGTH configurable per FPGA variant
authorPaul Mackerras <paulus@ozlabs.org>
Tue, 16 Jun 2020 01:37:25 +0000 (11:37 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 16 Jun 2020 03:25:33 +0000 (13:25 +1000)
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 <paulus@ozlabs.org>
core.vhdl
core_debug.vhdl
fpga/top-arty.vhdl
microwatt.core
soc.vhdl

index 092df6d10c58e0d71611aea56586e623ace23df6..4a83d6933f87b61c43307bb8273d196805e908e1 100644 (file)
--- 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,
index 31e4ab860b46cd090412b2abe32aef8291dcc5fc..9efaa7c79e9f06462a9d7d0edb0d4db44e8200c2 100644 (file)
@@ -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;
 
index b13ed34f70ebb2e9b6a3884e09c2b6b0be2c3f42..44b59c3344f1987e5e5d006e1dd68fb754cde969 100644 (file)
@@ -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
index 7d86cc25823062277565ce932d9ef6a85a67a48e..85710be10a490d35cd2589cd318358a5c1588666 100644 (file)
@@ -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
index 7c8e825438929d8431dcae97405f116772007022..8c2fbfb734ceaa7ddf7be488dba49fc76746e310 100644 (file)
--- 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,