You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
7.6 KiB
VHDL
227 lines
7.6 KiB
VHDL
-- VCU118 Debug Top-Level - Add heartbeat LED and basic diagnostics
|
|
|
|
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.ALL;
|
|
USE ieee.numeric_std.ALL;
|
|
|
|
LIBRARY unisim;
|
|
USE unisim.vcomponents.ALL;
|
|
|
|
LIBRARY work;
|
|
USE work.wishbone_types.ALL;
|
|
|
|
ENTITY toplevel IS
|
|
GENERIC (
|
|
MEMORY_SIZE : INTEGER := 16384; -- This can go up a lot more
|
|
DRAM_SIZE : INTEGER := 268435456;
|
|
RAM_INIT_FILE : STRING := "firmware.hex";
|
|
RESET_LOW : BOOLEAN := false; -- VCU118 reset button is active-high
|
|
CLK_INPUT : POSITIVE := 125000000; -- Match physical clock
|
|
CLK_FREQUENCY : POSITIVE := 125000000; -- Same as input (no PLL)
|
|
HAS_FPU : BOOLEAN := true;
|
|
HAS_BTC : BOOLEAN := true;
|
|
ICACHE_NUM_LINES : NATURAL := 64;
|
|
LOG_LENGTH : NATURAL := 512;
|
|
DISABLE_FLATTEN_CORE : BOOLEAN := false;
|
|
UART_IS_16550 : BOOLEAN := true;
|
|
NO_BRAM : BOOLEAN := false;
|
|
USE_LITEDRAM : BOOLEAN := false;
|
|
HAS_SPI_FLASH: BOOLEAN := false
|
|
);
|
|
PORT (
|
|
-- VCU118 differential clock input
|
|
ext_clk_p : IN STD_ULOGIC;
|
|
ext_clk_n : IN STD_ULOGIC;
|
|
|
|
-- VCU118 reset button
|
|
ext_rst : IN STD_ULOGIC;
|
|
|
|
-- UART0 signals
|
|
uart0_txd : OUT STD_ULOGIC;
|
|
uart0_rxd : IN STD_ULOGIC;
|
|
|
|
-- Debug LEDs (use some GPIO LEDs from VCU118)
|
|
debug_led0 : OUT STD_ULOGIC; -- Heartbeat - clock working
|
|
debug_led1 : OUT STD_ULOGIC; -- Reset state
|
|
debug_led2 : OUT STD_ULOGIC; -- SoC running
|
|
debug_led3 : OUT STD_ULOGIC; -- UART activity
|
|
debug_led4 : OUT STD_ULOGIC; -- Init done
|
|
debug_led5 : OUT STD_ULOGIC -- Init error
|
|
|
|
);
|
|
END ENTITY toplevel;
|
|
|
|
ARCHITECTURE behaviour OF toplevel IS
|
|
|
|
-- Reset signals
|
|
SIGNAL soc_rst : STD_ULOGIC;
|
|
SIGNAL pll_rst : STD_ULOGIC;
|
|
|
|
-- Internal clock signals
|
|
SIGNAL system_clk : STD_ULOGIC;
|
|
SIGNAL system_clk_locked : STD_ULOGIC;
|
|
|
|
-- Single-ended clock from differential input
|
|
SIGNAL ext_clk_single : STD_ULOGIC;
|
|
|
|
-- Debug signals
|
|
SIGNAL heartbeat_counter : unsigned(27 DOWNTO 0) := (OTHERS => '0');
|
|
SIGNAL uart_activity : STD_ULOGIC := '0';
|
|
SIGNAL uart_activity_counter : unsigned(23 DOWNTO 0) := (OTHERS => '0');
|
|
SIGNAL soc_run_out : STD_ULOGIC;
|
|
SIGNAL soc_run_outs : STD_ULOGIC_VECTOR(0 DOWNTO 0); -- Add run_outs signal for NCPUS=1
|
|
SIGNAL init_done : STD_ULOGIC;
|
|
SIGNAL init_error : STD_ULOGIC;
|
|
-- Dummy DRAM wishbone interface (not used when USE_LITEDRAM = false)
|
|
SIGNAL wb_dram_in : wishbone_master_out;
|
|
SIGNAL wb_dram_out : wishbone_slave_out;
|
|
SIGNAL wb_ext_io_in : wb_io_master_out;
|
|
SIGNAL wb_ext_io_out : wb_io_slave_out;
|
|
SIGNAL wb_ext_is_dram_csr : STD_ULOGIC;
|
|
SIGNAL wb_ext_is_dram_init : STD_ULOGIC;
|
|
function get_bram_size return natural is
|
|
begin
|
|
if USE_LITEDRAM and NO_BRAM then
|
|
return 0;
|
|
else
|
|
return MEMORY_SIZE;
|
|
end if;
|
|
end function;
|
|
function get_payload_size return natural is
|
|
begin
|
|
if USE_LITEDRAM and NO_BRAM then
|
|
return MEMORY_SIZE;
|
|
else
|
|
return 0;
|
|
end if;
|
|
end function;
|
|
|
|
constant BRAM_SIZE : natural := get_bram_size;
|
|
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
BEGIN
|
|
-- Convert differential clock to single-ended (MUST come before BUFG)
|
|
clk_ibufgds : IBUFGDS
|
|
PORT MAP(
|
|
I => ext_clk_p,
|
|
IB => ext_clk_n,
|
|
O => ext_clk_single
|
|
);
|
|
-- Clock buffering (no PLL for 125MHz passthrough)
|
|
clk_bufg : BUFG
|
|
PORT MAP(
|
|
I => ext_clk_single,
|
|
O => system_clk
|
|
);
|
|
|
|
-- Since we're not using a PLL, clock is always "locked"
|
|
system_clk_locked <= '1';
|
|
|
|
-- Use the soc_reset entity for proper reset sequencing
|
|
reset_controller : ENTITY work.soc_reset
|
|
GENERIC MAP(
|
|
RESET_LOW => RESET_LOW,
|
|
PLL_RESET_BITS => 18 -- Adjust as needed
|
|
)
|
|
PORT MAP(
|
|
ext_clk => ext_clk_single,
|
|
pll_clk => system_clk,
|
|
pll_locked_in => system_clk_locked,
|
|
ext_rst_in => ext_rst,
|
|
pll_rst_out => pll_rst,
|
|
rst_out => soc_rst
|
|
);
|
|
-- Heartbeat counter for LED - ~0.93Hz at 125MHz (2^27 / 125MHz)
|
|
heartbeat_proc : PROCESS (system_clk)
|
|
BEGIN
|
|
IF rising_edge(system_clk) THEN
|
|
IF soc_rst = '1' THEN
|
|
heartbeat_counter <= (OTHERS => '0');
|
|
ELSE
|
|
heartbeat_counter <= heartbeat_counter + 1;
|
|
END IF;
|
|
END IF;
|
|
END PROCESS;
|
|
|
|
-- UART activity detector with timeout
|
|
uart_activity_proc : PROCESS (system_clk)
|
|
BEGIN
|
|
IF rising_edge(system_clk) THEN
|
|
IF soc_rst = '1' THEN
|
|
uart_activity <= '0';
|
|
uart_activity_counter <= (OTHERS => '0');
|
|
ELSE
|
|
-- Detect any UART transmit activity (start bit = '0')
|
|
IF uart0_txd = '0' THEN
|
|
uart_activity <= '1';
|
|
uart_activity_counter <= (OTHERS => '1');
|
|
ELSIF uart_activity_counter /= 0 THEN
|
|
uart_activity_counter <= uart_activity_counter - 1;
|
|
ELSE
|
|
uart_activity <= '0';
|
|
END IF;
|
|
END IF;
|
|
END IF;
|
|
END PROCESS;
|
|
|
|
-- Debug LED assignments
|
|
debug_led0 <= heartbeat_counter(27); -- Heartbeat - proves clock works
|
|
debug_led1 <= NOT soc_rst; -- ON when system running (not in reset)
|
|
debug_led2 <= soc_run_outs(0); -- SoC run status
|
|
debug_led3 <= uart_activity; -- UART activity indicator
|
|
debug_led4 <= init_done; -- Always '1' for no-DRAM config
|
|
debug_led5 <= init_error; -- Always '0' for no-DRAM config
|
|
|
|
-- Conditional DDR4 Generation
|
|
no_litedram_gen : IF NOT USE_LITEDRAM GENERATE
|
|
|
|
init_done <= '1';
|
|
init_error <= '0';
|
|
wb_dram_out.dat <= (OTHERS => '0');
|
|
wb_dram_out.ack <= '0';
|
|
wb_dram_out.stall <= '0';
|
|
wb_ext_io_out.dat <= (OTHERS => '0');
|
|
wb_ext_io_out.ack <= '0';
|
|
wb_ext_io_out.stall <= '0';
|
|
wb_ext_is_dram_csr <= '0';
|
|
wb_ext_is_dram_init <= '0';
|
|
|
|
END GENERATE no_litedram_gen;
|
|
|
|
-- Main SoC
|
|
soc0 : ENTITY work.soc
|
|
GENERIC MAP(
|
|
MEMORY_SIZE => BRAM_SIZE,
|
|
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
HAS_SPI_FLASH => false,
|
|
SIM => false,
|
|
NCPUS => 1,
|
|
CLK_FREQ => CLK_FREQUENCY,
|
|
HAS_FPU => HAS_FPU,
|
|
HAS_BTC => HAS_BTC,
|
|
HAS_DRAM => USE_LITEDRAM,
|
|
DRAM_SIZE => DRAM_SIZE,
|
|
DRAM_INIT_SIZE => 0, -- No DRAM init when not using LiteDRAM
|
|
ICACHE_NUM_LINES => ICACHE_NUM_LINES,
|
|
LOG_LENGTH => LOG_LENGTH,
|
|
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
|
UART0_IS_16550 => UART_IS_16550,
|
|
HAS_UART1 => false
|
|
|
|
)
|
|
PORT MAP(
|
|
system_clk => system_clk,
|
|
rst => soc_rst,
|
|
uart0_txd => uart0_txd,
|
|
uart0_rxd => uart0_rxd,
|
|
-- DRAM wishbone (not used but needs to be connected)
|
|
wb_dram_in => wb_dram_in,
|
|
wb_dram_out => wb_dram_out,
|
|
wb_ext_io_in => wb_ext_io_in,
|
|
wb_ext_io_out => wb_ext_io_out,
|
|
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
-- Run status output
|
|
run_outs => soc_run_outs
|
|
);
|
|
|
|
END ARCHITECTURE behaviour; |