📄 debug.vhd
字号:
-----------------------------------------------------------------------------
-- This file is a part of the LEON VHDL model
-- Copyright (C) 1999 European Space Agency (ESA)
--
-- 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.
--
-- See the file COPYING for the full details of the license.
-----------------------------------------------------------------------------
-- Package: debug
-- File: debug.vhd
-- Author: Jiri Gaisler - ESA/ESTEC
-- Description: This package implements a SPARC disassembler and LEON
-- trace function.
------------------------------------------------------------------------------
-- Version control:
-- 17-12-1998: : First implemetation
-- 27-08-1999: : Moved trace function from iu
-- 26-09-1999: : Release 1.0
------------------------------------------------------------------------------
library IEEE;
use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_unsigned."+";
use IEEE.Std_Logic_arith.all;
use work.config.all;
use work.sparcv8.all;
use work.iface.all;
library MMS;
use MMS.stdioimp.all;
use STD.TEXTIO.all;
package debug is
type debug_info is record
op : std_logic_vector(31 downto 0);
pc : std_logic_vector(31 downto 0);
end record;
type base_type is (hex, dec);
subtype nibble is std_logic_vector(3 downto 0);
function disas(insn : debug_info) return string;
procedure trace(signal debug : in iu_debug_type);
end debug;
package body debug is
function tohex(n:nibble) return character is
begin
case n is
when "0000" => return('0');
when "0001" => return('1');
when "0010" => return('2');
when "0011" => return('3');
when "0100" => return('4');
when "0101" => return('5');
when "0110" => return('6');
when "0111" => return('7');
when "1000" => return('8');
when "1001" => return('9');
when "1010" => return('a');
when "1011" => return('b');
when "1100" => return('c');
when "1101" => return('d');
when "1110" => return('e');
when "1111" => return('f');
when others => return('X');
end case;
end;
function tost(v:std_logic_vector) return string is
constant vlen : natural := v'length;
constant slen : natural := (vlen+3)/4;
variable vv : std_logic_vector(vlen-1 downto 0);
variable s : string(1 to slen);
begin
vv := v;
for i in slen downto 1 loop
s(i) := tohex(vv(3 downto 0));
vv(vlen-5 downto 0) := vv(vlen-1 downto 4);
end loop;
return(s);
end;
function regdec(v : std_logic_vector) return string is
variable t : std_logic_vector(4 downto 0);
variable rt : character;
begin
t := v;
case t(4 downto 3) is
when "00" => rt := 'g';
when "01" => rt := 'o';
when "10" => rt := 'l';
when "11" => rt := 'i';
when others => rt := 'X';
end case;
if v(4 downto 0) = "11110" then
return("%fp");
elsif v(4 downto 0) = "01110" then
return("%sp");
else
return('%' & rt & tostring(conv_integer(unsigned(t(2 downto 0)))));
end if;
end;
function simm13dec(insn : debug_info; base : base_type; merge : boolean) return string is
variable simm : std_logic_vector(12 downto 0) := insn.op(12 downto 0);
variable rs1 : std_logic_vector(4 downto 0) := insn.op(18 downto 14);
variable i : std_logic := insn.op(13);
variable sig : character;
variable fill : std_logic_vector(31 downto 13) := (others => simm(12));
begin
if i = '0' then
return("");
else
if (simm(12) = '1') and (base = dec) then
sig := '-'; simm := (not simm) + 1;
else
sig := '+';
end if;
if base = dec then
if merge then
if rs1 = "00000" then
return(tostring(conv_integer(unsigned(simm))));
else
return(sig & tostring(conv_integer(unsigned(simm))));
end if;
else
if rs1 = "00000" then
return(tostring(conv_integer(unsigned(simm))));
else
if sig = '-' then
return(", " & sig & tostring(conv_integer(unsigned(simm))));
else
return(", " & tostring(conv_integer(unsigned(simm))));
end if;
end if;
end if;
else
if rs1 = "00000" then
if simm(12) = '1' then return("0x" & tost(fill & simm));
else return("0x" & tost("000" & simm)); end if;
else
if simm(12) = '1' then return(", 0x" & tost(fill & simm));
else return(", 0x" & tost("000" & simm)); end if;
end if;
end if;
end if;
end;
function regimm(insn : debug_info; base : base_type; merge : boolean) return string is
variable rs1, rs2 : std_logic_vector(4 downto 0);
variable i : std_logic;
begin
rs1 := insn.op(18 downto 14);
rs2 := insn.op(4 downto 0);
i := insn.op(13);
if i = '0' then
if (rs1 = "00000") then
if (rs2 = "00000") then
return("0");
else
return(regdec(rs2));
end if;
else
if (rs2 = "00000") then
return(regdec(rs1));
elsif merge then
return(regdec(rs1) & " + " & regdec(rs2));
else
return(regdec(rs1) & ", " & regdec(rs2));
end if;
end if;
else
if (rs1 = "00000") then
return(simm13dec(insn, base, merge));
elsif insn.op(12 downto 0) = "0000000000000" then
return(regdec(rs1));
else
return(regdec(rs1) & simm13dec(insn, base, merge));
end if;
end if;
end;
function regres(insn : debug_info; base : base_type) return string is
variable rs1, rs2, rd : std_logic_vector(4 downto 0);
variable i : std_logic;
begin
rd := insn.op(29 downto 25);
return(regimm(insn, base,false) & ", " & regdec(rd ));
end;
function branchop(insn : debug_info) return string is
variable simm : std_logic_vector(31 downto 0);
begin
case insn.op(28 downto 25) is
when "0000" => return("n");
when "0001" => return("e");
when "0010" => return("le");
when "0011" => return("l");
when "0100" => return("lue");
when "0101" => return("cs");
when "0110" => return("neg");
when "0111" => return("vs");
when "1000" => return("a");
when "1001" => return("ne");
when "1010" => return("g");
when "1011" => return("ge");
when "1100" => return("gu");
when "1101" => return("cc");
when "1110" => return("pos");
when "1111" => return("vc");
when others => return("XXX");
end case;
end;
function ldpar(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
return("[" & regimm(insn,dec,true) & "]" & ", " & regdec(rd));
end;
function ldpara(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
return("[" & regimm(insn,dec,true) & "]" & " 0x" & tost(insn.op(12 downto 5)) & ", " & regdec(rd));
end;
function stparc(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
if rd = "00000" then
return("[" & regimm(insn,dec,true) & "]");
else
return(regdec(rd) & ", [" & regimm(insn,dec,true) & "]");
end if;
end;
function stpar(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
return(regdec(rd) & ", [" & regimm(insn,dec,true) & "]");
end;
function stpara(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
return(regdec(rd) & ", [" & regimm(insn,dec,true) & "]" & " 0x" & tost(insn.op(12 downto 5)));
end;
function disas(insn : debug_info) return string is
constant STMAX : natural := 9;
constant bl2 : string(1 to 2) := (others => ' ');
constant bb : string(1 to (4)) := (others => ' ');
variable op : std_logic_vector(1 downto 0);
variable op2 : std_logic_vector(2 downto 0);
variable op3 : std_logic_vector(5 downto 0);
variable cond : std_logic_vector(3 downto 0);
variable rs1, rs2, rd : std_logic_vector(4 downto 0);
variable addr : std_logic_vector(31 downto 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -