Skip to content

Commit

Permalink
Prototype linked definitions flow (#1019)
Browse files Browse the repository at this point in the history
* Init test

* Refactor module def json code into function

* Add link definition api

* Prototype linked_definitions flow

* revert file reader change

* Remove debug print

* Add C-API's for module linking

* Add linked_definitions to coreir -> json pass

* Rename linked_definitions -> linked_modules

* Only allow linking to decls, add default logic

* Add more tests

* Update instancegraph.h

* Add C-API for linking default module

Also adds serialization (out) of default linked module.

* Trigger build

Co-authored-by: Raj Setaluri <[email protected]>
Co-authored-by: rsetaluri <[email protected]>
  • Loading branch information
3 people authored Sep 7, 2021
1 parent edf5ac5 commit ce354bd
Show file tree
Hide file tree
Showing 19 changed files with 653 additions and 23 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ project(verilogAST-download NONE)
include(ExternalProject)
ExternalProject_Add(verilogAST
GIT_REPOSITORY https://github.com/leonardt/verilogAST-cpp.git
GIT_TAG dc7610b
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/verilogAST-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/verilogAST-build"
CONFIGURE_COMMAND ""
Expand Down
7 changes: 7 additions & 0 deletions include/coreir-c/coreir.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ extern COREModuleDef* COREModuleNewDef(COREModule* m);
// extern COREModuleDef* COREModuleGetDef(COREModule* m);
void COREModuleSetDef(COREModule* module, COREModuleDef* module_def);
extern COREDirectedModule* COREModuleGetDirectedModule(COREModule* module);
extern bool COREModuleLinkModule(
char* key, COREModule* source, COREModule* target);
extern bool COREModuleGetLinkedModules(
COREModule* source, char*** keys, COREModule*** targets, int* size);
extern bool COREModuleLinkDefaultModule(COREModule* source, COREModule* target);
extern bool COREModuleHasDefaultLinkedModule(COREModule* source);
extern COREModule* COREModuleGetDefaultLinkedModule(COREModule* source);

// Errors:
// Invalid arg: instance name already exists
Expand Down
4 changes: 4 additions & 0 deletions include/coreir/ir/instancegraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class InstanceGraphNode {
int mark = 0; // unmarked=0, temp=1,perm=2
void addInstance(Instance* i, InstanceGraphNode* ign) {
instanceList.push_back(i);
addInstanceGraphNode(ign);
}

void addInstanceGraphNode(InstanceGraphNode* ign) {
ignList.push_back(ign);
}

Expand Down
36 changes: 36 additions & 0 deletions include/coreir/ir/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace CoreIR {
class Module : public GlobalValue, public Args, public VerilogPrimitive {
RecordType* type;
ModuleDef* def = nullptr;
Module* defaultLinkedModule = nullptr;
std::map<std::string,Module*> linkedModules;

const Params modparams;
Values defaultModArgs;
Expand Down Expand Up @@ -44,6 +46,40 @@ class Module : public GlobalValue, public Args, public VerilogPrimitive {
// This will validate def
void setDef(ModuleDef* def, bool validate = true);

void linkDefaultModule(Module* mod) {
if (this->hasDef()) {
throw std::runtime_error("Cannot link to definition");
}
this->defaultLinkedModule = mod;
};

bool hasDefaultLinkedModule() {
return this->defaultLinkedModule != nullptr;
};

Module* getDefaultLinkedModule() const {
return this->defaultLinkedModule;
};

bool hasLinkedModule() const {
return this->defaultLinkedModule != nullptr ||
this->linkedModules.size() > 0;
};

void linkModule(std::string key, Module* mod) {
if (this->hasDef()) {
throw std::runtime_error("Cannot link to definition");
}
if (this->linkedModules.count(key) > 0) {
throw std::runtime_error("Key: " + key + "has already been linked");
}
this->linkedModules[key] = mod;
};

std::map<std::string,Module*> getLinkedModules() const {
return this->linkedModules;
};

bool hasVerilogDef();

ModuleDef* newModuleDef();
Expand Down
6 changes: 6 additions & 0 deletions include/coreir/passes/analysis/verilog.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Verilog : public InstanceGraphPass {
// serializing to a single or multiple files
std::vector<std::pair<std::string, std::unique_ptr<vAST::AbstractModule>>>
modules;
std::map<Module*, std::string> linked_module_map;

// Externally defined modules (no moduleDef), for now we just emit comments
// listing them when compiling to a single file
Expand Down Expand Up @@ -74,6 +75,11 @@ class Verilog : public InstanceGraphPass {
std::set<std::string>& wires,
std::set<std::string>& inlined_wires);

std::vector<std::variant<
std::unique_ptr<vAST::StructuralStatement>,
std::unique_ptr<vAST::Declaration>>>
compileLinkedModuleBody(Module* module);

std::unique_ptr<vAST::AbstractModule> compileStringBodyModule(
json verilog_json,
std::string name,
Expand Down
71 changes: 57 additions & 14 deletions src/coreir-c/coreir-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@
using namespace std;
namespace CoreIR {

namespace {

void lowerModuleMap(
const std::map<std::string, Module*>& modules,
char*** keys,
COREModule*** values,
int* size) {
*size = modules.size();
*keys = static_cast<char**>(malloc((*size) * sizeof(char*)));
*values = static_cast<COREModule**>(malloc((*size) * sizeof(COREModule*)));
int i = 0;
for (auto const& item : modules) {
const char* key = item.first.c_str();
(*keys)[i] = static_cast<char*>(malloc(strlen(key) + 1));
strcpy((*keys)[i], key);
(*values)[i] = rcast<COREModule*>(item.second);
i++;
}
}

} // namespace

extern "C" {

void* CORENewMap(
Expand Down Expand Up @@ -544,6 +566,39 @@ COREDirectedModule* COREModuleGetDirectedModule(COREModule* module) {
rcast<Module*>(module)->newDirectedModule());
}

bool COREModuleLinkModule(char* key, COREModule* source, COREModule* target) {
auto s = rcast<Module*>(source);
auto t = rcast<Module*>(target);
s->linkModule(std::string(key), t);
return true;
}

bool COREModuleGetLinkedModules(
COREModule* source, char*** keys, COREModule*** targets, int* size) {
auto s = rcast<Module*>(source);
auto ts = s->getLinkedModules();
lowerModuleMap(ts, keys, targets, size);
return true;
}

bool COREModuleLinkDefaultModule(COREModule* source, COREModule* target) {
auto s = rcast<Module*>(source);
auto t = rcast<Module*>(target);
s->linkDefaultModule(t);
return true;
}

bool COREModuleHasDefaultLinkedModule(COREModule* source) {
auto s = rcast<Module*>(source);
return s->hasDefaultLinkedModule();
}

COREModule* COREModuleGetDefaultLinkedModule(COREModule* source) {
auto s = rcast<Module*>(source);
auto linked = s->getDefaultLinkedModule();
return rcast<COREModule*>(linked);
}

void COREModuleDefConnect(
COREModuleDef* module_def,
COREWireable* a,
Expand Down Expand Up @@ -708,20 +763,8 @@ void CORENamespaceGetModules(
COREModule*** values,
int* num_items) {

std::map<std::string, Module*> modules = rcast<Namespace*>(core_namespace)
->getModules();

*num_items = modules.size();
*keys = (char**)malloc(*num_items * sizeof(char*));
*values = (COREModule**)malloc(*num_items * sizeof(COREModule*));
int i = 0;
for (auto const& item : modules) {
const char* key = item.first.c_str();
(*keys)[i] = (char*)malloc(strlen(key) + 1);
strcpy((*keys)[i], key);
(*values)[i] = rcast<COREModule*>(item.second);
i++;
}
auto modules = rcast<Namespace*>(core_namespace)->getModules();
lowerModuleMap(modules, keys, values, num_items);
}

void CORENamespaceGetGenerators(
Expand Down
6 changes: 4 additions & 2 deletions src/ir/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@ JsonType* Context::Json() { return JsonType::make(this); }

void Context::setTop(Module* top) {
ASSERT(
top && (top->hasDef() || top->hasVerilogDef()),
top && (top->hasDef() || top->hasVerilogDef() ||
top->hasLinkedModule()),
top->toString() + " has no def!");
this->top = top;
}
Expand All @@ -302,7 +303,8 @@ void Context::setTop(string topRef) {
ASSERT(topns->hasModule(topsplit[1]), "Missing module " + topRef);
this->top = topns->getModule(topsplit[1]);
ASSERT(
this->top->hasDef() || this->top->hasVerilogDef(),
this->top->hasDef() || this->top->hasVerilogDef() ||
top->hasLinkedModule(),
topRef + " has no def!");
}

Expand Down
23 changes: 21 additions & 2 deletions src/ir/fileReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,10 @@ bool load(Context* c, string filename, Module** top, std::vector<Module*>& loade
"defaultmodargs",
"instances",
"connections",
"metadata"});
"metadata",
"default_linked_module",
"linked_modules",
});
Type* t = json2Type(c, jmod.at("type"));
Params modparams;
if (jmod.count("modparams")) {
Expand Down Expand Up @@ -240,6 +243,23 @@ bool load(Context* c, string filename, Module** top, std::vector<Module*>& loade
loaded_modules.push_back(m);
if (loading_def) { modqueue.push_back({m, jmod}); }
}
// Module linking loop comes after all the declarations have been
// created
for (auto& [jmodname, jmod] : jns.at("modules").get<jsonmap>()) {
Module* m = ns->getModule(jmodname);
if (jmod.count("default_linked_module")) {
Module* linked_module = getModSymbol(
c,
jmod.at("default_linked_module").get<string>());
m->linkDefaultModule(linked_module);
}
if (jmod.count("linked_modules")) {
for (auto entry : jmod.at("linked_modules").get<jsonmap>()) {
Module* linked_module = getModSymbol(c, entry.second);
m->linkModule(entry.first, linked_module);
}
}
}
}
if (jns.count("generators")) {
for (auto &[genname, jgen] : jns.at("generators").get<jsonmap>()) {
Expand Down Expand Up @@ -370,7 +390,6 @@ bool load(Context* c, string filename, Module** top, std::vector<Module*>& loade
if (jcon.size() == 3) { mdef->getMetaData(a, b) = jcon[2]; }
}
}

// Add Def back in
m->setDef(mdef);
} // End Module loop
Expand Down
19 changes: 19 additions & 0 deletions src/ir/instancegraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ void InstanceGraph::construct(Context* c) {
for (auto nodemap : nodeMap) { nodeMap2.insert(nodemap); }
for (auto nodemap : nodeMap2) {
Module* m = nodemap.first;
if (m->hasLinkedModule()) {
if (m->hasDefaultLinkedModule()) {
InstanceGraphNode* node = nodeMap[m->getDefaultLinkedModule()];
node->addInstanceGraphNode(nodemap.second);
}
for (auto entry : m->getLinkedModules()) {
InstanceGraphNode* node = nodeMap[entry.second];
node->addInstanceGraphNode(nodemap.second);
}
}
if (!m->hasDef()) continue;
ModuleDef* mdef = cast<Module>(nodemap.first)->getDef();
for (auto instmap : mdef->getInstances()) {
Expand All @@ -56,6 +66,15 @@ void getAllDependentModules(
std::set<Module*, InstanceGraph::ModuleCmp>& onlyTopNodes) {
if (onlyTopNodes.count(m)) { return; }
onlyTopNodes.insert(m);
if (m->hasLinkedModule()) {
if (m->hasDefaultLinkedModule()) {
getAllDependentModules(m->getDefaultLinkedModule(), onlyTopNodes);
}
for (auto entry : m->getLinkedModules()) {
getAllDependentModules(entry.second, onlyTopNodes);
}
return;
}
if (!m->hasDef()) { return; }
for (auto ipair : m->getDef()->getInstances()) {
Module* imod = ipair.second->getModuleRef();
Expand Down
14 changes: 14 additions & 0 deletions src/passes/analysis/coreir_json_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,20 @@ string Module2Json(Module* m, bool onlyDecl=false) {
}
if (m->hasMetaData()) { j.add("metadata", toString(m->getMetaData())); }
}
if (m->hasDefaultLinkedModule()) {
auto linked = m->getDefaultLinkedModule();
auto ref_name = quote(linked->getRefName());
j.add("default_linked_module", ref_name);
}
const auto linked = m->getLinkedModules();
if (linked.size() > 0) {
Dict linked_json(taboffset + 2);
for (const auto& entry : linked) {
auto ref_name = quote(entry.second->getRefName());
linked_json.add(entry.first, ref_name);
}
j.add("linked_modules", linked_json.toMultiString());
}
return j.toMultiString();
}

Expand Down
Loading

0 comments on commit ce354bd

Please sign in to comment.