/*
* yosys -- Yosys Open SYnthesis Suite
*
- * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include "kernel/celltypes.h"
#include "frontends/verilog/verilog_frontend.h"
#include "frontends/verilog/preproc.h"
-#include "backends/ilang/ilang_backend.h"
+#include "backends/rtlil/rtlil_backend.h"
#include <string.h>
#include <algorithm>
return true;
}
+bool RTLIL::Const::is_onehot(int *pos) const
+{
+ cover("kernel.rtlil.const.is_onehot");
+
+ bool found = false;
+ for (int i = 0; i < GetSize(*this); i++) {
+ auto &bit = bits[i];
+ if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
+ return false;
+ if (bit == RTLIL::State::S1) {
+ if (found)
+ return false;
+ if (pos)
+ *pos = i;
+ found = true;
+ }
+ }
+ return found;
+}
+
bool RTLIL::AttrObject::has_attribute(RTLIL::IdString id) const
{
return attributes.count(id);
RTLIL::Design::~Design()
{
- for (auto it = modules_.begin(); it != modules_.end(); ++it)
- delete it->second;
+ for (auto &pr : modules_)
+ delete pr.second;
for (auto n : verilog_packages)
delete n;
for (auto n : verilog_globals)
return modules_.count(name) ? modules_.at(name) : NULL;
}
+const RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name) const
+{
+ return modules_.count(name) ? modules_.at(name) : NULL;
+}
+
RTLIL::Module *RTLIL::Design::top_module()
{
RTLIL::Module *module = nullptr;
RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name)
{
- log_assert(modules_.count(name) == 0);
+ if (modules_.count(name) != 0)
+ log_error("Attempted to add new module named '%s', but a module by that name already exists\n", name.c_str());
log_assert(refcount_modules_ == 0);
RTLIL::Module *module = new RTLIL::Module;
return result;
}
-std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn() const
+std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn(bool include_wb) const
{
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (it.second->get_blackbox_attribute())
+ if (it.second->get_blackbox_attribute(include_wb))
continue;
else if (selected_whole_module(it.first))
result.push_back(it.second);
RTLIL::Module::~Module()
{
- for (auto it = wires_.begin(); it != wires_.end(); ++it)
- delete it->second;
- for (auto it = memories.begin(); it != memories.end(); ++it)
- delete it->second;
- for (auto it = cells_.begin(); it != cells_.end(); ++it)
- delete it->second;
- for (auto it = processes.begin(); it != processes.end(); ++it)
- delete it->second;
+ for (auto &pr : wires_)
+ delete pr.second;
+ for (auto &pr : memories)
+ delete pr.second;
+ for (auto &pr : cells_)
+ delete pr.second;
+ for (auto &pr : processes)
+ delete pr.second;
#ifdef WITH_PYTHON
RTLIL::Module::get_all_modules()->erase(hashidx_);
#endif
void error(int linenr)
{
std::stringstream buf;
- ILANG_BACKEND::dump_cell(buf, " ", cell);
+ RTLIL_BACKEND::dump_cell(buf, " ", cell);
log_error("Found error in internal cell %s%s%s (%s) at %s:%d:\n%s",
module ? module->name.c_str() : "", module ? "." : "",
cell->module = this;
}
+void RTLIL::Module::add(RTLIL::Process *process)
+{
+ log_assert(!process->name.empty());
+ log_assert(count_id(process->name) == 0);
+ processes[process->name] = process;
+ process->module = this;
+}
+
void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
{
log_assert(refcount_wires_ == 0);
sig.pack();
for (auto &c : sig.chunks_)
if (c.wire != NULL && wires_p->count(c.wire)) {
- c.wire = module->addWire(NEW_ID, c.width);
+ c.wire = module->addWire(stringf("$delete_wire$%d", autoidx++), c.width);
c.offset = 0;
}
}
delete cell;
}
+void RTLIL::Module::remove(RTLIL::Process *process)
+{
+ log_assert(processes.count(process->name) != 0);
+ processes.erase(process->name);
+ delete process;
+}
+
void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name)
{
log_assert(wires_[wire->name] == wire);
return mem;
}
+RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name)
+{
+ RTLIL::Process *proc = new RTLIL::Process;
+ proc->name = name;
+ add(proc);
+ return proc;
+}
+
RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Process *other)
{
RTLIL::Process *proc = other->clone();
proc->name = name;
- processes[name] = proc;
+ add(proc);
return proc;
}
#endif
}
+RTLIL::Process::Process() : module(nullptr)
+{
+ static unsigned int hashidx_count = 123456789;
+ hashidx_count = mkhash_xorshift(hashidx_count);
+ hashidx_ = hashidx_count;
+}
+
RTLIL::Cell::Cell() : module(nullptr)
{
static unsigned int hashidx_count = 123456789;
check();
}
+bool RTLIL::Cell::has_memid() const
+{
+ return type.in(ID($memwr), ID($memrd), ID($meminit));
+}
+
+bool RTLIL::Cell::is_mem_cell() const
+{
+ return type == ID($mem) || has_memid();
+}
+
RTLIL::SigChunk::SigChunk()
{
wire = NULL;
{
cover("kernel.rtlil.sigspec.init.const");
- chunks_.emplace_back(value);
- width_ = chunks_.back().width;
+ if (GetSize(value) != 0) {
+ chunks_.emplace_back(value);
+ width_ = chunks_.back().width;
+ } else {
+ width_ = 0;
+ }
hash_ = 0;
check();
}
{
cover("kernel.rtlil.sigspec.init.chunk");
- chunks_.emplace_back(chunk);
- width_ = chunks_.back().width;
+ if (chunk.width != 0) {
+ chunks_.emplace_back(chunk);
+ width_ = chunks_.back().width;
+ } else {
+ width_ = 0;
+ }
hash_ = 0;
check();
}
{
cover("kernel.rtlil.sigspec.init.wire");
- chunks_.emplace_back(wire);
- width_ = chunks_.back().width;
+ if (wire->width != 0) {
+ chunks_.emplace_back(wire);
+ width_ = chunks_.back().width;
+ } else {
+ width_ = 0;
+ }
hash_ = 0;
check();
}
{
cover("kernel.rtlil.sigspec.init.wire_part");
- chunks_.emplace_back(wire, offset, width);
- width_ = chunks_.back().width;
+ if (width != 0) {
+ chunks_.emplace_back(wire, offset, width);
+ width_ = chunks_.back().width;
+ } else {
+ width_ = 0;
+ }
hash_ = 0;
check();
}
{
cover("kernel.rtlil.sigspec.init.str");
- chunks_.emplace_back(str);
- width_ = chunks_.back().width;
+ if (str.size() != 0) {
+ chunks_.emplace_back(str);
+ width_ = chunks_.back().width;
+ } else {
+ width_ = 0;
+ }
hash_ = 0;
check();
}
{
cover("kernel.rtlil.sigspec.init.int");
- chunks_.emplace_back(val, width);
+ if (width != 0)
+ chunks_.emplace_back(val, width);
width_ = width;
hash_ = 0;
check();
{
cover("kernel.rtlil.sigspec.init.state");
- chunks_.emplace_back(bit, width);
+ if (width != 0)
+ chunks_.emplace_back(bit, width);
width_ = width;
hash_ = 0;
check();
{
cover("kernel.rtlil.sigspec.init.bit");
- if (bit.wire == NULL)
- chunks_.emplace_back(bit.data, width);
- else
- for (int i = 0; i < width; i++)
- chunks_.push_back(bit);
+ if (width != 0) {
+ if (bit.wire == NULL)
+ chunks_.emplace_back(bit.data, width);
+ else
+ for (int i = 0; i < width; i++)
+ chunks_.push_back(bit);
+ }
width_ = width;
hash_ = 0;
check();
width_ = 0;
for (auto &chunk : chunks_)
if (chunk.wire != NULL) {
- new_chunks.push_back(chunk);
+ if (!new_chunks.empty() &&
+ new_chunks.back().wire == chunk.wire &&
+ new_chunks.back().offset + new_chunks.back().width == chunk.offset) {
+ new_chunks.back().width += chunk.width;
+ } else {
+ new_chunks.push_back(chunk);
+ }
width_ += chunk.width;
}
int w = 0;
for (size_t i = 0; i < chunks_.size(); i++) {
const RTLIL::SigChunk &chunk = chunks_[i];
+ log_assert(chunk.width != 0);
if (chunk.wire == NULL) {
if (i > 0)
log_assert(chunks_[i-1].wire != NULL);
return false;
}
+bool RTLIL::SigSpec::is_onehot(int *pos) const
+{
+ cover("kernel.rtlil.sigspec.is_onehot");
+
+ pack();
+ if (!is_fully_const())
+ return false;
+ log_assert(GetSize(chunks_) <= 1);
+ if (width_)
+ return RTLIL::Const(chunks_[0].data).is_onehot(pos);
+ return false;
+}
+
bool RTLIL::SigSpec::as_bool() const
{
cover("kernel.rtlil.sigspec.as_bool");
new_syncrule->type = type;
new_syncrule->signal = signal;
new_syncrule->actions = actions;
+ new_syncrule->mem_write_actions = mem_write_actions;
return new_syncrule;
}