2013-11-24 22:52:30 +01:00
/*
* yosys - - Yosys Open SYnthesis Suite
*
2021-06-08 00:39:36 +02:00
* Copyright ( C ) 2012 Claire Xenia Wolf < claire @ yosyshq . com >
2015-07-02 11:14:30 +02:00
*
2013-11-24 22:52:30 +01: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 11:14:30 +02:00
*
2013-11-24 22:52:30 +01: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 .
*
*/
2014-12-24 10:49:24 +01:00
# include "simplemap.h"
2023-09-29 19:53:37 +02:00
# include "kernel/sigtools.h"
2023-09-29 22:20:43 +02:00
# include "kernel/ff.h"
2023-09-29 19:53:37 +02:00
# include <stdlib.h>
2023-09-29 22:20:43 +02:00
# include <stdio.h>
2013-11-24 22:52:30 +01:00
# include <string.h>
2014-09-27 16:17:53 +02:00
USING_YOSYS_NAMESPACE
2014-12-24 10:49:24 +01:00
YOSYS_NAMESPACE_BEGIN
2013-11-24 23:31:14 +01:00
2014-12-24 10:49:24 +01:00
void simplemap_not ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2013-11-24 22:52:30 +01:00
2020-04-02 18:51:32 +02:00
sig_a . extend_u0 ( GetSize ( sig_y ) , cell - > parameters . at ( ID : : A_SIGNED ) . as_bool ( ) ) ;
2014-07-23 16:09:27 +02:00
2014-10-10 16:59:44 +02:00
for ( int i = 0 ; i < GetSize ( sig_y ) ; i + + ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _NOT_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a [ i ] ) ;
gate - > setPort ( ID : : Y , sig_y [ i ] ) ;
2013-11-24 22:52:30 +01:00
}
}
2014-12-24 10:49:24 +01:00
void simplemap_pos ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2013-11-24 22:52:30 +01:00
2020-04-02 18:51:32 +02:00
sig_a . extend_u0 ( GetSize ( sig_y ) , cell - > parameters . at ( ID : : A_SIGNED ) . as_bool ( ) ) ;
2014-07-23 16:09:27 +02:00
2014-07-26 14:32:50 +02:00
module - > connect ( RTLIL : : SigSig ( sig_y , sig_a ) ) ;
2013-12-28 11:54:40 +01:00
}
2014-12-24 10:49:24 +01:00
void simplemap_bitop ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_b = cell - > getPort ( ID : : B ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2014-07-23 16:09:27 +02:00
2022-11-02 17:12:51 +01:00
if ( cell - > type ! = ID ( $ bweqx ) ) {
sig_a . extend_u0 ( GetSize ( sig_y ) , cell - > parameters . at ( ID : : A_SIGNED ) . as_bool ( ) ) ;
sig_b . extend_u0 ( GetSize ( sig_y ) , cell - > parameters . at ( ID : : B_SIGNED ) . as_bool ( ) ) ;
}
2013-11-24 22:52:30 +01:00
2019-08-15 19:05:08 +02:00
IdString gate_type ;
2023-09-29 22:20:43 +02:00
if ( cell - > type = = ID ( $ and ) ) gate_type = ID ( $ _AND_ ) ;
if ( cell - > type = = ID ( $ or ) ) gate_type = ID ( $ _OR_ ) ;
if ( cell - > type = = ID ( $ xor ) ) gate_type = ID ( $ _XOR_ ) ;
if ( cell - > type = = ID ( $ xnor ) ) gate_type = ID ( $ _XNOR_ ) ;
if ( cell - > type = = ID ( $ bweqx ) ) gate_type = ID ( $ _XNOR_ ) ;
2013-11-24 22:52:30 +01:00
log_assert ( ! gate_type . empty ( ) ) ;
2014-10-10 16:59:44 +02:00
for ( int i = 0 ; i < GetSize ( sig_y ) ; i + + ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , gate_type ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a [ i ] ) ;
gate - > setPort ( ID : : B , sig_b [ i ] ) ;
gate - > setPort ( ID : : Y , sig_y [ i ] ) ;
2013-11-24 22:52:30 +01:00
}
}
2014-12-24 10:49:24 +01:00
void simplemap_reduce ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2013-11-24 22:52:30 +01:00
2014-07-22 20:15:14 +02:00
if ( sig_y . size ( ) = = 0 )
2013-11-24 22:52:30 +01:00
return ;
2015-07-02 11:14:30 +02:00
2014-07-22 20:15:14 +02:00
if ( sig_a . size ( ) = = 0 ) {
2023-09-29 22:20:43 +02:00
if ( cell - > type = = ID ( $ reduce_and ) ) module - > connect ( RTLIL : : SigSig ( sig_y , RTLIL : : SigSpec ( 1 , sig_y . size ( ) ) ) ) ;
if ( cell - > type = = ID ( $ reduce_or ) ) module - > connect ( RTLIL : : SigSig ( sig_y , RTLIL : : SigSpec ( 0 , sig_y . size ( ) ) ) ) ;
if ( cell - > type = = ID ( $ reduce_xor ) ) module - > connect ( RTLIL : : SigSig ( sig_y , RTLIL : : SigSpec ( 0 , sig_y . size ( ) ) ) ) ;
if ( cell - > type = = ID ( $ reduce_xnor ) ) module - > connect ( RTLIL : : SigSig ( sig_y , RTLIL : : SigSpec ( 1 , sig_y . size ( ) ) ) ) ;
if ( cell - > type = = ID ( $ reduce_bool ) ) module - > connect ( RTLIL : : SigSig ( sig_y , RTLIL : : SigSpec ( 0 , sig_y . size ( ) ) ) ) ;
2013-11-24 22:52:30 +01:00
return ;
}
2014-07-22 20:15:14 +02:00
if ( sig_y . size ( ) > 1 ) {
2023-09-29 22:20:43 +02:00
module - > connect ( RTLIL : : SigSig ( sig_y . extract ( 1 , sig_y . size ( ) - 1 ) , RTLIL : : SigSpec ( 0 , sig_y . size ( ) - 1 ) ) ) ;
2013-11-24 22:52:30 +01:00
sig_y = sig_y . extract ( 0 , 1 ) ;
}
2019-08-15 19:05:08 +02:00
IdString gate_type ;
2023-09-29 22:20:43 +02:00
if ( cell - > type = = ID ( $ reduce_and ) ) gate_type = ID ( $ _AND_ ) ;
if ( cell - > type = = ID ( $ reduce_or ) ) gate_type = ID ( $ _OR_ ) ;
if ( cell - > type = = ID ( $ reduce_xor ) ) gate_type = ID ( $ _XOR_ ) ;
if ( cell - > type = = ID ( $ reduce_xnor ) ) gate_type = ID ( $ _XOR_ ) ;
if ( cell - > type = = ID ( $ reduce_bool ) ) gate_type = ID ( $ _OR_ ) ;
2013-11-24 22:52:30 +01:00
log_assert ( ! gate_type . empty ( ) ) ;
2014-07-26 15:57:57 +02:00
RTLIL : : Cell * last_output_cell = NULL ;
2013-11-24 22:52:30 +01:00
2023-09-29 22:20:43 +02:00
while ( sig_a . size ( ) > 1 )
{
2024-12-17 19:48:28 +01:00
RTLIL : : SigSpec sig_t = module - > addWire ( NEW_ID2_SUFFIX ( " t " ) , sig_a . size ( ) / 2 ) ; // SILIMATE: Improve the naming
2013-11-24 22:52:30 +01:00
2023-09-29 22:20:43 +02:00
for ( int i = 0 ; i < sig_a . size ( ) ; i + = 2 )
{
if ( i + 1 = = sig_a . size ( ) ) {
2014-07-23 16:09:27 +02:00
sig_t . append ( sig_a [ i ] ) ;
2013-11-24 22:52:30 +01:00
continue ;
}
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , gate_type ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a [ i ] ) ;
2023-09-29 22:20:43 +02:00
gate - > setPort ( ID : : B , sig_a [ i + 1 ] ) ;
gate - > setPort ( ID : : Y , sig_t [ i / 2 ] ) ;
2014-07-26 15:57:57 +02:00
last_output_cell = gate ;
2013-11-24 22:52:30 +01:00
}
sig_a = sig_t ;
}
2019-08-15 19:05:08 +02:00
if ( cell - > type = = ID ( $ reduce_xnor ) ) {
2024-12-17 19:48:28 +01:00
RTLIL : : SigSpec sig_t = module - > addWire ( NEW_ID2_SUFFIX ( " t " ) ) ; // SILIMATE: Improve the naming
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _NOT_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a ) ;
gate - > setPort ( ID : : Y , sig_t ) ;
2014-07-26 15:57:57 +02:00
last_output_cell = gate ;
2013-11-24 22:52:30 +01:00
sig_a = sig_t ;
}
2014-07-26 15:57:57 +02:00
if ( last_output_cell = = NULL ) {
2014-07-26 14:32:50 +02:00
module - > connect ( RTLIL : : SigSig ( sig_y , sig_a ) ) ;
2013-11-24 22:52:30 +01:00
} else {
2019-08-15 23:50:10 +02:00
last_output_cell - > setPort ( ID : : Y , sig_y ) ;
2013-11-24 22:52:30 +01:00
}
}
2015-04-24 22:04:05 +02:00
static void logic_reduce ( RTLIL : : Module * module , RTLIL : : SigSpec & sig , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2023-09-29 22:20:43 +02:00
while ( sig . size ( ) > 1 )
{
2024-12-17 19:48:28 +01:00
RTLIL : : SigSpec sig_t = module - > addWire ( NEW_ID2_SUFFIX ( " t " ) , sig . size ( ) / 2 ) ; // SILIMATE: Improve the naming
2013-11-24 22:52:30 +01:00
2023-09-29 22:20:43 +02:00
for ( int i = 0 ; i < sig . size ( ) ; i + = 2 )
{
if ( i + 1 = = sig . size ( ) ) {
2014-07-23 16:09:27 +02:00
sig_t . append ( sig [ i ] ) ;
2013-11-24 22:52:30 +01:00
continue ;
}
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _OR_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig [ i ] ) ;
2023-09-29 22:20:43 +02:00
gate - > setPort ( ID : : B , sig [ i + 1 ] ) ;
gate - > setPort ( ID : : Y , sig_t [ i / 2 ] ) ;
2013-11-24 22:52:30 +01:00
}
sig = sig_t ;
}
2014-07-22 20:15:14 +02:00
if ( sig . size ( ) = = 0 )
2019-08-07 01:22:47 +02:00
sig = State : : S0 ;
2013-11-24 22:52:30 +01:00
}
2014-12-24 10:49:24 +01:00
void simplemap_lognot ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
2015-04-24 22:04:05 +02:00
logic_reduce ( module , sig_a , cell ) ;
2013-11-24 22:52:30 +01:00
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2013-11-24 22:52:30 +01:00
2014-07-22 20:15:14 +02:00
if ( sig_y . size ( ) = = 0 )
2013-11-24 22:52:30 +01:00
return ;
2015-07-02 11:14:30 +02:00
2014-07-22 20:15:14 +02:00
if ( sig_y . size ( ) > 1 ) {
2023-09-29 22:20:43 +02:00
module - > connect ( RTLIL : : SigSig ( sig_y . extract ( 1 , sig_y . size ( ) - 1 ) , RTLIL : : SigSpec ( 0 , sig_y . size ( ) - 1 ) ) ) ;
2013-11-24 22:52:30 +01:00
sig_y = sig_y . extract ( 0 , 1 ) ;
}
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _NOT_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a ) ;
gate - > setPort ( ID : : Y , sig_y ) ;
2013-11-24 22:52:30 +01:00
}
2014-12-24 10:49:24 +01:00
void simplemap_logbin ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
2015-04-24 22:04:05 +02:00
logic_reduce ( module , sig_a , cell ) ;
2013-11-24 22:52:30 +01:00
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_b = cell - > getPort ( ID : : B ) ;
2015-04-24 22:04:05 +02:00
logic_reduce ( module , sig_b , cell ) ;
2013-11-24 22:52:30 +01:00
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2013-11-24 22:52:30 +01:00
2014-07-22 20:15:14 +02:00
if ( sig_y . size ( ) = = 0 )
2013-11-24 22:52:30 +01:00
return ;
2015-07-02 11:14:30 +02:00
2014-07-22 20:15:14 +02:00
if ( sig_y . size ( ) > 1 ) {
2023-09-29 22:20:43 +02:00
module - > connect ( RTLIL : : SigSig ( sig_y . extract ( 1 , sig_y . size ( ) - 1 ) , RTLIL : : SigSpec ( 0 , sig_y . size ( ) - 1 ) ) ) ;
2013-11-24 22:52:30 +01:00
sig_y = sig_y . extract ( 0 , 1 ) ;
}
2019-08-15 19:05:08 +02:00
IdString gate_type ;
2023-09-29 22:20:43 +02:00
if ( cell - > type = = ID ( $ logic_and ) ) gate_type = ID ( $ _AND_ ) ;
if ( cell - > type = = ID ( $ logic_or ) ) gate_type = ID ( $ _OR_ ) ;
2013-11-24 22:52:30 +01:00
log_assert ( ! gate_type . empty ( ) ) ;
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , gate_type ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a ) ;
gate - > setPort ( ID : : B , sig_b ) ;
gate - > setPort ( ID : : Y , sig_y ) ;
2013-11-24 22:52:30 +01:00
}
2014-12-24 10:49:24 +01:00
void simplemap_eqne ( RTLIL : : Module * module , RTLIL : : Cell * cell )
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_b = cell - > getPort ( ID : : B ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2020-04-02 18:51:32 +02:00
bool is_signed = cell - > parameters . at ( ID : : A_SIGNED ) . as_bool ( ) ;
2019-08-15 19:05:08 +02:00
bool is_ne = cell - > type . in ( ID ( $ ne ) , ID ( $ nex ) ) ;
2014-12-24 10:49:24 +01:00
2024-11-12 02:06:11 +01:00
RTLIL : : SigSpec xor_out = module - > addWire ( NEW_ID2_SUFFIX ( " xor_out " ) , max ( GetSize ( sig_a ) , GetSize ( sig_b ) ) ) ; // SILIMATE: Improve the naming
RTLIL : : Cell * xor_cell = module - > addXor ( NEW_ID2 , sig_a , sig_b , xor_out , is_signed , cell - > get_src_attribute ( ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
xor_cell - > attributes = cell - > attributes ;
2014-12-24 10:49:24 +01:00
simplemap_bitop ( module , xor_cell ) ;
module - > remove ( xor_cell ) ;
2024-11-12 02:06:11 +01:00
RTLIL : : SigSpec reduce_out = is_ne ? sig_y : module - > addWire ( NEW_ID2_SUFFIX ( " reduce_out " ) ) ; // SILIMATE: Improve the naming
RTLIL : : Cell * reduce_cell = module - > addReduceOr ( NEW_ID2_SUFFIX ( " reduce_or " ) , xor_out , reduce_out , false , cell - > get_src_attribute ( ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
reduce_cell - > attributes = cell - > attributes ;
2014-12-24 10:49:24 +01:00
simplemap_reduce ( module , reduce_cell ) ;
module - > remove ( reduce_cell ) ;
2014-12-25 16:41:20 +01:00
if ( ! is_ne ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * not_cell = module - > addLogicNot ( NEW_ID2_SUFFIX ( " not " ) , reduce_out , sig_y , false , cell - > get_src_attribute ( ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
not_cell - > attributes = cell - > attributes ;
2023-09-29 22:20:43 +02:00
simplemap_lognot ( module , not_cell ) ;
2014-12-25 16:41:20 +01:00
module - > remove ( not_cell ) ;
}
2014-12-24 10:49:24 +01:00
}
void simplemap_mux ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2013-11-24 22:52:30 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_b = cell - > getPort ( ID : : B ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2013-11-24 22:52:30 +01:00
2014-10-10 16:59:44 +02:00
for ( int i = 0 ; i < GetSize ( sig_y ) ; i + + ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _MUX_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a [ i ] ) ;
gate - > setPort ( ID : : B , sig_b [ i ] ) ;
2020-04-02 18:51:32 +02:00
gate - > setPort ( ID : : S , cell - > getPort ( ID : : S ) ) ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : Y , sig_y [ i ] ) ;
2013-11-24 22:52:30 +01:00
}
}
2022-11-02 17:12:51 +01:00
void simplemap_bwmux ( RTLIL : : Module * module , RTLIL : : Cell * cell )
{
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_b = cell - > getPort ( ID : : B ) ;
RTLIL : : SigSpec sig_s = cell - > getPort ( ID : : S ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
for ( int i = 0 ; i < GetSize ( sig_y ) ; i + + ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _MUX_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2022-11-02 17:12:51 +01:00
gate - > setPort ( ID : : A , sig_a [ i ] ) ;
gate - > setPort ( ID : : B , sig_b [ i ] ) ;
gate - > setPort ( ID : : S , sig_s [ i ] ) ;
gate - > setPort ( ID : : Y , sig_y [ i ] ) ;
}
}
2015-08-16 12:54:52 +02:00
void simplemap_tribuf ( RTLIL : : Module * module , RTLIL : : Cell * cell )
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
2020-04-02 18:51:32 +02:00
RTLIL : : SigSpec sig_e = cell - > getPort ( ID : : EN ) ;
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2015-08-16 12:54:52 +02:00
for ( int i = 0 ; i < GetSize ( sig_y ) ; i + + ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _TBUF_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , sig_a [ i ] ) ;
2020-04-02 18:51:32 +02:00
gate - > setPort ( ID : : E , sig_e ) ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : Y , sig_y [ i ] ) ;
2015-08-16 12:54:52 +02:00
}
}
2022-01-24 16:02:29 +01:00
void simplemap_bmux ( RTLIL : : Module * module , RTLIL : : Cell * cell )
{
SigSpec sel = cell - > getPort ( ID : : S ) ;
SigSpec data = cell - > getPort ( ID : : A ) ;
int width = GetSize ( cell - > getPort ( ID : : Y ) ) ;
for ( int idx = 0 ; idx < GetSize ( sel ) ; idx + + ) {
2024-11-12 02:06:11 +01:00
SigSpec new_data = module - > addWire ( NEW_ID2_SUFFIX ( " data " ) , GetSize ( data ) / 2 ) ; // SILIMATE: Improve the naming
2022-01-24 16:02:29 +01:00
for ( int i = 0 ; i < GetSize ( new_data ) ; i + = width ) {
for ( int k = 0 ; k < width ; k + + ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _MUX_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2023-09-29 22:20:43 +02:00
gate - > setPort ( ID : : A , data [ i * 2 + k ] ) ;
gate - > setPort ( ID : : B , data [ i * 2 + width + k ] ) ;
2022-01-24 16:02:29 +01:00
gate - > setPort ( ID : : S , sel [ idx ] ) ;
2023-09-29 22:20:43 +02:00
gate - > setPort ( ID : : Y , new_data [ i + k ] ) ;
2022-01-24 16:02:29 +01:00
}
}
data = new_data ;
}
module - > connect ( cell - > getPort ( ID : : Y ) , data ) ;
}
2015-04-27 10:16:07 +02:00
void simplemap_lut ( RTLIL : : Module * module , RTLIL : : Cell * cell )
{
2019-08-15 23:50:10 +02:00
SigSpec lut_ctrl = cell - > getPort ( ID : : A ) ;
2020-04-02 18:51:32 +02:00
SigSpec lut_data = cell - > getParam ( ID : : LUT ) ;
lut_data . extend_u0 ( 1 < < cell - > getParam ( ID : : WIDTH ) . as_int ( ) ) ;
2015-04-27 10:16:07 +02:00
for ( int idx = 0 ; GetSize ( lut_data ) > 1 ; idx + + ) {
2024-11-12 02:06:11 +01:00
SigSpec new_lut_data = module - > addWire ( NEW_ID2_SUFFIX ( " data " ) , GetSize ( lut_data ) / 2 ) ; // SILIMATE: Improve the naming
2015-04-27 10:16:07 +02:00
for ( int i = 0 ; i < GetSize ( lut_data ) ; i + = 2 ) {
2024-11-12 02:06:11 +01:00
RTLIL : : Cell * gate = module - > addCell ( NEW_ID2 , ID ( $ _MUX_ ) ) ; // SILIMATE: Improve the naming
2024-11-26 00:08:42 +01:00
gate - > attributes = cell - > attributes ;
2019-08-15 23:50:10 +02:00
gate - > setPort ( ID : : A , lut_data [ i ] ) ;
2023-09-29 22:20:43 +02:00
gate - > setPort ( ID : : B , lut_data [ i + 1 ] ) ;
2020-04-02 18:51:32 +02:00
gate - > setPort ( ID : : S , lut_ctrl [ idx ] ) ;
2023-09-29 22:20:43 +02:00
gate - > setPort ( ID : : Y , new_lut_data [ i / 2 ] ) ;
2015-04-27 10:16:07 +02:00
}
lut_data = new_lut_data ;
}
2019-08-15 23:50:10 +02:00
module - > connect ( cell - > getPort ( ID : : Y ) , lut_data ) ;
2015-04-27 10:16:07 +02:00
}
2016-06-17 16:31:16 +02:00
void simplemap_sop ( RTLIL : : Module * module , RTLIL : : Cell * cell )
{
2019-08-15 23:50:10 +02:00
SigSpec ctrl = cell - > getPort ( ID : : A ) ;
2020-04-02 18:51:32 +02:00
SigSpec table = cell - > getParam ( ID : : TABLE ) ;
2016-06-17 16:31:16 +02:00
2020-04-02 18:51:32 +02:00
int width = cell - > getParam ( ID : : WIDTH ) . as_int ( ) ;
int depth = cell - > getParam ( ID : : DEPTH ) . as_int ( ) ;
2016-06-17 16:31:16 +02:00
table . extend_u0 ( 2 * width * depth ) ;
SigSpec products ;
for ( int i = 0 ; i < depth ; i + + ) {
SigSpec in , pat ;
for ( int j = 0 ; j < width ; j + + ) {
2023-09-29 22:20:43 +02:00
if ( table [ 2 * i * width + 2 * j + 0 ] = = State : : S1 ) {
2016-06-17 16:31:16 +02:00
in . append ( ctrl [ j ] ) ;
pat . append ( State : : S0 ) ;
}
2023-09-29 22:20:43 +02:00
if ( table [ 2 * i * width + 2 * j + 1 ] = = State : : S1 ) {
2016-06-17 16:31:16 +02:00
in . append ( ctrl [ j ] ) ;
pat . append ( State : : S1 ) ;
}
}
2024-11-26 00:08:42 +01:00
SigSpec eq_y = module - > addWire ( NEW_ID2_SUFFIX ( " eq_out " ) , max ( GetSize ( in ) , GetSize ( pat ) ) ) ; // SILIMATE: Improve the naming
Cell * eq = module - > addEq ( NEW_ID2_SUFFIX ( " eq " ) , in , pat , eq_y , false , cell - > get_src_attribute ( ) ) ;
eq - > attributes = cell - > attributes ;
products . append ( GetSize ( in ) > 0 ? eq_y : State : : S1 ) ; // SILIMATE: Improve the naming
2016-06-17 16:31:16 +02:00
}
2024-11-26 00:08:42 +01:00
SigSpec red_or_y = module - > addWire ( NEW_ID2_SUFFIX ( " red_or_out " ) , GetSize ( products ) ) ; // SILIMATE: Improve the naming
Cell * red_or = module - > addReduceOr ( NEW_ID2_SUFFIX ( " reduce_or " ) , products , red_or_y , false , cell - > get_src_attribute ( ) ) ;
red_or - > attributes = cell - > attributes ;
module - > connect ( cell - > getPort ( ID : : Y ) , red_or_y ) ; // SILIMATE: Improve the naming
2016-06-17 16:31:16 +02:00
}
2014-12-24 10:49:24 +01:00
void simplemap_slice ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2014-02-07 17:44:57 +01:00
{
2020-04-02 18:51:32 +02:00
int offset = cell - > parameters . at ( ID : : OFFSET ) . as_int ( ) ;
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_a = cell - > getPort ( ID : : A ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2014-07-26 14:32:50 +02:00
module - > connect ( RTLIL : : SigSig ( sig_y , sig_a . extract ( offset , sig_y . size ( ) ) ) ) ;
2014-02-07 17:44:57 +01:00
}
2014-12-24 10:49:24 +01:00
void simplemap_concat ( RTLIL : : Module * module , RTLIL : : Cell * cell )
2014-02-07 17:44:57 +01:00
{
2019-08-15 23:50:10 +02:00
RTLIL : : SigSpec sig_ab = cell - > getPort ( ID : : A ) ;
sig_ab . append ( cell - > getPort ( ID : : B ) ) ;
RTLIL : : SigSpec sig_y = cell - > getPort ( ID : : Y ) ;
2014-07-26 14:32:50 +02:00
module - > connect ( RTLIL : : SigSig ( sig_y , sig_ab ) ) ;
2014-02-07 17:44:57 +01:00
}
2021-10-06 22:16:55 +02:00
void simplemap_ff ( RTLIL : : Module * , RTLIL : : Cell * cell )
2016-10-12 01:18:39 +02:00
{
2021-10-02 00:42:36 +02:00
FfData ff ( nullptr , cell ) ;
for ( int i = 0 ; i < ff . width ; i + + ) {
FfData fff = ff . slice ( { i } ) ;
fff . is_fine = true ;
2021-10-06 22:16:55 +02:00
fff . emit ( ) ;
2020-04-09 03:55:56 +02:00
}
}
2023-09-29 22:20:43 +02:00
void simplemap_get_mappers ( dict < IdString , void ( * ) ( RTLIL : : Module * , RTLIL : : Cell * ) > & mappers )
2013-11-24 23:31:14 +01:00
{
2023-09-29 22:20:43 +02:00
mappers [ ID ( $ not ) ] = simplemap_not ;
mappers [ ID ( $ pos ) ] = simplemap_pos ;
mappers [ ID ( $ and ) ] = simplemap_bitop ;
mappers [ ID ( $ or ) ] = simplemap_bitop ;
mappers [ ID ( $ xor ) ] = simplemap_bitop ;
mappers [ ID ( $ xnor ) ] = simplemap_bitop ;
mappers [ ID ( $ bweqx ) ] = simplemap_bitop ;
mappers [ ID ( $ reduce_and ) ] = simplemap_reduce ;
mappers [ ID ( $ reduce_or ) ] = simplemap_reduce ;
mappers [ ID ( $ reduce_xor ) ] = simplemap_reduce ;
2019-08-15 19:05:08 +02:00
mappers [ ID ( $ reduce_xnor ) ] = simplemap_reduce ;
mappers [ ID ( $ reduce_bool ) ] = simplemap_reduce ;
2023-09-29 22:20:43 +02:00
mappers [ ID ( $ logic_not ) ] = simplemap_lognot ;
mappers [ ID ( $ logic_and ) ] = simplemap_logbin ;
mappers [ ID ( $ logic_or ) ] = simplemap_logbin ;
mappers [ ID ( $ eq ) ] = simplemap_eqne ;
mappers [ ID ( $ eqx ) ] = simplemap_eqne ;
mappers [ ID ( $ ne ) ] = simplemap_eqne ;
mappers [ ID ( $ nex ) ] = simplemap_eqne ;
mappers [ ID ( $ mux ) ] = simplemap_mux ;
mappers [ ID ( $ bwmux ) ] = simplemap_bwmux ;
mappers [ ID ( $ tribuf ) ] = simplemap_tribuf ;
mappers [ ID ( $ bmux ) ] = simplemap_bmux ;
mappers [ ID ( $ lut ) ] = simplemap_lut ;
mappers [ ID ( $ sop ) ] = simplemap_sop ;
mappers [ ID ( $ slice ) ] = simplemap_slice ;
mappers [ ID ( $ concat ) ] = simplemap_concat ;
mappers [ ID ( $ sr ) ] = simplemap_ff ;
mappers [ ID ( $ ff ) ] = simplemap_ff ;
mappers [ ID ( $ dff ) ] = simplemap_ff ;
mappers [ ID ( $ dffe ) ] = simplemap_ff ;
mappers [ ID ( $ dffsr ) ] = simplemap_ff ;
mappers [ ID ( $ dffsre ) ] = simplemap_ff ;
mappers [ ID ( $ adff ) ] = simplemap_ff ;
mappers [ ID ( $ sdff ) ] = simplemap_ff ;
mappers [ ID ( $ adffe ) ] = simplemap_ff ;
mappers [ ID ( $ sdffe ) ] = simplemap_ff ;
mappers [ ID ( $ sdffce ) ] = simplemap_ff ;
mappers [ ID ( $ aldff ) ] = simplemap_ff ;
mappers [ ID ( $ aldffe ) ] = simplemap_ff ;
mappers [ ID ( $ dlatch ) ] = simplemap_ff ;
mappers [ ID ( $ adlatch ) ] = simplemap_ff ;
mappers [ ID ( $ dlatchsr ) ] = simplemap_ff ;
2013-11-24 23:31:14 +01:00
}
2014-12-24 10:49:24 +01:00
void simplemap ( RTLIL : : Module * module , RTLIL : : Cell * cell )
{
2023-09-29 22:20:43 +02:00
static dict < IdString , void ( * ) ( RTLIL : : Module * , RTLIL : : Cell * ) > mappers ;
2014-12-24 10:49:24 +01:00
static bool initialized_mappers = false ;
if ( ! initialized_mappers ) {
simplemap_get_mappers ( mappers ) ;
initialized_mappers = true ;
}
mappers . at ( cell - > type ) ( module , cell ) ;
}
2014-09-27 16:17:53 +02:00
YOSYS_NAMESPACE_END
PRIVATE_NAMESPACE_BEGIN
2013-11-24 22:52:30 +01:00
struct SimplemapPass : public Pass {
2023-09-29 22:20:43 +02:00
SimplemapPass ( ) : Pass ( " simplemap " , " mapping simple coarse-grain cells " ) { }
2020-06-19 01:34:52 +02:00
void help ( ) override
2013-11-24 22:52:30 +01:00
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log ( " \n " ) ;
log ( " simplemap [selection] \n " ) ;
log ( " \n " ) ;
log ( " This pass maps a small selection of simple coarse-grain cells to yosys gate \n " ) ;
log ( " primitives. The following internal cell types are mapped by this pass: \n " ) ;
log ( " \n " ) ;
2014-09-04 02:07:52 +02:00
log ( " $not, $pos, $and, $or, $xor, $xnor \n " ) ;
2013-11-24 22:52:30 +01:00
log ( " $reduce_and, $reduce_or, $reduce_xor, $reduce_xnor, $reduce_bool \n " ) ;
2015-08-16 12:54:52 +02:00
log ( " $logic_not, $logic_and, $logic_or, $mux, $tribuf \n " ) ;
2022-08-24 00:28:27 +02:00
log ( " $sr, $ff, $dff, $dffe, $dffsr, $dffsre, $adff, $adffe, $aldff, $aldffe, $sdff, \n " ) ;
log ( " $sdffe, $sdffce, $dlatch, $adlatch, $dlatchsr \n " ) ;
2013-11-24 22:52:30 +01:00
log ( " \n " ) ;
}
2020-06-19 01:34:52 +02:00
void execute ( std : : vector < std : : string > args , RTLIL : : Design * design ) override
2013-11-24 22:52:30 +01:00
{
2016-04-21 23:28:37 +02:00
log_header ( design , " Executing SIMPLEMAP pass (map simple cells to gate primitives). \n " ) ;
2013-11-24 22:52:30 +01:00
extra_args ( args , 1 , design ) ;
2023-09-29 22:20:43 +02:00
dict < IdString , void ( * ) ( RTLIL : : Module * , RTLIL : : Cell * ) > mappers ;
2013-11-24 23:31:14 +01:00
simplemap_get_mappers ( mappers ) ;
2013-11-24 22:52:30 +01:00
2014-07-27 10:41:42 +02:00
for ( auto mod : design - > modules ( ) ) {
2019-04-20 11:10:05 +02:00
if ( ! design - > selected ( mod ) | | mod - > get_blackbox_attribute ( ) )
2013-11-24 22:52:30 +01:00
continue ;
2023-09-29 22:20:43 +02:00
std : : vector < RTLIL : : Cell * > cells = mod - > cells ( ) ;
2014-07-27 10:41:42 +02:00
for ( auto cell : cells ) {
if ( mappers . count ( cell - > type ) = = 0 )
2013-11-24 22:52:30 +01:00
continue ;
2014-07-27 10:41:42 +02:00
if ( ! design - > selected ( mod , cell ) )
2013-11-24 22:52:30 +01:00
continue ;
2014-07-27 10:41:42 +02:00
log ( " Mapping %s.%s (%s). \n " , log_id ( mod ) , log_id ( cell ) , log_id ( cell - > type ) ) ;
mappers . at ( cell - > type ) ( mod , cell ) ;
mod - > remove ( cell ) ;
2013-11-24 22:52:30 +01:00
}
}
}
} SimplemapPass ;
2015-07-02 11:14:30 +02:00
2014-09-27 16:17:53 +02:00
PRIVATE_NAMESPACE_END