aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/verific/verific.cc
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/verific/verific.cc')
-rw-r--r--frontends/verific/verific.cc123
1 files changed, 115 insertions, 8 deletions
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index a93d79c80..ab3e55427 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -361,10 +361,16 @@ RTLIL::SigSpec VerificImporter::operatorInport(Instance *inst, const char *portn
for (unsigned i = 0; i < portbus->Size(); i++) {
Net *net = inst->GetNet(portbus->ElementAtIndex(i));
if (net) {
- if (net->IsGnd())
- sig.append(RTLIL::State::S0);
- else if (net->IsPwr())
- sig.append(RTLIL::State::S1);
+ if (net->IsConstant()) {
+ if (net->IsGnd())
+ sig.append(RTLIL::State::S0);
+ else if (net->IsPwr())
+ sig.append(RTLIL::State::S1);
+ else if (net->IsX())
+ sig.append(RTLIL::State::Sx);
+ else
+ sig.append(RTLIL::State::Sz);
+ }
else
sig.append(net_map_at(net));
} else
@@ -379,6 +385,36 @@ RTLIL::SigSpec VerificImporter::operatorInport(Instance *inst, const char *portn
}
}
+RTLIL::SigSpec VerificImporter::operatorInportCase(Instance *inst, const char *portname)
+{
+ PortBus *portbus = inst->View()->GetPortBus(portname);
+ if (portbus) {
+ RTLIL::SigSpec sig;
+ for (unsigned i = 0; i < portbus->Size(); i++) {
+ Net *net = inst->GetNet(portbus->ElementAtIndex(i));
+ if (net) {
+ if (net->IsConstant()) {
+ if (net->IsGnd())
+ sig.append(RTLIL::State::S0);
+ else if (net->IsPwr())
+ sig.append(RTLIL::State::S1);
+ else
+ sig.append(RTLIL::State::Sa);
+ }
+ else
+ sig.append(net_map_at(net));
+ } else
+ sig.append(RTLIL::State::Sa);
+ }
+ return sig;
+ } else {
+ Port *port = inst->View()->GetPort(portname);
+ log_assert(port != NULL);
+ Net *net = inst->GetNet(port);
+ return net_map_at(net);
+ }
+}
+
RTLIL::SigSpec VerificImporter::operatorOutput(Instance *inst, const pool<Net*, hash_ptr_ops> *any_all_nets)
{
RTLIL::SigSpec sig;
@@ -989,6 +1025,75 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr
return true;
}
+ if (inst->Type() == OPER_WIDE_CASE_SELECT_BOX)
+ {
+ RTLIL::SigSpec sig_out_val = operatorInport(inst, "out_value");
+ RTLIL::SigSpec sig_select = operatorInport(inst, "select");
+ RTLIL::SigSpec sig_select_values = operatorInportCase(inst, "select_values");
+ RTLIL::SigSpec sig_data_values = operatorInport(inst, "data_values");
+ RTLIL::SigSpec sig_data_default = operatorInport(inst, "default_value");
+
+ RTLIL::Process *proc = module->addProcess(new_verific_id(inst));
+ import_attributes(proc->attributes, inst);
+
+ RTLIL::CaseRule *current_case = &proc->root_case;
+ current_case = &proc->root_case;
+
+ RTLIL::SwitchRule *sw = new RTLIL::SwitchRule;
+ sw->signal = sig_select;
+ current_case->switches.push_back(sw);
+
+ unsigned select_width = inst->InputSize();
+ unsigned data_width = inst->OutputSize();
+ unsigned offset_data = 0;
+ unsigned offset_select = 0;
+
+ OperWideCaseSelector* selector = (OperWideCaseSelector*) inst->View();
+
+ for (unsigned i = 0 ; i < selector->GetNumBranches() ; ++i) {
+
+ SigSig action(sig_out_val, sig_data_values.extract(offset_data, data_width));
+ offset_data += data_width;
+
+ for (unsigned j = 0 ; j < selector->GetNumConditions(i) ; ++j) {
+ Array left_bound, right_bound ;
+ selector->GetCondition(i, j, &left_bound, &right_bound);
+
+ SigSpec sel_left = sig_select_values.extract(offset_select, select_width);
+ offset_select += select_width;
+
+ if (right_bound.Size()) {
+ SigSpec sel_right = sig_select_values.extract(offset_select, select_width);
+ offset_select += select_width;
+
+ log_assert(sel_right.is_fully_const() && sel_right.is_fully_def());
+ log_assert(sel_left.is_fully_const() && sel_right.is_fully_def());
+
+ int32_t left = sel_left.as_int();
+ int32_t right = sel_right.as_int();
+ int width = sel_left.size();
+
+ for (int32_t i = right; i<left; i++) {
+ RTLIL::CaseRule *cs = new RTLIL::CaseRule;
+ cs->compare.push_back(RTLIL::Const(i,width));
+ cs->actions.push_back(action);
+ sw->cases.push_back(cs);
+ }
+ }
+
+ RTLIL::CaseRule *cs = new RTLIL::CaseRule;
+ cs->compare.push_back(sel_left);
+ cs->actions.push_back(action);
+ sw->cases.push_back(cs);
+ }
+ }
+ RTLIL::CaseRule *cs_default = new RTLIL::CaseRule;
+ cs_default->actions.push_back(SigSig(sig_out_val, sig_data_default));
+ sw->cases.push_back(cs_default);
+
+ return true;
+ }
+
#undef IN
#undef IN1
#undef IN2
@@ -2317,8 +2422,8 @@ std::string verific_import(Design *design, const std::map<std::string,std::strin
const char *lib_name = (prefix) ? prefix->GetName() : 0 ;
if (!Strings::compare("work", lib_name)) lib = veri_file::GetLibrary(lib_name, 1) ;
}
- veri_module = (lib && module_name) ? lib->GetModule(module_name->GetName(), 1) : 0;
- top = veri_module->GetName();
+ if (lib && module_name)
+ top = lib->GetModule(module_name->GetName(), 1)->GetName();
}
}
@@ -2344,6 +2449,7 @@ std::string verific_import(Design *design, const std::map<std::string,std::strin
int i;
FOREACH_ARRAY_ITEM(netlists, i, nl) {
+ if (!nl) continue;
if (!top.empty() && nl->CellBaseName() != top)
continue;
nl->AddAtt(new Att(" \\top", NULL));
@@ -3297,8 +3403,8 @@ struct VerificPass : public Pass {
const char *lib_name = (prefix) ? prefix->GetName() : 0 ;
if (!Strings::compare("work", lib_name)) lib = veri_file::GetLibrary(lib_name, 1) ;
}
- veri_module = (lib && module_name) ? lib->GetModule(module_name->GetName(), 1) : 0;
- top_mod_names.insert(veri_module->GetName());
+ if (lib && module_name)
+ top_mod_names.insert(lib->GetModule(module_name->GetName(), 1)->GetName());
}
} else {
log("Adding Verilog module '%s' to elaboration queue.\n", name);
@@ -3333,6 +3439,7 @@ struct VerificPass : public Pass {
int i;
FOREACH_ARRAY_ITEM(netlists, i, nl) {
+ if (!nl) continue;
if (!top_mod_names.count(nl->CellBaseName()))
continue;
nl->AddAtt(new Att(" \\top", NULL));