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 5 years ago
parent ec2fa61792
commit 78de4fef72

@ -11,7 +11,8 @@ entity core is
SIM : boolean := false; SIM : boolean := false;
DISABLE_FLATTEN : boolean := false; DISABLE_FLATTEN : boolean := false;
EX1_BYPASS : boolean := true; 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 ( port (
clk : in std_ulogic; clk : in std_ulogic;
@ -372,6 +373,9 @@ begin
log_data(139 downto 135) <= "00000"; log_data(139 downto 135) <= "00000";


debug_0: entity work.core_debug debug_0: entity work.core_debug
generic map (
LOG_LENGTH => LOG_LENGTH
)
port map ( port map (
clk => clk, clk => clk,
rst => rst_dbg, rst => rst_dbg,

@ -9,7 +9,7 @@ use work.common.all;
entity core_debug is entity core_debug is
generic ( generic (
-- Length of log buffer -- Length of log buffer
LOG_LENGTH : positive := 2048 LOG_LENGTH : natural := 512
); );
port ( port (
clk : in std_logic; 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_ADDR : std_ulogic_vector(3 downto 0) := "0110";
constant DBG_CORE_LOG_DATA : std_ulogic_vector(3 downto 0) := "0111"; constant DBG_CORE_LOG_DATA : std_ulogic_vector(3 downto 0) := "0111";


constant LOG_INDEX_BITS : natural := log2(LOG_LENGTH);

-- Some internal wires -- Some internal wires
signal stat_reg : std_ulogic_vector(63 downto 0); 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 do_gspr_rd : std_ulogic;
signal gspr_index : gspr_index_t; signal gspr_index : gspr_index_t;


-- Logging RAM signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0');
constant LOG_INDEX_BITS : natural := log2(LOG_LENGTH); signal log_dmi_data : std_ulogic_vector(63 downto 0) := (others => '0');
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 do_dmi_log_rd : std_ulogic; 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 : std_ulogic;
signal dmi_read_log_data_1 : 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 begin
-- Single cycle register accesses on DMI except for GSPR data -- Single cycle register accesses on DMI except for GSPR data
dmi_ack <= dmi_req when dmi_addr /= DBG_CORE_GSPR_DATA dmi_ack <= dmi_req when dmi_addr /= DBG_CORE_GSPR_DATA
@ -241,50 +217,86 @@ begin
icache_rst <= do_icreset; icache_rst <= do_icreset;
terminated_out <= terminated; terminated_out <= terminated;


-- Use MSB of read addresses to stop the logging -- Logging RAM
log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31)); maybe_log: if LOG_LENGTH > 0 generate

subtype log_ptr_t is unsigned(LOG_INDEX_BITS - 1 downto 0);
log_ram: process(clk) type log_array_t is array(0 to LOG_LENGTH - 1) of std_ulogic_vector(255 downto 0);
begin signal log_array : log_array_t;
if rising_edge(clk) then signal log_rd_ptr : log_ptr_t;
if log_wr_enable = '1' then signal log_wr_ptr : log_ptr_t;
log_array(to_integer(log_wr_ptr)) <= log_data; signal log_toggle : std_ulogic;
end if; signal log_wr_enable : std_ulogic;
log_rd <= log_array(to_integer(log_rd_ptr_latched)); signal log_rd_ptr_latched : log_ptr_t;
end if; signal log_rd : std_ulogic_vector(255 downto 0);
end process; 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 begin
if rising_edge(clk) then -- Use MSB of read addresses to stop the logging
if rst = '1' then log_wr_enable <= not (log_read_addr(31) or log_dmi_addr(31));
log_wr_ptr <= (others => '0');
log_toggle <= '0'; log_ram: process(clk)
elsif log_wr_enable = '1' then begin
if log_wr_ptr = to_unsigned(LOG_LENGTH - 1, LOG_INDEX_BITS) then if rising_edge(clk) then
log_toggle <= not log_toggle; if log_wr_enable = '1' then
log_array(to_integer(log_wr_ptr)) <= log_data;
end if; 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 if; end if;
if log_dmi_read_done = '1' then end process;
log_dmi_data <= select_dword(log_rd, log_dmi_addr);
else
log_read_data <= select_dword(log_rd, log_read_addr); 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; end if;
log_dmi_read_done <= log_dmi_reading; end process;
log_dmi_reading <= do_dmi_log_rd; log_write_addr(LOG_INDEX_BITS - 1 downto 0) <= std_ulogic_vector(log_wr_ptr);
end if; log_write_addr(LOG_INDEX_BITS) <= '1';
end process; log_write_addr(31 downto LOG_INDEX_BITS + 1) <= (others => '0');
log_write_addr(LOG_INDEX_BITS - 1 downto 0) <= std_ulogic_vector(log_wr_ptr); end generate;
log_write_addr(LOG_INDEX_BITS) <= '1';
log_write_addr(31 downto LOG_INDEX_BITS + 1) <= (others => '0'); no_log: if LOG_LENGTH = 0 generate
begin
log_read_data <= (others => '0');
log_write_addr <= x"00000001";
end generate;

end behave; end behave;



@ -20,7 +20,8 @@ entity toplevel is
SCLK_STARTUPE2 : boolean := false; SCLK_STARTUPE2 : boolean := false;
SPI_FLASH_OFFSET : integer := 4194304; SPI_FLASH_OFFSET : integer := 4194304;
SPI_FLASH_DEF_CKDV : natural := 1; SPI_FLASH_DEF_CKDV : natural := 1;
SPI_FLASH_DEF_QUAD : boolean := true SPI_FLASH_DEF_QUAD : boolean := true;
LOG_LENGTH : natural := 512
); );
port( port(
ext_clk : in std_ulogic; ext_clk : in std_ulogic;
@ -139,7 +140,8 @@ begin
SPI_FLASH_DLINES => 4, SPI_FLASH_DLINES => 4,
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET, SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV, 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 ( port map (
-- System signals -- System signals

@ -110,6 +110,7 @@ targets:
- clk_input - clk_input
- clk_frequency - clk_frequency
- disable_flatten_core - disable_flatten_core
- log_length=2048
tools: tools:
vivado: {part : xc7a100tcsg324-1} vivado: {part : xc7a100tcsg324-1}
toplevel : toplevel toplevel : toplevel
@ -124,6 +125,7 @@ targets:
- clk_frequency - clk_frequency
- disable_flatten_core - disable_flatten_core
- spi_flash_offset=10485760 - spi_flash_offset=10485760
- log_length=2048
tools: tools:
vivado: {part : xc7a200tsbg484-1} vivado: {part : xc7a200tsbg484-1}
toplevel : toplevel toplevel : toplevel
@ -138,6 +140,7 @@ targets:
- disable_flatten_core - disable_flatten_core
- no_bram - no_bram
- spi_flash_offset=10485760 - spi_flash_offset=10485760
- log_length=2048
generate: [dram_nexys_video] generate: [dram_nexys_video]
tools: tools:
vivado: {part : xc7a200tsbg484-1} vivado: {part : xc7a200tsbg484-1}
@ -153,6 +156,7 @@ targets:
- clk_frequency - clk_frequency
- disable_flatten_core - disable_flatten_core
- spi_flash_offset=3145728 - spi_flash_offset=3145728
- log_length=512
tools: tools:
vivado: {part : xc7a35ticsg324-1L} vivado: {part : xc7a35ticsg324-1L}
toplevel : toplevel toplevel : toplevel
@ -167,6 +171,7 @@ targets:
- disable_flatten_core - disable_flatten_core
- no_bram - no_bram
- spi_flash_offset=3145728 - spi_flash_offset=3145728
- log_length=512
generate: [dram_arty] generate: [dram_arty]
tools: tools:
vivado: {part : xc7a35ticsg324-1L} vivado: {part : xc7a35ticsg324-1L}
@ -182,6 +187,7 @@ targets:
- clk_frequency - clk_frequency
- disable_flatten_core - disable_flatten_core
- spi_flash_offset=4194304 - spi_flash_offset=4194304
- log_length=2048
tools: tools:
vivado: {part : xc7a100ticsg324-1L} vivado: {part : xc7a100ticsg324-1L}
toplevel : toplevel toplevel : toplevel
@ -196,6 +202,7 @@ targets:
- disable_flatten_core - disable_flatten_core
- no_bram - no_bram
- spi_flash_offset=4194304 - spi_flash_offset=4194304
- log_length=2048
generate: [dram_arty] generate: [dram_arty]
tools: tools:
vivado: {part : xc7a100ticsg324-1L} vivado: {part : xc7a100ticsg324-1L}
@ -211,6 +218,7 @@ targets:
- clk_input=12000000 - clk_input=12000000
- clk_frequency - clk_frequency
- disable_flatten_core - disable_flatten_core
- log_length=512
tools: tools:
vivado: {part : xc7a35tcpg236-1} vivado: {part : xc7a35tcpg236-1}
toplevel : toplevel toplevel : toplevel
@ -281,3 +289,8 @@ parameters:
datatype : int datatype : int
description : Offset (in bytes) in the SPI flash of the code payload to run description : Offset (in bytes) in the SPI flash of the code payload to run
paramtype : generic 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_DLINES : positive := 1;
SPI_FLASH_OFFSET : integer := 0; SPI_FLASH_OFFSET : integer := 0;
SPI_FLASH_DEF_CKDV : natural := 2; SPI_FLASH_DEF_CKDV : natural := 2;
SPI_FLASH_DEF_QUAD : boolean := false SPI_FLASH_DEF_QUAD : boolean := false;
LOG_LENGTH : natural := 512
); );
port( port(
rst : in std_ulogic; rst : in std_ulogic;
@ -186,7 +187,8 @@ begin
generic map( generic map(
SIM => SIM, SIM => SIM,
DISABLE_FLATTEN => DISABLE_FLATTEN_CORE, 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( port map(
clk => system_clk, clk => system_clk,

Loading…
Cancel
Save