debug.vhd

来自「sparc org, vhdl rtl code」· VHDL 代码 · 共 832 行 · 第 1/3 页

VHD
832
字号
  return("%f" & tostd(rs1) & ", %f" & tostd(rs2));
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 fbranchop(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("ne");
  when "0010" => return("lg");
  when "0011" => return("ul");
  when "0100" => return("l");
  when "0101" => return("ug");
  when "0110" => return("g");
  when "0111" => return("u");
  when "1000" => return("a");
  when "1001" => return("e");
  when "1010" => return("ue");
  when "1011" => return("ge");
  when "1100" => return("uge");
  when "1101" => return("le");
  when "1110" => return("ule");
  when "1111" => return("o");
  when others => return("XXX");
  end case;
end;

function ldparcp(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
  return("[" & regimm(insn,dec,true) & "]" & ", " & "%c" & tost(rd));
end;

function ldparf(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
  return("[" & regimm(insn,dec,true) & "]" & ", " & "%f" & tostd(rd));
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) & "]" & " " & 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 stparcp(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
  return("%c" & tost(rd) & ", [" & regimm(insn,dec,true) & "]");
end;
function stparf(insn : debug_info; rd : std_logic_vector; base : base_type) return string is
begin
  return("%f" & tostd(rd) & ", [" & regimm(insn,dec,true) & "]");
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) & "]" & " " & 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 opf    : std_logic_vector(8 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);
  variable annul  : std_logic;
  variable i      : std_logic;
  variable simm : std_logic_vector(12 downto 0);

  variable disen      : boolean := true;

begin

  if disen then

    op    := insn.op(31 downto 30);
    op2   := insn.op(24 downto 22);

    op3   := insn.op(24 downto 19);
    opf   := insn.op(13 downto 5);
    cond  := insn.op(28 downto 25);
    annul := insn.op(29);
    rs1   := insn.op(18 downto 14);
    rs2   := insn.op(4 downto 0);
    rd    := insn.op(29 downto 25);
    i     := insn.op(13);
    simm  := insn.op(12 downto 0);

    case op is
    when CALL => 
      addr := insn.pc + (insn.op(29 downto 0) & "00");
      return(tostf(insn.pc) & bb & "call" & bl2 & tost(addr));
    when FMT2 =>
      case op2 is
      when UNIMP => return(tostf(insn.pc) & bb & "unimp");
      when SETHI =>
	if rd = "00000" then
          return(tostf(insn.pc) & bb & "nop");
	else
          return(tostf(insn.pc) & bb & "sethi" & bl2 & "%hi(" &
		tost(insn.op(21 downto 0) & "0000000000") & "), " & regdec(rd));
	end if;
      when BICC | FBFCC => 
        addr(31 downto 24) := (others => '0');
        addr(1 downto 0) := (others => '0');
        addr(23 downto 2) := insn.op(21 downto 0);
        if addr(23) = '1' then
          addr(31 downto 24) := (others => '1');
        else
          addr(31 downto 24) := (others => '0');
        end if;
        addr := addr + insn.pc;
	if op2 = BICC then
          if insn.op(29) = '1' then
            return(tostf(insn.pc) & bb & 'b' & branchop(insn) & ",a" & bl2 & 
		tost(addr));
          else
            return(tostf(insn.pc) & bb & 'b' & branchop(insn) & bl2 & 
		tost(addr));
	  end if;
	else
          if insn.op(29) = '1' then
            return(tostf(insn.pc) & bb & "fb" & fbranchop(insn) & ",a" & bl2 & 
		tost(addr));
          else
            return(tostf(insn.pc) & bb & "fb" & fbranchop(insn) & bl2 & 
		tost(addr));
	  end if;
	end if;
--      when CBCCC => cptrap := '1';
      when others => return(tostf(insn.pc) & bb & "unknown opcode: " & tost(insn.op));
      end case;
    when FMT3 =>
      case op3 is
      when IAND => return(tostf(insn.pc) & bb & "and" & bl2 & regres(insn,hex));
      when IADD => return(tostf(insn.pc) & bb & "add" & bl2 & regres(insn,dec));
      when IOR  => 
	if ((i = '0') and (rs1 = "00000") and (rs2 = "00000")) then
	  return(tostf(insn.pc) & bb & "clr" & bl2 & regdec(rd));
	elsif ((i = '1') and (simm = "0000000000000")) or (rs1 = "00000") then
	  return(tostf(insn.pc) & bb & "mov" & bl2 & regres(insn,hex));
	else
	  return(tostf(insn.pc) & bb & "or " & bl2 & regres(insn,hex));
	end if;
      when IXOR => return(tostf(insn.pc) & bb & "xor" & bl2 & regres(insn,hex));
      when ISUB => return(tostf(insn.pc) & bb & "sub" & bl2 & regres(insn,dec));
      when ANDN => return(tostf(insn.pc) & bb & "andn" & bl2 & regres(insn,hex));
      when ORN  => return(tostf(insn.pc) & bb & "orn" & bl2 & regres(insn,hex));
      when IXNOR =>
	if ((i = '0') and ((rs1 = rd) or (rs2 = "00000"))) then
	  return(tostf(insn.pc) & bb & "not" & bl2 & regdec(rd));
	else
	  return(tostf(insn.pc) & bb & "xnor" & bl2 & regdec(rd));
	end if;
      when ADDX => return(tostf(insn.pc) & bb & "addx" & bl2 & regres(insn,dec));
      when SUBX => return(tostf(insn.pc) & bb & "subx" & bl2 & regres(insn,dec));
      when ADDCC => return(tostf(insn.pc) & bb & "addcc" & bl2 & regres(insn,dec));
      when ANDCC => return(tostf(insn.pc) & bb & "andcc" & bl2 & regres(insn,hex));
      when ORCC => return(tostf(insn.pc) & bb & "orcc" & bl2 & regres(insn,hex));
      when XORCC => return(tostf(insn.pc) & bb & "xorcc" & bl2 & regres(insn,hex));
      when SUBCC => return(tostf(insn.pc) & bb & "subcc" & bl2 & regres(insn,dec));
      when ANDNCC => return(tostf(insn.pc) & bb & "andncc" & bl2 & regres(insn,hex));
      when ORNCC => return(tostf(insn.pc) & bb & "orncc" & bl2 & regres(insn,hex));
      when XNORCC => return(tostf(insn.pc) & bb & "xnorcc" & bl2 & regres(insn,hex));
      when ADDXCC => return(tostf(insn.pc) & bb & "addxcc" & bl2 & regres(insn,hex));
      when UMAC   => return(tostf(insn.pc) & bb & "umac" & bl2 & regres(insn,dec));
      when SMAC   => return(tostf(insn.pc) & bb & "smac" & bl2 & regres(insn,dec));
      when UMUL   => return(tostf(insn.pc) & bb & "umul" & bl2 & regres(insn,dec));
      when SMUL   => return(tostf(insn.pc) & bb & "smul" & bl2 & regres(insn,dec));
      when UMULCC => return(tostf(insn.pc) & bb & "umulcc" & bl2 & regres(insn,dec));
      when SMULCC => return(tostf(insn.pc) & bb & "smulcc" & bl2 & regres(insn,dec));
      when SUBXCC => return(tostf(insn.pc) & bb & "subxcc" & bl2 & regres(insn,dec));
      when UDIV   => return(tostf(insn.pc) & bb & "udiv" & bl2 & regres(insn,dec));
      when SDIV   => return(tostf(insn.pc) & bb & "sdiv" & bl2 & regres(insn,dec));
      when UDIVCC => return(tostf(insn.pc) & bb & "udivcc" & bl2 & regres(insn,dec));
      when SDIVCC => return(tostf(insn.pc) & bb & "sdivcc" & bl2 & regres(insn,dec));
      when TADDCC => return(tostf(insn.pc) & bb & "taddcc" & bl2 & regres(insn,dec));
      when TSUBCC => return(tostf(insn.pc) & bb & "tsubcc" & bl2 & regres(insn,dec));
      when TADDCCTV => return(tostf(insn.pc) & bb & "taddcctv" & bl2 & regres(insn,dec));
      when TSUBCCTV => return(tostf(insn.pc) & bb & "tsubcctv" & bl2 & regres(insn,dec));
      when MULSCC => return(tostf(insn.pc) & bb & "mulscc" & bl2 & regres(insn,dec));
      when ISLL => return(tostf(insn.pc) & bb & "sll" & bl2 & regres(insn,dec));
      when ISRL => return(tostf(insn.pc) & bb & "srl" & bl2 & regres(insn,dec));
      when ISRA => return(tostf(insn.pc) & bb & "sra" & bl2 & regres(insn,dec));
      when RDY  => 
        if rs1 /= "00000" then
	  return(tostf(insn.pc) & bb & "mov" & bl2 & "%asr" &
	         tost(rs1) & ", " & regdec(rd));
	else
	  return(tostf(insn.pc) & bb & "mov" & bl2 & "%y, " & regdec(rd));
        end if;
      when RDPSR  => return(tostf(insn.pc) & bb & "mov" & bl2 & "%psr, " & regdec(rd));
      when RDWIM  => return(tostf(insn.pc) & bb & "mov" & bl2 & "%wim, " & regdec(rd));
      when RDTBR  => return(tostf(insn.pc) & bb & "mov" & bl2 & "%tbr, " & regdec(rd));
      when WRY  =>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?