83 f(f), module(module), design(design), config(config),
ct(design),
sigmap(module)
87 for(
auto it=module->
wires_.begin(); it!=module->
wires_.end(); ++it)
89 if(it->second->port_input)
163 for (
size_t i = 0; i <
str.size(); ++i)
164 if (
str[i] ==
'#' ||
str[i] ==
'=')
184 else return it->second;
188 log(
"case of non-basic wire - %s\n",
cstr(wire->
name));
195 for(
auto dep_set_it=dep_set.begin(); dep_set_it!=dep_set.end(); ++dep_set_it)
200 log(
" -- found cell %s\n",
cstr(cell_id));
205 if(dep_set.size()==1 && wire->
width == cell_output->
size())
207 wire_line = cell_line;
212 int prev_wire_line=0;
214 for(
unsigned j=0; j<cell_output->
chunks().size(); ++j)
216 start_bit+=cell_output->
chunks().at(j).width;
217 if(cell_output->
chunks().at(j).wire->name == wire->
name)
219 prev_wire_line = wire_line;
222 cell_line, start_bit-1, start_bit-cell_output->
chunks().at(j).width);
224 wire_width += cell_output->
chunks().at(j).width;
225 if(prev_wire_line!=0)
236 if(dep_set.size()==0)
238 log(
" - checking sigmap\n");
248 log(
" -- already processed wire\n");
263 int address_bits = ceil(
log(memory->
size)/
log(2));
269 else return it->second;
274 log(
"writing const \n");
278 width = data->
bits.size() - offset;
280 std::string data_str = data->
as_string();
282 data_str = data_str.substr(offset, width);
290 log(
"writing const error\n");
297 log(
"writing sigchunk\n");
324 log(
"writing sigspec\n");
339 w1 = s.
chunks().front().width;
340 for (
unsigned i=1; i < s.
chunks().size(); ++i)
344 w2 = s.
chunks().at(i).width;
360 if (expected_width != s.
size())
362 log(
" - changing width of sigspec\n");
364 if(expected_width > s.
size())
371 str =
stringf (
"%d concat %d %d %d", line_num, expected_width, line_num-1, l);
375 else if(expected_width < s.
size())
378 str =
stringf (
"%d slice %d %d %d %d;3",
line_num, expected_width, l, expected_width-1, 0);
394 if(cell->
type ==
"$assert")
396 log(
"writing assert cell - %s\n",
cstr(cell->
type));
411 expr_line, one_line);
423 else if(cell->
type ==
"$not" || cell->
type ==
"$neg" || cell->
type ==
"$pos" || cell->
type ==
"$reduce_and" ||
424 cell->
type ==
"$reduce_or" || cell->
type ==
"$reduce_xor" || cell->
type ==
"$reduce_bool")
426 log(
"writing unary cell - %s\n",
cstr(cell->
type));
429 w = w>output_width ? w:output_width;
432 if(cell->
type !=
"$pos")
435 bool reduced = (cell->
type ==
"$not" || cell->
type ==
"$neg") ?
false :
true;
439 if(output_width < w && (cell->
type ==
"$not" || cell->
type ==
"$neg" || cell->
type ==
"$pos"))
442 str =
stringf (
"%d slice %d %d %d %d;4",
line_num, output_width, cell_line, output_width-1, 0);
448 else if(cell->
type ==
"$reduce_xnor" || cell->
type ==
"$logic_not")
450 log(
"writing unary cell - %s\n",
cstr(cell->
type));
455 if(cell->
type ==
"$logic_not" && w > 1)
461 else if(cell->
type ==
"$reduce_xnor")
473 else if(cell->
type ==
"$and" || cell->
type ==
"$or" || cell->
type ==
"$xor" || cell->
type ==
"$xnor" ||
474 cell->
type ==
"$lt" || cell->
type ==
"$le" || cell->
type ==
"$eq" || cell->
type ==
"$ne" ||
475 cell->
type ==
"$eqx" || cell->
type ==
"$nex" || cell->
type ==
"$ge" || cell->
type ==
"$gt" )
477 log(
"writing binary cell - %s\n",
cstr(cell->
type));
480 cell->
type ==
"$ge" || cell->
type ==
"$gt") || output_width == 1);
487 l1_width = l1_width > output_width ? l1_width : output_width;
488 l1_width = l1_width > l2_width ? l1_width : l2_width;
489 l2_width = l2_width > l1_width ? l2_width : l1_width;
496 if(cell->
type ==
"$lt" || cell->
type ==
"$le" ||
497 cell->
type ==
"$eq" || cell->
type ==
"$ne" || cell->
type ==
"$eqx" || cell->
type ==
"$nex" ||
498 cell->
type ==
"$ge" || cell->
type ==
"$gt")
504 str =
stringf (
"%d %s %d %d %d", line_num, op.c_str(), output_width, l1, l2);
509 else if(cell->
type ==
"$add" || cell->
type ==
"$sub" || cell->
type ==
"$mul" || cell->
type ==
"$div" ||
510 cell->
type ==
"$mod" )
513 log(
"writing binary cell - %s\n",
cstr(cell->
type));
521 l1_width = l1_width > output_width ? l1_width : output_width;
522 l1_width = l1_width > l2_width ? l1_width : l2_width;
523 l2_width = l2_width > l1_width ? l2_width : l1_width;
530 if(cell->
type ==
"$div" && l1_signed)
532 else if(cell->
type ==
"$mod")
539 str =
stringf (
"%d %s %d %d %d", line_num, op.c_str(), l1_width, l1, l2);
542 if(output_width < l1_width)
545 str =
stringf (
"%d slice %d %d %d %d;5", line_num, output_width, line_num-1, output_width-1, 0);
550 else if(cell->
type ==
"$shr" || cell->
type ==
"$shl" || cell->
type ==
"$sshr" || cell->
type ==
"$sshl" || cell->
type ==
"$shift" || cell->
type ==
"$shiftx")
552 log(
"writing binary cell - %s\n",
cstr(cell->
type));
557 l1_width = pow(2, ceil(
log(l1_width)/
log(2)));
566 if(l2_width > ceil(
log(l1_width)/
log(2)))
568 int extra_width = l2_width - ceil(
log(l1_width)/
log(2));
571 str =
stringf (
"%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width);
574 str =
stringf (
"%d one %d", line_num, extra_width);
580 str =
stringf(
"%d %s %d", line_num, l1_signed && cell->
type ==
"$sshr" ?
"ones":
"zero", l1_width);
588 if(output_width < l1_width)
591 str =
stringf (
"%d slice %d %d %d %d;5",
line_num, output_width, cell_output, output_width-1, 0);
597 else if(cell->
type ==
"$logic_and" || cell->
type ==
"$logic_or")
599 log(
"writing binary cell - %s\n",
cstr(cell->
type));
620 if(cell->
type ==
"$logic_and")
625 else if(cell->
type ==
"$logic_or")
634 else if(cell->
type ==
"$mux")
636 log(
"writing mux cell\n");
648 else if(cell->
type ==
"$pmux")
650 log(
"writing pmux cell\n");
656 int *c =
new int[select_width];
658 for (
int i=0; i<select_width; ++i)
665 str =
stringf (
"%d slice %d %d %d %d",
line_num, output_width, cases, i*output_width+output_width-1,
671 str =
stringf (
"%d cond %d %d %d %d",
line_num, output_width, c[select_width-1], c[select_width-1]+1, default_case);
674 for (
int i=select_width-2; i>=0; --i)
684 else if(cell->
type ==
"$dff" || cell->
type ==
"$adff" || cell->
type ==
"$dffsr")
689 log(
" - width is %d\n", output_width);
694 unsigned start_bit = 0;
695 for(
unsigned i=0; i<cell_output->
chunks().size(); ++i)
697 output_width = cell_output->
chunks().at(i).width;
701 if(cell_output->
chunks().size()>1)
703 start_bit+=output_width;
706 start_bit-output_width);
709 if(cell->
type ==
"$dffsr")
718 output_width, sync_reset_pol ?
"":
"-", sync_reset, sync_reset_value_pol?
"":
"-",
719 sync_reset_value, slice);
725 output_width, polarity?
"":
"-", cond, slice, reg);
729 if(cell->
type ==
"$adff")
737 output_width, async_reset_pol ?
"":
"-", async_reset, async_reset_value, next);
742 output_width, reg, next);
748 else if(cell->
type ==
"$memrd")
750 log(
"writing memrd cell\n");
751 if (cell->
parameters.at(
"\\CLK_ENABLE").as_bool() ==
true)
752 log_error(
"The btor backen does not support $memrd cells with built-in registers. Run memory_dff with -wr_only.\n");
763 else if(cell->
type ==
"$memwr")
765 log(
"writing memwr cell\n");
766 if (cell->
parameters.at(
"\\CLK_ENABLE").as_bool() ==
false)
767 log_error(
"The btor backen does not support $memwr cells without built-in registers. Run memory_dff (but with -wr_only).\n");
784 int address_bits = ceil(
log(memory->
size)/
log(2));
788 str =
stringf(
"%d eq 1 %d %d", line_num, mem, line_num - 1);
799 str =
stringf(
"%d eq 1 %d %d", line_num, clk, line_num-1);
802 str =
stringf(
"%d and 1 %d %d", line_num, line_num-1, enable);
805 str =
stringf(
"%d write %d %d %d %d %d", line_num, data_width, address_width, mem, address, data);
808 str =
stringf(
"%d acond %d %d %d %d %d", line_num, data_width, address_width, line_num-2, line_num-1, mem);
811 str =
stringf(
"%d anext %d %d %d %d", line_num, data_width, address_width, mem, line_num-1);
816 else if(cell->
type ==
"$slice")
818 log(
"writing slice cell\n");
832 else if(cell->
type ==
"$concat")
834 log(
"writing concat cell\n");
838 int input_a_line =
dump_sigspec(input_a, input_a_width);
842 int input_b_line =
dump_sigspec(input_b, input_b_width);
845 input_a_line, input_b_line);
861 if (cell->
type ==
"$memrd")
865 else if(cell->
type ==
"$memwr" || cell->
type ==
"$assert")
869 else if(cell->
type ==
"$dff" || cell->
type ==
"$adff" || cell->
type ==
"$dffsr")
892 log(
"creating intermediate wires map\n");
898 if(output_sig==
nullptr)
902 log(
" - %s\n",
cstr(it->second->type));
903 if (cell->
type ==
"$memrd")
905 for(
unsigned i=0; i<output_sig->
chunks().size(); ++i)
912 else if(cell->
type ==
"$memwr")
916 else if(cell->
type ==
"$dff" || cell->
type ==
"$adff" || cell->
type ==
"$dffsr")
919 for(
unsigned i=0; i<output_sig->
chunks().size(); ++i)
929 for(
unsigned i=0; i<output_sig->
chunks().size(); ++i)
938 log(
"writing input\n");
939 std::map<int, RTLIL::Wire*> inputs, outputs;
940 std::vector<RTLIL::Wire*> safety;
948 if (wire->
name.
str().find(
"safety") != std::string::npos )
949 safety.push_back(wire);
954 for (
auto &it : inputs) {
960 log(
"writing memories\n");
966 log(
"writing output wires\n");
967 for (
auto &it : outputs) {
972 log(
"writing cells\n");
983 log(
"writing outputs info\n");
985 for (
auto &it : outputs) {
995 BtorDumper dumper(f, module, design, &config);
1007 log(
" write_btor [filename]\n");
1009 log(
"Write the current design to an BTOR file.\n");
1014 std::string top_module_name;
1015 std::string buf_type, buf_in, buf_out;
1016 std::string true_type, true_out;
1017 std::string false_type, false_out;
1025 if (top_module_name.empty())
1026 for (
auto & mod_it:design->
modules_)
1027 if (mod_it.second->get_bool_attribute(
"\\top"))
1028 top_module_name = mod_it.first.str();
1032 *f <<
stringf(
"; BTOR Backend developed by Ahmed Irfan <irfan@fbk.eu> - Fondazione Bruno Kessler, Trento, Italy\n");
1033 *f <<
stringf(
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
1035 std::vector<RTLIL::Module*> mod_list;
1037 for (
auto module_it : design->
modules_)
1040 if (module->get_bool_attribute(
"\\blackbox"))
1044 log_error(
"Found unmapped processes in module %s: unmapped processes are not supported in BTOR backend!\n",
RTLIL::id2cstr(module->
name));
1048 top_module_name.clear();
1052 mod_list.push_back(module);
1055 if (!top_module_name.empty())
1056 log_error(
"Can't find top module `%s'!\n", top_module_name.c_str());
1058 for (
auto module : mod_list)
const char * yosys_version_str
std::string stringf(const char *fmt,...)
std::vector< std::string > cstr_buf
std::map< RTLIL::IdString, int > line_ref
void log_header(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
static std::string unescape_id(std::string str)
virtual void execute(std::ostream *&f, std::string filename, std::vector< std::string > args, RTLIL::Design *design)
std::map< RTLIL::IdString, RTLIL::Memory * > memories
int dump_wire(RTLIL::Wire *wire)
void log_error(const char *format,...)
std::map< RTLIL::IdString, RTLIL::Const > parameters
std::map< std::string, std::string > cell_type_translation
void dump_property(RTLIL::Wire *wire)
BtorDumperConfig * config
const char * cstr(const RTLIL::IdString id)
static std::string escape_id(std::string str)
RTLIL::IdString curr_cell
int dump_const(const RTLIL::Const *data, int width, int offset)
void extra_args(std::ostream *&f, std::string &filename, std::vector< std::string > args, size_t argidx)
static void dump(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config)
std::string as_string() const
#define PRIVATE_NAMESPACE_BEGIN
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
bool operator()(const WireInfo &x, const WireInfo &y)
int dump_memory(const RTLIL::Memory *memory)
#define log_assert(_assert_expr_)
RTLIL::IdString cell_name
std::map< RTLIL::SigSpec, int > sig_ref
BtorDumper(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config)
int dump_sigchunk(const RTLIL::SigChunk *chunk)
int dump_sigspec(const RTLIL::SigSpec *sig, int expected_width)
#define PRIVATE_NAMESPACE_END
std::map< RTLIL::IdString, std::set< WireInfo, WireInfoOrder > > inter_wire_map
static const char * id2cstr(const RTLIL::IdString &str)
const RTLIL::SigChunk * chunk
std::map< RTLIL::IdString, RTLIL::Process * > processes
const RTLIL::SigSpec * get_cell_output(RTLIL::Cell *cell)
#define USING_YOSYS_NAMESPACE
std::map< RTLIL::IdString, RTLIL::Module * > modules_
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
void log(const char *format,...)
int dump_cell(const RTLIL::Cell *cell)
WireInfo(RTLIL::IdString c, const RTLIL::SigChunk *ch)
std::vector< RTLIL::State > bits
std::map< RTLIL::IdString, bool > basic_wires
std::map< std::string, std::string > s_cell_type_translation
std::vector< RTLIL::State > data
const std::vector< RTLIL::SigChunk > & chunks() const