2012-04-13 01:08:20 +00:00
|
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Preprocessing wrapper
|
|
|
|
|
//
|
2008-04-25 12:14:27 +00:00
|
|
|
|
// Code available from: http://www.veripool.org/verilator
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2018-01-02 23:05:06 +00:00
|
|
|
|
// Copyright 2004-2018 by Wilson Snyder. This program is free software; you can
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// redistribute it and/or modify it under the terms of either the GNU
|
2009-05-04 21:07:57 +00:00
|
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//
|
|
|
|
|
// Verilator 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.
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
|
2006-12-18 19:20:45 +00:00
|
|
|
|
#include "config_build.h"
|
|
|
|
|
#include "verilatedos.h"
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
#include "V3Global.h"
|
|
|
|
|
#include "V3PreShell.h"
|
|
|
|
|
#include "V3PreProc.h"
|
|
|
|
|
#include "V3File.h"
|
2009-10-31 14:08:38 +00:00
|
|
|
|
#include "V3Parse.h"
|
2017-02-09 23:33:18 +00:00
|
|
|
|
#include "V3Os.h"
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2018-10-14 17:43:24 +00:00
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cstdarg>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <list>
|
|
|
|
|
#include <set>
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//######################################################################
|
|
|
|
|
|
|
|
|
|
class V3PreShellImp {
|
|
|
|
|
protected:
|
|
|
|
|
friend class V3PreShell;
|
|
|
|
|
|
|
|
|
|
static V3PreShellImp s_preImp;
|
|
|
|
|
static V3PreProc* s_preprocp;
|
2010-01-20 12:15:51 +00:00
|
|
|
|
static V3InFilter* s_filterp;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
//---------------------------------------
|
|
|
|
|
// METHODS
|
|
|
|
|
|
2010-04-10 12:20:28 +00:00
|
|
|
|
static int debug(bool reset=false) {
|
2009-01-21 21:56:50 +00:00
|
|
|
|
static int level = -1;
|
2010-04-10 12:20:28 +00:00
|
|
|
|
if (VL_UNLIKELY(level < 0) || reset) {
|
|
|
|
|
level = v3Global.opt.debugSrcLevel(__FILE__);
|
|
|
|
|
if (s_preprocp) s_preprocp->debug(debug());
|
|
|
|
|
}
|
2009-01-21 21:56:50 +00:00
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
void boot(char** env) {
|
|
|
|
|
// Create the implementation pointer
|
|
|
|
|
if (env) {}
|
|
|
|
|
if (!s_preprocp) {
|
|
|
|
|
FileLine* cmdfl = new FileLine("COMMAND_LINE",0);
|
|
|
|
|
s_preprocp = V3PreProc::createPreProc(cmdfl);
|
|
|
|
|
s_preprocp->debug(debug());
|
|
|
|
|
// Default defines
|
|
|
|
|
FileLine* prefl = new FileLine("INTERNAL_VERILATOR_DEFINE",0);
|
2010-01-15 00:22:12 +00:00
|
|
|
|
s_preprocp->defineCmdLine(prefl,"VERILATOR", "1"); // LEAK_OK
|
2009-12-21 03:26:48 +00:00
|
|
|
|
s_preprocp->defineCmdLine(prefl,"verilator", "1"); // LEAK_OK
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"verilator3", "1"); // LEAK_OK
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"systemc_clock", "/*verilator systemc_clock*/"); // LEAK_OK
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); // LEAK_OK
|
2013-01-17 00:11:56 +00:00
|
|
|
|
if (prefl->language().systemVerilog()) {
|
|
|
|
|
// Synthesis compatibility
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SYSTEMVERILOG", "1"); // LEAK_OK
|
|
|
|
|
// IEEE predefined
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_START", "0");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_STOP", "1");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_RESET", "2");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_CHECK", "3");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_MODULE", "10");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_HIER", "11");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_ASSERTION", "20");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_FSM_STATE", "21");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_STATEMENT", "22");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_TOGGLE", "23");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_OVERFLOW", "-2");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_ERROR", "-1");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_NOCOV", "0");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_OK", "1");
|
|
|
|
|
s_preprocp->defineCmdLine(prefl,"SV_COV_PARTIAL", "2");
|
|
|
|
|
}
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-25 13:52:45 +00:00
|
|
|
|
bool preproc(FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep,
|
|
|
|
|
const string& errmsg) { // "" for no error
|
2010-04-10 12:20:28 +00:00
|
|
|
|
debug(true); // Recheck if debug on - first check was before command line passed
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// Preprocess the given module, putting output in vppFilename
|
|
|
|
|
UINFONL(1," Preprocessing "<<modname<<endl);
|
|
|
|
|
|
|
|
|
|
// Preprocess
|
2010-01-20 12:15:51 +00:00
|
|
|
|
s_filterp = filterp;
|
2017-02-09 23:33:18 +00:00
|
|
|
|
bool ok = preprocOpen(fl, s_filterp, modname, "", errmsg);
|
2011-10-28 00:56:38 +00:00
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
while (!s_preprocp->isEof()) {
|
|
|
|
|
string line = s_preprocp->getline();
|
2009-10-31 14:08:38 +00:00
|
|
|
|
V3Parse::ppPushText(parsep, line);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
2011-10-28 00:56:38 +00:00
|
|
|
|
return true;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-25 13:52:45 +00:00
|
|
|
|
void preprocInclude(FileLine* fl, const string& modname) {
|
2010-12-25 20:50:07 +00:00
|
|
|
|
if (modname[0]=='/' || modname[0]=='\\') {
|
2010-12-26 13:19:45 +00:00
|
|
|
|
fl->v3warn(INCABSPATH,"Suggest `include with absolute path be made relative, and use +include: "<<modname);
|
2010-12-25 20:50:07 +00:00
|
|
|
|
}
|
2017-02-09 23:33:18 +00:00
|
|
|
|
preprocOpen(fl, s_filterp, modname, V3Os::filenameDir(fl->filename()), "Cannot find include file: ");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-25 13:52:45 +00:00
|
|
|
|
bool preprocOpen(FileLine* fl, V3InFilter* filterp, const string& modname, const string& lastpath,
|
|
|
|
|
const string& errmsg) { // Error message or "" to suppress
|
2011-10-28 00:56:38 +00:00
|
|
|
|
// Returns true if successful
|
2017-11-22 23:43:48 +00:00
|
|
|
|
// Try a pure name in case user has a bogus `filename they don't expect
|
2018-08-25 13:52:45 +00:00
|
|
|
|
string filename = v3Global.opt.filePath(fl, modname, lastpath, errmsg);
|
2017-11-22 23:43:48 +00:00
|
|
|
|
if (filename=="") {
|
|
|
|
|
// Allow user to put `defined names on the command line instead of filenames,
|
|
|
|
|
// then convert them properly.
|
2018-08-25 13:52:45 +00:00
|
|
|
|
string ppmodname = s_preprocp->removeDefines(modname);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2018-08-25 13:52:45 +00:00
|
|
|
|
filename = v3Global.opt.filePath(fl, ppmodname, lastpath, errmsg);
|
2017-11-22 23:43:48 +00:00
|
|
|
|
}
|
2011-10-28 00:56:38 +00:00
|
|
|
|
if (filename=="") return false; // Not found
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
UINFO(2," Reading "<<filename<<endl);
|
2010-01-20 12:15:51 +00:00
|
|
|
|
s_preprocp->openFile(fl, filterp, filename);
|
2011-10-28 00:56:38 +00:00
|
|
|
|
return true;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CONSTRUCTORS
|
|
|
|
|
V3PreShellImp() {}
|
2010-01-20 12:15:51 +00:00
|
|
|
|
~V3PreShellImp() {}
|
2006-08-26 11:35:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
V3PreShellImp V3PreShellImp::s_preImp;
|
|
|
|
|
V3PreProc* V3PreShellImp::s_preprocp = NULL;
|
2010-01-20 12:15:51 +00:00
|
|
|
|
V3InFilter* V3PreShellImp::s_filterp = NULL;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
// Perl class functions
|
|
|
|
|
|
|
|
|
|
void V3PreShell::boot(char** env) {
|
|
|
|
|
V3PreShellImp::s_preImp.boot(env);
|
|
|
|
|
}
|
2011-10-28 00:56:38 +00:00
|
|
|
|
bool V3PreShell::preproc(FileLine* fl, const string& modname, V3InFilter* filterp,
|
|
|
|
|
V3ParseImp* parsep, const string& errmsg) {
|
|
|
|
|
return V3PreShellImp::s_preImp.preproc(fl, modname, filterp, parsep, errmsg);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
void V3PreShell::preprocInclude(FileLine* fl, const string& modname) {
|
|
|
|
|
V3PreShellImp::s_preImp.preprocInclude(fl, modname);
|
|
|
|
|
}
|
2009-12-21 03:26:48 +00:00
|
|
|
|
void V3PreShell::defineCmdLine(const string& name, const string& value) {
|
2006-08-26 11:35:28 +00:00
|
|
|
|
FileLine* prefl = new FileLine("COMMAND_LINE_DEFINE",0);
|
2009-12-21 03:26:48 +00:00
|
|
|
|
V3PreShellImp::s_preprocp->defineCmdLine(prefl, name, value);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
void V3PreShell::undef(const string& name) {
|
|
|
|
|
V3PreShellImp::s_preprocp->undef(name);
|
|
|
|
|
}
|