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>
pull/208/head
Paul Mackerras 4 years ago
parent ec2fa61792
commit 78de4fef72

@ -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,

@ -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;


@ -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

@ -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,

Loading…
Cancel
Save