2024-03-01 03:43:34 -06:00
/*
* yosys - - Yosys Open SYnthesis Suite
*
* Copyright ( C ) 2024 Hannah Ravensloft < lofty @ yosyshq . com >
2024-03-01 04:11:23 -06:00
* Copyright ( C ) 2024 Miodrag Milanovic < micko @ yosyshq . com >
2024-03-01 03:43:34 -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 .
*
* 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 .
*
*/
# include "kernel/register.h"
# include "kernel/celltypes.h"
# include "kernel/rtlil.h"
# include "kernel/log.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SynthNanoXplorePass : public ScriptPass
{
SynthNanoXplorePass ( ) : ScriptPass ( " synth_nanoxplore " , " synthesis for NanoXplore FPGAs " ) { }
void on_register ( ) override
{
RTLIL : : constpad [ " synth_nanoxplore.abc9.W " ] = " 300 " ;
}
void help ( ) override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log ( " \n " ) ;
log ( " synth_nanoxplore [options] \n " ) ;
log ( " \n " ) ;
log ( " This command runs synthesis for NanoXplore FPGAs. \n " ) ;
log ( " \n " ) ;
log ( " -top <module> \n " ) ;
log ( " use the specified module as top module \n " ) ;
log ( " \n " ) ;
2024-03-01 04:11:23 -06:00
log ( " -family <family> \n " ) ;
log ( " run synthesis for the specified NanoXplore architecture \n " ) ;
log ( " generate the synthesis netlist for the specified family. \n " ) ;
log ( " supported values: \n " ) ;
log ( " - medium: NG-Medium \n " ) ;
log ( " - large: NG-Large \n " ) ;
log ( " - ultra: NG-Ultra \n " ) ;
log ( " - u300: NG-Ultra300 \n " ) ;
log ( " \n " ) ;
2024-03-01 03:43:34 -06:00
log ( " -json <file> \n " ) ;
log ( " write the design to the specified JSON file. writing of an output file \n " ) ;
log ( " is omitted if this parameter is not specified. \n " ) ;
log ( " \n " ) ;
log ( " -run <from_label>:<to_label> \n " ) ;
log ( " only run the commands between the labels (see below). an empty \n " ) ;
log ( " from label is synonymous to 'begin', and empty to label is \n " ) ;
log ( " synonymous to the end of the command list. \n " ) ;
log ( " \n " ) ;
log ( " -noflatten \n " ) ;
log ( " do not flatten design before synthesis \n " ) ;
log ( " \n " ) ;
log ( " -abc9 \n " ) ;
log ( " use new ABC9 flow (EXPERIMENTAL) \n " ) ;
log ( " \n " ) ;
2024-03-01 04:11:23 -06:00
log ( " -nocy \n " ) ;
log ( " do not map adders to CY cells \n " ) ;
log ( " \n " ) ;
2024-04-29 01:18:04 -05:00
log ( " -nodffe \n " ) ;
log ( " do not use flipflops with L in output netlist \n " ) ;
log ( " \n " ) ;
2024-03-13 12:19:41 -05:00
log ( " -norfram \n " ) ;
log ( " do not use Register File RAM cells in output netlist \n " ) ;
2024-03-01 06:41:25 -06:00
log ( " \n " ) ;
log ( " -nobram \n " ) ;
2024-03-13 12:19:41 -05:00
log ( " do not use block NX_RAM cells in output netlist \n " ) ;
2024-03-01 06:41:25 -06:00
log ( " \n " ) ;
log ( " -nodsp \n " ) ;
log ( " do not map multipliers to NX_DSP cells \n " ) ;
log ( " \n " ) ;
2024-03-01 06:52:11 -06:00
log ( " -iopad \n " ) ;
log ( " insert IO buffers \n " ) ;
2024-03-01 06:41:25 -06:00
log ( " \n " ) ;
2024-03-14 02:40:14 -05:00
log ( " -no-rw-check \n " ) ;
log ( " marks all recognized read ports as \" return don't-care value on \n " ) ;
log ( " read/write collision \" (same result as setting the no_rw_check \n " ) ;
log ( " attribute on all memories). \n " ) ;
log ( " \n " ) ;
2024-03-01 03:43:34 -06:00
log ( " \n " ) ;
log ( " The following commands are executed by this synthesis command: \n " ) ;
help_script ( ) ;
log ( " \n " ) ;
}
2024-03-01 04:11:23 -06:00
string top_opt , json_file , family ;
2024-04-29 01:18:04 -05:00
bool flatten , abc9 , nocy , nodffe , norfram , nobram , nodsp , iopad , no_rw_check ;
2024-03-14 02:40:14 -05:00
std : : string postfix ;
2024-03-01 03:43:34 -06:00
void clear_flags ( ) override
{
top_opt = " -auto-top " ;
json_file = " " ;
2024-03-01 04:11:23 -06:00
family = " " ;
2024-03-01 03:43:34 -06:00
flatten = true ;
abc9 = false ;
2024-03-01 04:11:23 -06:00
nocy = false ;
2024-04-29 01:18:04 -05:00
nodffe = false ;
2024-03-13 12:19:41 -05:00
norfram = false ;
2024-03-01 06:41:25 -06:00
nobram = false ;
nodsp = false ;
2024-03-01 06:52:11 -06:00
iopad = false ;
2024-03-14 02:40:14 -05:00
no_rw_check = false ;
2024-03-11 07:03:20 -05:00
postfix = " " ;
2024-03-01 03:43:34 -06:00
}
void execute ( std : : vector < std : : string > args , RTLIL : : Design * design ) override
{
string run_from , run_to ;
clear_flags ( ) ;
size_t argidx ;
for ( argidx = 1 ; argidx < args . size ( ) ; argidx + + )
{
if ( args [ argidx ] = = " -top " & & argidx + 1 < args . size ( ) ) {
top_opt = " -top " + args [ + + argidx ] ;
continue ;
}
2024-03-01 04:11:23 -06:00
if ( ( args [ argidx ] = = " -family " | | args [ argidx ] = = " -arch " ) & & argidx + 1 < args . size ( ) ) {
family = args [ + + argidx ] ;
continue ;
}
2024-03-01 03:43:34 -06:00
if ( args [ argidx ] = = " -json " & & argidx + 1 < args . size ( ) ) {
json_file = args [ + + argidx ] ;
continue ;
}
if ( args [ argidx ] = = " -run " & & argidx + 1 < args . size ( ) ) {
size_t pos = args [ argidx + 1 ] . find ( ' : ' ) ;
if ( pos = = std : : string : : npos )
break ;
run_from = args [ + + argidx ] . substr ( 0 , pos ) ;
run_to = args [ argidx ] . substr ( pos + 1 ) ;
continue ;
}
if ( args [ argidx ] = = " -flatten " ) {
flatten = true ;
continue ;
}
if ( args [ argidx ] = = " -noflatten " ) {
flatten = false ;
continue ;
}
if ( args [ argidx ] = = " -abc9 " ) {
abc9 = true ;
continue ;
}
2024-03-01 04:11:23 -06:00
if ( args [ argidx ] = = " -nocy " ) {
nocy = true ;
continue ;
}
2024-04-29 01:18:04 -05:00
if ( args [ argidx ] = = " -nodffe " ) {
nodffe = true ;
continue ;
}
2024-03-13 12:19:41 -05:00
if ( args [ argidx ] = = " -norfram " ) {
norfram = true ;
2024-03-01 06:41:25 -06:00
continue ;
}
if ( args [ argidx ] = = " -nobram " ) {
nobram = true ;
continue ;
}
if ( args [ argidx ] = = " -nodsp " ) {
nodsp = true ;
continue ;
}
2024-03-01 06:52:11 -06:00
if ( args [ argidx ] = = " -iopad " ) {
iopad = true ;
2024-03-01 06:41:25 -06:00
continue ;
}
2024-03-14 02:40:14 -05:00
if ( args [ argidx ] = = " -no-rw-check " ) {
no_rw_check = true ;
continue ;
}
2024-03-01 03:43:34 -06:00
break ;
}
extra_args ( args , argidx , design ) ;
2024-03-01 04:11:23 -06:00
if ( family . empty ( ) ) {
2024-03-01 06:41:25 -06:00
//log_warning("NanoXplore family not set, setting it to NG-ULTRA.\n");
2024-03-01 04:11:23 -06:00
family = " ultra " ;
}
2024-03-11 07:03:20 -05:00
if ( family = = " ultra " ) {
postfix = " _u " ;
} else if ( family = = " u300 " ) {
postfix = " _u " ;
} else if ( family = = " medium " ) {
postfix = " _m " ;
} else if ( family = = " large " ) {
postfix = " _l " ;
} else
log_cmd_error ( " Invalid NanoXplore -family setting: '%s'. \n " , family . c_str ( ) ) ;
2024-03-01 03:43:34 -06:00
if ( ! design - > full_selection ( ) )
log_cmd_error ( " This command only operates on fully selected designs! \n " ) ;
log_header ( design , " Executing SYNTH_NANOXPLORE pass. \n " ) ;
log_push ( ) ;
run_script ( design , run_from , run_to ) ;
log_pop ( ) ;
}
void script ( ) override
{
2024-03-14 02:40:14 -05:00
std : : string no_rw_check_opt = " " ;
if ( no_rw_check )
no_rw_check_opt = " -no-rw-check " ;
if ( help_mode )
no_rw_check_opt = " [-no-rw-check] " ;
2024-03-01 03:43:34 -06:00
if ( check_label ( " begin " ) )
{
2024-05-10 04:15:56 -05:00
run ( " read_verilog -lib -specify +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim " + postfix + " .v +/nanoxplore/cells_bb.v +/nanoxplore/cells_bb " + postfix + " .v " ) ;
2024-03-13 05:09:02 -05:00
run ( " techmap -map +/nanoxplore/cells_wrap.v " ) ;
2024-03-11 07:03:20 -05:00
run ( " techmap -map +/nanoxplore/cells_wrap " + postfix + " .v " ) ;
2024-03-01 03:43:34 -06:00
run ( stringf ( " hierarchy -check %s " , help_mode ? " -top <top> " : top_opt . c_str ( ) ) ) ;
}
if ( check_label ( " coarse " ) )
{
run ( " proc " ) ;
if ( flatten | | help_mode )
run ( " flatten " , " (skip if -noflatten) " ) ;
run ( " tribuf -logic " ) ;
run ( " deminout " ) ;
run ( " opt_expr " ) ;
run ( " opt_clean " ) ;
run ( " check " ) ;
run ( " opt -nodffe -nosdff " ) ;
run ( " fsm " ) ;
run ( " opt " ) ;
run ( " wreduce " ) ;
run ( " peepopt " ) ;
run ( " opt_clean " ) ;
run ( " share " ) ;
run ( " techmap -map +/cmp2lut.v -D LUT_WIDTH=4 " ) ;
run ( " opt_expr " ) ;
run ( " opt_clean " ) ;
run ( " alumacc " ) ;
run ( " opt " ) ;
2024-03-14 02:40:14 -05:00
run ( " memory -nomap " + no_rw_check_opt ) ;
2024-03-01 03:43:34 -06:00
run ( " opt_clean " ) ;
}
2024-03-13 12:19:41 -05:00
if ( check_label ( " map_ram " ) )
{
std : : string args = " " ;
if ( nobram )
args + = " -no-auto-block " ;
if ( norfram )
args + = " -no-auto-distributed " ;
if ( help_mode )
args + = " [-no-auto-block] [-no-auto-distributed] " ;
2024-03-14 02:40:14 -05:00
run ( " memory_libmap -lib +/nanoxplore/rf_rams " + postfix + " .txt -lib +/nanoxplore/brams.txt " + args , " (-no-auto-block if -nobram, -no-auto-distributed if -norfram) " ) ;
run ( " techmap -map +/nanoxplore/rf_rams_map " + postfix + " .v -map +/nanoxplore/brams_map.v " ) ;
2024-04-24 04:28:03 -05:00
run ( " techmap -map +/nanoxplore/cells_wrap.v t:NX_RAM* " ) ;
2024-03-13 12:19:41 -05:00
run ( " techmap -map +/nanoxplore/cells_wrap " + postfix + " .v t:NX_XRFB* t:NX_RFB* " ) ;
2024-03-01 03:43:34 -06:00
}
if ( check_label ( " map_ffram " ) )
{
2024-04-24 04:01:27 -05:00
run ( " opt -fast -mux_undef -undriven -fine " ) ;
2024-03-01 03:43:34 -06:00
run ( " memory_map " ) ;
2024-04-24 04:01:27 -05:00
run ( " opt -undriven -fine -mux_undef " ) ;
2024-03-01 03:43:34 -06:00
}
if ( check_label ( " map_gates " ) )
{
2024-03-01 04:11:23 -06:00
if ( nocy )
run ( " techmap " ) ;
2024-03-18 07:27:33 -05:00
else {
2024-03-01 04:11:23 -06:00
run ( " techmap -map +/techmap.v -map +/nanoxplore/arith_map.v " ) ;
2024-03-18 07:27:33 -05:00
run ( " nx_carry " ) ;
}
2024-03-01 06:52:11 -06:00
if ( help_mode | | iopad ) {
2024-05-07 02:06:10 -05:00
run ( " iopadmap -bits -outpad $__BEYOND_OBUF I:PAD -toutpad $__BEYOND_TOBUF C:I:PAD -inpad $__BEYOND_IBUF O:PAD -tinoutpad $__BEYOND_IOBUF C:O:I:PAD A:top " , " (only if '-iopad') " ) ;
2024-03-01 06:52:11 -06:00
run ( " techmap -map +/nanoxplore/io_map.v " ) ;
}
2024-03-01 03:43:34 -06:00
run ( " opt -fast " ) ;
}
if ( check_label ( " map_ffs " ) )
{
2024-04-30 06:40:35 -05:00
std : : string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r " ;
2024-04-29 01:18:04 -05:00
if ( help_mode ) {
2024-04-30 06:40:35 -05:00
dfflegalize_args + = " [-cell $_DFFE_?P_ 01 -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r] " ;
2024-04-29 01:18:04 -05:00
} else if ( ! nodffe ) {
2024-04-30 06:40:35 -05:00
dfflegalize_args + = " -cell $_DFFE_?P_ 01 -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r " ;
2024-04-29 01:18:04 -05:00
}
dfflegalize_args + = " -cell $_DLATCH_?_ x " ;
run ( " dfflegalize " + dfflegalize_args , " ($_*DFFE_* only if not -nodffe) " ) ;
2024-04-19 11:09:47 -05:00
run ( " techmap -map +/nanoxplore/latches_map.v " ) ;
2024-03-01 03:43:34 -06:00
run ( " techmap -map +/nanoxplore/cells_map.v " ) ;
run ( " opt_expr -undriven -mux_undef " ) ;
run ( " clean -purge " ) ;
}
if ( check_label ( " map_luts " ) )
{
if ( abc9 ) {
std : : string abc9_opts = " -maxlut 4 " ;
std : : string k = " synth_nanoxplore.abc9.W " ;
if ( active_design & & active_design - > scratchpad . count ( k ) )
abc9_opts + = stringf ( " -W %s " , active_design - > scratchpad_get_string ( k ) . c_str ( ) ) ;
else
abc9_opts + = stringf ( " -W %s " , RTLIL : : constpad . at ( k ) . c_str ( ) ) ;
run ( " abc9 " + abc9_opts ) ;
} else {
std : : string abc_args = " -dress " ;
abc_args + = " -lut 4 " ;
run ( " abc " + abc_args ) ;
}
run ( " techmap -map +/nanoxplore/cells_map.v t:$lut " ) ;
run ( " opt -fast " ) ;
run ( " clean " ) ;
}
if ( check_label ( " check " ) )
{
run ( " autoname " ) ;
run ( " hierarchy -check " ) ;
run ( " stat " ) ;
run ( " check -noinit " ) ;
run ( " blackbox =A:whitebox " ) ;
}
if ( check_label ( " json " ) )
{
if ( ! json_file . empty ( ) | | help_mode )
run ( stringf ( " write_json %s " , help_mode ? " <file-name> " : json_file . c_str ( ) ) ) ;
}
}
} SynthNanoXplorePass ;
PRIVATE_NAMESPACE_END