2013-01-05 04:13:26 -06:00
/*
* yosys - - Yosys Open SYnthesis Suite
*
* Copyright ( C ) 2012 Clifford Wolf < clifford @ clifford . at >
2015-07-02 04:14:30 -05:00
*
2013-01-05 04:13:26 -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
*
2013-01-05 04:13:26 -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 .
*
*/
# ifndef SIGTOOLS_H
# define SIGTOOLS_H
2014-07-31 06:19:47 -05:00
# include "kernel/yosys.h"
YOSYS_NAMESPACE_BEGIN
2013-01-05 04:13:26 -06:00
struct SigPool
{
2014-07-23 09:09:27 -05:00
struct bitDef_t : public std : : pair < RTLIL : : Wire * , int > {
bitDef_t ( ) : std : : pair < RTLIL : : Wire * , int > ( NULL , 0 ) { }
bitDef_t ( const RTLIL : : SigBit & bit ) : std : : pair < RTLIL : : Wire * , int > ( bit . wire , bit . offset ) { }
2014-12-26 15:08:44 -06:00
unsigned int hash ( ) const { return first - > name . hash ( ) + second ; }
2014-07-23 09:09:27 -05:00
} ;
2014-12-26 15:08:44 -06:00
pool < bitDef_t > bits ;
2013-01-05 04:13:26 -06:00
void clear ( )
{
bits . clear ( ) ;
}
void add ( RTLIL : : SigSpec sig )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL )
bits . insert ( bit ) ;
2013-01-05 04:13:26 -06:00
}
void add ( const SigPool & other )
{
for ( auto & bit : other . bits )
bits . insert ( bit ) ;
}
void del ( RTLIL : : SigSpec sig )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL )
bits . erase ( bit ) ;
2013-01-05 04:13:26 -06:00
}
void del ( const SigPool & other )
{
for ( auto & bit : other . bits )
2013-08-06 08:04:24 -05:00
bits . erase ( bit ) ;
2013-01-05 04:13:26 -06:00
}
void expand ( RTLIL : : SigSpec from , RTLIL : : SigSpec to )
{
2014-10-10 09:59:44 -05:00
log_assert ( GetSize ( from ) = = GetSize ( to ) ) ;
for ( int i = 0 ; i < GetSize ( from ) ; i + + ) {
2014-07-23 09:09:27 -05:00
bitDef_t bit_from ( from [ i ] ) , bit_to ( to [ i ] ) ;
if ( bit_from . first ! = NULL & & bit_to . first ! = NULL & & bits . count ( bit_from ) > 0 )
2013-01-05 04:13:26 -06:00
bits . insert ( bit_to ) ;
}
}
RTLIL : : SigSpec extract ( RTLIL : : SigSpec sig )
{
RTLIL : : SigSpec result ;
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL & & bits . count ( bit ) )
result . append_bit ( bit ) ;
2013-01-05 04:13:26 -06:00
return result ;
}
RTLIL : : SigSpec remove ( RTLIL : : SigSpec sig )
{
RTLIL : : SigSpec result ;
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL & & bits . count ( bit ) = = 0 )
result . append ( bit ) ;
2013-01-05 04:13:26 -06:00
return result ;
}
2014-07-27 08:38:02 -05:00
bool check ( RTLIL : : SigBit bit )
{
return bit . wire ! = NULL & & bits . count ( bit ) ;
}
2013-01-05 04:13:26 -06:00
bool check_any ( RTLIL : : SigSpec sig )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL & & bits . count ( bit ) )
2013-01-05 04:13:26 -06:00
return true ;
return false ;
}
bool check_all ( RTLIL : : SigSpec sig )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL & & bits . count ( bit ) = = 0 )
2013-01-05 04:13:26 -06:00
return false ;
return true ;
}
2013-06-08 02:34:36 -05:00
RTLIL : : SigSpec export_one ( )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : bits )
return RTLIL : : SigSpec ( bit . first , bit . second ) ;
return RTLIL : : SigSpec ( ) ;
2013-06-08 02:34:36 -05:00
}
RTLIL : : SigSpec export_all ( )
{
2014-12-26 15:08:44 -06:00
pool < RTLIL : : SigBit > sig ;
2013-06-08 02:34:36 -05:00
for ( auto & bit : bits )
2014-07-23 09:09:27 -05:00
sig . insert ( RTLIL : : SigBit ( bit . first , bit . second ) ) ;
2013-06-08 02:34:36 -05:00
return sig ;
}
2015-01-31 06:58:04 -06:00
size_t size ( ) const
2013-06-08 02:34:36 -05:00
{
return bits . size ( ) ;
}
2013-01-05 04:13:26 -06:00
} ;
2013-08-09 05:42:32 -05:00
template < typename T , class Compare = std : : less < T > >
2013-01-05 04:13:26 -06:00
struct SigSet
{
2019-09-12 13:45:17 -05:00
static_assert ( ! std : : is_pointer < T > : : value | | ! std : : is_same < Compare , std : : less < T > > : : value , " Explicit `Compare' class require for SigSet with pointer-type values! " ) ;
2014-07-23 09:09:27 -05:00
struct bitDef_t : public std : : pair < RTLIL : : Wire * , int > {
bitDef_t ( ) : std : : pair < RTLIL : : Wire * , int > ( NULL , 0 ) { }
bitDef_t ( const RTLIL : : SigBit & bit ) : std : : pair < RTLIL : : Wire * , int > ( bit . wire , bit . offset ) { }
2014-12-26 15:08:44 -06:00
unsigned int hash ( ) const { return first - > name . hash ( ) + second ; }
2014-07-23 09:09:27 -05:00
} ;
2014-12-26 15:08:44 -06:00
dict < bitDef_t , std : : set < T , Compare > > bits ;
2013-01-05 04:13:26 -06:00
void clear ( )
{
bits . clear ( ) ;
}
void insert ( RTLIL : : SigSpec sig , T data )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL )
bits [ bit ] . insert ( data ) ;
2013-01-05 04:13:26 -06:00
}
2013-03-15 04:22:23 -05:00
void insert ( RTLIL : : SigSpec sig , const std : : set < T > & data )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL )
bits [ bit ] . insert ( data . begin ( ) , data . end ( ) ) ;
2013-03-15 04:22:23 -05:00
}
2013-01-05 04:13:26 -06:00
void erase ( RTLIL : : SigSpec sig )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL )
bits [ bit ] . clear ( ) ;
2013-01-05 04:13:26 -06:00
}
void erase ( RTLIL : : SigSpec sig , T data )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL )
bits [ bit ] . erase ( data ) ;
2013-01-05 04:13:26 -06:00
}
2013-03-15 04:22:23 -05:00
void erase ( RTLIL : : SigSpec sig , const std : : set < T > & data )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL )
bits [ bit ] . erase ( data . begin ( ) , data . end ( ) ) ;
2013-03-15 04:22:23 -05:00
}
2013-01-05 04:13:26 -06:00
void find ( RTLIL : : SigSpec sig , std : : set < T > & result )
2014-12-28 21:06:52 -06:00
{
for ( auto & bit : sig )
if ( bit . wire ! = NULL ) {
auto & data = bits [ bit ] ;
result . insert ( data . begin ( ) , data . end ( ) ) ;
}
}
void find ( RTLIL : : SigSpec sig , pool < T > & result )
2013-01-05 04:13:26 -06:00
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL ) {
auto & data = bits [ bit ] ;
result . insert ( data . begin ( ) , data . end ( ) ) ;
}
2013-01-05 04:13:26 -06:00
}
std : : set < T > find ( RTLIL : : SigSpec sig )
{
std : : set < T > result ;
find ( sig , result ) ;
return result ;
}
2013-02-27 09:27:20 -06:00
bool has ( RTLIL : : SigSpec sig )
{
2014-07-23 09:09:27 -05:00
for ( auto & bit : sig )
if ( bit . wire ! = NULL & & bits . count ( bit ) )
2013-02-27 09:27:20 -06:00
return true ;
return false ;
}
2013-01-05 04:13:26 -06:00
} ;
2015-10-27 09:04:47 -05:00
struct SigMap
{
mfp < SigBit > database ;
SigMap ( RTLIL : : Module * module = NULL )
{
if ( module ! = NULL )
set ( module ) ;
}
void swap ( SigMap & other )
{
database . swap ( other . database ) ;
}
void clear ( )
{
database . clear ( ) ;
}
void set ( RTLIL : : Module * module )
{
2016-02-01 03:10:20 -06:00
int bitcount = 0 ;
for ( auto & it : module - > connections ( ) )
bitcount + = it . first . size ( ) ;
database . clear ( ) ;
database . reserve ( bitcount ) ;
2015-10-27 09:04:47 -05:00
for ( auto & it : module - > connections ( ) )
add ( it . first , it . second ) ;
}
void add ( RTLIL : : SigSpec from , RTLIL : : SigSpec to )
{
log_assert ( GetSize ( from ) = = GetSize ( to ) ) ;
for ( int i = 0 ; i < GetSize ( from ) ; i + + )
{
2015-10-28 05:21:55 -05:00
int bfi = database . lookup ( from [ i ] ) ;
int bti = database . lookup ( to [ i ] ) ;
const RTLIL : : SigBit & bf = database [ bfi ] ;
const RTLIL : : SigBit & bt = database [ bti ] ;
2015-10-27 09:04:47 -05:00
2015-10-27 18:39:53 -05:00
if ( bf . wire | | bt . wire )
{
2015-10-28 05:21:55 -05:00
database . imerge ( bfi , bti ) ;
2015-10-27 18:39:53 -05:00
if ( bf . wire = = nullptr )
2015-10-28 05:21:55 -05:00
database . ipromote ( bfi ) ;
2015-10-27 18:39:53 -05:00
if ( bt . wire = = nullptr )
2015-10-28 05:21:55 -05:00
database . ipromote ( bti ) ;
2015-10-27 18:39:53 -05:00
}
2015-10-27 09:04:47 -05:00
}
}
void add ( RTLIL : : SigSpec sig )
{
2015-10-27 18:39:53 -05:00
for ( auto & bit : sig ) {
RTLIL : : SigBit b = database . find ( bit ) ;
if ( b . wire ! = nullptr )
database . promote ( bit ) ;
}
2015-10-27 09:04:47 -05:00
}
void apply ( RTLIL : : SigBit & bit ) const
{
bit = database . find ( bit ) ;
}
void apply ( RTLIL : : SigSpec & sig ) const
{
for ( auto & bit : sig )
apply ( bit ) ;
}
RTLIL : : SigBit operator ( ) ( RTLIL : : SigBit bit ) const
{
apply ( bit ) ;
return bit ;
}
RTLIL : : SigSpec operator ( ) ( RTLIL : : SigSpec sig ) const
{
apply ( sig ) ;
return sig ;
}
RTLIL : : SigSpec operator ( ) ( RTLIL : : Wire * wire ) const
{
SigSpec sig ( wire ) ;
apply ( sig ) ;
return sig ;
}
2015-11-30 12:43:52 -06:00
RTLIL : : SigSpec allbits ( ) const
{
RTLIL : : SigSpec sig ;
for ( auto & bit : database )
if ( bit . wire ! = nullptr )
sig . append ( bit ) ;
return sig ;
}
2015-10-27 09:04:47 -05:00
} ;
2013-01-05 04:13:26 -06:00
2014-07-31 06:19:47 -05:00
YOSYS_NAMESPACE_END
2013-01-05 04:13:26 -06:00
# endif /* SIGTOOLS_H */