blob: 9c6e5253d89005e96da701f86c6ca6bba3939fb5 [file] [log] [blame]
/*
Copyright 2019 Alain Dargelas
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
* File: CompileModule.cpp
* Author: alain
*
* Created on March 22, 2018, 9:43 PM
*/
#include "SourceCompile/VObjectTypes.h"
#include "Design/VObject.h"
#include "Library/Library.h"
#include "Design/Signal.h"
#include "Design/FileContent.h"
#include "Design/ClockingBlock.h"
#include "SourceCompile/SymbolTable.h"
#include "ErrorReporting/Error.h"
#include "ErrorReporting/Location.h"
#include "ErrorReporting/Error.h"
#include "CommandLine/CommandLineParser.h"
#include "ErrorReporting/ErrorDefinition.h"
#include "ErrorReporting/ErrorContainer.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/PreprocessFile.h"
#include "SourceCompile/CompileSourceFile.h"
#include "SourceCompile/ParseFile.h"
#include "SourceCompile/Compiler.h"
#include "Testbench/ClassDefinition.h"
#include "DesignCompile/CompileHelper.h"
#include "DesignCompile/CompileDesign.h"
#include "DesignCompile/CompileModule.h"
using namespace SURELOG;
CompileModule::~CompileModule() {}
int FunctorCompileModule::operator()() const {
CompileModule* instance = new CompileModule(m_compileDesign, m_module,
m_design, m_symbols, m_errors);
instance->compile();
delete instance;
return true;
}
bool CompileModule::compile() {
FileContent* fC = m_module->m_fileContents[0];
NodeId nodeId = m_module->m_nodeIds[0];
Location loc(m_symbols->registerSymbol(fC->getFileName(nodeId)),
fC->Line(nodeId), 0,
m_symbols->registerSymbol(m_module->getName()));
VObjectType moduleType = fC->Type(nodeId);
ErrorDefinition::ErrorType errType = ErrorDefinition::COMP_COMPILE_MODULE;
switch (moduleType) {
case VObjectType::slInterface_declaration:
errType = ErrorDefinition::COMP_COMPILE_INTERFACE;
break;
case VObjectType::slUdp_declaration:
errType = ErrorDefinition::COMP_COMPILE_UDP;
break;
case VObjectType::slChecker_declaration:
errType = ErrorDefinition::COMP_COMPILE_CHECKER;
break;
default:
break;
}
Error err(errType, loc);
ErrorContainer* errors = new ErrorContainer(m_symbols);
errors->regiterCmdLine(
m_compileDesign->getCompiler()->getCommandLineParser());
errors->addError(err);
errors->printMessage(
err,
m_compileDesign->getCompiler()->getCommandLineParser()->muteStdout());
delete errors;
switch (moduleType) {
case VObjectType::slModule_declaration:
if (!collectModuleObjects_()) return false;
if (!checkModule_()) return false;
break;
case VObjectType::slInterface_declaration:
if (!collectInterfaceObjects_()) return false;
if (!checkInterface_()) return false;
break;
case VObjectType::slUdp_declaration:
break;
case VObjectType::slChecker_declaration:
break;
case VObjectType::slProgram_declaration:
break;
default:
break;
}
return true;
}
VObjectType getSignalType(FileContent* fC, NodeId net_port_type) {
VObjectType signal_type = VObjectType::slData_type_or_implicit;
if (net_port_type) {
NodeId data_type_or_implicit = fC->Child(net_port_type);
if (fC->Type(data_type_or_implicit) == VObjectType::slNetType_Wire) {
signal_type = VObjectType::slNetType_Wire;
} else {
NodeId data_type = fC->Child(data_type_or_implicit);
if (data_type) {
VObjectType the_type = fC->Type(data_type);
if (the_type == VObjectType::slData_type) {
NodeId integer_vector_type = fC->Child(data_type);
the_type = fC->Type(integer_vector_type);
if (the_type == VObjectType::slIntVec_TypeBit ||
the_type == VObjectType::slIntVec_TypeLogic ||
the_type == VObjectType::slIntVec_TypeReg) {
signal_type = the_type;
}
}
}
}
}
return signal_type;
}
void setDirectionAndType(ModuleDefinition* module, FileContent* fC,
NodeId signal, VObjectType type,
VObjectType signal_type) {
while (signal) {
for (auto& port : module->getPorts()) {
if (port.getName() == fC->SymName(signal)) {
VObjectType dir_type = slNoType;
if (type == VObjectType::slInput_declaration)
dir_type = slPortDir_Inp;
else if (type == VObjectType::slOutput_declaration)
dir_type = slPortDir_Out;
else if (type == VObjectType::slInout_declaration)
dir_type = slPortDir_Inout;
port.setDirection(dir_type);
if (signal_type != VObjectType::slData_type_or_implicit)
port.setType(signal_type);
break;
}
}
signal = fC->Sibling(signal);
}
}
bool CompileModule::collectModuleObjects_() {
std::vector<VObjectType> stopPoints = {
VObjectType::slConditional_generate_construct,
VObjectType::slGenerate_module_conditional_statement,
VObjectType::slLoop_generate_construct,
VObjectType::slGenerate_module_loop_statement,
VObjectType::slPar_block,
VObjectType::slSeq_block,
VObjectType::slModule_declaration,
VObjectType::slClass_declaration};
for (unsigned int i = 0; i < m_module->m_fileContents.size(); i++) {
FileContent* fC = m_module->m_fileContents[i];
std::string libName = fC->getLibrary()->getName();
VObject current = fC->Object(m_module->m_nodeIds[i]);
NodeId id = current.m_child;
if (!id) id = current.m_sibling;
if (!id) return false;
// Package imports
std::vector<FileCNodeId> pack_imports;
// - Local file imports
for (auto import : fC->getObjects(VObjectType::slPackage_import_item)) {
pack_imports.push_back(import);
}
for (auto pack_import : pack_imports) {
FileContent* pack_fC = pack_import.fC;
NodeId pack_id = pack_import.nodeId;
m_helper.importPackage(m_module, m_design, pack_fC, pack_id);
}
std::stack<NodeId> stack;
stack.push(id);
VObjectType port_direction = VObjectType::slNoType;
while (stack.size()) {
id = stack.top();
stack.pop();
current = fC->Object(id);
VObjectType type = fC->Type(id);
switch (type) {
case VObjectType::slPackage_import_item: {
m_helper.importPackage(m_module, m_design, fC, id);
break;
}
case VObjectType::slAnsi_port_declaration: {
NodeId net_port_header = fC->Child(id);
NodeId identifier = fC->Sibling(net_port_header);
NodeId net_port_type = fC->Child(net_port_header);
VObjectType dir_type = fC->Type(net_port_type);
if (dir_type == VObjectType::slPortDir_Out ||
dir_type == VObjectType::slPortDir_Inp ||
dir_type == VObjectType::slPortDir_Inout ||
dir_type == VObjectType::slPortDir_Ref) {
port_direction = dir_type;
net_port_type = fC->Sibling(net_port_type);
VObjectType signal_type = getSignalType(fC, net_port_type);
Signal signal(fC, identifier, signal_type, port_direction);
m_module->m_ports.push_back(signal);
} else {
NodeId data_type_or_implicit = fC->Child(net_port_type);
NodeId data_type = fC->Child(data_type_or_implicit);
if (data_type) {
NodeId if_type_name_s = fC->Child(data_type);
if (fC->Type(if_type_name_s) == VObjectType::slIntVec_TypeReg ||
fC->Type(if_type_name_s) == VObjectType::slIntVec_TypeLogic) {
Signal signal(fC, identifier, fC->Type(if_type_name_s),
VObjectType::slNoType);
m_module->m_ports.push_back(signal);
} else {
std::string interfaceName =
libName + "@" + fC->SymName(if_type_name_s);
Signal signal(fC, if_type_name_s, identifier);
ModuleDefinition* interface =
m_design->getModuleDefinition(interfaceName);
if (interface) {
signal.setInterfaceDef(interface);
} else {
Location loc(m_symbols->registerSymbol(
fC->getFileName(if_type_name_s)),
fC->Line(if_type_name_s), 0,
m_symbols->registerSymbol(interfaceName));
Error err(ErrorDefinition::COMP_UNDEFINED_INTERFACE, loc);
m_errors->addError(err);
}
}
} else {
Signal signal(fC, identifier,
VObjectType::slData_type_or_implicit,
port_direction);
m_module->m_ports.push_back(signal);
}
}
break;
}
case VObjectType::slPort:
/*
n<mem_if> u<3> t<StringConst> p<6> s<5> l<1>
n<> u<4> t<Constant_bit_select> p<5> l<1>
n<> u<5> t<Constant_select> p<6> c<4> l<1>
n<> u<6> t<Port_reference> p<11> c<3> s<10> l<1>
n<mif> u<7> t<StringConst> p<10> s<9> l<1>
n<> u<8> t<Constant_bit_select> p<9> l<1>
n<> u<9> t<Constant_select> p<10> c<8> l<1>
n<> u<10> t<Port_reference> p<11> c<7> l<1>
n<> u<11> t<Port_expression> p<12> c<6> l<1>
n<> u<12> t<Port> p<13> c<11> l<1>
*/
{
NodeId Port_expression = fC->Child(id);
if (Port_expression &&
(fC->Type(Port_expression) == VObjectType::slPort_expression)) {
NodeId if_type = fC->Child(Port_expression);
if (fC->Type(if_type) == VObjectType::slPort_reference) {
NodeId if_type_name_s = fC->Child(if_type);
NodeId if_name = fC->Sibling(if_type);
if (if_name) {
NodeId if_name_s = fC->Child(if_name);
std::string interfaceName =
libName + "@" + fC->SymName(if_type_name_s);
Signal signal(fC, if_type_name_s, if_name_s);
ModuleDefinition* interface =
m_design->getModuleDefinition(interfaceName);
if (interface) {
signal.setInterfaceDef(interface);
} else {
Location loc(m_symbols->registerSymbol(
fC->getFileName(if_type_name_s)),
fC->Line(if_type_name_s), 0,
m_symbols->registerSymbol(interfaceName));
Error err(ErrorDefinition::COMP_UNDEFINED_INTERFACE, loc);
m_errors->addError(err);
}
m_module->m_ports.push_back(signal);
} else {
Signal signal(fC, if_type_name_s,
VObjectType::slData_type_or_implicit,
port_direction);
m_module->m_ports.push_back(signal);
}
}
}
break;
}
case VObjectType::slInput_declaration:
case VObjectType::slOutput_declaration:
case VObjectType::slInout_declaration: {
/*
n<> u<24> t<Data_type_or_implicit> p<25> l<7>
n<> u<25> t<Net_port_type> p<28> c<24> s<27> l<7>
n<c0> u<26> t<StringConst> p<27> l<7>
n<> u<27> t<List_of_port_identifiers> p<28> c<26> l<7>
n<> u<28> t<Output_declaration> p<29> c<25> l<7>
*/
NodeId net_port_type = fC->Child(id);
VObjectType signal_type = getSignalType(fC, net_port_type);
NodeId list_of_port_identifiers = fC->Sibling(net_port_type);
if (fC->Type(list_of_port_identifiers) ==
VObjectType::slPacked_dimension) {
list_of_port_identifiers = fC->Sibling(list_of_port_identifiers);
}
NodeId signal = fC->Child(list_of_port_identifiers);
setDirectionAndType(m_module, fC, signal, type, signal_type);
break;
}
case VObjectType::slClocking_declaration:
compileClockingBlock_(fC, id);
break;
case VObjectType::slNet_declaration: {
/*
n<> u<17> t<NetType_Wire> p<18> l<27>
n<> u<18> t<NetTypeOrTrireg_Net> p<22> c<17> s<21> l<27>
n<a> u<19> t<StringConst> p<20> l<27>
n<> u<20> t<Net_decl_assignment> p<21> c<19> l<27>
n<> u<21> t<List_of_net_decl_assignments> p<22> c<20> l<27>
n<> u<22> t<Net_declaration> p<23> c<18> l<27>
*/
NodeId netTypeOrTrireg_Net = fC->Child(id);
NodeId netType_Wire = fC->Child(netTypeOrTrireg_Net);
NodeId list_of_net_decl_assignments =
fC->Sibling(netTypeOrTrireg_Net);
if (fC->Type(list_of_net_decl_assignments) ==
VObjectType::slPacked_dimension) {
list_of_net_decl_assignments =
fC->Sibling(list_of_net_decl_assignments);
}
NodeId net_decl_assignment = fC->Child(list_of_net_decl_assignments);
while (net_decl_assignment) {
NodeId signal = fC->Child(net_decl_assignment);
for (auto& port : m_module->m_ports) {
if (port.getName() == fC->SymName(signal)) {
port.setType(fC->Type(netType_Wire));
break;
}
}
net_decl_assignment = fC->Sibling(net_decl_assignment);
}
break;
}
case VObjectType::slData_declaration: {
NodeId subNode = fC->Child(id);
VObjectType subType = fC->Type(subNode);
switch (subType) {
case VObjectType::slType_declaration: {
/*
n<> u<15> t<Data_type> p<17> c<8> s<16> l<13>
n<fsm_t> u<16> t<StringConst> p<17> l<13>
n<> u<17> t<Type_declaration> p<18> c<15> l<13>
n<> u<18> t<Data_declaration> p<19> c<17> l<13>
*/
m_helper.compileTypeDef(m_module, fC, id);
break;
}
case VObjectType::slVariable_declaration: {
/*
n<> u<29> t<IntVec_TypeReg> p<30> l<29>
n<> u<30> t<Data_type> p<34> c<29> s<33> l<29>
n<b> u<31> t<StringConst> p<32> l<29>
n<> u<32> t<Variable_decl_assignment> p<33> c<31> l<29>
n<> u<33> t<List_of_variable_decl_assignments> p<34> c<32> l<29>
n<> u<34> t<Variable_declaration> p<35> c<30> l<29>
n<> u<35> t<Data_declaration> p<36> c<34> l<29>
*/
NodeId variable_declaration = fC->Child(id);
NodeId data_type = fC->Child(variable_declaration);
NodeId intVec_TypeReg = fC->Child(data_type);
NodeId list_of_variable_decl_assignments = fC->Sibling(data_type);
if (fC->Type(list_of_variable_decl_assignments) ==
VObjectType::slPacked_dimension) {
list_of_variable_decl_assignments =
fC->Sibling(list_of_variable_decl_assignments);
}
NodeId variable_decl_assignment =
fC->Child(list_of_variable_decl_assignments);
while (variable_decl_assignment) {
NodeId signal = fC->Child(variable_decl_assignment);
for (auto& port : m_module->m_ports) {
if (port.getName() == fC->SymName(signal)) {
port.setType(fC->Type(intVec_TypeReg));
break;
}
}
variable_decl_assignment =
fC->Sibling(variable_decl_assignment);
}
break;
}
default:
break;
}
break;
}
case VObjectType::slPort_declaration: {
/*
n<Configuration> u<21> t<StringConst> p<22> l<7>
n<> u<22> t<Interface_identifier> p<26> c<21> s<25> l<7>
n<cfg> u<23> t<StringConst> p<24> l<7>
n<> u<24> t<Interface_identifier> p<25> c<23> l<7>
n<> u<25> t<List_of_interface_identifiers> p<26> c<24> l<7>
n<> u<26> t<Interface_port_declaration> p<27> c<22> l<7>
n<> u<27> t<Port_declaration> p<28> c<26> l<7>
*/
NodeId subNode = fC->Child(id);
VObjectType subType = fC->Type(subNode);
switch (subType) {
case VObjectType::slInterface_port_declaration: {
NodeId interface_identifier = fC->Child(subNode);
NodeId interfIdName = fC->Child(interface_identifier);
std::string interfName = fC->SymName(interfIdName);
DesignComponent* def = NULL;
DataType* type = NULL;
std::pair<FileCNodeId, DesignComponent*>* datatype =
m_module->getNamedObject(interfName);
if (!datatype) {
def = m_module->getClassDefinition(m_module->getName() +
"::" + interfName);
}
if (datatype) {
def = datatype->second;
}
if (def == NULL) {
def = m_design->getComponentDefinition(libName + "@" +
interfName);
}
if (def == NULL) {
type = m_module->getDataType(interfName);
}
if (def == NULL && type == NULL && (interfName != "logic") &&
(interfName != "byte") && (interfName != "bit") &&
(interfName != "new") && (interfName != "expect") &&
(interfName != "var") && (interfName != "signed") &&
(interfName != "unsigned") && (interfName != "do") &&
(interfName != "final") && (interfName != "global") &&
(interfName != "soft")) {
Location loc(m_symbols->registerSymbol(fC->getFileName(id)),
fC->Line(id), 0,
m_symbols->registerSymbol(interfName));
Error err(ErrorDefinition::COMP_UNDEFINED_TYPE, loc);
m_errors->addError(err);
}
NodeId list_of_interface_identifiers =
fC->Sibling(interface_identifier);
NodeId identifier = fC->Child(list_of_interface_identifiers);
while (identifier) {
std::string name = fC->SymName(identifier);
identifier = fC->Sibling(identifier);
// TODO
}
break;
}
case VObjectType::slInput_declaration:
case VObjectType::slOutput_declaration:
case VObjectType::slInout_declaration: {
/*
n<> u<24> t<Data_type_or_implicit> p<25> l<7>
n<> u<25> t<Net_port_type> p<28> c<24> s<27> l<7>
n<c0> u<26> t<StringConst> p<27> l<7>
n<> u<27> t<List_of_port_identifiers> p<28> c<26> l<7>
n<> u<28> t<Output_declaration> p<29> c<25> l<7>
*/
NodeId net_port_type = fC->Child(subNode);
VObjectType signal_type = getSignalType(fC, net_port_type);
NodeId list_of_port_identifiers = fC->Sibling(net_port_type);
if (fC->Type(list_of_port_identifiers) ==
VObjectType::slPacked_dimension) {
list_of_port_identifiers =
fC->Sibling(list_of_port_identifiers);
}
NodeId signal = fC->Child(list_of_port_identifiers);
setDirectionAndType(m_module, fC, signal, subType, signal_type);
break;
}
default:
break;
}
break;
}
case VObjectType::slParam_assignment:
case VObjectType::slHierarchical_instance:
case VObjectType::slN_input_gate_instance:
case VObjectType::slN_output_gate_instance:
case VObjectType::slUdp_instance:
case VObjectType::slUdp_instantiation:
case VObjectType::slModule_instantiation:
case VObjectType::slInterface_instantiation:
case VObjectType::slGate_instantiation:
case VObjectType::slConditional_generate_construct:
case VObjectType::slGenerate_module_conditional_statement:
case VObjectType::slLoop_generate_construct:
case VObjectType::slGenerate_module_loop_statement:
case VObjectType::slPar_block:
case VObjectType::slSeq_block:
case VObjectType::slDefparam_assignment: {
FileCNodeId fnid(fC, id);
m_module->addObject(type, fnid);
break;
}
default:
break;
}
if (current.m_sibling) stack.push(current.m_sibling);
if (current.m_child) {
if (stopPoints.size()) {
bool stop = false;
for (auto t : stopPoints) {
if (t == current.m_type) {
stop = true;
break;
}
}
if (!stop)
if (current.m_child) stack.push(current.m_child);
} else {
if (current.m_child) stack.push(current.m_child);
}
}
}
}
return true;
}
bool CompileModule::collectInterfaceObjects_() {
for (unsigned int i = 0; i < m_module->m_fileContents.size(); i++) {
FileContent* fC = m_module->m_fileContents[i];
VObject current = fC->Object(m_module->m_nodeIds[i]);
NodeId id = current.m_child;
if (!id) id = current.m_sibling;
if (!id) return false;
// Package imports
std::vector<FileCNodeId> pack_imports;
// - Local file imports
for (auto import : fC->getObjects(VObjectType::slPackage_import_item)) {
pack_imports.push_back(import);
}
for (auto pack_import : pack_imports) {
FileContent* pack_fC = pack_import.fC;
NodeId pack_id = pack_import.nodeId;
m_helper.importPackage(m_module, m_design, pack_fC, pack_id);
}
std::stack<NodeId> stack;
stack.push(id);
while (stack.size()) {
id = stack.top();
stack.pop();
current = fC->Object(id);
VObjectType type = fC->Type(id);
switch (type) {
case VObjectType::slPackage_import_item: {
m_helper.importPackage(m_module, m_design, fC, id);
break;
}
case VObjectType::slAnsi_port_declaration: {
NodeId Net_port_header = fC->Child(id);
NodeId net = fC->Sibling(Net_port_header);
NodeId Direction = fC->Child(Net_port_header);
VObjectType direction = fC->Type(Direction);
NodeId Net_port_type = fC->Sibling(Direction);
NodeId NetType = fC->Child(Net_port_type);
VObjectType nettype = fC->Type(NetType);
Signal signal(fC, net, nettype, direction);
m_module->m_ports.push_back(signal);
break;
}
case VObjectType::slNet_declaration: {
NodeId NetTypeOrTrireg_Net = fC->Child(id);
NodeId NetType = fC->Child(NetTypeOrTrireg_Net);
VObjectType nettype = fC->Type(NetType);
NodeId net = fC->Sibling(NetTypeOrTrireg_Net);
NodeId List_of_net_decl_assignments;
if (fC->Type(net) == slPacked_dimension) {
List_of_net_decl_assignments = fC->Sibling(net);
} else {
List_of_net_decl_assignments = net;
}
NodeId Net_decl_assignment = fC->Child(List_of_net_decl_assignments);
net = fC->Child(Net_decl_assignment);
bool existing = false;
for (auto& port : m_module->m_ports) {
if (port.getName() == fC->SymName(net)) {
existing = true;
port.setType(nettype);
break;
}
}
if (!existing) {
Signal signal(fC, net, nettype, VObjectType::slNoType);
m_module->m_ports.push_back(signal);
}
break;
}
case VObjectType::slData_declaration: {
/*
n<> u<29> t<IntVec_TypeReg> p<30> l<29>
n<> u<30> t<Data_type> p<34> c<29> s<33> l<29>
n<b> u<31> t<StringConst> p<32> l<29>
n<> u<32> t<Variable_decl_assignment> p<33> c<31> l<29>
n<> u<33> t<List_of_variable_decl_assignments> p<34> c<32> l<29>
n<> u<34> t<Variable_declaration> p<35> c<30> l<29>
n<> u<35> t<Data_declaration> p<36> c<34> l<29>
*/
NodeId variable_declaration = fC->Child(id);
NodeId data_type = fC->Child(variable_declaration);
NodeId intVec_TypeReg = fC->Child(data_type);
NodeId list_of_variable_decl_assignments = fC->Sibling(data_type);
if (fC->Type(list_of_variable_decl_assignments) ==
VObjectType::slPacked_dimension) {
list_of_variable_decl_assignments =
fC->Sibling(list_of_variable_decl_assignments);
}
NodeId variable_decl_assignment =
fC->Child(list_of_variable_decl_assignments);
while (variable_decl_assignment) {
NodeId signal = fC->Child(variable_decl_assignment);
bool port_exist = false;
for (auto& port : m_module->m_ports) {
if (port.getName() == fC->SymName(signal)) {
port_exist = true;
port.setType(fC->Type(intVec_TypeReg));
break;
}
}
if (!port_exist) {
Signal sig(fC, signal, fC->Type(intVec_TypeReg),
VObjectType::slNoType);
m_module->m_ports.push_back(sig);
}
variable_decl_assignment = fC->Sibling(variable_decl_assignment);
}
break;
}
case VObjectType::slClocking_declaration:
compileClockingBlock_(fC, id);
break;
case VObjectType::slGenerate_interface_item: {
// TODO: rewrite this rough implementation
std::vector<VObjectType> types = {VObjectType::slModport_item};
std::vector<NodeId> items = fC->sl_collect_all(id, types);
for (auto nodeId : items) {
Location loc(m_symbols->registerSymbol(fC->getFileName(nodeId)),
fC->Line(nodeId), 0, 0);
Error err(ErrorDefinition::COMP_NO_MODPORT_IN_GENERATE, loc);
m_errors->addError(err);
}
break;
}
case VObjectType::slModport_item:
/*
n<tb> u<45> t<StringConst> p<56> s<50> l<43>
n<> u<46> t<PortDir_Inp> p<49> s<48> l<43>
n<clk> u<47> t<StringConst> p<48> l<43>
n<> u<48> t<Modport_simple_port> p<49> c<47> l<43>
n<> u<49> t<Modport_simple_ports_declaration> p<50> c<46> l<43>
n<> u<50> t<Modport_ports_declaration> p<56> c<49> s<55> l<43>
n<> u<51> t<PortDir_Out> p<54> s<53> l<43>
n<reset> u<52> t<StringConst> p<53> l<43>
n<> u<53> t<Modport_simple_port> p<54> c<52> l<43>
n<> u<54> t<Modport_simple_ports_declaration> p<55> c<51> l<43>
n<> u<55> t<Modport_ports_declaration> p<56> c<54> l<43>
n<> u<56> t<Modport_item> p<57> c<45> l<43>
*/
{
NodeId modportname = fC->Child(id);
SymbolId modportsymb = fC->Name(modportname);
NodeId modport_ports_declaration = fC->Sibling(modportname);
VObjectType port_direction_type = VObjectType::slNoType;
while (modport_ports_declaration) {
NodeId port_declaration = fC->Child(modport_ports_declaration);
VObjectType port_declaration_type = fC->Type(port_declaration);
if (port_declaration_type ==
VObjectType::slModport_simple_ports_declaration) {
NodeId port_direction = fC->Child(port_declaration);
port_direction_type = fC->Type(port_direction);
NodeId modport_simple_port = fC->Sibling(port_direction);
while (modport_simple_port) {
NodeId simple_port_name = fC->Child(modport_simple_port);
SymbolId port_symbol = fC->Name(simple_port_name);
bool port_exists = false;
for (auto& port : m_module->m_ports) {
if (fC->Name(port.getNodeId()) == port_symbol) {
port_exists = true;
break;
}
}
if (!port_exists) {
Location loc(m_symbols->registerSymbol(
fC->getFileName(simple_port_name)),
fC->Line(simple_port_name), 0,
m_symbols->registerSymbol(
fC->SymName(simple_port_name)));
Error err(ErrorDefinition::COMP_MODPORT_UNDEFINED_PORT,
loc);
m_errors->addError(err);
}
Signal signal(fC, simple_port_name,
VObjectType::slData_type_or_implicit,
port_direction_type);
m_module->insertModPort(modportsymb, signal);
modport_simple_port = fC->Sibling(modport_simple_port);
}
} else if (port_declaration_type ==
VObjectType::
slModport_hierarchical_ports_declaration) {
} else if (port_declaration_type ==
VObjectType::slModport_tf_ports_declaration) {
} else {
// CLOCKING
NodeId clocking_block_name = port_declaration;
SymbolId clocking_block_symbol =
m_symbols->registerSymbol(fC->SymName(clocking_block_name));
ClockingBlock* cb =
m_module->getClockingBlock(clocking_block_symbol);
if (cb == NULL) {
Location loc(m_symbols->registerSymbol(
fC->getFileName(clocking_block_name)),
fC->Line(clocking_block_name), 0,
clocking_block_symbol);
Error err(
ErrorDefinition::COMP_MODPORT_UNDEFINED_CLOCKING_BLOCK,
loc);
m_errors->addError(err);
} else {
m_module->insertModPort(modportsymb, *cb);
}
}
modport_ports_declaration =
fC->Sibling(modport_ports_declaration);
}
}
default:
break;
}
if (current.m_sibling) stack.push(current.m_sibling);
if (current.m_child) stack.push(current.m_child);
}
}
return true;
}
bool CompileModule::checkModule_() {
int countMissingType = 0;
int countMissingDirection = 0;
Location* missingTypeLoc = NULL;
Location* missingDirectionLoc = NULL;
for (auto& port : m_module->m_ports) {
if (port.isInterface()) continue;
if (port.getType() == VObjectType::slData_type_or_implicit) {
if (port.getDirection() == VObjectType::slPortDir_Out ||
port.getDirection() == VObjectType::slPortDir_Inout) {
if (countMissingType == 0)
missingTypeLoc = new Location(
m_symbols->registerSymbol(
port.getFileContent()->getFileName(port.getNodeId())),
port.getFileContent()->Line(port.getNodeId()), 0,
m_symbols->registerSymbol(port.getName()));
countMissingType++;
}
}
if (port.getDirection() == VObjectType::slNoType) {
if (countMissingDirection == 0)
missingDirectionLoc = new Location(
m_symbols->registerSymbol(
port.getFileContent()->getFileName(port.getNodeId())),
port.getFileContent()->Line(port.getNodeId()), 0,
m_symbols->registerSymbol(port.getName()));
countMissingDirection++;
}
}
if (countMissingType) {
Location countLoc(
0, 0, 0,
m_symbols->registerSymbol(std::to_string(countMissingType - 1)));
if (countMissingType - 1 > 0) {
Error err(ErrorDefinition::COMP_PORT_MISSING_TYPE, *missingTypeLoc,
countLoc);
m_errors->addError(err);
} else {
Error err(ErrorDefinition::COMP_PORT_MISSING_TYPE, *missingTypeLoc);
m_errors->addError(err);
}
delete missingTypeLoc;
}
if (countMissingDirection) {
Location countLoc(
0, 0, 0,
m_symbols->registerSymbol(std::to_string(countMissingDirection - 1)));
if (countMissingDirection - 1 > 0) {
Error err(ErrorDefinition::COMP_PORT_MISSING_DIRECTION,
*missingDirectionLoc, countLoc);
m_errors->addError(err);
} else {
Error err(ErrorDefinition::COMP_PORT_MISSING_DIRECTION,
*missingDirectionLoc);
m_errors->addError(err);
}
delete missingDirectionLoc;
}
return true;
}
bool CompileModule::checkInterface_() {
int countMissingType = 0;
Location* missingTypeLoc = NULL;
for (auto& port : m_module->m_ports) {
if (port.getType() == VObjectType::slData_type_or_implicit) {
if (port.getDirection() == VObjectType::slPortDir_Out ||
port.getDirection() == VObjectType::slPortDir_Inout) {
if (countMissingType == 0)
missingTypeLoc = new Location(
m_symbols->registerSymbol(
port.getFileContent()->getFileName(port.getNodeId())),
port.getFileContent()->Line(port.getNodeId()), 0,
m_symbols->registerSymbol(port.getName()));
countMissingType++;
}
}
}
if (countMissingType) {
Location countLoc(
0, 0, 0,
m_symbols->registerSymbol(std::to_string(countMissingType - 1)));
if (countMissingType - 1 > 0) {
Error err(ErrorDefinition::COMP_PORT_MISSING_TYPE, *missingTypeLoc,
countLoc);
m_errors->addError(err);
} else {
Error err(ErrorDefinition::COMP_PORT_MISSING_TYPE, *missingTypeLoc);
m_errors->addError(err);
}
delete missingTypeLoc;
}
return true;
}
void CompileModule::compileClockingBlock_(FileContent* fC, NodeId id) {
/*
n<cb> u<12> t<StringConst> p<21> s<20> l<39>
n<> u<13> t<Edge_Posedge> p<19> s<18> l<39>
n<clk> u<14> t<StringConst> p<17> s<16> l<39>
n<> u<15> t<Bit_select> p<16> l<39>
n<> u<16> t<Select> p<17> c<15> l<39>
n<> u<17> t<Primary> p<18> c<14> l<39>
n<> u<18> t<Expression> p<19> c<17> l<39>
n<> u<19> t<Event_expression> p<20> c<13> l<39>
n<> u<20> t<Clocking_event> p<21> c<19> l<39>
n<> u<21> t<Clocking_declaration> p<22> c<12> l<39>
*/
NodeId clocking_block_name = fC->Child(id);
SymbolId clocking_block_symbol =
m_symbols->registerSymbol(fC->SymName(clocking_block_name));
NodeId clocking_event = fC->Sibling(clocking_block_name);
ClockingBlock cb(fC, clocking_block_name, clocking_event);
m_module->addClockingBlock(clocking_block_symbol, cb);
}