From ffd768ce865e330a631c56d63c6f472e9ad85511 Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Fri, 3 Jan 2014 10:52:44 +0100 Subject: btor --- backends/btor/Makefile.inc | 3 + backends/btor/btor.cc | 771 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 774 insertions(+) create mode 100644 backends/btor/Makefile.inc create mode 100644 backends/btor/btor.cc (limited to 'backends') diff --git a/backends/btor/Makefile.inc b/backends/btor/Makefile.inc new file mode 100644 index 00000000..af7ab14d --- /dev/null +++ b/backends/btor/Makefile.inc @@ -0,0 +1,3 @@ + +OBJS += backends/btor/btor.o + diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc new file mode 100644 index 00000000..6ffb4730 --- /dev/null +++ b/backends/btor/btor.cc @@ -0,0 +1,771 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2013 Ahmed Irfan + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +// [[CITE]] BTOR: Bit-Precise Modelling of Word-Level Problems for Model Checking +// Johannes Kepler University, Linz, Austria +// http://fmv.jku.at/papers/BrummayerBiereLonsing-BPR08.pdf + +#include "kernel/rtlil.h" +#include "kernel/register.h" +#include "kernel/sigtools.h" +#include "kernel/celltypes.h" +#include "kernel/log.h" +#include +#include +#include +#include + +struct BtorDumperConfig +{ + bool subckt_mode; + bool conn_mode; + bool impltf_mode; + + std::string buf_type, buf_in, buf_out; + std::string true_type, true_out, false_type, false_out; + + BtorDumperConfig() : subckt_mode(false), conn_mode(false), impltf_mode(false) { } +}; + +struct BtorDumper +{ + FILE *f; + RTLIL::Module *module; + RTLIL::Design *design; + BtorDumperConfig *config; + CellTypes ct; + + std::map> inter_wire_map;// for maping the intermediate wires that are output of some cell + std::map line_ref;//mapping of ids to line_num of the btor file + int line_num;//last line number of btor file + std::string str;//temp string + std::queue conn_list; + std::map basic_wires;//input wires and wires with dff + RTLIL::IdString curr_cell; + std::map cell_type_translation; + BtorDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) : + f(f), module(module), design(design), config(config), ct(design) + { + line_num=0; + str.clear(); + for(auto it=module->connections.begin(); it !=module->connections.end(); it++) + { + conn_list.push(*it); + } + for(auto it=module->wires.begin(); it!=module->wires.end(); it++) + { + if(it->second->port_input) + { + basic_wires[it->first]=true; + } + else + { + basic_wires[it->first]=false; + } + inter_wire_map[it->first].clear(); + } + curr_cell.clear(); + cell_type_translation = { + //unary + {"$not","not"},{"$neg","neg"},{"$reduce_and","redand"}, + {"$reduce_or","redor"},{"$reduce_xor","redxor"},{"$reduce_bool","redor"}, + //binary + {"$and","and"},{"$or","or"},{"$xor","xor"},{"$xnor","xnor"}, + {"$shr","srl"},{"$shl","sll"},{"$sshr","sra"},{"$sshl","sll"}, + {"$lt","ult"},{"$le","ulte"},{"$eq","eq"},{"$ne","ne"},{"$gt","ugt"},{"$ge","ugte"}, + {"$add","add"},{"$sub","sub"},{"$mul","mul"},{"$mod","urem"},{"$div","udiv"}, + //mux + {"$mux","cond"}, + //reg + {"$dff","next"},{"$adff","next"},{"$dffsr","next"} + //memories + }; + } + + std::vector cstr_buf; + + const char *cstr(const RTLIL::IdString id) + { + str = RTLIL::unescape_id(id); + for (size_t i = 0; i < str.size(); i++) + if (str[i] == '#' || str[i] == '=') + str[i] = '?'; + cstr_buf.push_back(str); + return cstr_buf.back().c_str(); + } + + int dump_wire(const RTLIL::Wire* wire) + { + log("writing wire %s\n", cstr(wire->name)); + if(basic_wires[wire->name]) + { + auto it = line_ref.find(wire->name); + if(it==std::end(line_ref)) + { + line_num++; + line_ref[wire->name]=line_num; + str = stringf("%d var %d %s", line_num, wire->width, cstr(wire->name)); + fprintf(f, "%s\n", str.c_str()); + return line_num; + } + else return it->second; + } + else // case when the wire is intermediate wire (auto generated) + { + log(" - case of intermediate wire - %s\n", cstr(wire->name)); + auto it = line_ref.find(wire->name); + if(it==std::end(line_ref)) + { + auto cell_it = inter_wire_map.find(wire->name); + if(cell_it !=std::end(inter_wire_map) && cell_it->second != curr_cell) + { + log(" -- found cell %s\n", cstr(cell_it->second)); + RTLIL::Cell *cell = module->cells.at(cell_it->second); + int l = dump_cell(cell); + line_ref[wire->name] = l; + return l; + } + else + { + log(" -- checking connections\n"); + for(unsigned i=0; ichunks.size(); + unsigned sig2_wires_count = sig2->chunks.size(); + int start_bit=sig1->width-1; + for(unsigned j=0; jchunks[j].wire!=NULL && sig1->chunks[j].wire->name == wire->name && sig1->chunks[j].offset == 0) + { + log(" ---- found match sig1\n"); + conn_list.push(ss); + if(sig1_wires_count == 1) + { + int l = dump_sigspec(sig2, sig2->width); + line_ref[wire->name] = l; + return l; + } + else + { + int l = dump_sigspec(sig2, sig2->width); + line_num++; + str = stringf("%d slice %d %d %d %d", line_num, wire->width, l, start_bit, start_bit-wire->width+1); + fprintf(f, "%s\n", str.c_str()); + line_ref[wire->name]=line_num; + return line_num; + } + } + start_bit-=sig1->chunks[j].width; + } + start_bit=sig2->width-1; + for(unsigned j=0; jchunks[j].wire!=NULL && sig2->chunks[j].wire->name == wire->name && sig2->chunks[j].offset == 0) + { + log(" ---- found match sig2\n"); + conn_list.push(ss); + if(sig2_wires_count == 1) + { + int l = dump_sigspec(sig1, sig1->width); + line_ref[wire->name] = l; + return l; + } + else + { + int l = dump_sigspec(sig1, sig1->width); + line_num++; + str = stringf("%d slice %d %d %d %d", line_num, wire->width, l, start_bit, start_bit-wire->width+1); + fprintf(f, "%s\n", str.c_str()); + line_ref[wire->name]=line_num; + return line_num; + } + } + start_bit-=sig2->chunks[j].width; + } + conn_list.push(ss); + } + log(" --- nothing found\n"); + return -1; + } + } + else + { + log(" -- already processed wire\n"); + return it->second; + } + } + } + + int dump_memory(const RTLIL::Memory* memory) + { + log("writing memory %s\n", cstr(memory->name)); + auto it = line_ref.find(memory->name); + if(it==std::end(line_ref)) + { + line_num++; + int address_bits = ceil(log(memory->size)/log(2)); + str = stringf("%d array %d %d", line_num, memory->width, address_bits); + line_ref[memory->name]=line_num; + fprintf(f, "%s\n", str.c_str()); + return line_num; + } + else return it->second; + } + + int dump_const(const RTLIL::Const* data, int width, int offset) + { + log("writing const \n"); + if((data->flags & RTLIL::CONST_FLAG_STRING) == 0) + { + if(width<0) + width = data->bits.size() - offset; + + std::string data_str = data->as_string(); + if(offset > 0) + data_str = data_str.substr(offset, width); + + line_num++; + str = stringf("%d const %d %s", line_num, width, data_str.c_str()); + fprintf(f, "%s\n", str.c_str()); + return line_num; + } + else + log("writing const error\n"); + return -1; + } + + int dump_sigchunk(const RTLIL::SigChunk* chunk) + { + log("writing sigchunk\n"); + int l=-1; + if(chunk->wire == NULL) + { + l=dump_const(&chunk->data, chunk->width, chunk->offset); + } + else + { + if (chunk->width == chunk->wire->width && chunk->offset == 0) + l = dump_wire(chunk->wire); + else + { + str = stringf("%s[%d:%d]", chunk->wire->name.c_str(), + chunk->offset + chunk->width - 1, chunk->offset); + auto it = line_ref.find(RTLIL::IdString(str)); + if(it==std::end(line_ref)) + { + int wire_line_num = dump_wire(chunk->wire); + if(wire_line_num<=0) + return -1; + line_num++; + line_ref[RTLIL::IdString(str)] = line_num; + str = stringf("%d slice %d %d %d %d", line_num, chunk->width, + wire_line_num, chunk->offset + chunk->width - 1, chunk->offset); + fprintf(f, "%s\n", str.c_str()); + l = line_num; + } + else + l=it->second; + } + } + return l; + } + + int dump_sigspec(const RTLIL::SigSpec* sig, int expected_width) + { + log("writing sigspec\n"); + assert(sig->width<=expected_width); + int l = -1; + if (sig->chunks.size() == 1) + { + l = dump_sigchunk(&sig->chunks[0]); + } + else + { + int l1, l2, w1, w2; + l1 = dump_sigchunk(&sig->chunks[0]); + if(l1<=0) + return -1; + w1 = sig->chunks[0].width; + for (unsigned i=1; i < sig->chunks.size(); i++) + { + l2 = dump_sigchunk(&sig->chunks[i]); + if(l2<=0) + return -1; + w2 = sig->chunks[i].width; + line_num++; + str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); + fprintf(f, "%s\n", str.c_str()); + l1=line_num; + w1+=w2; + } + l = line_num; + } + if(expected_width > sig->width) + { + line_num++; + str = stringf ("%d zero %d", line_num, expected_width - sig->width); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l); + fprintf(f, "%s\n", str.c_str()); + l = line_num; + } + return l; + } + + int dump_cell(const RTLIL::Cell* cell) + { + auto it = line_ref.find(cell->name); + if(it==std::end(line_ref)) + { + curr_cell = cell->name; + //unary cells + if(cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos" || cell->type == "$reduce_and" || + cell->type == "$reduce_or" || cell->type == "$reduce_xor" || cell->type == "$reduce_bool") + { + log("writing unary cell - %s\n", cstr(cell->type)); + RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name + int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); + int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + assert((cell->type == "$not" || cell->type == "$neg") && w==output_width); + int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); + if(cell->type == "$pos") + return l; + line_num++; + line_ref[output_id]=line_num; + line_ref[cell->name]=line_num; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, l); + fprintf(f, "%s\n", str.c_str()); + } + else if(cell->type == "$reduce_xnor" || cell->type == "$logic_not")//no direct translation in btor + { + log("writing unary cell - %s\n", cstr(cell->type)); + RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name + int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); + int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); + if(cell->type == "$logic_not") + { + line_num++; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l); + fprintf(f, "%s\n", str.c_str()); + } + else if(cell->type == "$reduce_xnor") + { + line_num++; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_xor").c_str(), output_width, l); + fprintf(f, "%s\n", str.c_str()); + } + line_ref[output_id]=line_num; + line_ref[cell->name]=line_num; + line_num++; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$not").c_str(), output_width, line_num-1); + fprintf(f, "%s\n", str.c_str()); + } + //binary cells + else if(cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || + cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || + cell->type == "$mod" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || + cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt" || + cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") + { + log("writing binary cell - %s\n", cstr(cell->type)); + RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name + int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); + line_num++; + line_ref[output_id]=line_num; + line_ref[cell->name]=line_num; + str = stringf ("%d %s %d %d %d", + line_num, cell_type_translation.at(cell->type).c_str(), output_width, l1, l2); + fprintf(f, "%s\n", str.c_str()); + } + else if(cell->type == "$logic_and" || cell->type == "$logic_or")//no direct translation in btor + { + log("writing binary cell - %s\n", cstr(cell->type)); + RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name + int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); + line_num++; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l1); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l2); + fprintf(f, "%s\n", str.c_str()); + if(cell->type == "$logic_and") + { + line_num++; + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$and").c_str(), output_width, line_num-2, line_num-1); + } + else if(cell->type == "$logic_or") + { + line_num++; + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$or").c_str(), output_width, line_num-2, line_num-1); + } + line_ref[output_id]=line_num; + line_ref[cell->name]=line_num; + fprintf(f, "%s\n", str.c_str()); + } + //multiplexers + else if(cell->type == "$mux") + { + log("writing mux cell\n"); + RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name + int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); + int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); + int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); + int s = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\S")), 1); + line_num++; + line_ref[output_id]=line_num; + line_ref[cell->name]=line_num; + str = stringf ("%d %s %d %d %d %d", + line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell + fprintf(f, "%s\n", str.c_str()); + } + //registers + else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") + { + log("writing cell - %s\n", cstr(cell->type)); + int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); + int reg = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\Q")), output_width);//register + int cond = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1); + bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); + int value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\D")), output_width); + if(cell->type == "$dffsr") + { + int sync_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLR")), 1); + bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); + int sync_reset_value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\SET")), output_width); + bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); + line_num++; + str = stringf ("%d %s %d %s%d %s%d %d", line_num, cell_type_translation.at("$mux").c_str(), + output_width, sync_reset_pol ? "":"-", sync_reset, sync_reset_value_pol? "":"-", + sync_reset_value, value); + fprintf(f, "%s\n", str.c_str()); + value = line_num; + } + line_num++; + str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), + output_width, polarity?"":"-", cond, value, reg); + + fprintf(f, "%s\n", str.c_str()); + int next = line_num; + if(cell->type == "$adff") + { + int async_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ARST")), 1); + bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); + int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), + output_width, 0); + line_num++; + str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), + output_width, async_reset_pol ? "":"-", async_reset, async_reset_value, next); + fprintf(f, "%s\n", str.c_str()); + } + line_num++; + line_ref[cell->name]=line_num; + str = stringf ("%d %s %d %d %d", + line_num, cell_type_translation.at(cell->type).c_str(), output_width, reg, next); + fprintf(f, "%s\n", str.c_str()); + } + //memories + else if(cell->type == "$memrd") + { + log("writing memrd cell\n"); + RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\DATA")).chunks[0].wire->name;//output wire + str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); + int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); + int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); + int address = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ADDR")), address_width); + int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); + line_num++; + str = stringf("%d read %d %d %d", line_num, data_width, mem, address); + fprintf(f, "%s\n", str.c_str()); + line_ref[output_id]=line_num; + line_ref[cell->name]=line_num; + } + else if(cell->type == "$memwr") + { + log("writing memwr cell\n"); + int clk = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1); + bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); + int enable = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\EN")), 1); + int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); + int address = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ADDR")), address_width); + int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); + int data = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\DATA")), data_width); + str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); + int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); + line_num++; + if(polarity) + str = stringf("%d one 1", line_num); + else + str = stringf("%d zero 1", line_num); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf("%d eq 1 %d %d", line_num, clk, line_num-1); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf("%d and 1 %d %d", line_num, line_num-1, enable); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf("%d write %d %d %d %d %d", line_num, data_width, address_width, mem, address, data); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf("%d acond %d %d %d %d %d", line_num, data_width, address_width, line_num-2/*enable*/, line_num-1, mem); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf("%d anext %d %d %d %d", line_num, data_width, address_width, mem, line_num-1); + fprintf(f, "%s\n", str.c_str()); + line_ref[cell->name]=line_num; + } + return line_num; + } + else + { + return it->second; + } + } + + void dump() + { + fprintf(f, ";module %s\n", cstr(module->name)); + + log("creating intermediate wires map\n"); + //creating map of intermediate wires as output of some cell + for (auto it = module->cells.begin(); it != module->cells.end(); it++) + { + RTLIL::Cell *cell = it->second; + log(" - %s\n", cstr(it->second->type)); + if (cell->type == "$memrd") + { + RTLIL::SigSpec *ss = &cell->connections.at(RTLIL::IdString("\\DATA")); + for(int i=0; ichunks.size(); i++) + { + RTLIL::Wire *w = ss->chunks[i].wire; + RTLIL::IdString wire_id = w->name; + inter_wire_map[wire_id].push_back(cell->name); + } + } + else if(it->second->type == "$memwr") + { + /*RTLIL::IdString wire_id = it->second->connections.at(RTLIL::IdString("\\MEMID")).chunks[0].wire->name; + if(inter_wire_map.find(wire_id)==std::end(inter_wire_map)) + inter_wire_map[wire_id] = it->second->name;*/ + } + else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") + { + RTLIL::IdString wire_id = cell->connections.at(RTLIL::IdString("\\Q")).chunks[0].wire->name; + if(inter_wire_map.find(wire_id)==std::end(inter_wire_map)) + { + inter_wire_map[wire_id] = it->second->name; + basic_wires[wire_id] = true; + } + } + else + { + RTLIL::SigSpec *ss = &cell->connections.at(RTLIL::IdString("\\Y")); + for(int i=0; ichunks.size(); i++) + { + RTLIL::Wire *w = ss->chunks[i].wire; + RTLIL::IdString wire_id = w->name; + inter_wire_map[wire_id].push_back(cell->name); + } + } + } + + //removing duplicates + for(auto it = inter_wire_map.begin(); it != inter_wire_map.end(); it++) + { + it->sort(); + unique(it->begin(), it->end()); + } + + log("writing input\n"); + std::map inputs; + + for (auto &wire_it : module->wires) { + RTLIL::Wire *wire = wire_it.second; + if (wire->port_input) + inputs[wire->port_id] = wire; + } + + fprintf(f, ";inputs\n"); + for (auto &it : inputs) { + RTLIL::Wire *wire = it.second; + for (int i = 0; i < wire->width; i++) + dump_wire(wire); + } + fprintf(f, "\n"); + + /*log("writing cells\n"); + fprintf(f, ";cells\n"); + for (auto it = module->cells.begin(); it != module->cells.end(); it++) + { + dump_cell(it->second); + } + + log("writing connections\n"); + fprintf(f, ";output connections\n"); + for (auto it = module->connections.begin(); it != module->connections.end(); it++) + { + RTLIL::SigSpec *sig1 = &it->first; + RTLIL::SigSpec *sig2 = &it->second; + unsigned sig1_wires_count = sig1->chunks.size(); + unsigned sig2_wires_count = sig2->chunks.size(); + int start_bit=sig1->width-1; + for(unsigned j=0; jchunks[j].wire!=NULL && sig1->chunks[j].wire->port_output) + { + if(sig1_wires_count == 1) + { + int next = dump_sigspec(sig2, sig2->width); + int reg = dump_sigchunk(&sig1->chunks[j]); + if(reg!=next) + { + line_num++; + str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), + sig1->chunks[j].width, reg, next); + fprintf(f, "%s\n", str.c_str()); + } + } + else + { + int l = dump_sigspec(sig2, sig2->width); + int reg = dump_sigchunk(&sig1->chunks[j]); + line_num++; + str = stringf("%d slice %d %d %d %d", line_num, sig1->chunks[j].width, l, start_bit, + start_bit-sig1->chunks[j].width+1); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), + sig1->chunks[j].width, reg, line_num-1); + fprintf(f, "%s\n", str.c_str()); + } + } + start_bit-=sig1->chunks[j].width; + } + start_bit=sig2->width-1; + for(unsigned j=0; jchunks[j].wire!=NULL && sig2->chunks[j].wire->port_output) + { + if(sig2_wires_count == 1) + { + int next = dump_sigspec(sig1, sig1->width); + int reg = dump_sigchunk(&sig2->chunks[j]); + if(reg!=next) + { + line_num++; + str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), + sig2->chunks[j].width, reg, next); + fprintf(f, "%s\n", str.c_str()); + } + } + else + { + int l = dump_sigspec(sig1, sig1->width); + int reg = dump_sigchunk(&sig2->chunks[j]); + line_num++; + str = stringf("%d slice %d %d %d %d", line_num, sig2->chunks[j].width, l, start_bit, + start_bit-sig2->chunks[j].width+1); + fprintf(f, "%s\n", str.c_str()); + line_num++; + str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), + sig2->chunks[j].width, reg, line_num-1); + fprintf(f, "%s\n", str.c_str()); + } + } + start_bit-=sig2->chunks[j].width; + } + }*/ + } + + static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config) + { + BtorDumper dumper(f, module, design, &config); + dumper.dump(); + } +}; + +struct BtorBackend : public Backend { + BtorBackend() : Backend("btor", "write design to BTOR file") { } + + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" write_btor [filename]\n"); + log("\n"); + log("Write the current design to an BTOR file.\n"); + } + + virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + { + std::string top_module_name; + std::string buf_type, buf_in, buf_out; + std::string true_type, true_out; + std::string false_type, false_out; + BtorDumperConfig config; + + log_header("Executing BTOR backend.\n"); + + size_t argidx=1; + extra_args(f, filename, args, argidx); + + if (top_module_name.empty()) + for (auto & mod_it:design->modules) + if (mod_it.second->get_bool_attribute("\\top")) + top_module_name = mod_it.first; + + fprintf(f, "; Generated by %s\n", yosys_version_str); + + std::vector mod_list; + + for (auto module_it : design->modules) + { + RTLIL::Module *module = module_it.second; + if (module->get_bool_attribute("\\blackbox")) + continue; + + if (module->name == RTLIL::escape_id(top_module_name)) { + BtorDumper::dump(f, module, design, config); + top_module_name.clear(); + continue; + } + + mod_list.push_back(module); + } + + if (!top_module_name.empty()) + log_error("Can't find top module `%s'!\n", top_module_name.c_str()); + + for (auto module : mod_list) + BtorDumper::dump(f, module, design, config); + } +} BtorBackend; + -- cgit v1.2.3 From 661b5a993ebbe331c8d4085372622587e1712ab4 Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Tue, 14 Jan 2014 12:03:53 +0100 Subject: BTOR backend --- backends/btor/btor.cc | 602 +++++++++++++++++++++++++++----------------------- 1 file changed, 328 insertions(+), 274 deletions(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 6ffb4730..4190fc89 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf - * Copyright (C) 2013 Ahmed Irfan + * Copyright (C) 2014 Ahmed Irfan * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,6 +31,7 @@ #include #include #include +#include struct BtorDumperConfig { @@ -44,6 +45,22 @@ struct BtorDumperConfig BtorDumperConfig() : subckt_mode(false), conn_mode(false), impltf_mode(false) { } }; +struct WireInfo +{ + RTLIL::IdString cell_name; + RTLIL::SigChunk *chunk; + + WireInfo(RTLIL::IdString c, RTLIL::SigChunk* ch) : cell_name(c), chunk(ch) { } +}; + +struct WireInfoOrder +{ + bool operator() (const WireInfo& x, const WireInfo& y) + { + return x.chunk < y.chunk; + } +}; + struct BtorDumper { FILE *f; @@ -52,24 +69,21 @@ struct BtorDumper BtorDumperConfig *config; CellTypes ct; - std::map> inter_wire_map;// for maping the intermediate wires that are output of some cell + SigMap sigmap; + std::map> inter_wire_map;// for maping the intermediate wires that are output of some cell std::map line_ref;//mapping of ids to line_num of the btor file + std::map sig_ref;//mapping of sigspec to the line_num of the btor file int line_num;//last line number of btor file - std::string str;//temp string - std::queue conn_list; - std::map basic_wires;//input wires and wires with dff - RTLIL::IdString curr_cell; - std::map cell_type_translation; + std::string str;//temp string for writing file + std::map basic_wires;//input wires and registers + RTLIL::IdString curr_cell; //current cell being dumped + std::map cell_type_translation, s_cell_type_translation; //RTLIL to BTOR translation BtorDumper(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig *config) : - f(f), module(module), design(design), config(config), ct(design) + f(f), module(module), design(design), config(config), ct(design), sigmap(module) { line_num=0; str.clear(); - for(auto it=module->connections.begin(); it !=module->connections.end(); it++) - { - conn_list.push(*it); - } - for(auto it=module->wires.begin(); it!=module->wires.end(); it++) + for(auto it=module->wires.begin(); it!=module->wires.end(); ++it) { if(it->second->port_input) { @@ -97,6 +111,11 @@ struct BtorDumper {"$dff","next"},{"$adff","next"},{"$dffsr","next"} //memories }; + s_cell_type_translation = { + //binary + {"$modx","srem"},{"$mody","smod"},{"$div","sdiv"}, + {"$lt","slt"},{"$le","slte"},{"$gt","sgt"},{"$ge","sgte"} + }; } std::vector cstr_buf; @@ -104,22 +123,22 @@ struct BtorDumper const char *cstr(const RTLIL::IdString id) { str = RTLIL::unescape_id(id); - for (size_t i = 0; i < str.size(); i++) + for (size_t i = 0; i < str.size(); ++i) if (str[i] == '#' || str[i] == '=') str[i] = '?'; cstr_buf.push_back(str); return cstr_buf.back().c_str(); } - int dump_wire(const RTLIL::Wire* wire) + int dump_wire(RTLIL::Wire* wire) { - log("writing wire %s\n", cstr(wire->name)); if(basic_wires[wire->name]) { + log("writing wire %s\n", cstr(wire->name)); auto it = line_ref.find(wire->name); if(it==std::end(line_ref)) { - line_num++; + ++line_num; line_ref[wire->name]=line_num; str = stringf("%d var %d %s", line_num, wire->width, cstr(wire->name)); fprintf(f, "%s\n", str.c_str()); @@ -127,88 +146,65 @@ struct BtorDumper } else return it->second; } - else // case when the wire is intermediate wire (auto generated) + else // case when the wire is not basic wire { - log(" - case of intermediate wire - %s\n", cstr(wire->name)); + log("case of non-basic wire - %s\n", cstr(wire->name)); auto it = line_ref.find(wire->name); if(it==std::end(line_ref)) { - auto cell_it = inter_wire_map.find(wire->name); - if(cell_it !=std::end(inter_wire_map) && cell_it->second != curr_cell) + std::set& dep_set = inter_wire_map.at(wire->name); + int wire_line = 0; + int wire_width = 0; + for(auto dep_set_it=dep_set.begin(); dep_set_it!=dep_set.end(); ++dep_set_it) { - log(" -- found cell %s\n", cstr(cell_it->second)); - RTLIL::Cell *cell = module->cells.at(cell_it->second); - int l = dump_cell(cell); - line_ref[wire->name] = l; - return l; - } - else - { - log(" -- checking connections\n"); - for(unsigned i=0; icell_name; + if(cell_id == curr_cell) + break; + log(" -- found cell %s\n", cstr(cell_id)); + RTLIL::Cell* cell = module->cells.at(cell_id); + RTLIL::SigSpec* cell_output = get_cell_output(cell); + int cell_line = dump_cell(cell); + + if(dep_set.size()==1 && wire->width == cell_output->width) + { + wire_line = cell_line; + break; + } + else { - log(" --- checking %d\n", i); - RTLIL::SigSig ss = conn_list.front(); - conn_list.pop(); - RTLIL::SigSpec *sig1 = &ss.first; - RTLIL::SigSpec *sig2 = &ss.second; - unsigned sig1_wires_count = sig1->chunks.size(); - unsigned sig2_wires_count = sig2->chunks.size(); - int start_bit=sig1->width-1; - for(unsigned j=0; jwidth-1; + for(unsigned j=0; jchunks.size(); ++j) { - if(sig1->chunks[j].wire!=NULL && sig1->chunks[j].wire->name == wire->name && sig1->chunks[j].offset == 0) + if(cell_output->chunks[j].wire->name == wire->name) { - log(" ---- found match sig1\n"); - conn_list.push(ss); - if(sig1_wires_count == 1) + prev_wire_line = wire_line; + wire_line = ++line_num; + str = stringf("%d slice %d %d %d %d", line_num, cell_output->chunks[j].width, cell_line, + start_bit, start_bit-cell_output->chunks[j].width+1); + fprintf(f, "%s\n", str.c_str()); + wire_width += cell_output->chunks[j].width; + if(prev_wire_line!=0) { - int l = dump_sigspec(sig2, sig2->width); - line_ref[wire->name] = l; - return l; - } - else - { - int l = dump_sigspec(sig2, sig2->width); - line_num++; - str = stringf("%d slice %d %d %d %d", line_num, wire->width, l, start_bit, start_bit-wire->width+1); + ++line_num; + str = stringf("%d concat %d %d %d", line_num, wire_width, prev_wire_line, wire_line); fprintf(f, "%s\n", str.c_str()); - line_ref[wire->name]=line_num; - return line_num; - } - } - start_bit-=sig1->chunks[j].width; - } - start_bit=sig2->width-1; - for(unsigned j=0; jchunks[j].wire!=NULL && sig2->chunks[j].wire->name == wire->name && sig2->chunks[j].offset == 0) - { - log(" ---- found match sig2\n"); - conn_list.push(ss); - if(sig2_wires_count == 1) - { - int l = dump_sigspec(sig1, sig1->width); - line_ref[wire->name] = l; - return l; + wire_line = line_num; } - else - { - int l = dump_sigspec(sig1, sig1->width); - line_num++; - str = stringf("%d slice %d %d %d %d", line_num, wire->width, l, start_bit, start_bit-wire->width+1); - fprintf(f, "%s\n", str.c_str()); - line_ref[wire->name]=line_num; - return line_num; - } } - start_bit-=sig2->chunks[j].width; + start_bit-=cell_output->chunks[j].width; } - conn_list.push(ss); } - log(" --- nothing found\n"); - return -1; } + if(dep_set.size()==0) + { + log(" - checking sigmap\n"); + RTLIL::SigSpec s = RTLIL::SigSpec(wire); + wire_line = dump_sigspec(&s, s.width); + line_ref[wire->name]=wire_line; + } + line_ref[wire->name]=wire_line; + return wire_line; } else { @@ -216,6 +212,8 @@ struct BtorDumper return it->second; } } + assert(false); + return -1; } int dump_memory(const RTLIL::Memory* memory) @@ -224,7 +222,7 @@ struct BtorDumper auto it = line_ref.find(memory->name); if(it==std::end(line_ref)) { - line_num++; + ++line_num; int address_bits = ceil(log(memory->size)/log(2)); str = stringf("%d array %d %d", line_num, memory->width, address_bits); line_ref[memory->name]=line_num; @@ -246,13 +244,14 @@ struct BtorDumper if(offset > 0) data_str = data_str.substr(offset, width); - line_num++; + ++line_num; str = stringf("%d const %d %s", line_num, width, data_str.c_str()); fprintf(f, "%s\n", str.c_str()); return line_num; } else log("writing const error\n"); + assert(false); return -1; } @@ -278,7 +277,7 @@ struct BtorDumper int wire_line_num = dump_wire(chunk->wire); if(wire_line_num<=0) return -1; - line_num++; + ++line_num; line_ref[RTLIL::IdString(str)] = line_num; str = stringf("%d slice %d %d %d %d", line_num, chunk->width, wire_line_num, chunk->offset + chunk->width - 1, chunk->offset); @@ -295,43 +294,79 @@ struct BtorDumper int dump_sigspec(const RTLIL::SigSpec* sig, int expected_width) { log("writing sigspec\n"); - assert(sig->width<=expected_width); + RTLIL::SigSpec s = sigmap(*sig); int l = -1; - if (sig->chunks.size() == 1) + auto it = sig_ref.find(s); + if(it == std::end(sig_ref)) { - l = dump_sigchunk(&sig->chunks[0]); - } - else - { - int l1, l2, w1, w2; - l1 = dump_sigchunk(&sig->chunks[0]); - if(l1<=0) - return -1; - w1 = sig->chunks[0].width; - for (unsigned i=1; i < sig->chunks.size(); i++) + if (s.chunks.size() == 1) { - l2 = dump_sigchunk(&sig->chunks[i]); - if(l2<=0) - return -1; - w2 = sig->chunks[i].width; - line_num++; - str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); - fprintf(f, "%s\n", str.c_str()); - l1=line_num; - w1+=w2; + l = dump_sigchunk(&s.chunks[0]); + } + else + { + int l1, l2, w1, w2; + l1 = dump_sigchunk(&s.chunks[0]); + assert(l1>0); + w1 = s.chunks[0].width; + for (unsigned i=1; i < s.chunks.size(); ++i) + { + l2 = dump_sigchunk(&s.chunks[i]); + assert(l2>0); + w2 = s.chunks[i].width; + ++line_num; + str = stringf("%d concat %d %d %d", line_num, w1+w2, l2, l1); + fprintf(f, "%s\n", str.c_str()); + l1=line_num; + w1+=w2; + } + l = line_num; } - l = line_num; + sig_ref[s] = l; } - if(expected_width > sig->width) + else { - line_num++; - str = stringf ("%d zero %d", line_num, expected_width - sig->width); - fprintf(f, "%s\n", str.c_str()); - line_num++; - str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l); - fprintf(f, "%s\n", str.c_str()); - l = line_num; + l = it->second; + } + + if (expected_width != s.width) + { + log(" - changing width of sigspec\n"); + //TODO: save the new signal in map + /*if(expected_width > s.width) + s.extend_u0(expected_width); + else if (expected_width < s.width) + s = s.extract(0, expected_width); + + it = sig_ref.find(s); + if(it == std::end(sig_ref)) + {*/ + if(expected_width > s.width) + { + //TODO: case the signal is signed + ++line_num; + str = stringf ("%d zero %d", line_num, expected_width - s.width); + fprintf(f, "%s\n", str.c_str()); + ++line_num; + str = stringf ("%d concat %d %d %d", line_num, expected_width, line_num-1, l); + fprintf(f, "%s\n", str.c_str()); + l = line_num; + } + else if(expected_width < s.width) + { + ++line_num; + str = stringf ("%d slice %d %d %d %d", line_num, expected_width, l, s.width-1, expected_width); + fprintf(f, "%s\n", str.c_str()); + l = line_num; + } + /*sig_ref[s] = l; + } + else + { + l = it->second; + }*/ } + assert(l>0); return l; } @@ -346,43 +381,49 @@ struct BtorDumper cell->type == "$reduce_or" || cell->type == "$reduce_xor" || cell->type == "$reduce_bool") { log("writing unary cell - %s\n", cstr(cell->type)); - RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - assert((cell->type == "$not" || cell->type == "$neg") && w==output_width); + w = w>output_width ? w:output_width; int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); - if(cell->type == "$pos") - return l; - line_num++; - line_ref[output_id]=line_num; - line_ref[cell->name]=line_num; - str = stringf ("%d %s %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, l); - fprintf(f, "%s\n", str.c_str()); + int cell_line = l; + if(cell->type != "$pos") + { + cell_line = ++line_num; + bool reduced = (cell->type == "$not" || cell->type == "$neg") ? false : true; + str = stringf ("%d %s %d %d", cell_line, cell_type_translation.at(cell->type).c_str(), reduced?output_width:w, l); + fprintf(f, "%s\n", str.c_str()); + } + if(output_width < w && (cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos")) + { + ++line_num; + str = stringf ("%d slice %d %d %d %d", line_num, output_width, cell_line, output_width-1, 0); + fprintf(f, "%s\n", str.c_str()); + cell_line = line_num; + } + line_ref[cell->name]=cell_line; } else if(cell->type == "$reduce_xnor" || cell->type == "$logic_not")//no direct translation in btor { log("writing unary cell - %s\n", cstr(cell->type)); - RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); - if(cell->type == "$logic_not") + if(cell->type == "$logic_not" && w > 1) { - line_num++; + ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l); fprintf(f, "%s\n", str.c_str()); } else if(cell->type == "$reduce_xnor") { - line_num++; + ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_xor").c_str(), output_width, l); fprintf(f, "%s\n", str.c_str()); } - line_ref[output_id]=line_num; - line_ref[cell->name]=line_num; - line_num++; + ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$not").c_str(), output_width, line_num-1); fprintf(f, "%s\n", str.c_str()); + line_ref[cell->name]=line_num; } //binary cells else if(cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || @@ -391,66 +432,101 @@ struct BtorDumper cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt" || cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") { + //TODO: division by zero case log("writing binary cell - %s\n", cstr(cell->type)); - RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); - int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); - line_num++; - line_ref[output_id]=line_num; - line_ref[cell->name]=line_num; + bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool(); + bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool(); + int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); + int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); + if(cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || + cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || + cell->type == "$mod" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || + cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt") + { + l1_width = l1_width > output_width ? l1_width : output_width; + l1_width = l1_width > l2_width ? l1_width : l2_width; + l2_width = l2_width > l1_width ? l2_width : l1_width; + } + else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") + { + assert(l2_width <= ceil(log(l1_width)/log(2)) ); + l2_width = ceil(log(l1_width)/log(2)); + } + int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width); + ++line_num; + std::string op = cell_type_translation.at(cell->type); + if(cell->type == "$div" || cell->type == "$lt" || cell->type == "$le" || + cell->type == "$eq" || cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt") + { + assert(l1_signed == l2_signed); + if(l1_signed) + op = s_cell_type_translation.at(cell->type); + } + if(cell->type == "$mod") + { + if(l1_signed) + op = s_cell_type_translation.at("$modx"); + else if(l2_signed) + op = s_cell_type_translation.at("$mody"); + } str = stringf ("%d %s %d %d %d", - line_num, cell_type_translation.at(cell->type).c_str(), output_width, l1, l2); + line_num, op.c_str(), output_width, l1, l2); fprintf(f, "%s\n", str.c_str()); + if(output_width < l1_width) + { + ++line_num; + str = stringf ("%d slice %d %d %d %d", line_num, output_width, line_num-1, output_width-1, 0); + fprintf(f, "%s\n", str.c_str()); + } + line_ref[cell->name]=line_num; } else if(cell->type == "$logic_and" || cell->type == "$logic_or")//no direct translation in btor { log("writing binary cell - %s\n", cstr(cell->type)); - RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); - line_num++; + ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l1); fprintf(f, "%s\n", str.c_str()); - line_num++; + ++line_num; str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l2); fprintf(f, "%s\n", str.c_str()); if(cell->type == "$logic_and") { - line_num++; + ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$and").c_str(), output_width, line_num-2, line_num-1); } else if(cell->type == "$logic_or") { - line_num++; + ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$or").c_str(), output_width, line_num-2, line_num-1); } - line_ref[output_id]=line_num; - line_ref[cell->name]=line_num; fprintf(f, "%s\n", str.c_str()); + line_ref[cell->name]=line_num; } //multiplexers else if(cell->type == "$mux") { log("writing mux cell\n"); - RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\Y")).chunks[0].wire->name;//output wire name int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); int s = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\S")), 1); - line_num++; - line_ref[output_id]=line_num; - line_ref[cell->name]=line_num; + ++line_num; str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, s, l2, l1);//if s is 0 then l1, if s is 1 then l2 //according to the implementation of mux cell fprintf(f, "%s\n", str.c_str()); + line_ref[cell->name]=line_num; } //registers else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { log("writing cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); + log(" - width is %d\n", output_width); int reg = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\Q")), output_width);//register int cond = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); @@ -461,14 +537,14 @@ struct BtorDumper bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); int sync_reset_value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\SET")), output_width); bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); - line_num++; + ++line_num; str = stringf ("%d %s %d %s%d %s%d %d", line_num, cell_type_translation.at("$mux").c_str(), output_width, sync_reset_pol ? "":"-", sync_reset, sync_reset_value_pol? "":"-", sync_reset_value, value); fprintf(f, "%s\n", str.c_str()); value = line_num; } - line_num++; + ++line_num; str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), output_width, polarity?"":"-", cond, value, reg); @@ -480,31 +556,29 @@ struct BtorDumper bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), output_width, 0); - line_num++; + ++line_num; str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), output_width, async_reset_pol ? "":"-", async_reset, async_reset_value, next); fprintf(f, "%s\n", str.c_str()); } - line_num++; - line_ref[cell->name]=line_num; + ++line_num; str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), output_width, reg, next); fprintf(f, "%s\n", str.c_str()); + line_ref[cell->name]=line_num; } //memories else if(cell->type == "$memrd") { log("writing memrd cell\n"); - RTLIL::IdString output_id = cell->connections.at(RTLIL::IdString("\\DATA")).chunks[0].wire->name;//output wire str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); int address_width = cell->parameters.at(RTLIL::IdString("\\ABITS")).as_int(); int address = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ADDR")), address_width); int data_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); - line_num++; + ++line_num; str = stringf("%d read %d %d %d", line_num, data_width, mem, address); fprintf(f, "%s\n", str.c_str()); - line_ref[output_id]=line_num; line_ref[cell->name]=line_num; } else if(cell->type == "$memwr") @@ -519,29 +593,30 @@ struct BtorDumper int data = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\DATA")), data_width); str = cell->parameters.at(RTLIL::IdString("\\MEMID")).decode_string(); int mem = dump_memory(module->memories.at(RTLIL::IdString(str.c_str()))); - line_num++; + ++line_num; if(polarity) str = stringf("%d one 1", line_num); else str = stringf("%d zero 1", line_num); fprintf(f, "%s\n", str.c_str()); - line_num++; + ++line_num; str = stringf("%d eq 1 %d %d", line_num, clk, line_num-1); fprintf(f, "%s\n", str.c_str()); - line_num++; + ++line_num; str = stringf("%d and 1 %d %d", line_num, line_num-1, enable); fprintf(f, "%s\n", str.c_str()); - line_num++; + ++line_num; str = stringf("%d write %d %d %d %d %d", line_num, data_width, address_width, mem, address, data); fprintf(f, "%s\n", str.c_str()); - line_num++; + ++line_num; str = stringf("%d acond %d %d %d %d %d", line_num, data_width, address_width, line_num-2/*enable*/, line_num-1, mem); fprintf(f, "%s\n", str.c_str()); - line_num++; + ++line_num; str = stringf("%d anext %d %d %d %d", line_num, data_width, address_width, mem, line_num-1); fprintf(f, "%s\n", str.c_str()); line_ref[cell->name]=line_num; } + curr_cell.clear(); return line_num; } else @@ -549,160 +624,136 @@ struct BtorDumper return it->second; } } - + + RTLIL::SigSpec* get_cell_output(RTLIL::Cell* cell) + { + RTLIL::SigSpec *output_sig = nullptr; + if (cell->type == "$memrd") + { + output_sig = &cell->connections.at(RTLIL::IdString("\\DATA")); + } + else if(cell->type == "$memwr") + { + //no output + } + else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") + { + output_sig = &cell->connections.at(RTLIL::IdString("\\Q")); + } + else + { + output_sig = &cell->connections.at(RTLIL::IdString("\\Y")); + } + return output_sig; + } + + void dump_property(RTLIL::Wire *wire) + { + int l = dump_wire(wire); + ++line_num; + str = stringf("%d root 1 %d", line_num, l); + fprintf(f, "%s\n", str.c_str()); + } + void dump() { fprintf(f, ";module %s\n", cstr(module->name)); log("creating intermediate wires map\n"); //creating map of intermediate wires as output of some cell - for (auto it = module->cells.begin(); it != module->cells.end(); it++) + for (auto it = module->cells.begin(); it != module->cells.end(); ++it) { RTLIL::Cell *cell = it->second; + RTLIL::SigSpec* output_sig = get_cell_output(cell); + if(output_sig==nullptr) + continue; + RTLIL::SigSpec s = sigmap(*output_sig); + output_sig = &s; log(" - %s\n", cstr(it->second->type)); if (cell->type == "$memrd") { - RTLIL::SigSpec *ss = &cell->connections.at(RTLIL::IdString("\\DATA")); - for(int i=0; ichunks.size(); i++) + for(unsigned i=0; ichunks.size(); ++i) { - RTLIL::Wire *w = ss->chunks[i].wire; + RTLIL::Wire *w = output_sig->chunks[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].push_back(cell->name); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i])); } } - else if(it->second->type == "$memwr") + else if(cell->type == "$memwr") { - /*RTLIL::IdString wire_id = it->second->connections.at(RTLIL::IdString("\\MEMID")).chunks[0].wire->name; - if(inter_wire_map.find(wire_id)==std::end(inter_wire_map)) - inter_wire_map[wire_id] = it->second->name;*/ + continue;//nothing to do } else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { - RTLIL::IdString wire_id = cell->connections.at(RTLIL::IdString("\\Q")).chunks[0].wire->name; - if(inter_wire_map.find(wire_id)==std::end(inter_wire_map)) - { - inter_wire_map[wire_id] = it->second->name; - basic_wires[wire_id] = true; - } + RTLIL::IdString wire_id = output_sig->chunks[0].wire->name; + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[0])); + basic_wires[wire_id] = true; } else { - RTLIL::SigSpec *ss = &cell->connections.at(RTLIL::IdString("\\Y")); - for(int i=0; ichunks.size(); i++) + for(unsigned i=0; ichunks.size(); ++i) { - RTLIL::Wire *w = ss->chunks[i].wire; + RTLIL::Wire *w = output_sig->chunks[i].wire; RTLIL::IdString wire_id = w->name; - inter_wire_map[wire_id].push_back(cell->name); + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i])); } } } - //removing duplicates - for(auto it = inter_wire_map.begin(); it != inter_wire_map.end(); it++) - { - it->sort(); - unique(it->begin(), it->end()); - } - log("writing input\n"); - std::map inputs; + std::map inputs, outputs; + std::vector safety; + std::regex safety_regex("(safety)(.*)"); for (auto &wire_it : module->wires) { RTLIL::Wire *wire = wire_it.second; if (wire->port_input) inputs[wire->port_id] = wire; + if (wire->port_output) { + outputs[wire->port_id] = wire; + if (std::regex_match(cstr(wire->name), safety_regex ) ) + safety.push_back(wire); + } } fprintf(f, ";inputs\n"); for (auto &it : inputs) { RTLIL::Wire *wire = it.second; - for (int i = 0; i < wire->width; i++) - dump_wire(wire); + dump_wire(wire); } fprintf(f, "\n"); - - /*log("writing cells\n"); - fprintf(f, ";cells\n"); - for (auto it = module->cells.begin(); it != module->cells.end(); it++) + + log("writing memories\n"); + for(auto mem_it = module->memories.begin(); mem_it != module->memories.end(); ++mem_it) { - dump_cell(it->second); + dump_memory(mem_it->second); } - log("writing connections\n"); - fprintf(f, ";output connections\n"); - for (auto it = module->connections.begin(); it != module->connections.end(); it++) + log("writing output wires\n"); + for (auto &it : outputs) { + RTLIL::Wire *wire = it.second; + dump_wire(wire); + } + + log("writing cells\n"); + for(auto cell_it = module->cells.begin(); cell_it != module->cells.end(); ++cell_it) { - RTLIL::SigSpec *sig1 = &it->first; - RTLIL::SigSpec *sig2 = &it->second; - unsigned sig1_wires_count = sig1->chunks.size(); - unsigned sig2_wires_count = sig2->chunks.size(); - int start_bit=sig1->width-1; - for(unsigned j=0; jchunks[j].wire!=NULL && sig1->chunks[j].wire->port_output) - { - if(sig1_wires_count == 1) - { - int next = dump_sigspec(sig2, sig2->width); - int reg = dump_sigchunk(&sig1->chunks[j]); - if(reg!=next) - { - line_num++; - str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), - sig1->chunks[j].width, reg, next); - fprintf(f, "%s\n", str.c_str()); - } - } - else - { - int l = dump_sigspec(sig2, sig2->width); - int reg = dump_sigchunk(&sig1->chunks[j]); - line_num++; - str = stringf("%d slice %d %d %d %d", line_num, sig1->chunks[j].width, l, start_bit, - start_bit-sig1->chunks[j].width+1); - fprintf(f, "%s\n", str.c_str()); - line_num++; - str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), - sig1->chunks[j].width, reg, line_num-1); - fprintf(f, "%s\n", str.c_str()); - } - } - start_bit-=sig1->chunks[j].width; - } - start_bit=sig2->width-1; - for(unsigned j=0; jchunks[j].wire!=NULL && sig2->chunks[j].wire->port_output) - { - if(sig2_wires_count == 1) - { - int next = dump_sigspec(sig1, sig1->width); - int reg = dump_sigchunk(&sig2->chunks[j]); - if(reg!=next) - { - line_num++; - str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), - sig2->chunks[j].width, reg, next); - fprintf(f, "%s\n", str.c_str()); - } - } - else - { - int l = dump_sigspec(sig1, sig1->width); - int reg = dump_sigchunk(&sig2->chunks[j]); - line_num++; - str = stringf("%d slice %d %d %d %d", line_num, sig2->chunks[j].width, l, start_bit, - start_bit-sig2->chunks[j].width+1); - fprintf(f, "%s\n", str.c_str()); - line_num++; - str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$dff").c_str(), - sig2->chunks[j].width, reg, line_num-1); - fprintf(f, "%s\n", str.c_str()); - } - } - start_bit-=sig2->chunks[j].width; - } - }*/ + dump_cell(cell_it->second); + } + + for(auto it: safety) + dump_property(it); + + fprintf(f, "\n"); + + log("writing outputs info\n"); + fprintf(f, ";outputs\n"); + for (auto &it : outputs) { + RTLIL::Wire *wire = it.second; + int l = dump_wire(wire); + fprintf(f, ";%d %s", l, cstr(wire->name)); + } + fprintf(f, "\n"); } static void dump(FILE *f, RTLIL::Module *module, RTLIL::Design *design, BtorDumperConfig &config) @@ -752,6 +803,9 @@ struct BtorBackend : public Backend { if (module->get_bool_attribute("\\blackbox")) continue; + if (module->processes.size() != 0) + log_error("Found unmapped processes in module %s: unmapped processes are not supported in BLIF backend!\n", RTLIL::id2cstr(module->name)); + if (module->name == RTLIL::escape_id(top_module_name)) { BtorDumper::dump(f, module, design, config); top_module_name.clear(); -- cgit v1.2.3 From 3a1490888d05ac49d82aebad9ec6979aae32a8b0 Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Wed, 15 Jan 2014 17:36:33 +0100 Subject: width issues dff cell for more than one registers --- backends/btor/btor.cc | 151 +++++++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 64 deletions(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 4190fc89..fcb6a47a 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -28,7 +28,6 @@ #include "kernel/celltypes.h" #include "kernel/log.h" #include -#include #include #include #include @@ -173,15 +172,15 @@ struct BtorDumper else { int prev_wire_line=0; //previously dumped wire line - int start_bit=cell_output->width-1; + int start_bit=cell_output->width; for(unsigned j=0; jchunks.size(); ++j) { if(cell_output->chunks[j].wire->name == wire->name) { prev_wire_line = wire_line; wire_line = ++line_num; - str = stringf("%d slice %d %d %d %d", line_num, cell_output->chunks[j].width, cell_line, - start_bit, start_bit-cell_output->chunks[j].width+1); + str = stringf("%d slice %d %d %d %d;1", line_num, cell_output->chunks[j].width, + cell_line, start_bit-1, start_bit-cell_output->chunks[j].width); fprintf(f, "%s\n", str.c_str()); wire_width += cell_output->chunks[j].width; if(prev_wire_line!=0) @@ -241,7 +240,7 @@ struct BtorDumper width = data->bits.size() - offset; std::string data_str = data->as_string(); - if(offset > 0) + //if(offset > 0) data_str = data_str.substr(offset, width); ++line_num; @@ -269,23 +268,13 @@ struct BtorDumper l = dump_wire(chunk->wire); else { - str = stringf("%s[%d:%d]", chunk->wire->name.c_str(), - chunk->offset + chunk->width - 1, chunk->offset); - auto it = line_ref.find(RTLIL::IdString(str)); - if(it==std::end(line_ref)) - { - int wire_line_num = dump_wire(chunk->wire); - if(wire_line_num<=0) - return -1; - ++line_num; - line_ref[RTLIL::IdString(str)] = line_num; - str = stringf("%d slice %d %d %d %d", line_num, chunk->width, - wire_line_num, chunk->offset + chunk->width - 1, chunk->offset); - fprintf(f, "%s\n", str.c_str()); - l = line_num; - } - else - l=it->second; + int wire_line_num = dump_wire(chunk->wire); + assert(wire_line_num>0); + ++line_num; + str = stringf("%d slice %d %d %d %d;2", line_num, chunk->width, wire_line_num, + chunk->wire->width - chunk->offset - 1, chunk->wire->width - chunk->offset - chunk->width); + fprintf(f, "%s\n", str.c_str()); + l = line_num; } } return l; @@ -355,7 +344,7 @@ struct BtorDumper else if(expected_width < s.width) { ++line_num; - str = stringf ("%d slice %d %d %d %d", line_num, expected_width, l, s.width-1, expected_width); + str = stringf ("%d slice %d %d %d %d;3", line_num, expected_width, l, expected_width-1, 0); fprintf(f, "%s\n", str.c_str()); l = line_num; } @@ -396,7 +385,7 @@ struct BtorDumper if(output_width < w && (cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos")) { ++line_num; - str = stringf ("%d slice %d %d %d %d", line_num, output_width, cell_line, output_width-1, 0); + str = stringf ("%d slice %d %d %d %d;4", line_num, output_width, cell_line, output_width-1, 0); fprintf(f, "%s\n", str.c_str()); cell_line = line_num; } @@ -450,6 +439,7 @@ struct BtorDumper } else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") { + //TODO: second operand width greater than the log_2(width of the first operand) assert(l2_width <= ceil(log(l1_width)/log(2)) ); l2_width = ceil(log(l1_width)/log(2)); } @@ -477,7 +467,7 @@ struct BtorDumper if(output_width < l1_width) { ++line_num; - str = stringf ("%d slice %d %d %d %d", line_num, output_width, line_num-1, output_width-1, 0); + str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, line_num-1, output_width-1, 0); fprintf(f, "%s\n", str.c_str()); } line_ref[cell->name]=line_num; @@ -488,21 +478,31 @@ struct BtorDumper int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); - ++line_num; - str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l1); - fprintf(f, "%s\n", str.c_str()); - ++line_num; - str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l2); - fprintf(f, "%s\n", str.c_str()); + int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); + int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); + if(l1_width >1) + { + ++line_num; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l1); + fprintf(f, "%s\n", str.c_str()); + l1 = line_num; + } + if(l2_width > 1) + { + ++line_num; + str = stringf ("%d %s %d %d", line_num, cell_type_translation.at("$reduce_or").c_str(), output_width, l2); + fprintf(f, "%s\n", str.c_str()); + l2 = line_num; + } if(cell->type == "$logic_and") { ++line_num; - str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$and").c_str(), output_width, line_num-2, line_num-1); + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$and").c_str(), output_width, l1, l2); } else if(cell->type == "$logic_or") { ++line_num; - str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$or").c_str(), output_width, line_num-2, line_num-1); + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$or").c_str(), output_width, l1, l2); } fprintf(f, "%s\n", str.c_str()); line_ref[cell->name]=line_num; @@ -527,44 +527,61 @@ struct BtorDumper log("writing cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); log(" - width is %d\n", output_width); - int reg = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\Q")), output_width);//register int cond = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLK")), 1); bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); + const RTLIL::SigSpec* cell_output = &cell->connections.at(RTLIL::IdString("\\Q")); int value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\D")), output_width); - if(cell->type == "$dffsr") + unsigned start_bit = output_width; + for(unsigned i=0; ichunks.size(); ++i) { - int sync_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLR")), 1); - bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); - int sync_reset_value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\SET")), output_width); - bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); + output_width = cell_output->chunks[i].width; + assert( output_width == cell_output->chunks[i].wire->width);//full reg is given the next value + int reg = dump_wire(cell_output->chunks[i].wire);//register + int slice = value; + if(cell_output->chunks.size()>1) + { + slice = ++line_num; + str = stringf ("%d slice %d %d %d %d;", line_num, output_width, value, start_bit-1, + start_bit-output_width); + fprintf(f, "%s\n", str.c_str()); + start_bit-=output_width; + } + if(cell->type == "$dffsr") + { + int sync_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\CLR")), 1); + bool sync_reset_pol = cell->parameters.at(RTLIL::IdString("\\CLR_POLARITY")).as_bool(); + int sync_reset_value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\SET")), + output_width); + bool sync_reset_value_pol = cell->parameters.at(RTLIL::IdString("\\SET_POLARITY")).as_bool(); + ++line_num; + str = stringf ("%d %s %d %s%d %s%d %d", line_num, cell_type_translation.at("$mux").c_str(), + output_width, sync_reset_pol ? "":"-", sync_reset, sync_reset_value_pol? "":"-", + sync_reset_value, slice); + fprintf(f, "%s\n", str.c_str()); + slice = line_num; + } ++line_num; - str = stringf ("%d %s %d %s%d %s%d %d", line_num, cell_type_translation.at("$mux").c_str(), - output_width, sync_reset_pol ? "":"-", sync_reset, sync_reset_value_pol? "":"-", - sync_reset_value, value); - fprintf(f, "%s\n", str.c_str()); - value = line_num; - } - ++line_num; - str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), - output_width, polarity?"":"-", cond, value, reg); + str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), + output_width, polarity?"":"-", cond, slice, reg); - fprintf(f, "%s\n", str.c_str()); - int next = line_num; - if(cell->type == "$adff") - { - int async_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ARST")), 1); - bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); - int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), - output_width, 0); + fprintf(f, "%s\n", str.c_str()); + int next = line_num; + if(cell->type == "$adff") + { + int async_reset = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\ARST")), 1); + bool async_reset_pol = cell->parameters.at(RTLIL::IdString("\\ARST_POLARITY")).as_bool(); + int async_reset_value = dump_const(&cell->parameters.at(RTLIL::IdString("\\ARST_VALUE")), + output_width, 0); + ++line_num; + str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), + output_width, async_reset_pol ? "":"-", async_reset, async_reset_value, next); + fprintf(f, "%s\n", str.c_str()); + } ++line_num; - str = stringf ("%d %s %d %s%d %d %d", line_num, cell_type_translation.at("$mux").c_str(), - output_width, async_reset_pol ? "":"-", async_reset, async_reset_value, next); + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), + output_width, reg, next); fprintf(f, "%s\n", str.c_str()); } - ++line_num; - str = stringf ("%d %s %d %d %d", - line_num, cell_type_translation.at(cell->type).c_str(), output_width, reg, next); - fprintf(f, "%s\n", str.c_str()); line_ref[cell->name]=line_num; } //memories @@ -686,8 +703,13 @@ struct BtorDumper else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { RTLIL::IdString wire_id = output_sig->chunks[0].wire->name; - inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[0])); - basic_wires[wire_id] = true; + for(unsigned i=0; ichunks.size(); ++i) + { + RTLIL::Wire *w = output_sig->chunks[i].wire; + RTLIL::IdString wire_id = w->name; + inter_wire_map[wire_id].insert(WireInfo(cell->name,&output_sig->chunks[i])); + basic_wires[wire_id] = true; + } } else { @@ -794,6 +816,7 @@ struct BtorBackend : public Backend { top_module_name = mod_it.first; fprintf(f, "; Generated by %s\n", yosys_version_str); + fprintf(f, "; BTOR Backend developed at FBK\n"); std::vector mod_list; -- cgit v1.2.3 From c7a2e582aac966034d59def611bd53109ecb581e Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Thu, 16 Jan 2014 20:16:01 +0100 Subject: slice error corrected --- backends/btor/btor.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index fcb6a47a..6ef9c3fc 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -172,9 +172,10 @@ struct BtorDumper else { int prev_wire_line=0; //previously dumped wire line - int start_bit=cell_output->width; + int start_bit=0; for(unsigned j=0; jchunks.size(); ++j) { + start_bit+=cell_output->chunks[j].width; if(cell_output->chunks[j].wire->name == wire->name) { prev_wire_line = wire_line; @@ -186,12 +187,11 @@ struct BtorDumper if(prev_wire_line!=0) { ++line_num; - str = stringf("%d concat %d %d %d", line_num, wire_width, prev_wire_line, wire_line); + str = stringf("%d concat %d %d %d", line_num, wire_width, wire_line, prev_wire_line); fprintf(f, "%s\n", str.c_str()); wire_line = line_num; } } - start_bit-=cell_output->chunks[j].width; } } } @@ -531,7 +531,7 @@ struct BtorDumper bool polarity = cell->parameters.at(RTLIL::IdString("\\CLK_POLARITY")).as_bool(); const RTLIL::SigSpec* cell_output = &cell->connections.at(RTLIL::IdString("\\Q")); int value = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\D")), output_width); - unsigned start_bit = output_width; + unsigned start_bit = 0; for(unsigned i=0; ichunks.size(); ++i) { output_width = cell_output->chunks[i].width; @@ -540,11 +540,11 @@ struct BtorDumper int slice = value; if(cell_output->chunks.size()>1) { + start_bit+=output_width; slice = ++line_num; str = stringf ("%d slice %d %d %d %d;", line_num, output_width, value, start_bit-1, start_bit-output_width); fprintf(f, "%s\n", str.c_str()); - start_bit-=output_width; } if(cell->type == "$dffsr") { -- cgit v1.2.3 From 9a689f33a56d4b351bab021989f79e9b19500c62 Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Fri, 17 Jan 2014 19:32:35 +0100 Subject: verilog default options pull shift operator width issues --- backends/btor/btor.cc | 125 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 28 deletions(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 6ef9c3fc..866bfe52 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -2,7 +2,7 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf - * Copyright (C) 2014 Ahmed Irfan + * Copyright (C) 2014 Ahmed Irfan * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -372,7 +372,7 @@ struct BtorDumper log("writing unary cell - %s\n", cstr(cell->type)); int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - w = w>output_width ? w:output_width; + w = w>output_width ? w:output_width; //padding of w int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); int cell_line = l; if(cell->type != "$pos") @@ -396,6 +396,7 @@ struct BtorDumper log("writing unary cell - %s\n", cstr(cell->type)); int w = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + assert(output_width == 1); int l = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), w); if(cell->type == "$logic_not" && w > 1) { @@ -416,54 +417,72 @@ struct BtorDumper } //binary cells else if(cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || - cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || - cell->type == "$mod" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || - cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt" || - cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") + cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || + cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt" ) { - //TODO: division by zero case log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + assert(!(cell->type == "$eq" || cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt") || output_width == 1); bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool(); bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool(); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); - if(cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || - cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || - cell->type == "$mod" || cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || - cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt") - { - l1_width = l1_width > output_width ? l1_width : output_width; - l1_width = l1_width > l2_width ? l1_width : l2_width; - l2_width = l2_width > l1_width ? l2_width : l1_width; - } - else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") - { - //TODO: second operand width greater than the log_2(width of the first operand) - assert(l2_width <= ceil(log(l1_width)/log(2)) ); - l2_width = ceil(log(l1_width)/log(2)); - } + + assert(l1_signed == l2_signed); + l1_width = l1_width > output_width ? l1_width : output_width; + l1_width = l1_width > l2_width ? l1_width : l2_width; + l2_width = l2_width > l1_width ? l2_width : l1_width; + int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width); int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width); + ++line_num; std::string op = cell_type_translation.at(cell->type); - if(cell->type == "$div" || cell->type == "$lt" || cell->type == "$le" || + if(cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt") { - assert(l1_signed == l2_signed); if(l1_signed) op = s_cell_type_translation.at(cell->type); } - if(cell->type == "$mod") + + str = stringf ("%d %s %d %d %d", line_num, op.c_str(), output_width, l1, l2); + fprintf(f, "%s\n", str.c_str()); + + line_ref[cell->name]=line_num; + } + else if(cell->type == "$add" || cell->type == "$sub" || cell->type == "$mul" || cell->type == "$div" || + cell->type == "$mod" ) + { + //TODO: division by zero case + log("writing binary cell - %s\n", cstr(cell->type)); + int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool(); + bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool(); + int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); + int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); + + assert(l1_signed == l2_signed); + l1_width = l1_width > output_width ? l1_width : output_width; + l1_width = l1_width > l2_width ? l1_width : l2_width; + l2_width = l2_width > l1_width ? l2_width : l1_width; + + int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width); + + ++line_num; + std::string op = cell_type_translation.at(cell->type); + if(cell->type == "$div" && l1_signed) + op = s_cell_type_translation.at(cell->type); + else if(cell->type == "$mod") { if(l1_signed) op = s_cell_type_translation.at("$modx"); else if(l2_signed) op = s_cell_type_translation.at("$mody"); } - str = stringf ("%d %s %d %d %d", - line_num, op.c_str(), output_width, l1, l2); + str = stringf ("%d %s %d %d %d", line_num, op.c_str(), l1_width, l1, l2); fprintf(f, "%s\n", str.c_str()); + if(output_width < l1_width) { ++line_num; @@ -472,10 +491,58 @@ struct BtorDumper } line_ref[cell->name]=line_num; } + else if(cell->type == "$shr" || cell->type == "$shl" || cell->type == "$sshr" || cell->type == "$sshl") + { + log("writing binary cell - %s\n", cstr(cell->type)); + int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool(); + //bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool(); + int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); + l1_width = pow(2, ceil(log(l1_width)/log(2))); + int l2_width = cell->parameters.at(RTLIL::IdString("\\B_WIDTH")).as_int(); + //assert(l2_width <= ceil(log(l1_width)/log(2)) ); + int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), l1_width); + int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), ceil(log(l1_width)/log(2))); + int cell_output = ++line_num; + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at(cell->type).c_str(), l1_width, l1, l2); + fprintf(f, "%s\n", str.c_str()); + + if(l2_width > ceil(log(l1_width)/log(2))) + { + int extra_width = l2_width - ceil(log(l1_width)/log(2)); + l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), l2_width); + ++line_num; + str = stringf ("%d slice %d %d %d %d;6", line_num, extra_width, l2, l2_width-1, l2_width-extra_width); + fprintf(f, "%s\n", str.c_str()); + ++line_num; + str = stringf ("%d one %d", line_num, extra_width); + fprintf(f, "%s\n", str.c_str()); + int mux = ++line_num; + str = stringf ("%d %s %d %d %d", line_num, cell_type_translation.at("$gt").c_str(), 1, line_num-2, line_num-1); + fprintf(f, "%s\n", str.c_str()); + ++line_num; + str = stringf("%d %s %d", line_num, l1_signed && cell->type == "$sshr" ? "ones":"zero", l1_width); + fprintf(f, "%s\n", str.c_str()); + ++line_num; + str = stringf ("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), l1_width, mux, line_num-1, cell_output); + fprintf(f, "%s\n", str.c_str()); + cell_output = line_num; + } + + if(output_width < l1_width) + { + ++line_num; + str = stringf ("%d slice %d %d %d %d;5", line_num, output_width, cell_output, output_width-1, 0); + fprintf(f, "%s\n", str.c_str()); + cell_output = line_num; + } + line_ref[cell->name] = cell_output; + } else if(cell->type == "$logic_and" || cell->type == "$logic_or")//no direct translation in btor { log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); + assert(output_width == 1); int l1 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\A")), output_width); int l2 = dump_sigspec(&cell->connections.at(RTLIL::IdString("\\B")), output_width); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); @@ -524,6 +591,7 @@ struct BtorDumper //registers else if(cell->type == "$dff" || cell->type == "$adff" || cell->type == "$dffsr") { + //TODO: remodelling fo adff cells log("writing cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\WIDTH")).as_int(); log(" - width is %d\n", output_width); @@ -816,7 +884,8 @@ struct BtorBackend : public Backend { top_module_name = mod_it.first; fprintf(f, "; Generated by %s\n", yosys_version_str); - fprintf(f, "; BTOR Backend developed at FBK\n"); + fprintf(f, "; BTOR Backend developed by Ahmed Irfan \n"); + fprintf(f, "; at Fondazione Bruno Kessler, Trento, Italy\n"); std::vector mod_list; -- cgit v1.2.3 From c347f2825f150451e6fb82d3c1d65015cd5405d8 Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Mon, 20 Jan 2014 10:45:02 +0100 Subject: assert feature --- backends/btor/btor.cc | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 866bfe52..8377b259 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -96,13 +96,16 @@ struct BtorDumper } curr_cell.clear(); cell_type_translation = { + //assert + {"$assert","root"}, //unary {"$not","not"},{"$neg","neg"},{"$reduce_and","redand"}, {"$reduce_or","redor"},{"$reduce_xor","redxor"},{"$reduce_bool","redor"}, //binary {"$and","and"},{"$or","or"},{"$xor","xor"},{"$xnor","xnor"}, {"$shr","srl"},{"$shl","sll"},{"$sshr","sra"},{"$sshl","sll"}, - {"$lt","ult"},{"$le","ulte"},{"$eq","eq"},{"$ne","ne"},{"$gt","ugt"},{"$ge","ugte"}, + {"$lt","ult"},{"$le","ulte"},{"$gt","ugt"},{"$ge","ugte"}, + {"$eq","eq"},{"$eqx","eq"},{"$ne","ne"},{"$nex","ne"}, {"$add","add"},{"$sub","sub"},{"$mul","mul"},{"$mod","urem"},{"$div","udiv"}, //mux {"$mux","cond"}, @@ -365,6 +368,31 @@ struct BtorDumper if(it==std::end(line_ref)) { curr_cell = cell->name; + //assert cell + if(cell->type == "$assert") + { + log("writing assert cell - %s\n", cstr(cell->type)); + const RTLIL::SigSpec* expr = &cell->connections.at(RTLIL::IdString("\\A")); + const RTLIL::SigSpec* en = &cell->connections.at(RTLIL::IdString("\\EN")); + assert(expr->width == 1); + assert(en->width == 1); + int expr_line = dump_sigspec(expr, 1); + int en_line = dump_sigspec(en, 1); + int one_line = ++line_num; + str = stringf("%d one 1", line_num); + fprintf(f, "%s\n", str.c_str()); + ++line_num; + str = stringf("%d %s %d %d %d", line_num, cell_type_translation.at("$eq").c_str(), 1, en_line, one_line); + fprintf(f, "%s\n", str.c_str()); + ++line_num; + str = stringf("%d %s %d %d %d %d", line_num, cell_type_translation.at("$mux").c_str(), 1, line_num-1, + expr_line, one_line); + fprintf(f, "%s\n", str.c_str()); + int cell_line = ++line_num; + str = stringf("%d %s %d %d", line_num, cell_type_translation.at("$assert").c_str(), 1, line_num-1); + fprintf(f, "%s\n", str.c_str()); + line_ref[cell->name]=cell_line; + } //unary cells if(cell->type == "$not" || cell->type == "$neg" || cell->type == "$pos" || cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" || cell->type == "$reduce_bool") @@ -417,12 +445,13 @@ struct BtorDumper } //binary cells else if(cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || - cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || - cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt" ) + cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || + cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt" ) { log("writing binary cell - %s\n", cstr(cell->type)); int output_width = cell->parameters.at(RTLIL::IdString("\\Y_WIDTH")).as_int(); - assert(!(cell->type == "$eq" || cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt") || output_width == 1); + assert(!(cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || + cell->type == "$ge" || cell->type == "$gt") || output_width == 1); bool l1_signed = cell->parameters.at(RTLIL::IdString("\\A_SIGNED")).as_bool(); bool l2_signed = cell->parameters.at(RTLIL::IdString("\\B_SIGNED")).as_bool(); int l1_width = cell->parameters.at(RTLIL::IdString("\\A_WIDTH")).as_int(); @@ -439,7 +468,8 @@ struct BtorDumper ++line_num; std::string op = cell_type_translation.at(cell->type); if(cell->type == "$lt" || cell->type == "$le" || - cell->type == "$eq" || cell->type == "$ne" || cell->type == "$ge" || cell->type == "$gt") + cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || + cell->type == "$ge" || cell->type == "$gt") { if(l1_signed) op = s_cell_type_translation.at(cell->type); @@ -717,7 +747,7 @@ struct BtorDumper { output_sig = &cell->connections.at(RTLIL::IdString("\\DATA")); } - else if(cell->type == "$memwr") + else if(cell->type == "$memwr" || cell->type == "$assert") { //no output } @@ -884,9 +914,10 @@ struct BtorBackend : public Backend { top_module_name = mod_it.first; fprintf(f, "; Generated by %s\n", yosys_version_str); - fprintf(f, "; BTOR Backend developed by Ahmed Irfan \n"); - fprintf(f, "; at Fondazione Bruno Kessler, Trento, Italy\n"); - + fprintf(f, "; %s developed and maintained by Clifford Wolf \n", yosys_version_str); + fprintf(f, "; BTOR Backend developed by Ahmed Irfan - Fondazione Bruno Kessler, Trento, Italy\n"); + fprintf(f, ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"); + std::vector mod_list; for (auto module_it : design->modules) -- cgit v1.2.3 From aa3cb20e1ecb268ea2a663916518c311ceb60808 Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Mon, 20 Jan 2014 18:35:52 +0100 Subject: slice bug corrected --- backends/btor/btor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 8377b259..7e36db9f 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -275,7 +275,7 @@ struct BtorDumper assert(wire_line_num>0); ++line_num; str = stringf("%d slice %d %d %d %d;2", line_num, chunk->width, wire_line_num, - chunk->wire->width - chunk->offset - 1, chunk->wire->width - chunk->offset - chunk->width); + chunk->width + chunk->offset - 1, chunk->offset); fprintf(f, "%s\n", str.c_str()); l = line_num; } -- cgit v1.2.3 From 6804edd5d4cc6cca1fbdf7cf6db236d0fcd46538 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 24 Jan 2014 15:48:07 +0100 Subject: Moved btor scripts to backends/btor/ --- backends/btor/btor.ys | 15 +++++++++++++++ backends/btor/verilog2btor.sh | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 backends/btor/btor.ys create mode 100755 backends/btor/verilog2btor.sh (limited to 'backends') diff --git a/backends/btor/btor.ys b/backends/btor/btor.ys new file mode 100644 index 00000000..7f3882b5 --- /dev/null +++ b/backends/btor/btor.ys @@ -0,0 +1,15 @@ +proc; +opt; opt_const -mux_undef; opt; +rename -hide;;; +#converting pmux to mux +techmap -map techlibs/common/pmux2mux.v;; +memory -nomap;; +#flatten design +flatten;; +#converting asyn memory write to syn memory +memory_unpack; +#cell output to be a single wire +splitnets -driver; +setundef -zero -undriven; +opt;;; + diff --git a/backends/btor/verilog2btor.sh b/backends/btor/verilog2btor.sh new file mode 100755 index 00000000..ef0134e0 --- /dev/null +++ b/backends/btor/verilog2btor.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# +# Script to writing btor from verilog design +# + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 input.v output.btor top-module-name" >&2 + exit 1 +fi +if ! [ -e "$1" ]; then + echo "$1 not found" >&2 + exit 1 +fi + +FULL_PATH=$(readlink -f $1) +DIR=$(dirname $FULL_PATH) + +./yosys -q -p " +read_verilog $1; +hierarchy -top $3; +hierarchy -libdir $DIR; +hierarchy -check; +proc; +opt; opt_const -mux_undef; opt; +rename -hide;;; +techmap -map $YOSYS_HOME/techlibs/common/pmux2mux.v;; +memory -nomap;; +flatten;; +memory_unpack; +splitnets -driver; +setundef -zero -undriven; +opt;;; +write_btor $2;" + -- cgit v1.2.3 From 210dda286f234db1c9a25acb6ca0be6e3c159358 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 24 Jan 2014 15:52:16 +0100 Subject: Use techmap -share_map in btor scripts --- backends/btor/btor.ys | 2 +- backends/btor/verilog2btor.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/btor/btor.ys b/backends/btor/btor.ys index 7f3882b5..20bce87e 100644 --- a/backends/btor/btor.ys +++ b/backends/btor/btor.ys @@ -2,7 +2,7 @@ proc; opt; opt_const -mux_undef; opt; rename -hide;;; #converting pmux to mux -techmap -map techlibs/common/pmux2mux.v;; +techmap -share_map pmux2mux.v;; memory -nomap;; #flatten design flatten;; diff --git a/backends/btor/verilog2btor.sh b/backends/btor/verilog2btor.sh index ef0134e0..a2f9ebc7 100755 --- a/backends/btor/verilog2btor.sh +++ b/backends/btor/verilog2btor.sh @@ -24,7 +24,7 @@ hierarchy -check; proc; opt; opt_const -mux_undef; opt; rename -hide;;; -techmap -map $YOSYS_HOME/techlibs/common/pmux2mux.v;; +techmap -share_map pmux2mux.v;; memory -nomap;; flatten;; memory_unpack; -- cgit v1.2.3 From 2e44b1b73a8b16a2a87e56bd887dae9150521c62 Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Fri, 24 Jan 2014 17:35:42 +0100 Subject: merged clifford changes + removed regex --- backends/btor/btor.cc | 78 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 26 deletions(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 7e36db9f..965d4aa4 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -95,29 +95,56 @@ struct BtorDumper inter_wire_map[it->first].clear(); } curr_cell.clear(); - cell_type_translation = { - //assert - {"$assert","root"}, - //unary - {"$not","not"},{"$neg","neg"},{"$reduce_and","redand"}, - {"$reduce_or","redor"},{"$reduce_xor","redxor"},{"$reduce_bool","redor"}, - //binary - {"$and","and"},{"$or","or"},{"$xor","xor"},{"$xnor","xnor"}, - {"$shr","srl"},{"$shl","sll"},{"$sshr","sra"},{"$sshl","sll"}, - {"$lt","ult"},{"$le","ulte"},{"$gt","ugt"},{"$ge","ugte"}, - {"$eq","eq"},{"$eqx","eq"},{"$ne","ne"},{"$nex","ne"}, - {"$add","add"},{"$sub","sub"},{"$mul","mul"},{"$mod","urem"},{"$div","udiv"}, - //mux - {"$mux","cond"}, - //reg - {"$dff","next"},{"$adff","next"},{"$dffsr","next"} - //memories - }; - s_cell_type_translation = { - //binary - {"$modx","srem"},{"$mody","smod"},{"$div","sdiv"}, - {"$lt","slt"},{"$le","slte"},{"$gt","sgt"},{"$ge","sgte"} - }; + //assert + cell_type_translation["$assert"] = "root"; + //unary + cell_type_translation["$not"] = "not"; + cell_type_translation["$neg"] = "neg"; + cell_type_translation["$reduce_and"] = "redand"; + cell_type_translation["$reduce_or"] = "redor"; + cell_type_translation["$reduce_xor"] = "redxor"; + cell_type_translation["$reduce_bool"] = "redor"; + //binary + cell_type_translation["$and"] = "and"; + cell_type_translation["$or"] = "or"; + cell_type_translation["$xor"] = "xor"; + cell_type_translation["$xnor"] = "xnor"; + cell_type_translation["$shr"] = "srl"; + cell_type_translation["$shl"] = "sll"; + cell_type_translation["$sshr"] = "sra"; + cell_type_translation["$sshl"] = "sll"; + cell_type_translation["$lt"] = "ult"; + cell_type_translation["$le"] = "ulte"; + cell_type_translation["$gt"] = "ugt"; + cell_type_translation["$ge"] = "ugte"; + cell_type_translation["$eq"] = "eq"; + cell_type_translation["$eqx"] = "eq"; + cell_type_translation["$ne"] = "ne"; + cell_type_translation["$nex"] = "ne"; + cell_type_translation["$add"] = "add"; + cell_type_translation["$sub"] = "sub"; + cell_type_translation["$mul"] = "mul"; + cell_type_translation["$mod"] = "urem"; + cell_type_translation["$div"] = "udiv"; + //mux + cell_type_translation["$mux"] = "cond"; + //reg + cell_type_translation["$dff"] = "next"; + cell_type_translation["$adff"] = "next"; + cell_type_translation["$dffsr"] = "next"; + //memories + //nothing here + + //signed cell type translation + //binary + s_cell_type_translation["$modx"] = "srem"; + s_cell_type_translation["$mody"] = "smod"; + s_cell_type_translation["$div"] = "sdiv"; + s_cell_type_translation["$lt"] = "slt"; + s_cell_type_translation["$le"] = "slte"; + s_cell_type_translation["$gt"] = "sgt"; + s_cell_type_translation["$ge"] = "sgte"; + } std::vector cstr_buf; @@ -823,15 +850,14 @@ struct BtorDumper log("writing input\n"); std::map inputs, outputs; std::vector safety; - std::regex safety_regex("(safety)(.*)"); - + for (auto &wire_it : module->wires) { RTLIL::Wire *wire = wire_it.second; if (wire->port_input) inputs[wire->port_id] = wire; if (wire->port_output) { outputs[wire->port_id] = wire; - if (std::regex_match(cstr(wire->name), safety_regex ) ) + if (wire->name.find("safety") != std::string::npos ) safety.push_back(wire); } } -- cgit v1.2.3 From 137742786e0409a43f9d69177f2929d9226dad8e Mon Sep 17 00:00:00 2001 From: Ahmed Irfan Date: Fri, 24 Jan 2014 18:04:37 +0100 Subject: removed regex include --- backends/btor/btor.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 965d4aa4..f5babebc 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -30,7 +30,6 @@ #include #include #include -#include struct BtorDumperConfig { -- cgit v1.2.3