2014-01-03 03:52:44 -06:00
/*
* yosys - - Yosys Open SYnthesis Suite
*
* Copyright ( C ) 2012 Clifford Wolf < clifford @ clifford . at >
2014-01-17 12:32:35 -06:00
* Copyright ( C ) 2014 Ahmed Irfan < irfan @ fbk . eu >
2015-07-02 04:14:30 -05:00
*
2014-01-03 03:52:44 -06:00
* 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 .
2015-07-02 04:14:30 -05:00
*
2014-01-03 03:52:44 -06:00
* 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 .
*
*/
2015-07-02 04:14:30 -05:00
// [[CITE]] BTOR: Bit-Precise Modelling of Word-Level Problems for Model Checking
2014-01-03 03:52:44 -06:00
// 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 <string>
# include <math.h>
2014-09-27 09:17:53 -05:00
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
2014-01-03 03:52:44 -06:00
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 ) { }
} ;
2014-01-14 05:03:53 -06:00
struct WireInfo
{
RTLIL : : IdString cell_name ;
2014-07-22 13:58:44 -05:00
const RTLIL : : SigChunk * chunk ;
2014-01-14 05:03:53 -06:00
2014-07-22 13:58:44 -05:00
WireInfo ( RTLIL : : IdString c , const RTLIL : : SigChunk * ch ) : cell_name ( c ) , chunk ( ch ) { }
2014-01-14 05:03:53 -06:00
} ;
struct WireInfoOrder
{
bool operator ( ) ( const WireInfo & x , const WireInfo & y )
{
return x . chunk < y . chunk ;
}
} ;
2014-01-03 03:52:44 -06:00
struct BtorDumper
{
2014-08-23 06:54:21 -05:00
std : : ostream & f ;
2014-01-03 03:52:44 -06:00
RTLIL : : Module * module ;
RTLIL : : Design * design ;
BtorDumperConfig * config ;
CellTypes ct ;
2014-01-14 05:03:53 -06:00
SigMap sigmap ;
std : : map < RTLIL : : IdString , std : : set < WireInfo , WireInfoOrder > > inter_wire_map ; //<wire, dependency list> for maping the intermediate wires that are output of some cell
2014-01-03 03:52:44 -06:00
std : : map < RTLIL : : IdString , int > line_ref ; //mapping of ids to line_num of the btor file
2014-01-14 05:03:53 -06:00
std : : map < RTLIL : : SigSpec , int > sig_ref ; //mapping of sigspec to the line_num of the btor file
2014-01-03 03:52:44 -06:00
int line_num ; //last line number of btor file
2014-01-14 05:03:53 -06:00
std : : string str ; //temp string for writing file
2015-07-02 04:14:30 -05:00
std : : map < RTLIL : : IdString , bool > basic_wires ; //input wires and registers
2014-01-14 05:03:53 -06:00
RTLIL : : IdString curr_cell ; //current cell being dumped
std : : map < std : : string , std : : string > cell_type_translation , s_cell_type_translation ; //RTLIL to BTOR translation
2015-07-02 04:14:30 -05:00
std : : map < int , std : : set < std : : pair < int , int > > > mem_next ; // memory (line_number)'s set of condition and write
2015-08-05 15:11:10 -05:00
BtorDumper ( std : : ostream & f , RTLIL : : Module * module , RTLIL : : Design * design , BtorDumperConfig * config ) :
f ( f ) , module ( module ) , design ( design ) , config ( config ) , ct ( design ) , sigmap ( module )
2014-01-03 03:52:44 -06:00
{
line_num = 0 ;
str . clear ( ) ;
2014-07-26 18:49:51 -05:00
for ( auto it = module - > wires_ . begin ( ) ; it ! = module - > wires_ . end ( ) ; + + it )
2014-01-03 03:52:44 -06:00
{
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 ( ) ;
2014-01-24 10:35:42 -06:00
//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 " ;
2014-07-29 07:42:33 -05:00
cell_type_translation [ " $shift " ] = " srl " ;
cell_type_translation [ " $shiftx " ] = " srl " ;
2014-01-24 10:35:42 -06:00
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
2014-02-11 06:06:01 -06:00
//slice
cell_type_translation [ " $slice " ] = " slice " ;
//concat
cell_type_translation [ " $concat " ] = " concat " ;
2014-01-24 10:35:42 -06:00
2015-07-02 04:14:30 -05:00
//signed cell type translation
2014-01-24 10:35:42 -06:00
//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 " ;
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
}
2015-07-02 04:14:30 -05:00
2015-06-11 06:39:49 -05:00
vector < shared_str > cstr_buf ;
2014-01-03 03:52:44 -06:00
const char * cstr ( const RTLIL : : IdString id )
{
str = RTLIL : : unescape_id ( id ) ;
2014-01-14 05:03:53 -06:00
for ( size_t i = 0 ; i < str . size ( ) ; + + i )
2014-01-03 03:52:44 -06:00
if ( str [ i ] = = ' # ' | | str [ i ] = = ' = ' )
str [ i ] = ' ? ' ;
cstr_buf . push_back ( str ) ;
return cstr_buf . back ( ) . c_str ( ) ;
}
2015-07-02 04:14:30 -05:00
2014-01-14 05:03:53 -06:00
int dump_wire ( RTLIL : : Wire * wire )
2014-01-03 03:52:44 -06:00
{
if ( basic_wires [ wire - > name ] )
2015-07-02 04:14:30 -05:00
{
2014-01-14 05:03:53 -06:00
log ( " writing wire %s \n " , cstr ( wire - > name ) ) ;
2014-01-03 03:52:44 -06:00
auto it = line_ref . find ( wire - > name ) ;
if ( it = = std : : end ( line_ref ) )
{
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
line_ref [ wire - > name ] = line_num ;
2014-01-03 03:52:44 -06:00
str = stringf ( " %d var %d %s " , line_num , wire - > width , cstr ( wire - > name ) ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-03 03:52:44 -06:00
return line_num ;
}
else return it - > second ;
}
2014-01-14 05:03:53 -06:00
else // case when the wire is not basic wire
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
log ( " case of non-basic wire - %s \n " , cstr ( wire - > name ) ) ;
2014-01-03 03:52:44 -06:00
auto it = line_ref . find ( wire - > name ) ;
if ( it = = std : : end ( line_ref ) )
{
2014-01-14 05:03:53 -06:00
std : : set < WireInfo , WireInfoOrder > & 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 )
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
RTLIL : : IdString cell_id = dep_set_it - > cell_name ;
if ( cell_id = = curr_cell )
break ;
log ( " -- found cell %s \n " , cstr ( cell_id ) ) ;
2014-07-26 18:51:45 -05:00
RTLIL : : Cell * cell = module - > cells_ . at ( cell_id ) ;
2014-07-26 08:57:57 -05:00
const RTLIL : : SigSpec * cell_output = get_cell_output ( cell ) ;
2015-07-02 04:14:30 -05:00
int cell_line = dump_cell ( cell ) ;
2014-01-14 05:03:53 -06:00
2014-07-22 13:15:14 -05:00
if ( dep_set . size ( ) = = 1 & & wire - > width = = cell_output - > size ( ) )
2014-01-14 05:03:53 -06:00
{
wire_line = cell_line ;
break ;
}
else
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
int prev_wire_line = 0 ; //previously dumped wire line
2014-01-16 13:16:01 -06:00
int start_bit = 0 ;
2014-07-22 13:15:14 -05:00
for ( unsigned j = 0 ; j < cell_output - > chunks ( ) . size ( ) ; + + j )
2014-01-03 03:52:44 -06:00
{
2014-07-25 07:23:31 -05:00
start_bit + = cell_output - > chunks ( ) . at ( j ) . width ;
if ( cell_output - > chunks ( ) . at ( j ) . wire - > name = = wire - > name )
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
prev_wire_line = wire_line ;
wire_line = + + line_num ;
2014-07-25 07:23:31 -05:00
str = stringf ( " %d slice %d %d %d %d;1 " , line_num , cell_output - > chunks ( ) . at ( j ) . width ,
cell_line , start_bit - 1 , start_bit - cell_output - > chunks ( ) . at ( j ) . width ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-07-25 07:23:31 -05:00
wire_width + = cell_output - > chunks ( ) . at ( j ) . width ;
2014-01-14 05:03:53 -06:00
if ( prev_wire_line ! = 0 )
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-01-16 13:16:01 -06:00
str = stringf ( " %d concat %d %d %d " , line_num , wire_width , wire_line , prev_wire_line ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
wire_line = line_num ;
2014-01-03 03:52:44 -06:00
}
}
}
}
}
2014-01-14 05:03:53 -06:00
if ( dep_set . size ( ) = = 0 )
{
2015-07-02 04:14:30 -05:00
log ( " - checking sigmap \n " ) ;
2014-01-14 05:03:53 -06:00
RTLIL : : SigSpec s = RTLIL : : SigSpec ( wire ) ;
2014-07-22 13:15:14 -05:00
wire_line = dump_sigspec ( & s , s . size ( ) ) ;
2014-01-14 05:03:53 -06:00
line_ref [ wire - > name ] = wire_line ;
}
line_ref [ wire - > name ] = wire_line ;
return wire_line ;
2014-01-03 03:52:44 -06:00
}
2015-07-02 04:14:30 -05:00
else
2014-01-03 03:52:44 -06:00
{
2015-07-02 04:14:30 -05:00
log ( " -- already processed wire \n " ) ;
2014-01-03 03:52:44 -06:00
return it - > second ;
}
}
2014-03-07 08:56:10 -06:00
log_abort ( ) ;
2014-01-14 05:03:53 -06:00
return - 1 ;
2014-01-03 03:52:44 -06:00
}
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
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 ) )
{
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-01-03 03:52:44 -06:00
int address_bits = ceil ( log ( memory - > size ) / log ( 2 ) ) ;
str = stringf ( " %d array %d %d " , line_num , memory - > width , address_bits ) ;
2015-07-02 04:14:30 -05:00
line_ref [ memory - > name ] = line_num ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-03 03:52:44 -06:00
return line_num ;
}
else return it - > second ;
}
2015-04-03 09:41:50 -05:00
int dump_memory_next ( const RTLIL : : Memory * memory )
{
auto mem_it = line_ref . find ( memory - > name ) ;
int address_bits = ceil ( log ( memory - > size ) / log ( 2 ) ) ;
if ( mem_it = = std : : end ( line_ref ) )
{
log ( " can not write next of a memory that is not dumped yet \n " ) ;
log_abort ( ) ;
}
else
{
auto acond_list_it = mem_next . find ( mem_it - > second ) ;
if ( acond_list_it ! = std : : end ( mem_next ) )
{
std : : set < std : : pair < int , int > > & cond_list = acond_list_it - > second ;
if ( cond_list . empty ( ) )
{
return 0 ;
}
auto it = cond_list . begin ( ) ;
+ + line_num ;
str = stringf ( " %d acond %d %d %d %d %d " , line_num , memory - > width , address_bits , it - > first , it - > second , mem_it - > second ) ;
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
+ + it ;
for ( ; it ! = cond_list . end ( ) ; + + it )
{
+ + line_num ;
str = stringf ( " %d acond %d %d %d %d %d " , line_num , memory - > width , address_bits , it - > first , it - > second , line_num - 1 ) ;
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
}
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d anext %d %d %d %d " , line_num , memory - > width , address_bits , mem_it - > second , line_num - 1 ) ;
2015-04-03 09:41:50 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
return 1 ;
}
return 0 ;
}
}
2014-01-03 03:52:44 -06:00
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 ( ) ;
2014-01-15 10:36:33 -06:00
//if(offset > 0)
2014-01-03 03:52:44 -06:00
data_str = data_str . substr ( offset , width ) ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-01-03 03:52:44 -06:00
str = stringf ( " %d const %d %s " , line_num , width , data_str . c_str ( ) ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-03 03:52:44 -06:00
return line_num ;
}
else
2015-07-02 04:14:30 -05:00
log ( " writing const error \n " ) ;
2014-03-07 08:56:10 -06:00
log_abort ( ) ;
2014-01-03 03:52:44 -06:00
return - 1 ;
}
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
int dump_sigchunk ( const RTLIL : : SigChunk * chunk )
{
log ( " writing sigchunk \n " ) ;
int l = - 1 ;
if ( chunk - > wire = = NULL )
{
2014-09-01 04:36:02 -05:00
RTLIL : : Const data_const ( chunk - > data ) ;
2015-07-02 04:14:30 -05:00
l = dump_const ( & data_const , chunk - > width , chunk - > offset ) ;
2014-01-03 03:52:44 -06:00
}
else
{
if ( chunk - > width = = chunk - > wire - > width & & chunk - > offset = = 0 )
l = dump_wire ( chunk - > wire ) ;
2015-07-02 04:14:30 -05:00
else
2014-01-03 03:52:44 -06:00
{
2014-01-15 10:36:33 -06:00
int wire_line_num = dump_wire ( chunk - > wire ) ;
2014-03-07 08:56:10 -06:00
log_assert ( wire_line_num > 0 ) ;
2014-01-15 10:36:33 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d slice %d %d %d %d;2 " , line_num , chunk - > width , wire_line_num ,
2014-01-20 11:35:52 -06:00
chunk - > width + chunk - > offset - 1 , chunk - > offset ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2015-07-02 04:14:30 -05:00
l = line_num ;
2014-01-03 03:52:44 -06:00
}
}
return l ;
}
int dump_sigspec ( const RTLIL : : SigSpec * sig , int expected_width )
{
log ( " writing sigspec \n " ) ;
2014-01-14 05:03:53 -06:00
RTLIL : : SigSpec s = sigmap ( * sig ) ;
2014-01-03 03:52:44 -06:00
int l = - 1 ;
2014-01-14 05:03:53 -06:00
auto it = sig_ref . find ( s ) ;
if ( it = = std : : end ( sig_ref ) )
2014-01-03 03:52:44 -06:00
{
2014-07-25 07:23:31 -05:00
if ( s . is_chunk ( ) )
2014-01-03 03:52:44 -06:00
{
2014-07-25 07:23:31 -05:00
l = dump_sigchunk ( & s . chunks ( ) . front ( ) ) ;
2015-07-02 04:14:30 -05:00
}
else
2014-01-14 05:03:53 -06:00
{
int l1 , l2 , w1 , w2 ;
2014-07-25 07:23:31 -05:00
l1 = dump_sigchunk ( & s . chunks ( ) . front ( ) ) ;
2014-03-07 08:56:10 -06:00
log_assert ( l1 > 0 ) ;
2014-07-25 07:23:31 -05:00
w1 = s . chunks ( ) . front ( ) . width ;
2014-07-22 13:15:14 -05:00
for ( unsigned i = 1 ; i < s . chunks ( ) . size ( ) ; + + i )
2014-01-14 05:03:53 -06:00
{
2014-07-25 07:23:31 -05:00
l2 = dump_sigchunk ( & s . chunks ( ) . at ( i ) ) ;
2014-03-07 08:56:10 -06:00
log_assert ( l2 > 0 ) ;
2014-07-25 07:23:31 -05:00
w2 = s . chunks ( ) . at ( i ) . width ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
str = stringf ( " %d concat %d %d %d " , line_num , w1 + w2 , l2 , l1 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
l1 = line_num ;
w1 + = w2 ;
}
l = line_num ;
2014-01-03 03:52:44 -06:00
}
2014-01-14 05:03:53 -06:00
sig_ref [ s ] = l ;
2014-01-03 03:52:44 -06:00
}
2014-01-14 05:03:53 -06:00
else
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
l = it - > second ;
}
2015-07-02 04:14:30 -05:00
2014-07-22 13:15:14 -05:00
if ( expected_width ! = s . size ( ) )
2014-01-14 05:03:53 -06:00
{
log ( " - changing width of sigspec \n " ) ;
2014-02-11 06:06:01 -06:00
//TODO: this block may not be needed anymore, due to explicit type conversion by "splice" command
2014-07-22 13:15:14 -05:00
if ( expected_width > s . size ( ) )
2014-02-11 06:06:01 -06:00
{
//TODO: case the signal is signed
+ + line_num ;
2014-07-22 13:15:14 -05:00
str = stringf ( " %d zero %d " , line_num , expected_width - s . size ( ) ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-02-11 06:06:01 -06:00
+ + line_num ;
str = stringf ( " %d concat %d %d %d " , line_num , expected_width , line_num - 1 , l ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-02-11 06:06:01 -06:00
l = line_num ;
2014-01-14 05:03:53 -06:00
}
2014-07-22 13:15:14 -05:00
else if ( expected_width < s . size ( ) )
2014-01-14 05:03:53 -06:00
{
2014-02-11 06:06:01 -06:00
+ + line_num ;
str = stringf ( " %d slice %d %d %d %d;3 " , line_num , expected_width , l , expected_width - 1 , 0 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-02-11 06:06:01 -06:00
l = line_num ;
}
2014-01-03 03:52:44 -06:00
}
2014-03-07 08:56:10 -06:00
log_assert ( l > 0 ) ;
2014-01-03 03:52:44 -06:00
return l ;
}
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
int dump_cell ( const RTLIL : : Cell * cell )
{
auto it = line_ref . find ( cell - > name ) ;
if ( it = = std : : end ( line_ref ) )
{
curr_cell = cell - > name ;
2014-01-20 03:45:02 -06:00
//assert cell
if ( cell - > type = = " $assert " )
{
log ( " writing assert cell - %s \n " , cstr ( cell - > type ) ) ;
2014-07-31 09:38:54 -05:00
const RTLIL : : SigSpec * expr = & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) ;
const RTLIL : : SigSpec * en = & cell - > getPort ( RTLIL : : IdString ( " \\ EN " ) ) ;
2014-07-22 13:15:14 -05:00
log_assert ( expr - > size ( ) = = 1 ) ;
log_assert ( en - > size ( ) = = 1 ) ;
2014-01-20 03:45:02 -06:00
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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-20 03:45:02 -06:00
+ + line_num ;
str = stringf ( " %d %s %d %d %d " , line_num , cell_type_translation . at ( " $eq " ) . c_str ( ) , 1 , en_line , one_line ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-20 03:45:02 -06:00
+ + 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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-20 03:45:02 -06:00
int cell_line = + + line_num ;
2014-01-25 12:33:24 -06:00
str = stringf ( " %d %s %d %d " , line_num , cell_type_translation . at ( " $assert " ) . c_str ( ) , 1 , - 1 * ( line_num - 1 ) ) ;
//multiplying the line number with -1, which means logical negation
//the reason for negative sign is that the properties in btor are given as "negation of the original property"
//bug identified by bobosoft
//http://www.reddit.com/r/yosys/comments/1w3xig/btor_backend_bug/
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-20 03:45:02 -06:00
line_ref [ cell - > name ] = cell_line ;
}
2014-01-03 03:52:44 -06:00
//unary cells
2014-09-18 04:15:46 -05:00
else if ( cell - > type = = " $not " | | cell - > type = = " $neg " | | cell - > type = = " $pos " | | cell - > type = = " $reduce_and " | |
2014-01-03 03:52:44 -06:00
cell - > type = = " $reduce_or " | | cell - > type = = " $reduce_xor " | | cell - > type = = " $reduce_bool " )
{
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 ( ) ;
2014-01-17 12:32:35 -06:00
w = w > output_width ? w : output_width ; //padding of w
2015-07-02 04:14:30 -05:00
int l = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , w ) ;
2014-01-14 05:03:53 -06:00
int cell_line = l ;
if ( cell - > type ! = " $pos " )
2015-07-02 04:14:30 -05:00
{
2014-01-14 05:03:53 -06:00
cell_line = + + line_num ;
bool reduced = ( cell - > type = = " $not " | | cell - > type = = " $neg " ) ? false : true ;
2014-08-02 06:11:01 -05:00
str = stringf ( " %d %s %d %d " , cell_line , cell_type_translation . at ( cell - > type . str ( ) ) . c_str ( ) , reduced ? output_width : w , l ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
}
if ( output_width < w & & ( cell - > type = = " $not " | | cell - > type = = " $neg " | | cell - > type = = " $pos " ) )
{
+ + line_num ;
2014-01-15 10:36:33 -06:00
str = stringf ( " %d slice %d %d %d %d;4 " , line_num , output_width , cell_line , output_width - 1 , 0 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
cell_line = line_num ;
2015-07-02 04:14:30 -05:00
}
2014-01-14 05:03:53 -06:00
line_ref [ cell - > name ] = cell_line ;
2014-01-03 03:52:44 -06:00
}
else if ( cell - > type = = " $reduce_xnor " | | cell - > type = = " $logic_not " ) //no direct translation in btor
{
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 ( ) ;
2014-03-07 08:56:10 -06:00
log_assert ( output_width = = 1 ) ;
2014-07-31 09:38:54 -05:00
int l = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , w ) ;
2014-01-14 05:03:53 -06:00
if ( cell - > type = = " $logic_not " & & w > 1 )
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-01-03 03:52:44 -06:00
str = stringf ( " %d %s %d %d " , line_num , cell_type_translation . at ( " $reduce_or " ) . c_str ( ) , output_width , l ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-03 03:52:44 -06:00
}
else if ( cell - > type = = " $reduce_xnor " )
{
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-01-03 03:52:44 -06:00
str = stringf ( " %d %s %d %d " , line_num , cell_type_translation . at ( " $reduce_xor " ) . c_str ( ) , output_width , l ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2015-07-02 04:14:30 -05:00
}
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-09-18 04:15:46 -05:00
str = stringf ( " %d %s %d %d " , line_num , cell_type_translation . at ( " $not " ) . c_str ( ) , output_width , l ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
line_ref [ cell - > name ] = line_num ;
2014-01-03 03:52:44 -06:00
}
//binary cells
else if ( cell - > type = = " $and " | | cell - > type = = " $or " | | cell - > type = = " $xor " | | cell - > type = = " $xnor " | |
2015-07-02 04:14:30 -05:00
cell - > type = = " $lt " | | cell - > type = = " $le " | | cell - > type = = " $eq " | | cell - > type = = " $ne " | |
2014-01-20 03:45:02 -06:00
cell - > type = = " $eqx " | | cell - > type = = " $nex " | | cell - > type = = " $ge " | | cell - > type = = " $gt " )
2014-01-03 03:52:44 -06:00
{
log ( " writing binary cell - %s \n " , cstr ( cell - > type ) ) ;
int output_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ Y_WIDTH " ) ) . as_int ( ) ;
2014-03-07 08:56:10 -06:00
log_assert ( ! ( cell - > type = = " $eq " | | cell - > type = = " $ne " | | cell - > type = = " $eqx " | | cell - > type = = " $nex " | |
2014-01-20 03:45:02 -06:00
cell - > type = = " $ge " | | cell - > type = = " $gt " ) | | output_width = = 1 ) ;
2014-01-14 05:03:53 -06:00
bool l1_signed = cell - > parameters . at ( RTLIL : : IdString ( " \\ A_SIGNED " ) ) . as_bool ( ) ;
2015-01-24 05:16:46 -06:00
bool l2_signed YS_ATTRIBUTE ( unused ) = cell - > parameters . at ( RTLIL : : IdString ( " \\ B_SIGNED " ) ) . as_bool ( ) ;
2014-01-14 05:03:53 -06:00
int l1_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ A_WIDTH " ) ) . as_int ( ) ;
2015-08-05 15:11:10 -05:00
int l2_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ B_WIDTH " ) ) . as_int ( ) ;
2015-07-02 04:14:30 -05:00
2014-02-06 15:49:14 -06:00
log_assert ( l1_signed = = l2_signed ) ;
2015-07-02 04:14:30 -05:00
l1_width = l1_width > output_width ? l1_width : output_width ;
2014-01-17 12:32:35 -06:00
l1_width = l1_width > l2_width ? l1_width : l2_width ;
l2_width = l2_width > l1_width ? l2_width : l1_width ;
2014-07-31 09:38:54 -05:00
int l1 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , l1_width ) ;
int l2 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) , l2_width ) ;
2015-07-02 04:14:30 -05:00
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-08-02 06:11:01 -05:00
std : : string op = cell_type_translation . at ( cell - > type . str ( ) ) ;
2014-01-17 12:32:35 -06:00
if ( cell - > type = = " $lt " | | cell - > type = = " $le " | |
2014-01-20 03:45:02 -06:00
cell - > type = = " $eq " | | cell - > type = = " $ne " | | cell - > type = = " $eqx " | | cell - > type = = " $nex " | |
cell - > type = = " $ge " | | cell - > type = = " $gt " )
2014-01-14 05:03:53 -06:00
{
if ( l1_signed )
2014-08-02 06:11:01 -05:00
op = s_cell_type_translation . at ( cell - > type . str ( ) ) ;
2014-01-14 05:03:53 -06:00
}
2015-07-02 04:14:30 -05:00
2014-01-17 12:32:35 -06:00
str = stringf ( " %d %s %d %d %d " , line_num , op . c_str ( ) , output_width , l1 , l2 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
line_ref [ cell - > name ] = line_num ;
}
2015-07-02 04:14:30 -05:00
else if ( cell - > type = = " $add " | | cell - > type = = " $sub " | | cell - > type = = " $mul " | | cell - > type = = " $div " | |
2014-01-17 12:32:35 -06:00
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 ( ) ;
2015-08-05 15:11:10 -05:00
int l2_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ B_WIDTH " ) ) . as_int ( ) ;
2015-07-02 04:14:30 -05:00
2014-03-07 08:56:10 -06:00
log_assert ( l1_signed = = l2_signed ) ;
2015-07-02 04:14:30 -05:00
l1_width = l1_width > output_width ? l1_width : output_width ;
2014-01-17 12:32:35 -06:00
l1_width = l1_width > l2_width ? l1_width : l2_width ;
l2_width = l2_width > l1_width ? l2_width : l1_width ;
2014-07-31 09:38:54 -05:00
int l1 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , l1_width ) ;
int l2 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) , l2_width ) ;
2015-07-02 04:14:30 -05:00
2014-01-17 12:32:35 -06:00
+ + line_num ;
2014-08-02 06:11:01 -05:00
std : : string op = cell_type_translation . at ( cell - > type . str ( ) ) ;
2014-01-17 12:32:35 -06:00
if ( cell - > type = = " $div " & & l1_signed )
2014-08-02 06:11:01 -05:00
op = s_cell_type_translation . at ( cell - > type . str ( ) ) ;
2014-01-17 12:32:35 -06:00
else if ( cell - > type = = " $mod " )
2014-01-14 05:03:53 -06:00
{
if ( l1_signed )
op = s_cell_type_translation . at ( " $modx " ) ;
else if ( l2_signed )
op = s_cell_type_translation . at ( " $mody " ) ;
}
2014-01-17 12:32:35 -06:00
str = stringf ( " %d %s %d %d %d " , line_num , op . c_str ( ) , l1_width , l1 , l2 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
2014-01-14 05:03:53 -06:00
if ( output_width < l1_width )
{
+ + line_num ;
2014-01-15 10:36:33 -06:00
str = stringf ( " %d slice %d %d %d %d;5 " , line_num , output_width , line_num - 1 , output_width - 1 , 0 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
}
line_ref [ cell - > name ] = line_num ;
2014-01-03 03:52:44 -06:00
}
2014-07-29 07:42:33 -05:00
else if ( cell - > type = = " $shr " | | cell - > type = = " $shl " | | cell - > type = = " $sshr " | | cell - > type = = " $sshl " | | cell - > type = = " $shift " | | cell - > type = = " $shiftx " )
2014-01-17 12:32:35 -06:00
{
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 ) ) ) ;
2015-08-05 15:11:10 -05:00
int l2_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ B_WIDTH " ) ) . as_int ( ) ;
2014-07-28 04:08:55 -05:00
//log_assert(l2_width <= ceil(log(l1_width)/log(2)) );
2014-07-31 09:38:54 -05:00
int l1 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , l1_width ) ;
int l2 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) , ceil ( log ( l1_width ) / log ( 2 ) ) ) ;
2014-01-17 12:32:35 -06:00
int cell_output = + + line_num ;
2014-08-02 06:11:01 -05:00
str = stringf ( " %d %s %d %d %d " , line_num , cell_type_translation . at ( cell - > type . str ( ) ) . c_str ( ) , l1_width , l1 , l2 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
if ( l2_width > ceil ( log ( l1_width ) / log ( 2 ) ) )
{
int extra_width = l2_width - ceil ( log ( l1_width ) / log ( 2 ) ) ;
2014-07-31 09:38:54 -05:00
l2 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) , l2_width ) ;
2014-01-17 12:32:35 -06:00
+ + line_num ;
str = stringf ( " %d slice %d %d %d %d;6 " , line_num , extra_width , l2 , l2_width - 1 , l2_width - extra_width ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
+ + line_num ;
str = stringf ( " %d one %d " , line_num , extra_width ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
+ + line_num ;
str = stringf ( " %d %s %d " , line_num , l1_signed & & cell - > type = = " $sshr " ? " ones " : " zero " , l1_width ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
+ + 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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-17 12:32:35 -06:00
cell_output = line_num ;
}
2015-07-02 04:14:30 -05:00
line_ref [ cell - > name ] = cell_output ;
2014-01-17 12:32:35 -06:00
}
2014-01-03 03:52:44 -06:00
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 ( ) ;
2014-03-07 08:56:10 -06:00
log_assert ( output_width = = 1 ) ;
2014-07-31 09:38:54 -05:00
int l1 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , output_width ) ;
int l2 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) , output_width ) ;
2014-01-15 10:36:33 -06:00
int l1_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ A_WIDTH " ) ) . as_int ( ) ;
2015-08-05 15:11:10 -05:00
int l2_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ B_WIDTH " ) ) . as_int ( ) ;
2014-01-15 10:36:33 -06:00
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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-15 10:36:33 -06:00
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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-15 10:36:33 -06:00
l2 = line_num ;
}
2014-01-03 03:52:44 -06:00
if ( cell - > type = = " $logic_and " )
{
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-01-15 10:36:33 -06:00
str = stringf ( " %d %s %d %d %d " , line_num , cell_type_translation . at ( " $and " ) . c_str ( ) , output_width , l1 , l2 ) ;
2014-01-03 03:52:44 -06:00
}
else if ( cell - > type = = " $logic_or " )
{
2014-01-14 05:03:53 -06:00
+ + line_num ;
2014-01-15 10:36:33 -06:00
str = stringf ( " %d %s %d %d %d " , line_num , cell_type_translation . at ( " $or " ) . c_str ( ) , output_width , l1 , l2 ) ;
2014-01-03 03:52:44 -06:00
}
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
line_ref [ cell - > name ] = line_num ;
2014-01-03 03:52:44 -06:00
}
//multiplexers
else if ( cell - > type = = " $mux " )
{
log ( " writing mux cell \n " ) ;
int output_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ WIDTH " ) ) . as_int ( ) ;
2014-07-31 09:38:54 -05:00
int l1 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , output_width ) ;
int l2 = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) , output_width ) ;
int s = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ S " ) ) , 1 ) ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d %s %d %d %d %d " ,
2014-09-22 04:35:04 -05:00
line_num , cell_type_translation . at ( cell - > type . str ( ) ) . 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
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
line_ref [ cell - > name ] = line_num ;
2014-01-03 03:52:44 -06:00
}
2014-09-02 07:47:51 -05:00
else if ( cell - > type = = " $pmux " )
{
log ( " writing pmux cell \n " ) ;
int output_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ WIDTH " ) ) . as_int ( ) ;
int select_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ S_WIDTH " ) ) . as_int ( ) ;
2014-09-22 04:35:04 -05:00
int default_case = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) , output_width ) ;
int cases = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) , output_width * select_width ) ;
int select = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ S " ) ) , select_width ) ;
2014-09-02 07:47:51 -05:00
int * c = new int [ select_width ] ;
2015-07-02 04:14:30 -05:00
2014-09-02 07:47:51 -05:00
for ( int i = 0 ; i < select_width ; + + i )
{
+ + line_num ;
str = stringf ( " %d slice 1 %d %d %d " , line_num , select , i , i ) ;
2014-09-22 04:35:04 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-09-02 07:47:51 -05:00
c [ i ] = line_num ;
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d slice %d %d %d %d " , line_num , output_width , cases , i * output_width + output_width - 1 ,
2014-09-02 07:47:51 -05:00
i * output_width ) ;
2014-09-22 04:35:04 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-09-02 07:47:51 -05:00
}
2015-07-02 04:14:30 -05:00
2014-09-02 07:47:51 -05:00
+ + line_num ;
2014-09-18 04:15:46 -05:00
str = stringf ( " %d cond %d %d %d %d " , line_num , output_width , c [ select_width - 1 ] , c [ select_width - 1 ] + 1 , default_case ) ;
2014-09-22 04:35:04 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2015-07-02 04:14:30 -05:00
2014-09-02 07:47:51 -05:00
for ( int i = select_width - 2 ; i > = 0 ; - - i )
{
+ + line_num ;
2014-09-18 04:15:46 -05:00
str = stringf ( " %d cond %d %d %d %d " , line_num , output_width , c [ i ] , c [ i ] + 1 , line_num - 1 ) ;
2014-09-22 04:35:04 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-09-02 07:47:51 -05:00
}
line_ref [ cell - > name ] = line_num ;
}
2014-09-22 04:35:04 -05:00
//registers
2014-01-03 03:52:44 -06:00
else if ( cell - > type = = " $dff " | | cell - > type = = " $adff " | | cell - > type = = " $dffsr " )
{
2014-01-17 12:32:35 -06:00
//TODO: remodelling fo adff cells
2014-01-03 03:52:44 -06:00
log ( " writing cell - %s \n " , cstr ( cell - > type ) ) ;
int output_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ WIDTH " ) ) . as_int ( ) ;
2014-01-14 05:03:53 -06:00
log ( " - width is %d \n " , output_width ) ;
2014-07-31 09:38:54 -05:00
int cond = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ CLK " ) ) , 1 ) ;
2014-01-03 03:52:44 -06:00
bool polarity = cell - > parameters . at ( RTLIL : : IdString ( " \\ CLK_POLARITY " ) ) . as_bool ( ) ;
2014-07-31 09:38:54 -05:00
const RTLIL : : SigSpec * cell_output = & cell - > getPort ( RTLIL : : IdString ( " \\ Q " ) ) ;
int value = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ D " ) ) , output_width ) ;
2014-01-16 13:16:01 -06:00
unsigned start_bit = 0 ;
2014-07-22 13:15:14 -05:00
for ( unsigned i = 0 ; i < cell_output - > chunks ( ) . size ( ) ; + + i )
2014-01-03 03:52:44 -06:00
{
2014-07-25 07:23:31 -05:00
output_width = cell_output - > chunks ( ) . at ( i ) . width ;
log_assert ( output_width = = cell_output - > chunks ( ) . at ( i ) . wire - > width ) ; //full reg is given the next value
int reg = dump_wire ( cell_output - > chunks ( ) . at ( i ) . wire ) ; //register
2014-01-15 10:36:33 -06:00
int slice = value ;
2014-07-22 13:15:14 -05:00
if ( cell_output - > chunks ( ) . size ( ) > 1 )
2014-01-15 10:36:33 -06:00
{
2014-01-16 13:16:01 -06:00
start_bit + = output_width ;
2014-01-15 10:36:33 -06:00
slice = + + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d slice %d %d %d %d; " , line_num , output_width , value , start_bit - 1 ,
2014-01-15 10:36:33 -06:00
start_bit - output_width ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-15 10:36:33 -06:00
}
if ( cell - > type = = " $dffsr " )
{
2014-07-31 09:38:54 -05:00
int sync_reset = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ CLR " ) ) , 1 ) ;
2014-01-15 10:36:33 -06:00
bool sync_reset_pol = cell - > parameters . at ( RTLIL : : IdString ( " \\ CLR_POLARITY " ) ) . as_bool ( ) ;
2014-07-31 09:38:54 -05:00
int sync_reset_value = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ SET " ) ) ,
2014-01-15 10:36:33 -06:00
output_width ) ;
bool sync_reset_value_pol = cell - > parameters . at ( RTLIL : : IdString ( " \\ SET_POLARITY " ) ) . as_bool ( ) ;
+ + line_num ;
2015-07-02 04:14:30 -05:00
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 ? " " : " - " ,
2014-01-15 10:36:33 -06:00
sync_reset_value , slice ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-15 10:36:33 -06:00
slice = line_num ;
}
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d %s %d %s%d %d %d " , line_num , cell_type_translation . at ( " $mux " ) . c_str ( ) ,
2014-01-15 10:36:33 -06:00
output_width , polarity ? " " : " - " , cond , slice , reg ) ;
2015-07-02 04:14:30 -05:00
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-15 10:36:33 -06:00
int next = line_num ;
if ( cell - > type = = " $adff " )
{
2014-07-31 09:38:54 -05:00
int async_reset = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ ARST " ) ) , 1 ) ;
2014-01-15 10:36:33 -06:00
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 ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d %s %d %s%d %d %d " , line_num , cell_type_translation . at ( " $mux " ) . c_str ( ) ,
2014-01-15 10:36:33 -06:00
output_width , async_reset_pol ? " " : " - " , async_reset , async_reset_value , next ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-15 10:36:33 -06:00
}
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d %s %d %d %d " , line_num , cell_type_translation . at ( cell - > type . str ( ) ) . c_str ( ) ,
2014-01-15 10:36:33 -06:00
output_width , reg , next ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-03 03:52:44 -06:00
}
2014-01-14 05:03:53 -06:00
line_ref [ cell - > name ] = line_num ;
2014-01-03 03:52:44 -06:00
}
//memories
else if ( cell - > type = = " $memrd " )
{
log ( " writing memrd cell \n " ) ;
2014-02-03 06:01:45 -06:00
if ( cell - > parameters . at ( " \\ CLK_ENABLE " ) . as_bool ( ) = = true )
log_error ( " The btor backen does not support $memrd cells with built-in registers. Run memory_dff with -wr_only. \n " ) ;
2014-01-03 03:52:44 -06:00
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 ( ) ;
2014-07-31 09:38:54 -05:00
int address = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ ADDR " ) ) , address_width ) ;
2014-01-03 03:52:44 -06:00
int data_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ WIDTH " ) ) . as_int ( ) ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d read %d %d %d " , line_num , data_width , mem , address ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-03 03:52:44 -06:00
line_ref [ cell - > name ] = line_num ;
}
else if ( cell - > type = = " $memwr " )
{
log ( " writing memwr cell \n " ) ;
2014-02-03 06:01:45 -06:00
if ( cell - > parameters . at ( " \\ CLK_ENABLE " ) . as_bool ( ) = = false )
log_error ( " The btor backen does not support $memwr cells without built-in registers. Run memory_dff (but with -wr_only). \n " ) ;
2014-07-31 09:38:54 -05:00
int clk = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ CLK " ) ) , 1 ) ;
2014-01-03 03:52:44 -06:00
bool polarity = cell - > parameters . at ( RTLIL : : IdString ( " \\ CLK_POLARITY " ) ) . as_bool ( ) ;
2014-07-31 09:38:54 -05:00
int enable = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ EN " ) ) , 1 ) ;
2014-01-03 03:52:44 -06:00
int address_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ ABITS " ) ) . as_int ( ) ;
2014-07-31 09:38:54 -05:00
int address = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ ADDR " ) ) , address_width ) ;
2014-01-03 03:52:44 -06:00
int data_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ WIDTH " ) ) . as_int ( ) ;
2014-07-31 09:38:54 -05:00
int data = dump_sigspec ( & cell - > getPort ( RTLIL : : IdString ( " \\ DATA " ) ) , data_width ) ;
2014-01-03 03:52:44 -06:00
str = cell - > parameters . at ( RTLIL : : IdString ( " \\ MEMID " ) ) . decode_string ( ) ;
int mem = dump_memory ( module - > memories . at ( RTLIL : : IdString ( str . c_str ( ) ) ) ) ;
2014-09-18 04:15:46 -05:00
//check if the memory has already next
2015-04-03 09:41:50 -05:00
/*
auto it = mem_next . find ( mem ) ;
2014-09-18 04:15:46 -05:00
if ( it ! = std : : end ( mem_next ) )
{
+ + line_num ;
str = cell - > parameters . at ( RTLIL : : IdString ( " \\ MEMID " ) ) . decode_string ( ) ;
RTLIL : : Memory * memory = module - > memories . at ( RTLIL : : IdString ( str . c_str ( ) ) ) ;
int address_bits = ceil ( log ( memory - > size ) / log ( 2 ) ) ;
str = stringf ( " %d array %d %d " , line_num , memory - > width , address_bits ) ;
2014-09-22 04:35:04 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-09-18 04:15:46 -05:00
+ + line_num ;
2015-04-03 09:41:50 -05:00
str = stringf ( " %d eq 1 %d %d; mem invar " , line_num , mem , line_num - 1 ) ;
2014-09-22 04:35:04 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-09-18 04:15:46 -05:00
mem = line_num - 1 ;
2015-04-03 09:41:50 -05:00
}
2015-07-02 04:14:30 -05:00
*/
2015-08-05 15:11:10 -05:00
+ + line_num ;
2014-01-03 03:52:44 -06:00
if ( polarity )
str = stringf ( " %d one 1 " , line_num ) ;
else
str = stringf ( " %d zero 1 " , line_num ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d eq 1 %d %d " , line_num , clk , line_num - 1 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d and 1 %d %d " , line_num , line_num - 1 , enable ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d write %d %d %d %d %d " , line_num , data_width , address_width , mem , address , data ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2015-04-03 09:41:50 -05:00
/*
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d acond %d %d %d %d %d " , line_num , data_width , address_width , line_num - 2 , line_num - 1 , mem ) ;
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d anext %d %d %d %d " , line_num , data_width , address_width , mem , line_num - 1 ) ;
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2015-04-03 09:41:50 -05:00
*/
mem_next [ mem ] . insert ( std : : make_pair ( line_num - 1 , line_num ) ) ;
2014-01-03 03:52:44 -06:00
}
2014-02-11 06:06:01 -06:00
else if ( cell - > type = = " $slice " )
{
log ( " writing slice cell \n " ) ;
2014-07-31 09:38:54 -05:00
const RTLIL : : SigSpec * input = & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) ;
2014-02-11 06:06:01 -06:00
int input_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ A_WIDTH " ) ) . as_int ( ) ;
2014-07-22 13:15:14 -05:00
log_assert ( input - > size ( ) = = input_width ) ;
2014-02-11 06:06:01 -06:00
int input_line = dump_sigspec ( input , input_width ) ;
2015-01-24 05:16:46 -06:00
const RTLIL : : SigSpec * output YS_ATTRIBUTE ( unused ) = & cell - > getPort ( RTLIL : : IdString ( " \\ Y " ) ) ;
2014-02-11 06:06:01 -06:00
int output_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ Y_WIDTH " ) ) . as_int ( ) ;
2014-07-22 13:15:14 -05:00
log_assert ( output - > size ( ) = = output_width ) ;
2015-07-02 04:14:30 -05:00
int offset = cell - > parameters . at ( RTLIL : : IdString ( " \\ OFFSET " ) ) . as_int ( ) ;
2014-02-11 06:06:01 -06:00
+ + line_num ;
2014-08-02 06:11:01 -05:00
str = stringf ( " %d %s %d %d %d %d " , line_num , cell_type_translation . at ( cell - > type . str ( ) ) . c_str ( ) , output_width , input_line , output_width + offset - 1 , offset ) ;
2015-07-02 04:14:30 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
line_ref [ cell - > name ] = line_num ;
2014-02-11 06:06:01 -06:00
}
else if ( cell - > type = = " $concat " )
{
log ( " writing concat cell \n " ) ;
2014-07-31 09:38:54 -05:00
const RTLIL : : SigSpec * input_a = & cell - > getPort ( RTLIL : : IdString ( " \\ A " ) ) ;
2014-02-11 06:06:01 -06:00
int input_a_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ A_WIDTH " ) ) . as_int ( ) ;
2014-07-22 13:15:14 -05:00
log_assert ( input_a - > size ( ) = = input_a_width ) ;
2014-02-11 06:06:01 -06:00
int input_a_line = dump_sigspec ( input_a , input_a_width ) ;
2014-07-31 09:38:54 -05:00
const RTLIL : : SigSpec * input_b = & cell - > getPort ( RTLIL : : IdString ( " \\ B " ) ) ;
2014-02-11 06:06:01 -06:00
int input_b_width = cell - > parameters . at ( RTLIL : : IdString ( " \\ B_WIDTH " ) ) . as_int ( ) ;
2014-07-22 13:15:14 -05:00
log_assert ( input_b - > size ( ) = = input_b_width ) ;
2014-02-11 06:06:01 -06:00
int input_b_line = dump_sigspec ( input_b , input_b_width ) ;
+ + line_num ;
2015-07-02 04:14:30 -05:00
str = stringf ( " %d %s %d %d %d " , line_num , cell_type_translation . at ( cell - > type . str ( ) ) . c_str ( ) , input_a_width + input_b_width ,
input_a_line , input_b_line ) ;
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
line_ref [ cell - > name ] = line_num ;
2014-02-11 06:06:01 -06:00
}
2014-01-14 05:03:53 -06:00
curr_cell . clear ( ) ;
2014-01-03 03:52:44 -06:00
return line_num ;
}
else
{
return it - > second ;
}
}
2014-01-14 05:03:53 -06:00
2014-07-26 08:57:57 -05:00
const RTLIL : : SigSpec * get_cell_output ( RTLIL : : Cell * cell )
2014-01-14 05:03:53 -06:00
{
2014-07-26 08:57:57 -05:00
const RTLIL : : SigSpec * output_sig = nullptr ;
2014-01-14 05:03:53 -06:00
if ( cell - > type = = " $memrd " )
{
2014-07-31 09:38:54 -05:00
output_sig = & cell - > getPort ( RTLIL : : IdString ( " \\ DATA " ) ) ;
2014-01-14 05:03:53 -06:00
}
2014-01-20 03:45:02 -06:00
else if ( cell - > type = = " $memwr " | | cell - > type = = " $assert " )
2014-01-14 05:03:53 -06:00
{
//no output
}
else if ( cell - > type = = " $dff " | | cell - > type = = " $adff " | | cell - > type = = " $dffsr " )
{
2014-07-31 09:38:54 -05:00
output_sig = & cell - > getPort ( RTLIL : : IdString ( " \\ Q " ) ) ;
2014-01-14 05:03:53 -06:00
}
2015-07-02 04:14:30 -05:00
else
2014-01-14 05:03:53 -06:00
{
2014-07-31 09:38:54 -05:00
output_sig = & cell - > getPort ( RTLIL : : IdString ( " \\ Y " ) ) ;
2014-01-14 05:03:53 -06:00
}
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 ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " %s \n " , str . c_str ( ) ) ;
2014-01-14 05:03:53 -06:00
}
2014-01-03 03:52:44 -06:00
void dump ( )
{
2014-08-23 06:54:21 -05:00
f < < stringf ( " ;module %s \n " , cstr ( module - > name ) ) ;
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
log ( " creating intermediate wires map \n " ) ;
//creating map of intermediate wires as output of some cell
2014-07-26 18:51:45 -05:00
for ( auto it = module - > cells_ . begin ( ) ; it ! = module - > cells_ . end ( ) ; + + it )
2014-01-03 03:52:44 -06:00
{
RTLIL : : Cell * cell = it - > second ;
2014-07-26 08:57:57 -05:00
const RTLIL : : SigSpec * output_sig = get_cell_output ( cell ) ;
2014-01-14 05:03:53 -06:00
if ( output_sig = = nullptr )
continue ;
RTLIL : : SigSpec s = sigmap ( * output_sig ) ;
output_sig = & s ;
2014-01-03 03:52:44 -06:00
log ( " - %s \n " , cstr ( it - > second - > type ) ) ;
if ( cell - > type = = " $memrd " )
{
2014-07-22 13:15:14 -05:00
for ( unsigned i = 0 ; i < output_sig - > chunks ( ) . size ( ) ; + + i )
2014-01-03 03:52:44 -06:00
{
2014-07-25 07:23:31 -05:00
RTLIL : : Wire * w = output_sig - > chunks ( ) . at ( i ) . wire ;
2014-01-03 03:52:44 -06:00
RTLIL : : IdString wire_id = w - > name ;
2014-07-25 07:23:31 -05:00
inter_wire_map [ wire_id ] . insert ( WireInfo ( cell - > name , & output_sig - > chunks ( ) . at ( i ) ) ) ;
2014-01-03 03:52:44 -06:00
}
}
2014-01-14 05:03:53 -06:00
else if ( cell - > type = = " $memwr " )
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
continue ; //nothing to do
2014-01-03 03:52:44 -06:00
}
else if ( cell - > type = = " $dff " | | cell - > type = = " $adff " | | cell - > type = = " $dffsr " )
{
2014-07-25 07:23:31 -05:00
RTLIL : : IdString wire_id = output_sig - > chunks ( ) . front ( ) . wire - > name ;
2014-07-22 13:15:14 -05:00
for ( unsigned i = 0 ; i < output_sig - > chunks ( ) . size ( ) ; + + i )
2014-01-15 10:36:33 -06:00
{
2014-07-25 07:23:31 -05:00
RTLIL : : Wire * w = output_sig - > chunks ( ) . at ( i ) . wire ;
2014-01-15 10:36:33 -06:00
RTLIL : : IdString wire_id = w - > name ;
2014-07-25 07:23:31 -05:00
inter_wire_map [ wire_id ] . insert ( WireInfo ( cell - > name , & output_sig - > chunks ( ) . at ( i ) ) ) ;
2014-01-15 10:36:33 -06:00
basic_wires [ wire_id ] = true ;
}
2014-01-03 03:52:44 -06:00
}
2015-07-02 04:14:30 -05:00
else
2014-01-03 03:52:44 -06:00
{
2014-07-22 13:15:14 -05:00
for ( unsigned i = 0 ; i < output_sig - > chunks ( ) . size ( ) ; + + i )
2014-01-03 03:52:44 -06:00
{
2014-07-25 07:23:31 -05:00
RTLIL : : Wire * w = output_sig - > chunks ( ) . at ( i ) . wire ;
2014-01-03 03:52:44 -06:00
RTLIL : : IdString wire_id = w - > name ;
2014-07-25 07:23:31 -05:00
inter_wire_map [ wire_id ] . insert ( WireInfo ( cell - > name , & output_sig - > chunks ( ) . at ( i ) ) ) ;
2014-01-03 03:52:44 -06:00
}
}
}
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
log ( " writing input \n " ) ;
2014-01-14 05:03:53 -06:00
std : : map < int , RTLIL : : Wire * > inputs , outputs ;
std : : vector < RTLIL : : Wire * > safety ;
2015-07-02 04:14:30 -05:00
2014-07-26 18:49:51 -05:00
for ( auto & wire_it : module - > wires_ ) {
2014-01-03 03:52:44 -06:00
RTLIL : : Wire * wire = wire_it . second ;
if ( wire - > port_input )
inputs [ wire - > port_id ] = wire ;
2014-01-14 05:03:53 -06:00
if ( wire - > port_output ) {
outputs [ wire - > port_id ] = wire ;
2014-08-02 06:11:01 -05:00
if ( wire - > name . str ( ) . find ( " safety " ) ! = std : : string : : npos )
2014-01-14 05:03:53 -06:00
safety . push_back ( wire ) ;
}
2014-01-03 03:52:44 -06:00
}
2014-08-23 06:54:21 -05:00
f < < stringf ( " ;inputs \n " ) ;
2014-01-03 03:52:44 -06:00
for ( auto & it : inputs ) {
RTLIL : : Wire * wire = it . second ;
2014-01-14 05:03:53 -06:00
dump_wire ( wire ) ;
2014-01-03 03:52:44 -06:00
}
2014-08-23 06:54:21 -05:00
f < < stringf ( " \n " ) ;
2015-07-02 04:14:30 -05:00
2014-01-14 05:03:53 -06:00
log ( " writing memories \n " ) ;
for ( auto mem_it = module - > memories . begin ( ) ; mem_it ! = module - > memories . end ( ) ; + + mem_it )
2014-01-03 03:52:44 -06:00
{
2014-01-14 05:03:53 -06:00
dump_memory ( mem_it - > second ) ;
2014-01-03 03:52:44 -06:00
}
2014-01-14 05:03:53 -06:00
log ( " writing output wires \n " ) ;
for ( auto & it : outputs ) {
RTLIL : : Wire * wire = it . second ;
dump_wire ( wire ) ;
}
log ( " writing cells \n " ) ;
2014-07-26 18:51:45 -05:00
for ( auto cell_it = module - > cells_ . begin ( ) ; cell_it ! = module - > cells_ . end ( ) ; + + cell_it )
2014-01-03 03:52:44 -06:00
{
2015-07-02 04:14:30 -05:00
dump_cell ( cell_it - > second ) ;
2014-01-14 05:03:53 -06:00
}
2015-07-02 04:14:30 -05:00
2015-04-03 09:41:50 -05:00
log ( " writing memory next " ) ;
for ( auto mem_it = module - > memories . begin ( ) ; mem_it ! = module - > memories . end ( ) ; + + mem_it )
{
dump_memory_next ( mem_it - > second ) ;
}
2014-01-14 05:03:53 -06:00
for ( auto it : safety )
dump_property ( it ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " \n " ) ;
2015-07-02 04:14:30 -05:00
2014-01-14 05:03:53 -06:00
log ( " writing outputs info \n " ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " ;outputs \n " ) ;
2014-01-14 05:03:53 -06:00
for ( auto & it : outputs ) {
RTLIL : : Wire * wire = it . second ;
int l = dump_wire ( wire ) ;
2014-08-23 06:54:21 -05:00
f < < stringf ( " ;%d %s " , l , cstr ( wire - > name ) ) ;
2014-01-14 05:03:53 -06:00
}
2014-08-23 06:54:21 -05:00
f < < stringf ( " \n " ) ;
2014-01-03 03:52:44 -06:00
}
2014-08-23 06:54:21 -05:00
static void dump ( std : : ostream & f , RTLIL : : Module * module , RTLIL : : Design * design , BtorDumperConfig & config )
2014-01-03 03:52:44 -06:00
{
BtorDumper dumper ( f , module , design , & config ) ;
dumper . dump ( ) ;
}
} ;
struct BtorBackend : public Backend {
BtorBackend ( ) : Backend ( " btor " , " write design to BTOR file " ) { }
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
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 " ) ;
}
2014-08-23 06:54:21 -05:00
virtual void execute ( std : : ostream * & f , std : : string filename , std : : vector < std : : string > args , RTLIL : : Design * design )
2014-01-03 03:52:44 -06:00
{
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 ) ;
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
if ( top_module_name . empty ( ) )
2014-07-27 03:18:00 -05:00
for ( auto & mod_it : design - > modules_ )
2014-01-03 03:52:44 -06:00
if ( mod_it . second - > get_bool_attribute ( " \\ top " ) )
2014-08-02 11:58:40 -05:00
top_module_name = mod_it . first . str ( ) ;
2014-01-03 03:52:44 -06:00
2014-08-23 06:54:21 -05:00
* f < < stringf ( " ; Generated by %s \n " , yosys_version_str ) ;
* f < < stringf ( " ; %s developed and maintained by Clifford Wolf <clifford@clifford.at> \n " , yosys_version_str ) ;
* f < < stringf ( " ; BTOR Backend developed by Ahmed Irfan <irfan@fbk.eu> - Fondazione Bruno Kessler, Trento, Italy \n " ) ;
* f < < stringf ( " ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \n " ) ;
2015-07-02 04:14:30 -05:00
2014-01-03 03:52:44 -06:00
std : : vector < RTLIL : : Module * > mod_list ;
2014-07-27 03:18:00 -05:00
for ( auto module_it : design - > modules_ )
2014-01-03 03:52:44 -06:00
{
RTLIL : : Module * module = module_it . second ;
if ( module - > get_bool_attribute ( " \\ blackbox " ) )
continue ;
2014-01-14 05:03:53 -06:00
if ( module - > processes . size ( ) ! = 0 )
2014-02-05 11:31:10 -06:00
log_error ( " Found unmapped processes in module %s: unmapped processes are not supported in BTOR backend! \n " , RTLIL : : id2cstr ( module - > name ) ) ;
2014-01-14 05:03:53 -06:00
2014-01-03 03:52:44 -06:00
if ( module - > name = = RTLIL : : escape_id ( top_module_name ) ) {
2014-08-23 06:54:21 -05:00
BtorDumper : : dump ( * f , module , design , config ) ;
2014-01-03 03:52:44 -06:00
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 )
2014-08-23 06:54:21 -05:00
BtorDumper : : dump ( * f , module , design , config ) ;
2014-01-03 03:52:44 -06:00
}
} BtorBackend ;
2014-09-27 09:17:53 -05:00
PRIVATE_NAMESPACE_END