Skip to content

Commit

Permalink
updated Xyce interface; analog simulation now generates atrace file
Browse files Browse the repository at this point in the history
  • Loading branch information
rmanohar committed Jul 13, 2022
1 parent 636b351 commit 9c93988
Show file tree
Hide file tree
Showing 8 changed files with 1,452 additions and 113 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ There are a number of things to keep in mind when building `actsim` with `Xyce`.

Building `Xyce`:
* Build and install `Xyce` itself, using `cmake` using `$ACT_HOME` as the install directory
* To build and install the Xyce C interface library (in the `utils/XyceCInterface` directory), use the following commands:
* Go to the `utils/XyceCInterface` directory
* Edit XyceCInterface.C and comment out `#include <N_DEV_Algorithm.h>`
* To build and install the Xyce C interface library (in the `xyce-bits` directory), use the following commands:
* Go to the `xyce-bits/` directory
* Build an object file using `g++ -std=c++17 -I$ACT_HOME/include -c N_CIR_XyceCInterface.C`
* Create the library using `ar ruv libxycecinterface.a N_CIR_XyceCInterface.o`
* If you need to, use `ranlib libxycecinterface.a`
* Copy `libxycecinterface.a` to `$ACT_HOME/lib`
* Copy `N_CIR_XyceCInterface.h` to `$ACT_HOME/include`
* Preserve your cmake build directory for the next step. (We need one file from it as described below.)

We hope that some of these changes will be added to the core Xyce
distribution, after which we will delete the `xyce-bits/` directory.

Building `actsim`:
* When you run `./configure`, it should detect that the Xyce C interface library exists.
* To use static linking for `actsim`, we need to extract the correct link-time options used by your Xyce build. To do so:
Expand Down
175 changes: 107 additions & 68 deletions actsim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ ActSimCore::ActSimCore (Process *p)
_have_filter = 0;
_vcd_out = NULL;
_vcd_emit_time = false;
_vcd_outa = NULL;
_vcd_emit_timea = false;
_watch_idx = 0;


A_INIT (_rand_init);

Expand Down Expand Up @@ -2791,12 +2794,16 @@ void ActSimCore::checkFragmentation (act_connection *idc, ActId *rid, ActSimObj
}

const char *ActSimCore::_idx_to_char (const watchpt_bucket *w)
{
return _idx_to_char (w->idx);
}

const char *ActSimCore::_idx_to_char (int idx)
{
const int start_code = 33;
const int end_code = 126;
static char buf[100];
int pos = 0;
int idx = w->idx;

do {
Assert (pos < 99, "Shortcut is too long; increase static buffer size!");
Expand All @@ -2808,6 +2815,7 @@ const char *ActSimCore::_idx_to_char (const watchpt_bucket *w)
return buf;
}


static int _vcd_group_signals (const void *a, const void *b)
{
int imode;
Expand Down Expand Up @@ -2861,78 +2869,85 @@ static int _vcd_group_signals (const void *a, const void *b)
return *as - *bs;
}

void ActSimCore::setVCD (FILE *fp)

static void _dump_vcdheader (FILE *fp)
{
extern ActSim *glob_sim;

if (!_vcd_out && fp) {
time_t curtime = time (NULL);
// emit VCD header
fprintf (fp, "$date\n");
fprintf (fp, " %s\n", ctime (&curtime));
fprintf (fp, "$end\n");
fprintf (fp, "$version\n");
fprintf (fp, " VCD generated by actsim.\n");
fprintf (fp, "$end\n");
fprintf (fp, "$comment\n");
fprintf (fp, " actual timescale is %g.\n", glob_sim->getTimescale());
fprintf (fp, "$end\n");
fprintf (fp, "$timescale ");
time_t curtime = time (NULL);
// emit VCD header
fprintf (fp, "$date\n");
fprintf (fp, " %s\n", ctime (&curtime));
fprintf (fp, "$end\n");
fprintf (fp, "$version\n");
fprintf (fp, " VCD generated by actsim.\n");
fprintf (fp, "$end\n");
fprintf (fp, "$comment\n");
fprintf (fp, " actual timescale is %g.\n", glob_sim->getTimescale());
fprintf (fp, "$end\n");
fprintf (fp, "$timescale ");

double l10 = log10 (glob_sim->getTimescale());
if (l10 < -14) {
fprintf (fp, "1 fs ");
}
else if (l10 < -13) {
fprintf (fp, "10 fs ");
}
else if (l10 < -12) {
fprintf (fp, "100 fs ");
}
else if (l10 < -11) {
fprintf (fp, "1 ps ");
}
else if (l10 < -10) {
fprintf (fp, "10 ps ");
}
else if (l10 < -9) {
fprintf (fp, "100 ps ");
}
else if (l10 < -8) {
fprintf (fp, "1 ns ");
}
else if (l10 < -7) {
fprintf (fp, "10 ns ");
}
else if (l10 < -6) {
fprintf (fp, "100 ns ");
}
else if (l10 < -5) {
fprintf (fp, "1 us ");
}
else if (l10 < -4) {
fprintf (fp, "10 us ");
}
else if (l10 < -3) {
fprintf (fp, "100 us ");
}
else if (l10 < -2) {
fprintf (fp, "1 ms ");
}
else if (l10 < -1) {
fprintf (fp, "10 ms ");
}
else if (l10 < 0) {
fprintf (fp, "100 ms ");
}
else {
fprintf (fp, "1 s ");
}
fprintf (fp, " $end\n");
fprintf (fp, "$scope module %s $end\n",
actsim_top()->getName());
double l10 = log10 (glob_sim->getTimescale());
if (l10 < -14) {
fprintf (fp, "1 fs ");
}
else if (l10 < -13) {
fprintf (fp, "10 fs ");
}
else if (l10 < -12) {
fprintf (fp, "100 fs ");
}
else if (l10 < -11) {
fprintf (fp, "1 ps ");
}
else if (l10 < -10) {
fprintf (fp, "10 ps ");
}
else if (l10 < -9) {
fprintf (fp, "100 ps ");
}
else if (l10 < -8) {
fprintf (fp, "1 ns ");
}
else if (l10 < -7) {
fprintf (fp, "10 ns ");
}
else if (l10 < -6) {
fprintf (fp, "100 ns ");
}
else if (l10 < -5) {
fprintf (fp, "1 us ");
}
else if (l10 < -4) {
fprintf (fp, "10 us ");
}
else if (l10 < -3) {
fprintf (fp, "100 us ");
}
else if (l10 < -2) {
fprintf (fp, "1 ms ");
}
else if (l10 < -1) {
fprintf (fp, "10 ms ");
}
else if (l10 < 0) {
fprintf (fp, "100 ms ");
}
else {
fprintf (fp, "1 s ");
}
fprintf (fp, " $end\n");
}

void ActSimCore::setVCD (FILE *fp, FILE *fpa)
{

if (!_vcd_out && fp) {
_dump_vcdheader (fp);
fprintf (fp, "$scope module %s $end\n", actsim_top()->getName());
// $var wire N char name $end


int idxmax = 0;
if (_W) {
ihash_bucket_t *b;
ihash_iter_t it;
Expand Down Expand Up @@ -2979,14 +2994,28 @@ void ActSimCore::setVCD (FILE *fp)
ch->width, _idx_to_char (w), w->s);
}
}
if (idxmax < w->idx) {
idxmax = w->idx;
}
}
if (bcnt > 0) {
FREE (bsort);
}
}
if (XyceActInterface::getXyceInterface()->hasIO() && fpa) {
_dump_vcdheader (fpa);
XyceActInterface::getXyceInterface()->step ();
XyceActInterface::getXyceInterface()->emitVCDNames (fpa, idxmax+1);
}

fprintf (fp, "$upscope $end\n");
fprintf (fp, "$enddefinitions $end\n");
fprintf (fp, "$dumpvars\n");
if (fpa) {
fprintf (fpa, "$upscope $end\n");
fprintf (fpa, "$enddefinitions $end\n");
fprintf (fpa, "$dumpvars\n");
}
if (_W) {
ihash_bucket_t *b;
ihash_iter_t it;
Expand Down Expand Up @@ -3020,7 +3049,17 @@ void ActSimCore::setVCD (FILE *fp)
}
}
}
if (fpa && XyceActInterface::getXyceInterface()->hasIO()) {
XyceActInterface::getXyceInterface()->dumpVCD (1);
}
fprintf (fp, "$end\n");
if (fpa && XyceActInterface::getXyceInterface()->hasIO()) {
fprintf (fpa, "$end\n");
}
}
_vcd_out = fp;
_vcd_outa = fpa;
if (fpa == NULL && XyceActInterface::getXyceInterface()->hasIO()) {
XyceActInterface::getXyceInterface()->stopVCD ();
}
}
18 changes: 17 additions & 1 deletion actsim.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ class ActSimCore {
}
}

void setVCD (FILE *fp); // initialize VCD output
void setVCD (FILE *fp, FILE *fpanalog); // initialize VCD output
// clear when it is NULL
void emitVCDTime() {
if (!_vcd_out) return;
Expand All @@ -475,10 +475,22 @@ class ActSimCore {
fprintf (_vcd_out, "\n");
}
}
void emitVCDTimeAnalog() {
if (!_vcd_outa) return;
if (_vcd_emit_timea == false || (SimDES::CurTime() != _last_vcd_timea)) {
_vcd_emit_timea = true;
fprintf (_vcd_outa, "#");
_last_vcd_timea = SimDES::CurTime ();
_last_vcd_timea.decPrint (_vcd_outa);
fprintf (_vcd_outa, "\n");
}
}


FILE *getVCD () { return _vcd_out; }

const char *_idx_to_char (const watchpt_bucket *w);
static const char *_idx_to_char (int idx);

protected:
Act *a;
Expand Down Expand Up @@ -537,6 +549,10 @@ class ActSimCore {
bool _vcd_emit_time; // emit vcd time
BigInt _last_vcd_time; // vcd time

FILE *_vcd_outa; // vcd output file (analog)
bool _vcd_emit_timea; // emit vcd time
BigInt _last_vcd_timea; // vcd time

/*-- timing forks --*/


Expand Down
34 changes: 26 additions & 8 deletions main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -946,30 +946,43 @@ int process_trace (int argc, char **argv)
}
}

static FILE *_cur_vcdfile;
static FILE *_cur_vcdfile, *_cur_vcda;

int process_createvcd (int argc, char **argv)
{
if (argc != 2) {
fprintf (stderr, "Usage: %s <file>\n", argv[0]);
if (argc != 2 && argc != 3) {
fprintf (stderr, "Usage: %s <file> [<analog-vcd>]\n", argv[0]);
return LISP_RET_ERROR;
}

if (_cur_vcdfile) {
fprintf (stderr, "%s: closing current VCD file\n", argv[0]);
fclose (_cur_vcdfile);
_cur_vcdfile = NULL;
glob_sim->setVCD (NULL);
if (_cur_vcda) {
fclose (_cur_vcda);
}
_cur_vcda = NULL;
glob_sim->setVCD (NULL, NULL);
}

FILE *fp = fopen (argv[1], "w");
if (!fp) {
fprintf (stderr, "%s: could not open file `%s'\n", argv[0], argv[1]);
return LISP_RET_ERROR;
}

glob_sim->setVCD (fp);
FILE *fp2 = NULL;
if (argc == 3) {
fp2 = fopen (argv[2], "w");
if (!fp2) {
fprintf (stderr, "%s: could not open file `%s'\n", argv[0], argv[2]);
fclose (fp);
return LISP_RET_ERROR;
}
}
glob_sim->setVCD (fp, fp2);
_cur_vcdfile = fp;
_cur_vcda = fp2;

return LISP_RET_TRUE;
}
Expand All @@ -983,7 +996,11 @@ int process_stopvcd (int argc, char **argv)
if (_cur_vcdfile) {
fclose (_cur_vcdfile);
_cur_vcdfile = NULL;
glob_sim->setVCD (NULL);
if (_cur_vcda) {
fclose (_cur_vcda);
}
_cur_vcda = NULL;
glob_sim->setVCD (NULL, NULL);
}
else {
fprintf (stderr, "%s: no current VCD file.\n", argv[0]);
Expand Down Expand Up @@ -1075,7 +1092,7 @@ struct LispCliCommand Cmds[] = {
{ "trace", "<file> <stop-time> - Create atrace file upto <stop-time> duration", process_trace },
{ "timescale", "<t> - set time scale to <t> picoseconds for tracing", process_timescale },
{ "get_sim_time", "- returns current simulation time in picoseconds", process_get_sim_time },
{ "vcd_start", "<file> - Create Verilog change dump for all watched values", process_createvcd },
{ "vcd_start", "<file> [<afile>]- Create Verilog change dump for all watched values", process_createvcd },
{ "vcd_stop", "- Stop VCD generation", process_stopvcd },

#if 0
Expand Down Expand Up @@ -1149,6 +1166,7 @@ int main (int argc, char **argv)
glob_act->Expand ();

_cur_vcdfile = NULL;
_cur_vcda = NULL;

/* map to cells: these get characterized */
//ActCellPass *cp = new ActCellPass (a);
Expand Down
Loading

0 comments on commit 9c93988

Please sign in to comment.