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: Emit Makefile
|
|
|
|
|
//
|
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"
|
2008-06-30 17:11:25 +00:00
|
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstdarg>
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#include <unistd.h>
|
2008-06-30 17:11:25 +00:00
|
|
|
|
#include <cmath>
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#include <map>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
#include "V3Global.h"
|
2015-02-27 01:40:45 +00:00
|
|
|
|
#include "V3Os.h"
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#include "V3EmitMk.h"
|
|
|
|
|
#include "V3EmitCBase.h"
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
// Emit statements and math operators
|
|
|
|
|
|
|
|
|
|
class EmitMkVisitor : public EmitCBaseVisitor {
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
// METHODS
|
2009-01-21 21:56:50 +00:00
|
|
|
|
static int debug() {
|
|
|
|
|
static int level = -1;
|
|
|
|
|
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
|
|
|
|
return level;
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
void putMakeClassEntry(V3OutMkFile& of, const string& name) {
|
2015-02-27 01:40:45 +00:00
|
|
|
|
of.puts("\t"+V3Os::filenameNonDirExt(name)+" \\\n");
|
2009-12-03 02:15:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
void emitClassMake() {
|
|
|
|
|
// Generate the makefile
|
|
|
|
|
V3OutMkFile of (v3Global.opt.makeDir()+"/"+ v3Global.opt.prefix() + "_classes.mk");
|
|
|
|
|
of.putsHeader();
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# DESCR" "IPTION: Verilator output: Make include file with class lists\n");
|
|
|
|
|
of.puts("#\n");
|
|
|
|
|
of.puts("# This file lists generated Verilated files, for including in higher level makefiles.\n");
|
|
|
|
|
of.puts("# See "+v3Global.opt.prefix()+".mk"+" for the caller.\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Switches...\n");
|
|
|
|
|
of.puts("# Coverage output mode? 0/1 (from --coverage)\n");
|
2008-09-04 13:43:53 +00:00
|
|
|
|
of.puts("VM_COVERAGE = "); of.puts(v3Global.opt.coverage()?"1":"0"); of.puts("\n");
|
2017-10-21 20:41:43 +00:00
|
|
|
|
of.puts("# Threaded output mode? 0/1/N threads (from --threads)\n");
|
|
|
|
|
of.puts("VM_THREADS = "); of.puts(cvtToStr(v3Global.opt.threads())); of.puts("\n");
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# Tracing output mode? 0/1 (from --trace)\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("VM_TRACE = "); of.puts(v3Global.opt.trace()?"1":"0"); of.puts("\n");
|
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Object file lists...\n");
|
|
|
|
|
for (int support=0; support<3; support++) {
|
2006-08-26 11:35:28 +00:00
|
|
|
|
for (int slow=0; slow<2; slow++) {
|
2009-12-03 02:15:56 +00:00
|
|
|
|
if (support==2) of.puts("# Global classes, need linked once per executable");
|
|
|
|
|
else if (support) of.puts("# Generated support classes");
|
|
|
|
|
else of.puts("# Generated module classes");
|
|
|
|
|
if (slow) of.puts(", non-fast-path, compile with low/medium optimization\n");
|
|
|
|
|
else of.puts(", fast-path, compile with highest optimization\n");
|
|
|
|
|
of.puts(support==2?"VM_GLOBAL":support==1?"VM_SUPPORT":"VM_CLASSES");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts(slow?"_SLOW":"_FAST");
|
|
|
|
|
of.puts(" += \\\n");
|
2009-12-03 02:15:56 +00:00
|
|
|
|
if (support==2 && !slow) {
|
|
|
|
|
putMakeClassEntry(of, "verilated.cpp");
|
2009-12-03 11:55:29 +00:00
|
|
|
|
if (v3Global.dpi()) {
|
2010-01-24 13:38:17 +00:00
|
|
|
|
putMakeClassEntry(of, "verilated_dpi.cpp");
|
2009-12-03 11:55:29 +00:00
|
|
|
|
}
|
2015-09-26 02:57:28 +00:00
|
|
|
|
if (v3Global.opt.vpi()) {
|
|
|
|
|
putMakeClassEntry(of, "verilated_vpi.cpp");
|
|
|
|
|
}
|
2012-08-27 01:13:47 +00:00
|
|
|
|
if (v3Global.opt.savable()) {
|
|
|
|
|
putMakeClassEntry(of, "verilated_save.cpp");
|
|
|
|
|
}
|
2014-11-24 02:06:10 +00:00
|
|
|
|
if (v3Global.opt.coverage()) {
|
|
|
|
|
putMakeClassEntry(of, "verilated_cov.cpp");
|
|
|
|
|
}
|
2017-09-08 01:08:49 +00:00
|
|
|
|
if (v3Global.opt.trace()) {
|
|
|
|
|
putMakeClassEntry(of, "verilated_vcd_c.cpp");
|
|
|
|
|
if (v3Global.opt.systemC()) {
|
|
|
|
|
putMakeClassEntry(of, "verilated_vcd_sc.cpp");
|
2010-01-24 23:37:01 +00:00
|
|
|
|
}
|
2009-12-03 02:15:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (support==2 && slow) {
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=nodep->nextp()->castCFile()) {
|
2017-07-07 00:25:59 +00:00
|
|
|
|
if (nodep->source() && nodep->slow()==(slow!=0) && nodep->support()==(support!=0)) {
|
2009-12-03 02:15:56 +00:00
|
|
|
|
putMakeClassEntry(of, nodep->name());
|
|
|
|
|
}
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
of.puts("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-12-03 02:15:56 +00:00
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("\n");
|
|
|
|
|
of.putsHeader();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void emitOverallMake() {
|
|
|
|
|
// Generate the makefile
|
|
|
|
|
V3OutMkFile of (v3Global.opt.makeDir()+"/"+ v3Global.opt.prefix() + ".mk");
|
|
|
|
|
of.putsHeader();
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# DESCR" "IPTION: Verilator output: Makefile for building Verilated archive or executable\n");
|
|
|
|
|
of.puts("#\n");
|
|
|
|
|
of.puts("# Execute this makefile from the object directory:\n");
|
|
|
|
|
of.puts("# make -f "+v3Global.opt.prefix()+".mk"+"\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("\n");
|
|
|
|
|
|
|
|
|
|
if (v3Global.opt.exe()) {
|
2010-01-30 14:42:44 +00:00
|
|
|
|
of.puts("default: "+v3Global.opt.exeName()+"\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
} else {
|
|
|
|
|
of.puts("default: "+v3Global.opt.prefix()+"__ALL.a\n");
|
|
|
|
|
}
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Constants...\n");
|
|
|
|
|
of.puts("# Perl executable (from $PERL)\n");
|
2008-03-18 15:21:13 +00:00
|
|
|
|
of.puts("PERL = "+V3Options::getenvPERL()+"\n");
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# Path to Verilator kit (from $VERILATOR_ROOT)\n");
|
2008-03-18 15:21:13 +00:00
|
|
|
|
of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n");
|
2012-01-20 01:30:41 +00:00
|
|
|
|
of.puts("# SystemC include directory with systemc.h (from $SYSTEMC_INCLUDE)\n");
|
|
|
|
|
of.puts(string("SYSTEMC_INCLUDE ?= ")+V3Options::getenvSYSTEMC_INCLUDE()+"\n");
|
|
|
|
|
of.puts("# SystemC library directory with libsystemc.a (from $SYSTEMC_LIBDIR)\n");
|
|
|
|
|
of.puts(string("SYSTEMC_LIBDIR ?= ")+V3Options::getenvSYSTEMC_LIBDIR()+"\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Switches...\n");
|
|
|
|
|
of.puts("# SystemC output mode? 0/1 (from --sc)\n");
|
2017-09-08 01:08:49 +00:00
|
|
|
|
of.puts(string("VM_SC = ")+((v3Global.opt.systemC())?"1":"0")+"\n");
|
|
|
|
|
of.puts("# Legacy or SystemC output mode? 0/1 (from --sc)\n");
|
|
|
|
|
of.puts(string("VM_SP_OR_SC = $(VM_SC)\n"));
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# Deprecated\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n");
|
2012-01-20 01:30:41 +00:00
|
|
|
|
of.puts("# Deprecated: SystemC architecture to find link library path (from $SYSTEMC_ARCH)\n");
|
2008-03-18 15:21:13 +00:00
|
|
|
|
of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvSYSTEMC_ARCH()+"\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Vars...\n");
|
|
|
|
|
of.puts("# Design prefix (from --prefix)\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts(string("VM_PREFIX = ")+v3Global.opt.prefix()+"\n");
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# Module prefix (from --prefix)\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts(string("VM_MODPREFIX = ")+v3Global.opt.modPrefix()+"\n");
|
|
|
|
|
|
2010-01-29 00:33:02 +00:00
|
|
|
|
of.puts("# User CFLAGS (from -CFLAGS on Verilator command line)\n");
|
|
|
|
|
of.puts("VM_USER_CFLAGS = \\\n");
|
2017-02-13 23:11:40 +00:00
|
|
|
|
const V3StringList& cFlags = v3Global.opt.cFlags();
|
|
|
|
|
for (V3StringList::const_iterator it = cFlags.begin(); it != cFlags.end(); ++it) {
|
2010-01-29 00:33:02 +00:00
|
|
|
|
of.puts("\t"+*it+" \\\n");
|
|
|
|
|
}
|
|
|
|
|
of.puts("\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2010-01-29 00:33:02 +00:00
|
|
|
|
of.puts("# User LDLIBS (from -LDFLAGS on Verilator command line)\n");
|
|
|
|
|
of.puts("VM_USER_LDLIBS = \\\n");
|
2017-02-13 23:11:40 +00:00
|
|
|
|
const V3StringList& ldLibs = v3Global.opt.ldLibs();
|
|
|
|
|
for (V3StringList::const_iterator it = ldLibs.begin(); it != ldLibs.end(); ++it) {
|
2010-01-29 00:33:02 +00:00
|
|
|
|
of.puts("\t"+*it+" \\\n");
|
|
|
|
|
}
|
|
|
|
|
of.puts("\n");
|
|
|
|
|
|
|
|
|
|
V3StringSet dirs;
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# User .cpp files (from .cpp's on Verilator command line)\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("VM_USER_CLASSES = \\\n");
|
2014-06-09 01:36:18 +00:00
|
|
|
|
const V3StringSet& cppFiles = v3Global.opt.cppFiles();
|
|
|
|
|
for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) {
|
2006-08-26 11:35:28 +00:00
|
|
|
|
string cppfile = *it;
|
2015-02-27 01:40:45 +00:00
|
|
|
|
of.puts("\t"+V3Os::filenameNonExt(cppfile)+" \\\n");
|
|
|
|
|
string dir = V3Os::filenameDir(cppfile);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
if (dirs.find(dir) == dirs.end()) dirs.insert(dir);
|
|
|
|
|
}
|
|
|
|
|
of.puts("\n");
|
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# User .cpp directories (from .cpp's on Verilator command line)\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("VM_USER_DIR = \\\n");
|
|
|
|
|
for (V3StringSet::iterator it = dirs.begin(); it!=dirs.end(); ++it) {
|
|
|
|
|
of.puts("\t"+*it+" \\\n");
|
|
|
|
|
}
|
|
|
|
|
of.puts("\n");
|
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Default rules...\n");
|
|
|
|
|
of.puts("# Include list of all generated classes\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("include "+v3Global.opt.prefix()+"_classes.mk\n");
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("# Include global rules\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("include $(VERILATOR_ROOT)/include/verilated.mk\n");
|
|
|
|
|
|
|
|
|
|
if (v3Global.opt.exe()) {
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Executable rules... (from --exe)\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("VPATH += $(VM_USER_DIR)\n");
|
|
|
|
|
of.puts("\n");
|
2014-06-09 01:36:18 +00:00
|
|
|
|
for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) {
|
2006-08-26 11:35:28 +00:00
|
|
|
|
string cppfile = *it;
|
2015-02-27 01:40:45 +00:00
|
|
|
|
string basename = V3Os::filenameNonExt(cppfile);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts(basename+".o: "+cppfile+"\n");
|
|
|
|
|
of.puts("\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<\n");
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-03 02:15:56 +00:00
|
|
|
|
of.puts("\n### Link rules... (from --exe)\n");
|
2010-01-30 14:42:44 +00:00
|
|
|
|
of.puts(v3Global.opt.exeName()+": $(VK_USER_OBJS) $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a\n");
|
2007-07-31 14:47:21 +00:00
|
|
|
|
of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS) 2>&1 | c++filt\n");
|
2006-08-26 11:35:28 +00:00
|
|
|
|
of.puts("\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
of.puts("\n");
|
|
|
|
|
of.putsHeader();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------
|
2016-11-27 13:11:38 +00:00
|
|
|
|
virtual void visit(AstNode* nodep) {
|
2006-08-26 11:35:28 +00:00
|
|
|
|
nodep->v3fatalSrc("No visitors implemented.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2015-10-04 02:33:06 +00:00
|
|
|
|
explicit EmitMkVisitor(AstNetlist*) {
|
2006-08-26 11:35:28 +00:00
|
|
|
|
emitClassMake();
|
|
|
|
|
emitOverallMake();
|
|
|
|
|
}
|
|
|
|
|
virtual ~EmitMkVisitor() {}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
// Gate class functions
|
|
|
|
|
|
|
|
|
|
void V3EmitMk::emitmk(AstNetlist* nodep) {
|
|
|
|
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
|
|
|
|
EmitMkVisitor visitor (nodep);
|
|
|
|
|
}
|