📄 dsu.vhd
字号:
----------------------------------------------------------------------------
-- This file is a part of the LEON VHDL model
-- Copyright (C) 1999 European Space Agency (ESA)
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2 of the License, or (at your option) any later version.
--
-- See the file COPYING.LGPL for the full details of the license.
-----------------------------------------------------------------------------
-- Entity: dsu
-- File: dsu.vhd
-- Author: Jiri Gaisler - Gaisler Research
-- Description: Debug support unit.
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use work.leon_target.all;
use work.leon_config.all;
use work.leon_iface.all;
use work.amba.all;
use work.tech_map.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";
entity dsu is
port (
rst : in std_logic;
clk : in clk_type;
ahbmi : in ahb_mst_in_type;
ahbsi : in ahb_slv_in_type;
ahbso : out ahb_slv_out_type;
dsui : in dsu_in_type;
dsuo : out dsu_out_type;
dbgi : in iu_debug_out_type;
dbgo : out iu_debug_in_type;
irqo : in irq_out_type;
dmi : out dsumem_in_type;
dmo : in dsumem_out_type
);
end;
architecture rtl of dsu is
-- constant dsuconfig : debug_config_type := leon_config_table(cfgindex).debug;
constant TTIMEBITS : integer := 30; -- timer bits
type dsu_config_reg is record
tenable : std_logic; -- trace enable
tmode : std_logic; -- trace delay counter mode
btrapa : std_logic; -- break on any IU trap
btrape : std_logic; -- break on all IU traps but 3,4,5,6,0x11-0x1f
berror : std_logic; -- break on IU error mode
bwatch : std_logic; -- break on IU watchpoint
bsoft : std_logic; -- break on software breakpoint (TA 1)
bahb : std_logic; -- break on AHB watchpoint hit
btrace : std_logic; -- break on trace freeze
ftimer : std_logic; -- freeze timer on break
rerror : std_logic; -- reset error mode
step : std_logic; -- single step
lresp : std_logic; -- link response enable
dresp : std_logic; -- debug response enable
dbreak : std_logic; -- force CPU in debug mode (write-only)
dcnten : std_logic; -- delay counter enable
delaycnt : std_logic_vector(TBUFABITS - 1 downto 0); -- delay counter
end record;
type trace_ctrl_reg is record
aindex : std_logic_vector(TBUFABITS - 1 downto 0); -- buffer index
pindex : std_logic_vector(TBUFABITS - 1 downto 0); -- buffer index
tproc : std_logic; -- trace processor enable
tahb : std_logic; -- trace AHB enable
end record;
type trace_break_reg is record
addr : std_logic_vector(31 downto 2);
mask : std_logic_vector(31 downto 2);
read : std_logic;
write : std_logic;
exec : std_logic;
end record;
type regtype is record
-- AHB signals
haddr : std_logic_vector(31 downto 0);
hwrite : std_logic;
htrans : std_logic_vector(1 downto 0);
hsize : std_logic_vector(2 downto 0);
hburst : std_logic_vector(2 downto 0);
hwdata : std_logic_vector(31 downto 0);
hmaster : std_logic_vector(3 downto 0);
hmastlock : std_logic;
hsel : std_logic;
hready : std_logic;
hready2 : std_logic;
hready3 : std_logic;
ahbactive : std_logic;
timer : std_logic_vector(TTIMEBITS - 1 downto 0); -- timer
dsubre : std_logic_vector(2 downto 0); -- external DSUBRE signal
dsuen : std_logic_vector(2 downto 0); -- external DSUBRE signal
dsuact : std_logic;
dsucfg : dsu_config_reg;
tbreg1 : trace_break_reg;
tbreg2 : trace_break_reg;
tctrl : trace_ctrl_reg;
end record;
signal r, rin : regtype;
constant zero30 : std_logic_vector(29 downto 0) := (others => '0');
begin
ctrl : process(rst, ahbmi, ahbsi, dsui, irqo, dbgi, r, dmo)
variable v : regtype;
variable vpbufi, vabufi : tracebuf_in_type;
variable regsd : std_logic_vector(31 downto 0); -- data from registers
variable pindex, aindex : std_logic_vector(TBUFABITS - 1 downto 0); -- buffer index
variable denable, ldst_cycle, bphit, bphit2 : std_logic;
variable bufdata : std_logic_vector(127 downto 0);
variable pbufo, abufo : tracebuf_out_type;
begin
v := r; regsd := (others => '0'); vpbufi.enable := '0'; vabufi.enable := '0';
vpbufi.data := (others => '0'); vabufi.data := (others => '0');
vpbufi.addr := (others => '0'); vabufi.addr := (others => '0');
vpbufi.write := (others => '0'); vabufi.write := (others => '0');
denable := '0'; bphit := '0'; bphit2 := '0';
v.hready := r.hready2; v.hready2 := r.hready3; v.hready3 := '0';
pbufo := dmo.pbufo; abufo := dmo.abufo;
bufdata := pbufo.data;
ldst_cycle := dbgi.wr.inst(31) and dbgi.wr.inst(30);
v.dsubre := r.dsubre(1 downto 0) & dsui.dsubre;
v.dsuen := r.dsuen(1 downto 0) & dsui.dsuen;
v.dsucfg.dbreak := r.dsucfg.dbreak or
(r.dsubre(1) and not r.dsubre(2)) or dbgi.dmode;
v.dsuact := dbgi.dmode; v.dsucfg.rerror := '0';
-- trace buffer index and delay counters
if DSUTRACE then
-- pragma translate_off
if not is_x(r.timer) then
-- pragma translate_on
if (r.dsucfg.tenable and not dbgi.dmode2) = '1' then
v.timer := r.timer + 1;
end if;
-- pragma translate_off
end if;
-- pragma translate_on
-- pragma translate_off
if not is_x(r.tctrl.pindex) then
-- pragma translate_on
pindex := r.tctrl.pindex + 1;
-- pragma translate_off
end if;
-- pragma translate_on
if DSUMIXED then
-- pragma translate_off
if not is_x(r.tctrl.aindex) then
-- pragma translate_on
aindex := r.tctrl.aindex + 1;
-- pragma translate_off
end if;
-- pragma translate_on
end if;
end if;
-- check for AHB watchpoints
if (ahbsi.hready and r.ahbactive ) = '1' then
if ((((r.tbreg1.addr xor r.haddr(31 downto 2)) and r.tbreg1.mask) = zero30) and
(((r.tbreg1.read and not r.hwrite) or (r.tbreg1.write and r.hwrite)) = '1'))
or ((((r.tbreg2.addr xor r.haddr(31 downto 2)) and r.tbreg2.mask) = zero30) and
(((r.tbreg2.read and not r.hwrite) or (r.tbreg2.write and r.hwrite)) = '1'))
then
bphit := '1';
if (r.dsucfg.dcnten = '0') and ((r.tctrl.tahb or r.tctrl.tproc) = '1') and
(r.dsucfg.delaycnt /= zero30(TBUFABITS-1 downto 0))
then v.dsucfg.dcnten := '1'; end if;
if r.dsucfg.bahb = '1' then v.dsucfg.dbreak := '1'; end if;
end if;
end if;
-- check for IU trace breakpoints
if (dbgi.holdn and dbgi.wr.pv and
not dbgi.wr.annul) = '1'
then
if ((((r.tbreg1.addr xor dbgi.wr.pc(31 downto 2)) and r.tbreg1.mask) = zero30) and
(r.tbreg1.exec = '1'))
or ((((r.tbreg2.addr xor dbgi.wr.pc(31 downto 2)) and r.tbreg2.mask) = zero30) and
(r.tbreg2.exec = '1'))
then
bphit2 := '1';
if (r.dsucfg.tenable = '1') and (r.dsucfg.dcnten = '0') and
(r.dsucfg.delaycnt /= zero30(TBUFABITS-1 downto 0))
then v.dsucfg.dcnten := '1'; end if;
if r.dsucfg.bahb = '1' then v.dsucfg.dbreak := '1'; end if;
end if;
end if;
-- generate buffer inputs
if DSUTRACE then
vpbufi.write := "0000"; vabufi.write := "0000";
if r.dsucfg.tenable = '1' then
vpbufi.addr := '0' & r.tctrl.pindex;
vabufi.addr := '0' & r.tctrl.aindex;
vabufi.data(125 downto 96) := r.timer;
vpbufi.data(125 downto 96) := r.timer;
vabufi.data(127) := bphit;
vabufi.data(95 downto 92) := irqo.irl;
vabufi.data(91 downto 88) := dbgi.psrpil;
vabufi.data(87 downto 80) := dbgi.psrtt;
vabufi.data(79) := r.hwrite;
vabufi.data(78 downto 77) := r.htrans;
vabufi.data(76 downto 74) := r.hsize;
vabufi.data(73 downto 71) := r.hburst;
vabufi.data(70 downto 67) := r.hmaster;
vabufi.data(66) := r.hmastlock;
vabufi.data(65 downto 64) := ahbmi.hresp;
if r.hwrite = '1' then
vabufi.data(63 downto 32) := ahbsi.hwdata;
else
vabufi.data(63 downto 32) := ahbmi.hrdata;
end if;
vabufi.data(31 downto 0) := r.haddr;
vpbufi.data(127) := bphit2;
vpbufi.data(126) := not dbgi.wr.pv;
vpbufi.data(95 downto 64) := dbgi.result;
vpbufi.data(63 downto 32) := dbgi.wr.pc(31 downto 2) &
dbgi.trap & dbgi.error;
vpbufi.data(31 downto 0) := dbgi.wr.inst;
else
vpbufi.addr := '0' & r.haddr(TBUFABITS+3 downto 4);
vabufi.addr := '1' & r.haddr(TBUFABITS+3 downto 4);
vpbufi.data := ahbsi.hwdata & ahbsi.hwdata & ahbsi.hwdata & ahbsi.hwdata;
vabufi.data := vpbufi.data;
end if;
-- write trace buffer
if r.dsucfg.tenable = '1' then
if (r.tctrl.tahb and r.ahbactive and ahbsi.hready) = '1' then
if DSUMIXED then
v.tctrl.aindex := aindex;
vabufi.enable := '1'; vabufi.write := "1111";
elsif (r.tctrl.tproc = '0') then
v.tctrl.pindex := pindex;
vpbufi.enable := '1'; vpbufi.write := "1111";
end if;
end if;
if (r.tctrl.tproc and dbgi.holdn and
(dbgi.wr.pv or dbgi.write_reg or ldst_cycle)
and (not dbgi.vdmode) and not dbgi.wr.annul) = '1'
then
vpbufi.enable := '1'; vpbufi.write := "1111";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -