Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / pli / src / SS_RegCompare.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_RegCompare.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named 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 work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
#include "SS_RegCompare.h"
SS_RegCompare::SS_RegCompare( SS_Strand* _strand, SS_PliSocket* _socket )/*{{{*/
:
dbg_out(0),
socket(_socket),
strand(_strand),
inited(false)
{
cmpr_on();
}
/*}}}*/
void SS_RegCompare::initialise()/*{{{*/
{
// the initialise() should be invoked right before the first sstep of each
// strand, so that any change (forced by rtl testbench) before that
// is not considered as a change made by the first instruction. One
// example is HVER, where testbench may do a ASR_WRITE to set a value
// before first sstep.
uint_t id = strand->strand_id();
strand->gl_save();
strand->cwp_save();
strand->tl_save();
for (int gl = 0; gl <= strand->max_gl(); gl++)
for (int gi = 0; gi < 8; gi++)
grf[gl * 8 + gi] = strand->grf[gl * 8 + gi];
for (int wp = 0; wp <= strand->max_wp(); wp++)
for (int wi = 0; wi < 16; wi++)
if (wi >= 8)
wrf[wp * 16 + wi] = strand->wrf[wp * 16 + wi - 8];
else if (wp == strand->max_wp())
wrf[wp * 16 + wi] = strand->wrf[wi + 8];
else
wrf[wp * 16 + wi] = strand->wrf[wp * 16 + wi + 24];
for (int fi =0; fi < 64; fi++)
frf[fi] = strand->get_frf(SS_Strand::freg_idx2off(fi));
inited = true;
}
/*}}}*/
void SS_RegCompare::compare()/*{{{*/
{
char cmp[64];
uint_t id = strand->strand_id();
strand->gl_save();
strand->cwp_save();
strand->tl_save();
new_delta = false;
for (int gl = 0; gl <= strand->max_gl(); gl++)
{
for (int gi = 0; gi < 8; gi++)
{
uint64_t old_val = grf[gl * 8 + gi];
uint64_t new_val = strand->grf[gl * 8 + gi];
if (new_val != old_val)
{
if (cmpr_list[CTR_G])
{
new_delta = true;
sprintf(cmp,"STEP: %d G %d %d %016llx ",id,gl,gi,new_val);
socket->write(cmp);
}
grf[gl * 8 + gi] = new_val;
}
}
}
for (int wp = 0; wp <= strand->max_wp(); wp++)
{
for (int wi = 0; wi < 16; wi++)
{
uint64_t old_val = wrf[wp * 16 + wi];
uint64_t new_val;
// Compare window: 8=o0,..,o7,16=l0,..,l7
// Vonk window is: 0=l0,..,l7,8=i0,..,i7,_______,24=o0,..,o7
if (wi >= 8)
new_val = strand->wrf[wp * 16 + wi - 8];
else if (wp == strand->max_wp())
new_val = strand->wrf[wi + 8];
else
new_val = strand->wrf[wp * 16 + wi + 24];
if (new_val != old_val)
{
if (cmpr_list[CTR_W])
{
new_delta = true;
sprintf(cmp,"STEP: %d W %d %d %016llx ",id,wp,wi + 8,new_val);
socket->write(cmp);
}
wrf[wp * 16 + wi] = new_val;
}
}
}
for (int fi =0; fi < 64; fi++)
{
uint32_t old_val = frf[fi];
uint32_t new_val = strand->get_frf(SS_Strand::freg_idx2off(fi));
if (new_val != old_val)
{
if (cmpr_list[CTR_F])
{
new_delta = true;
sprintf(cmp,"STEP: %d F %d %08x ",id,fi,new_val);
socket->write(cmp);
}
frf[fi] = new_val;
}
}
}
/*}}}*/
void SS_RegCompare::dump_regs()/*{{{*/
{
uint_t id = strand->strand_id();
strand->gl_save();
strand->cwp_save();
strand->tl_save();
fprintf(stdout, "Strand %d:\n", id);
fprintf(stdout, "%2s", "");
for (int gl = 0; gl <= strand->max_gl(); gl++)
fprintf(stdout, " %5s g[%d] %5s ", "", gl, "");
fprintf(stdout, "\n");
for (int gi = 0; gi < 8; gi++)
{
fprintf(stdout, "%d ", gi);
for (int gl = 0; gl <= strand->max_gl(); gl++)
fprintf(stdout, " %016llx ", strand->grf[gl * 8 + gi]);
fprintf(stdout,"\n");
}
for (int wp = 0; wp <= strand->max_wp(); wp++)
{
fprintf(stdout, " %5s o[%d] %5s %5s l[%d] %5s\n", "", wp, "", "", wp, "");
for (int wi = 0; wi < 8; wi++)
{
uint64_t new_val_o;
uint64_t new_val_l;
// Compare window: 8=o0,..,o7,16=l0,..,l7
// Vonk window is: 0=l0,..,l7,8=i0,..,i7,_______,24=o0,..,o7
if (wp == strand->max_wp())
new_val_o = strand->wrf[wi + 8];
else
new_val_o = strand->wrf[wp * 16 + wi + 24];
new_val_l = strand->wrf[wp * 16 + wi];
fprintf(stdout, "%d %016llx %016llx \n", wi, new_val_o, new_val_l);
}
}
for (int fi = 0; fi < 64; fi+=8)
{
fprintf(stdout, "%2s", "");
for (int i = 0; i < 4; i++)
if ((fi+i*2) < 10)
fprintf(stdout, " %13s f%1d ", "", (fi+i*2));
else
fprintf(stdout, " %12s f%2d ", "", (fi+i*2));
fprintf(stdout, "\n");
fprintf(stdout, "%2s", "");
for (int i = 0; i < 8; i+=2)
{
uint32_t new_val1 = strand->get_frf(SS_Strand::freg_idx2off(fi));
uint32_t new_val2 = strand->get_frf(SS_Strand::freg_idx2off(fi+1));
fprintf(stdout, " %08x%08x ", new_val1, new_val2);
}
fprintf(stdout, "\n");
}
}
/*}}}*/