mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-02-27 00:59:41 +00:00
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 <paulus@ozlabs.org>
This commit is contained in:
@@ -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,
|
||||
|
||||
148
core_debug.vhdl
148
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));
|
||||
-- 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_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;
|
||||
-- Use MSB of read addresses to stop the logging
|
||||
log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31));
|
||||
|
||||
|
||||
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;
|
||||
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;
|
||||
log_rd <= log_array(to_integer(log_rd_ptr_latched));
|
||||
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 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;
|
||||
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;
|
||||
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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
6
soc.vhdl
6
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,
|
||||
|
||||
Reference in New Issue
Block a user