Commit b91ef24c authored by Jose Jimenez's avatar Jose Jimenez

debugger_gw: Soft-Micro Debugger gateware

Signed-off-by: 's avatarJose Jimenez <ppjm@correo.ugr.es>
parent 411edf60
ETHERBONE_DIR = ./etherbone-core
FMC_DEL_DIR = ./fmc-delay
all: git_submodules
$(MAKE) -C $(FMC_DEL_DIR) -f Makefile
git_submodules:
@test -d $(ETHERBONE_DIR)/api || echo "Checking out submodules"
test -d $(ETHERBONE_DIR)/api || git submodule update --init
clean:
rm -f *.ram
$(MAKE) -C $(FMC_DEL_DIR)/spec -f Makefile $@
mrproper:
$(MAKE) -C $(FMC_DEL_DIR)/spec -f Makefile $@
files = ["wb_debugger.vhd", "debugger_pkg.vhd", "dbg_code.ram"]
-------------------------------------------------------------------------------
-- Title : Wishbone Debugger package
-- Project : FMC DEL 1ns 4cha-stand-alone application (fmc-delay-1ns-4cha-sa)
-------------------------------------------------------------------------------
-- File : debugger_pkg.vhd
-- Author : Jose Jimenez <jjimenez.wr@gmail.com>
-- Company : University of Granada
-- Created : 2014-06-08
-- Last update: 2014-07-31
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Wihsbone master with slave configuration interface for gateware
-- debuggin porpuses. Also provides a framework for stand alone
-- operation.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2014-06-08 1.0 jjimenez Created
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
----use work.gn4124_core_pkg.all;
--use work.gencores_pkg.all;
--use work.wrcore_pkg.all;
----use work.wr_fabric_pkg.all;
--use work.wishbone_pkg.all;
----use work.fine_delay_pkg.all;
----use work.etherbone_pkg.all;
----use work.wr_xilinx_pkg.all;
--use work.genram_pkg.all;
--use work.wb_irq_pkg.all;
----use work.gencores_pkg.all;
use work.wishbone_pkg.all;
--use work.genram_pkg.all;
--use work.wb_irq_pkg.all;
--use work.debugger_pkg.all;
--
--use work.synthesis_descriptor.all;
package debugger_pkg is
------------------------------------------------------------------------------
-- Constants
-------------------------------------------------------------------------------
constant c_dbg_uart_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7", -- 8/16/32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"00000000000000ff",
product => (
vendor_id => x"000000000000CE42", -- CERN
device_id => x"0deafbee", -- she didn't listen & cames & goes
version => x"00000001",
date => x"20120305",
name => "WB-UART-Debugger ")));
constant c_dbg_irq_ctrl_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7", -- 8/16/32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"00000000000000ff",
product => (
vendor_id => x"0000000000000651", -- GSI
device_id => x"e1fb1ade", -- balanced, perfect grip, absolute control
version => x"00000001",
date => x"20120308",
name => "IRQ_CTRL-Debugger ")));
constant c_xwb_dbg_tics_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"00",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7", -- 8/16/32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"0000000000000000",
product => (
vendor_id => x"000000000000CE42", -- GSIx
device_id => x"fade1eaf", -- Time is always ticking!
version => x"00000001",
date => x"20111004",
name => "WB-Tics-Debugger ")));
constant c_dbg_irq_timer_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7", -- 8/16/32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"00000000000000ff",
product => (
vendor_id => x"0000000000000651", -- GSI
device_id => x"deadface", -- eventully "the dead line" is going to arrive
version => x"00000001",
date => x"20120308",
name => "IRQ_TIMER-Debugger ")));
constant c_xwb_dbg_slave_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"00",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7", -- 8/16/32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"000000000003ffff",
product => (
vendor_id => x"a1eBEEFc0ffeeBED", -- Jose Jimenez Motel. Open 24/7. Next exit.
device_id => x"c0a110de", -- obvious (sadly)
version => x"00000001",
date => x"20140704",
name => "Debugger-Slave ")));
------------------------------------------------------------------------------
-- Functions
-------------------------------------------------------------------------------
function f_xwb_dbg_dpram(g_size : natural) return t_sdb_device
is
variable result : t_sdb_device;
begin
result.abi_class := x"0001"; -- RAM device
result.abi_ver_major := x"01";
result.abi_ver_minor := x"00";
result.wbd_width := x"7"; -- 32/16/8-bit supported
result.wbd_endian := c_sdb_endian_big;
result.sdb_component.addr_first := (others => '0');
result.sdb_component.addr_last := std_logic_vector(to_unsigned(g_size*4-1, 64));
result.sdb_component.product.vendor_id := x"000000000000CE42"; -- CERN
result.sdb_component.product.device_id := x"deafbeef"; -- she didn't listen & is as essential as protein
result.sdb_component.product.version := x"00000001";
result.sdb_component.product.date := x"20120305";
result.sdb_component.product.name := "BlockRAM-Debugger ";
return result;
end f_xwb_dbg_dpram;
------------------------------------------------------------------------------
-- Components declaration
-------------------------------------------------------------------------------
component wb_debugger is
generic (
g_dbg_dpram_size : integer := 40960/4;
g_dbg_init_file : string;
g_reset_vector : t_wishbone_address := x"00000000";
g_msi_queues : natural := 1;
g_profile : string := "medium_icache_debug";
g_internal_time_ref : boolean := true;
g_timers : integer := 1;
g_slave_interface_mode : t_wishbone_interface_mode := PIPELINED;
g_slave_granularity : t_wishbone_address_granularity := BYTE
);
port (
clk_sys : in std_logic;
reset_n : in std_logic;
master_i : in t_wishbone_master_in;
master_o : out t_wishbone_master_out;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
wrpc_uart_rxd_i : inout std_logic;
wrpc_uart_txd_o : inout std_logic;
uart_rxd_i : in std_logic;
uart_txd_o : out std_logic;
dbg_indicator : out std_logic;
dbg_control_select : in std_logic
);
end component;
end debugger_pkg;
package body debugger_pkg is
-- Notihg to include right now!!!
end debugger_pkg;
-------------------------------------------------------------------------------
-- Title : Wishbone Debugger component
-- Project : FMC DEL 1ns 4cha-stand-alone application (fmc-delay-1ns-4cha-sa)
-------------------------------------------------------------------------------
-- File : wb_debugger.vhd
-- Author : Jose Jimenez <jjimenez.wr@gmail.com>
-- Company : University of Granada
-- Created : 2014-06-08
-- Last update: 2014-07-31
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2014-06-08 1.0 jjimenez Created
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.wishbone_pkg.all;
use work.genram_pkg.all;
use work.wb_irq_pkg.all;
use work.debugger_pkg.all;
use work.synthesis_descriptor.all;
entity wb_debugger is
generic(
g_dbg_dpram_size : integer;
g_dbg_init_file : string;
g_reset_vector : t_wishbone_address := x"00000000"; -- if wb_irq_lm32 from general-cores::proposed-master
g_msi_queues : natural := 1;
g_profile : string := "medium_icache_debug";
g_internal_time_ref : boolean := true;
g_timers : integer := 1;
g_slave_interface_mode: t_wishbone_interface_mode := PIPELINED;
g_slave_granularity : t_wishbone_address_granularity := BYTE);
port(
clk_sys : in std_logic;
reset_n : in std_logic;
master_i : in t_wishbone_master_in;
master_o : out t_wishbone_master_out;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
wrpc_uart_rxd_i : inout std_logic;
wrpc_uart_txd_o : inout std_logic;
uart_rxd_i : in std_logic;
uart_txd_o : out std_logic;
dbg_indicator : out std_logic;
dbg_control_select : in std_logic);
end wb_debugger;
architecture Behavioral of wb_debugger is
function f_check_if_lm32_firmware_necessary return boolean is
begin
if(g_dbg_init_file /= "") then
return true;
else
return false;
end if;
end function;
function f_generate_irq_timer return integer is
begin
if(g_timers /= 0) then
return 1;
else
return 0;
end if;
end function;
function f_generate_time_ref return integer is
begin
if(g_internal_time_ref) then
return 1;
else
return 0;
end if;
end function;
function f_choose_lm32_firmware_file return string is
begin
if(g_dbg_init_file = "debugger") then
report "[Dbg Core] Using debugging firmware." severity note;
return "../../dbg.ram";
elsif (g_dbg_init_file = "FD_node") then
report "[Dbg Core] Using FMC Delay stand alone node firmware." severity note;
return "../../fd_std.ram";
else
report "[Dbg Core] Using user provided firmware." severity note;
return g_dbg_init_file;
end if;
end function;
function f_select_dpram_size return integer is
begin
if(g_dbg_init_file = "debugger") then
report "[Dbg Core] Using a 40960 Bytes size RAM." severity note;
return 40960/4;
elsif (g_dbg_init_file = "FD_node") then
report "[Dbg Core] Using a 114740 Bytes RAM." severity note;
return 94208/4;
else
report "[Dbg Core] Using user specifie size RAM size." severity note;
return g_dbg_dpram_size;
end if;
end function;
-- constant c_NUM_WB_MASTERS : integer := 6 + f_generate_irq_timer + f_generate_time_ref;
constant c_NUM_WB_MASTERS : integer := 4 + f_generate_irq_timer + f_generate_time_ref;
constant c_NUM_WB_SLAVES : integer := 3;
constant c_MASTER_LM32 : integer := 0;
constant c_MASTER_ADAPT : integer := 2;
constant c_EXT_BRIDGE : integer := 0;
constant c_SLAVE_DPRAM : integer := 1;
constant c_SLAVE_UART : integer := 2;
constant c_SLAVE_IRQ_CTRL : integer := 3;
constant c_SLAVE_TICS : integer := c_SLAVE_IRQ_CTRL + f_generate_time_ref;
constant c_SLAVE_TIMER_IRQ: integer := c_SLAVE_TICS + f_generate_irq_timer;
constant c_EXT_BRIDGE_SDB : t_sdb_bridge := f_xwb_bridge_manual_sdb(x"000effff", x"00000000");
constant c_FREQ_DIVIDER : integer := 62500; -- LM32 clk = 62.5 Mhz
function f_generate_c_interconection_layout(
num_wb_masters : integer;
last_mandatory_slave : integer
)
return t_sdb_record_array is
variable interconnect_layout : t_sdb_record_array(NUM_WB_MASTERS-1 downto 0);
variable offset : integer range last_mandatory_slave to NUM_WB_MASTERS-1 := last_mandatory_slave;
variable adr_off: unsigned (c_wishbone_address_width-1 downto 0);
begin
-- Vader is Coming Look Busy
interconnect_layout (offset downto 0):=
(c_EXT_BRIDGE => f_sdb_embed_bridge(c_EXT_BRIDGE_SDB, x"00100000"),
c_SLAVE_DPRAM => f_sdb_embed_device(f_xwb_dbg_dpram(f_select_dpram_size), x"00000000"),
c_SLAVE_UART => f_sdb_embed_device(c_dbg_uart_sdb, x"00020100"),
c_SLAVE_IRQ_CTRL => f_sdb_embed_device(c_dbg_irq_ctrl_sdb, x"00020200"));
adr_off := x"00020300";
if (f_generate_time_ref /= 0) then
offset := offset + f_generate_time_ref;
interconnect_layout (offset) := f_sdb_embed_device(c_xwb_dbg_tics_sdb, t_wishbone_address(adr_off));
adr_off := adr_off + x"100";
end if;
if (f_generate_irq_timer /= 0) then
offset := offset + f_generate_irq_timer;
interconnect_layout (offset) := f_sdb_embed_device(c_dbg_irq_timer_sdb, t_wishbone_address(adr_off));
adr_off := adr_off + x"100";
end if;
--interconnect_layout (offset+1) := f_sdb_embed_synthesis(c_sdb_synthesis_info);
--interconnect_layout (offset+2) := f_sdb_embed_repo_url(c_sdb_repo_url);
return interconnect_layout;
end function;
constant c_INTERCONNECT_LAYOUT : t_sdb_record_array := f_generate_c_interconection_layout (c_NUM_WB_MASTERS, c_SLAVE_IRQ_CTRL);
constant c_SDB_ADDRESS : t_wishbone_address := x"00020800";
signal cnx_master_out : t_wishbone_master_out_array(c_NUM_WB_MASTERS-1 downto 0);
signal cnx_master_in : t_wishbone_master_in_array (c_NUM_WB_MASTERS-1 downto 0);
signal cnx_slave_out : t_wishbone_slave_out_array(c_NUM_WB_SLAVES-1 downto 0);
signal cnx_slave_in : t_wishbone_slave_in_array (c_NUM_WB_SLAVES-1 downto 0);
signal dummy_debugger_ram_wbb_i : t_wishbone_slave_in;
signal forced_lm32_reset_n : std_logic := '1';
signal irq_slave_i : t_wishbone_slave_in_array(g_msi_queues-1 to 0);
signal irq_slave_o : t_wishbone_slave_out_array(g_msi_queues-1 to 0);
signal local_counter : unsigned (63 downto 0);
signal uart_dummy_i : std_logic;
signal uart_dummy_o : std_logic;
signal dbg_uart_rxd_i : std_logic;
signal dbg_uart_txd_o : std_logic;
signal use_dbg_uart : std_logic := '1';
signal state_control : unsigned (39 downto 0) := x"0000000000";
begin
dbg_indicator <= forced_lm32_reset_n;
master_o <= cnx_master_out(c_EXT_BRIDGE);
cnx_master_in(c_EXT_BRIDGE) <= master_i;
--------------------------------------
-- UART Selector & Reset controller
--------------------------------------
controller : process (clk_sys)
begin
if (rising_edge(clk_sys)) then
if (dbg_control_select = '0') then
if (state_control /= x"ffffffffff") then
state_control <= state_control + 1;
end if;
else
if ((state_control /= x"0000000000") and (state_control <= x"3B9ACA0")) then --0.5s
forced_lm32_reset_n <= not forced_lm32_reset_n;
elsif (state_control > x"3B9ACA0") then
use_dbg_uart <= not use_dbg_uart;
end if;
state_control <= x"0000000000";
end if;
end if;
end process;
--------------------------------------
-- UART
--------------------------------------
uart_txd_o <= dbg_uart_txd_o when use_dbg_uart ='1' else wrpc_uart_txd_o;
dbg_uart_rxd_i <= uart_rxd_i when use_dbg_uart ='1' else '1';
wrpc_uart_rxd_i <= uart_rxd_i when use_dbg_uart ='0' else '1';
DBG_UART : xwb_simple_uart
generic map(
g_with_virtual_uart => true,
g_with_physical_uart => true,
g_interface_mode => PIPELINED,
g_address_granularity => BYTE
)
port map(
clk_sys_i => clk_sys,
rst_n_i => reset_n,
slave_i => cnx_master_out(c_SLAVE_UART),
slave_o => cnx_master_in(c_SLAVE_UART),
desc_o => open,
uart_rxd_i => dbg_uart_rxd_i,
uart_txd_o => dbg_uart_txd_o
);
-----------------------------------------------------------------------------
-- LM32, with MSI interface
-----------------------------------------------------------------------------
DBG_IRQ_LM32_CORE : wb_irq_lm32
generic map(
g_msi_queues => g_msi_queues,
g_profile => g_profile
)
port map(
clk_sys_i => clk_sys,
rst_n_i => forced_lm32_reset_n,
dwb_o => cnx_slave_in(c_MASTER_LM32),
dwb_i => cnx_slave_out(c_MASTER_LM32),
iwb_o => cnx_slave_in(c_MASTER_LM32+1),
iwb_i => cnx_slave_out(c_MASTER_LM32+1),
irq_slave_o => irq_slave_o, -- wb msi interface
irq_slave_i => irq_slave_i,
ctrl_slave_o => cnx_master_in(c_SLAVE_IRQ_CTRL), -- ctrl interface for LM32 irq processing
ctrl_slave_i => cnx_master_out(c_SLAVE_IRQ_CTRL)
);
---------------------------------------------------------------------------
-- Dual-port RAM
-----------------------------------------------------------------------------
DBG_DPRAM : xwb_dpram
generic map(
g_size => f_select_dpram_size, --in 32-bit words
-- g_size => g_dbg_dpram_size, --in 32-bit words
g_init_file => f_choose_lm32_firmware_file,
g_must_have_init_file => f_check_if_lm32_firmware_necessary,
g_slave1_interface_mode => PIPELINED,
g_slave2_interface_mode => PIPELINED,
g_slave1_granularity => BYTE,
g_slave2_granularity => WORD
)
port map(
clk_sys_i => clk_sys,
rst_n_i => reset_n,
slave1_i => cnx_master_out(c_SLAVE_DPRAM),
slave1_o => cnx_master_in(c_SLAVE_DPRAM),
slave2_i => dummy_debugger_ram_wbb_i,
slave2_o => open
);
---------------------------------------------------------------------------
-- TIMER
---------------------------------------------------------------------------
gen_time_ref : if (f_generate_time_ref /= 0) generate
begin
DBG_TIME_REF : xwb_tics
generic map(
g_period => c_FREQ_DIVIDER
)
port map(
clk_sys_i => clk_sys,
rst_n_i => reset_n,
-- Wishbone
slave_i => cnx_master_out(c_SLAVE_TICS),
slave_o => cnx_master_in(c_SLAVE_TICS),
desc_o => open
);
end generate gen_time_ref;
gen_timer : if (g_timers > 0) generate
begin
process(clk_sys)
begin
if (clk_sys'event and clk_sys = '1') then
if (reset_n = '0') then
local_counter <= (others => '0');
else
local_counter <= local_counter + 1;
end if;
end if;
end process;
DBG_IRQ_TIMER : wb_irq_timer
generic map(
g_timers => g_timers
)
port map(
clk_sys_i => clk_sys,
rst_sys_n_i => forced_lm32_reset_n,
tm_tai8ns_i => std_logic_vector(local_counter),
ctrl_slave_o => cnx_master_in(c_SLAVE_TIMER_IRQ), -- ctrl interface for LM32 irq processing
ctrl_slave_i => cnx_master_out(c_SLAVE_TIMER_IRQ),
irq_master_o => irq_slave_i(g_timers-1), -- wb msi interface
irq_master_i => irq_slave_o(g_timers-1)
);
end generate gen_timer;
---------------------------------------------------------------------------
-- Crossbar
---------------------------------------------------------------------------
DBG_MAIN_INTERCON : xwb_sdb_crossbar
generic map (
g_num_masters => c_NUM_WB_SLAVES,
g_num_slaves => c_NUM_WB_MASTERS,
g_registered => true,
g_wraparound => true,
g_layout => c_INTERCONNECT_LAYOUT,
g_sdb_addr => c_SDB_ADDRESS
)
port map (
clk_sys_i => clk_sys,
rst_n_i => reset_n,
slave_i => cnx_slave_in,
slave_o => cnx_slave_out,
master_i => cnx_master_in,
master_o => cnx_master_out
);
---------------------------------------------------------------------------
-- Adatper
---------------------------------------------------------------------------
DBG_SALVE_ADAPTER : wb_slave_adapter
generic map (
g_master_use_struct => true,
g_master_mode => g_slave_interface_mode,
g_master_granularity => BYTE,
g_slave_use_struct => false,
g_slave_mode => g_slave_interface_mode,
g_slave_granularity => g_slave_granularity)
port map (
clk_sys_i => clk_sys,
rst_n_i => reset_n,
master_i => cnx_slave_out(c_MASTER_ADAPT),
master_o => cnx_slave_in(c_MASTER_ADAPT),
-- Slave interface 0x0 to 0x3ffff
sl_adr_i(c_wishbone_address_width-1 downto 18) => (others => '0'),
sl_adr_i(17 downto 0) => slave_i.adr(17 downto 0),
sl_dat_i => slave_i.dat,
sl_sel_i => slave_i.sel,
sl_cyc_i => slave_i.cyc,
sl_stb_i => slave_i.stb,
sl_we_i => slave_i.we,
sl_dat_o => slave_o.dat,
sl_ack_o => slave_o.ack,
sl_err_o => slave_o.err,
sl_rty_o => slave_o.rty,
sl_stall_o => slave_o.stall
);
end Behavioral;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment