📄 dsu3x.vhd
字号:
-------------------------------------------------------------------------------- This file is a part of the GRLIB VHDL IP LIBRARY-- Copyright (C) 2003, Gaisler Research---- This program is free software; you can redistribute it and/or modify-- it under the terms of the GNU General Public License as published by-- the Free Software Foundation; either version 2 of the License, or-- (at your option) any later version.---- This program is distributed in the hope that it will be useful,-- but WITHOUT ANY WARRANTY; without even the implied warranty of-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-- GNU General Public License for more details.---- You should have received a copy of the GNU General Public License-- along with this program; if not, write to the Free Software-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------- Entity: dsu-- File: dsu.vhd-- Author: Jiri Gaisler, Edvin Catovic - Gaisler Research-- Description: Combined LEON3 debug support and AHB trace unit------------------------------------------------------------------------------library ieee;use ieee.std_logic_1164.all;library grlib;use grlib.amba.all;use grlib.stdlib.all;use grlib.devices.all;library gaisler;use gaisler.leon3.all;use gaisler.libiu.all;use gaisler.libcache.all;library techmap;use techmap.gencomp.all;entity dsu3x is generic ( hindex : integer := 0; haddr : integer := 16#900#; hmask : integer := 16#f00#; ncpu : integer := 1; tbits : integer := 30; -- timer bits (instruction trace time tag) tech : integer := DEFMEMTECH; irq : integer := 0; kbytes : integer := 0; clk2x : integer range 0 to 1 := 0 ); port ( rst : in std_ulogic; hclk : in std_ulogic; cpuclk : in std_ulogic; ahbmi : in ahb_mst_in_type; ahbsi : in ahb_slv_in_type; ahbso : out ahb_slv_out_type; dbgi : in l3_debug_out_vector(0 to NCPU-1); dbgo : out l3_debug_in_vector(0 to NCPU-1); dsui : in dsu_in_type; dsuo : out dsu_out_type; hclken : in std_ulogic );end; architecture rtl of dsu3x is constant TBUFABITS : integer := log2(kbytes) + 6; constant NBITS : integer := log2x(ncpu); constant PROC_H : integer := 24+NBITS-1; constant PROC_L : integer := 24; constant AREA_H : integer := 23; constant AREA_L : integer := 20; constant HBITS : integer := 28; constant DSU3_VERSION : integer := 1; constant hconfig : ahb_config_type := ( 0 => ahb_device_reg ( VENDOR_GAISLER, GAISLER_LEON3DSU, 0, DSU3_VERSION, 0), 4 => ahb_membar(haddr, '0', '0', hmask), others => zero32); type slv_reg_type is record hsel : std_ulogic; haddr : std_logic_vector(PROC_H downto 0); hwrite : std_ulogic; hwdata : std_logic_vector(31 downto 0); hrdata : std_logic_vector(31 downto 0); hready : std_ulogic; hready2 : std_ulogic; end record; type reg_type is record slv : slv_reg_type; en : std_logic_vector(0 to NCPU-1); te : std_logic_vector(0 to NCPU-1); be : std_logic_vector(0 to NCPU-1); bw : std_logic_vector(0 to NCPU-1); bs : std_logic_vector(0 to NCPU-1); bx : std_logic_vector(0 to NCPU-1); bz : std_logic_vector(0 to NCPU-1); halt : std_logic_vector(0 to NCPU-1); reset : std_logic_vector(0 to NCPU-1); bn : std_logic_vector(NCPU-1 downto 0); ss : std_logic_vector(NCPU-1 downto 0); bmsk : std_logic_vector(NCPU-1 downto 0); dmsk : std_logic_vector(NCPU-1 downto 0); cnt : std_logic_vector(2 downto 0); dsubre : std_logic_vector(2 downto 0); dsuen : std_logic_vector(2 downto 0); act : std_ulogic; timer : std_logic_vector(tbits-1 downto 0); pwd : std_logic_vector(NCPU-1 downto 0); tstop : std_ulogic; 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; end record; type tregtype is record 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; ahbactive : std_logic; aindex : std_logic_vector(TBUFABITS - 1 downto 0); -- buffer index enable : std_logic; -- trace enable bphit : std_logic; -- AHB breakpoint hit bphit2 : std_logic; -- delayed bphit dcnten : std_logic; -- delay counter enable delaycnt : std_logic_vector(TBUFABITS - 1 downto 0); -- delay counter tbreg1 : trace_break_reg; tbreg2 : trace_break_reg; tbwr : std_logic; -- trace buffer write enable break : std_logic; -- break CPU when AHB tracing stops end record; type hclk_reg_type is record irq : std_ulogic; oen : std_ulogic; end record; constant TRACEN : boolean := (kbytes /= 0); signal tbi : tracebuf_in_type; signal tbo : tracebuf_out_type; signal tr, trin : tregtype; signal r, rin : reg_type; signal rh, rhin : hclk_reg_type; signal ahbsi2 : ahb_slv_in_type; signal hrdata2x : std_logic_vector(31 downto 0); begin comb: process(rst, r, ahbsi, ahbsi2, dbgi, dsui, ahbmi, tr, tbo, hclken, rh, hrdata2x) variable v : reg_type; variable iuacc : std_ulogic; variable dbgmode, tstop : std_ulogic; variable rawindex : integer range 0 to (2**NBITS)-1; variable index : natural range 0 to NCPU-1; variable hasel1 : std_logic_vector(AREA_H-1 downto AREA_L); variable hasel2 : std_logic_vector(6 downto 2); variable tv : tregtype; variable vabufi : tracebuf_in_type; variable aindex : std_logic_vector(TBUFABITS - 1 downto 0); -- buffer index variable hirq : std_logic_vector(NAHBIRQ-1 downto 0); variable cpwd : std_logic_vector(15 downto 0); variable hrdata : std_logic_vector(31 downto 0); variable bphit1, bphit2 : std_ulogic; variable vh : hclk_reg_type; begin v := r; iuacc := '0'; --v.slv.hready := '0'; dbgmode := '0'; tstop := '1'; v.dsubre := r.dsubre(1 downto 0) & dsui.break; v.dsuen := r.dsuen(1 downto 0) & dsui.enable; hrdata := r.slv.hrdata; tv := tr; vabufi.enable := '0'; tv.bphit := '0'; tv.tbwr := '0'; if (clk2x /= 0) then tv.bphit2 := tr.bphit; else tv.bphit2 := '0'; end if; vabufi.data := (others => '0'); vabufi.addr := (others => '0'); vabufi.write := (others => '0'); aindex := (others => '0'); hirq := (others => '0'); v.reset := (others => '0'); if TRACEN then aindex := tr.aindex + 1; if (clk2x /= 0) then vh.irq := tr.bphit or tr.bphit2; hirq(irq) := rh.irq; else hirq(irq) := tr.bphit; end if; end if; if hclken = '1' then v.slv.hready := '0'; v.act := '0'; end if; -- check for AHB watchpoints bphit1 := '0'; bphit2 := '0'; if TRACEN and ((ahbsi2.hready and tr.ahbactive) = '1') then if ((((tr.tbreg1.addr xor tr.haddr(31 downto 2)) and tr.tbreg1.mask) = zero32(29 downto 0)) and (((tr.tbreg1.read and not tr.hwrite) or (tr.tbreg1.write and tr.hwrite)) = '1')) then bphit1 := '1'; end if; if ((((tr.tbreg2.addr xor tr.haddr(31 downto 2)) and tr.tbreg2.mask) = zero32(29 downto 0)) and (((tr.tbreg2.read and not tr.hwrite) or (tr.tbreg2.write and tr.hwrite)) = '1')) then bphit2 := '1'; end if; if (bphit1 or bphit2) = '1' then if ((tr.enable and not r.act) = '1') and (tr.dcnten = '0') and (tr.delaycnt /= zero32(TBUFABITS-1 downto 0)) then tv.dcnten := '1'; else tv.enable := '0'; tv.bphit := tr.break; end if; end if; end if; -- generate AHB buffer inputs vabufi.write := "0000"; if TRACEN then if (tr.enable = '1') and (r.act = '0') then vabufi.addr(TBUFABITS-1 downto 0) := tr.aindex; vabufi.data(127) := bphit1 or bphit2; vabufi.data(96+tbits-1 downto 96) := r.timer; vabufi.data(94 downto 80) := ahbmi.hirq(15 downto 1); vabufi.data(79) := tr.hwrite; vabufi.data(78 downto 77) := tr.htrans; vabufi.data(76 downto 74) := tr.hsize; vabufi.data(73 downto 71) := tr.hburst; vabufi.data(70 downto 67) := tr.hmaster; vabufi.data(66) := tr.hmastlock; vabufi.data(65 downto 64) := ahbmi.hresp; if tr.hwrite = '1' then vabufi.data(63 downto 32) := ahbsi2.hwdata; else vabufi.data(63 downto 32) := ahbmi.hrdata; end if; vabufi.data(31 downto 0) := tr.haddr; else vabufi.addr(TBUFABITS-1 downto 0) := tr.haddr(TBUFABITS+3 downto 4); vabufi.data := ahbsi2.hwdata & ahbsi2.hwdata & ahbsi2.hwdata & ahbsi2.hwdata; end if;-- write trace buffer if (tr.enable and not r.act) = '1' then if (tr.ahbactive and ahbsi2.hready) = '1' then tv.aindex := aindex; tv.tbwr := '1'; vabufi.enable := '1'; vabufi.write := "1111"; end if; end if;-- trace buffer delay counter handling if (tr.dcnten = '1') then if (tr.delaycnt = zero32(TBUFABITS-1 downto 0)) then tv.enable := '0'; tv.dcnten := '0'; tv.bphit := tr.break; end if; if tr.tbwr = '1' then tv.delaycnt := tr.delaycnt - 1; end if; end if;-- save AHB transfer parameters if (ahbsi2.hready = '1' ) then tv.haddr := ahbsi2.haddr; tv.hwrite := ahbsi2.hwrite; tv.htrans := ahbsi2.htrans; tv.hsize := ahbsi2.hsize; tv.hburst := ahbsi2.hburst; tv.hmaster := ahbsi2.hmaster; tv.hmastlock := ahbsi2.hmastlock; end if; if tr.hsel = '1' then tv.hwdata := ahbsi2.hwdata; end if; if ahbsi2.hready = '1' then tv.hsel := ahbsi2.hsel(hindex); tv.ahbactive := ahbsi2.htrans(1); end if; end if; if r.slv.hsel = '1' then if (clk2x = 0) then v.cnt := r.cnt - 1; else if (r.cnt /= "111") or (hclken = '1') then v.cnt := r.cnt - 1; end if; end if; end if; if (r.slv.hready and hclken) = '1' then v.slv.hsel := '0'; --v.slv.act := '0'; end if; for i in 0 to NCPU-1 loop if dbgi(i).dsumode = '1' then if r.dmsk(i) = '0' then dbgmode := '1'; if hclken = '1' then v.act := '1'; end if; end if; v.bn(i) := '1'; else tstop := '0'; end if; end loop; if tstop = '0' then v.timer := r.timer + 1; end if; if (clk2x /= 0) then if hclken = '1' then v.tstop := tstop; end if; tstop := r.tstop; end if; cpwd := (others => '0'); for i in 0 to NCPU-1 loop v.bn(i) := v.bn(i) or (dbgmode and r.bmsk(i)) or (r.dsubre(1) and not r.dsubre(2)); if TRACEN then v.bn(i) := v.bn(i) or (tr.bphit and not r.ss(i) and not r.act); end if; v.pwd(i) := dbgi(i).idle and (not dbgi(i).ipend) and not v.bn(i); end loop; cpwd(NCPU-1 downto 0) := r.pwd; if (ahbsi2.hready and ahbsi2.hsel(hindex)) = '1' then if (ahbsi2.htrans(1) = '1') then v.slv.hsel := '1'; v.slv.haddr := ahbsi2.haddr(PROC_H downto 0); v.slv.hwrite := ahbsi2.hwrite; v.cnt := "111"; end if; end if; for i in 0 to NCPU-1 loop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -