@@ -82,6 +82,7 @@ struct SynthFpgaPass : public ScriptPass {
8282 // DFFs
8383 //
8484 pool<string> ys_dff_features;
85+ dict<string, string> ys_dff_models;
8586 string ys_dff_techmap = " " ;
8687 vector<string> ys_legal_flops;
8788 // BRAMs
@@ -357,6 +358,7 @@ struct SynthFpgaPass : public ScriptPass {
357358 "lut_size": 4,
358359 "flipflops": {
359360 "features": ["async_reset", "sync_reset", "sync_set", "flop_enable"],
361+ "models": {"dffr": "cad/techlib_custom_plugin/dffr.v", "dff": "cad/techlib_custom_plugin/dff.v", "dffe": "cad/techlib_custom_plugin/dffe.v", "dffer": "cad/techlib_custom_plugin/dffer.v"},
360362 "legalize_list": ["\$_DFFE_PP_", "\$_SDFF_PN1_", "\$_DFFE_PN0P_", "\$_DFF_PN0_", "\$_SDFF_PN0_", "\$_SDFFE_PN0P_", "\$_SDFFE_PN1P_", "\$_DFF_P_"],
361363 "techmap": "tech_flops.v"
362364 },
@@ -390,10 +392,10 @@ struct SynthFpgaPass : public ScriptPass {
390392 string partname;
391393 int lut_size;
392394
393- std::vector<std::string> illegal_final_state_cells;
394395 // DFF related
395396 //
396397 pool<string> dff_features;
398+ dict<string, string> dff_models;
397399
398400 string dff_techmap;
399401 vector<string> legal_flops;
@@ -445,6 +447,12 @@ struct SynthFpgaPass : public ScriptPass {
445447 log (" %s\n " , it.c_str ());
446448 }
447449
450+ log (" DFF MODELS : \n " );
451+ for (auto it : G_config.dff_models ) {
452+ log (" %s %s\n " , (it.first ).c_str (),
453+ (it.second ).c_str ());
454+ }
455+
448456 log (" DFF Legal Flop Types : \n " );
449457 for (auto it : G_config.legal_flops ) {
450458 log (" %s\n " , (it).c_str ());
@@ -490,10 +498,6 @@ struct SynthFpgaPass : public ScriptPass {
490498 log (" DSP pack_command : \n " );
491499 log (" %s\n " , (G_config.dsps_pack_command ).c_str ());
492500
493- log (" Illegal final state cells (flow will error out if these are still around at end of synthesis) : \n " );
494- for (auto it : G_config.illegal_final_state_cells ) {
495- log (" %s\n " , (it).c_str ());
496- }
497501 log (" ====================================================================="
498502 " =====\n " );
499503 }
@@ -632,6 +636,24 @@ struct SynthFpgaPass : public ScriptPass {
632636 ys_dff_features.insert (" async_set" );
633637 ys_dff_features.insert (" flop_enable" );
634638
639+ // Async. reset DFFs
640+ //
641+ ys_dff_models[" dff" ] = " +/plugins/wildebeest/ff_models/dff.v" ;
642+ ys_dff_models[" dffr" ] = " +/plugins/wildebeest/ff_models/dffr.v" ;
643+ ys_dff_models[" dffs" ] = " +/plugins/wildebeest/ff_models/dffs.v" ;
644+ ys_dff_models[" dffe" ] = " +/plugins/wildebeest/ff_models/dffe.v" ;
645+ ys_dff_models[" dffer" ] = " +/plugins/wildebeest/ff_models/dffer.v" ;
646+ ys_dff_models[" dffes" ] = " +/plugins/wildebeest/ff_models/dffes.v" ;
647+
648+ // Sync. set/reset DFFs
649+ //
650+ ys_dff_models[" dffh" ] = " +/plugins/wildebeest/ff_models/dffh.v" ;
651+ ys_dff_models[" dffeh" ] = " +/plugins/wildebeest/ff_models/dffeh.v" ;
652+ ys_dff_models[" dffl" ] = " +/plugins/wildebeest/ff_models/dffl.v" ;
653+ ys_dff_models[" dffel" ] = " +/plugins/wildebeest/ff_models/dffel.v" ;
654+ ys_dff_models[" dffhl" ] = " +/plugins/wildebeest/ff_models/dffhl.v" ;
655+ ys_dff_models[" dffehl" ] = " +/plugins/wildebeest/ff_models/dffehl.v" ;
656+
635657 // Legal Flops for dfflegalize
636658 //
637659 if ((part_name == " z1010" ) || (part_name == " z1060" )) {
@@ -912,14 +934,6 @@ struct SynthFpgaPass : public ScriptPass {
912934 log_error (" 'lut_size' must be an integer.\n " );
913935 }
914936
915- // illegal intermediate cell types (optional parameter)
916- if (root.data_dict .count (" illegal_final_state_cells" ) > 0 ) {
917- JsonNode *illegal_cells = root.data_dict .at (" illegal_final_state_cells" );
918- if (illegal_cells->type != ' A' ) {
919- log_error (" 'illegal_final_state_cells' must be an array.\n " );
920- }
921- }
922-
923937 // flipflops
924938 if (root.data_dict .count (" flipflops" ) == 0 ) {
925939 log_error (" 'flipflops' is missing in config file '%s'.\n " ,
@@ -990,27 +1004,6 @@ struct SynthFpgaPass : public ScriptPass {
9901004 (G_config.root_path ).c_str ());
9911005 }
9921006
993- // Process illegal intermediate cells
994- if (root.data_dict .count (" illegal_final_state_cells" )) {
995- JsonNode *illegal_cells = root.data_dict .at (" illegal_final_state_cells" );
996-
997- if (illegal_cells->type != ' A' ) {
998- log_error (
999- " 'illegal_final_state_cells' must be an array.\n " );
1000- }
1001-
1002- for (const auto & it : illegal_cells->data_array ) {
1003- JsonNode *illegal_cell = it;
1004- if (illegal_cell->type != ' S' ) {
1005- log_error (" Array associated to 'illegal_final_state_cells' must contain "
1006- " only strings.\n " );
1007- }
1008- std::string illegal_cell_string = illegal_cell->data_string ;
1009-
1010- (G_config.illegal_final_state_cells ).push_back (illegal_cell_string);
1011- }
1012-
1013- }
10141007 // Extract DFF associated parameters
10151008 //
10161009 if (flipflops->data_dict .count (" features" ) == 0 ) {
@@ -1033,6 +1026,27 @@ struct SynthFpgaPass : public ScriptPass {
10331026 (G_config.dff_features ).insert (dff_mode_str);
10341027 }
10351028
1029+ if (flipflops->data_dict .count (" models" ) == 0 ) {
1030+ log_error (" 'models' from 'flipflops' is missing in config file '%s'.\n " ,
1031+ config_file.c_str ());
1032+ }
1033+
1034+ JsonNode *dff_models = flipflops->data_dict .at (" models" );
1035+ if (dff_models->type != ' D' ) {
1036+ log_warning (" 'models' associated to 'flipflops' must be a dictionary to be read in. Ignoring contents.\n " );
1037+ }
1038+
1039+ for (auto it : dff_models->data_dict ) {
1040+ string dff_model_str = it.first ;
1041+ JsonNode *dff_model_path = it.second ;
1042+ if (dff_model_path->type != ' S' ) {
1043+ log_error (
1044+ " Second element associated to DFF models '%s' must be a string.\n " ,
1045+ dff_model_str.c_str ());
1046+ }
1047+ G_config.dff_models [dff_model_str] = dff_model_path->data_string ;
1048+ }
1049+
10361050 if (flipflops->data_dict .count (" legalize_list" ) == 0 ) {
10371051 log_error (
10381052 " 'legalize_list' from 'flipflops' is missing in config file '%s'.\n " ,
@@ -2398,24 +2412,7 @@ struct SynthFpgaPass : public ScriptPass {
23982412 // -------------------------
23992413 //
24002414 void load_bb_cells_models () {
2401- run (" read_verilog +/plugins/wildebeest/ff_models/dffer.v" );
2402- run (" read_verilog +/plugins/wildebeest/ff_models/dffes.v" );
2403- run (" read_verilog +/plugins/wildebeest/ff_models/dffe.v" );
2404- run (" read_verilog +/plugins/wildebeest/ff_models/dffr.v" );
2405- run (" read_verilog +/plugins/wildebeest/ff_models/dffs.v" );
2406- run (" read_verilog +/plugins/wildebeest/ff_models/dff.v" );
2407-
2408- run (" read_verilog +/plugins/wildebeest/ff_models/dffh.v" );
2409- run (" read_verilog +/plugins/wildebeest/ff_models/dffeh.v" );
2410- run (" read_verilog +/plugins/wildebeest/ff_models/dffl.v" );
2411- run (" read_verilog +/plugins/wildebeest/ff_models/dffel.v" );
2412- run (" read_verilog +/plugins/wildebeest/ff_models/dffhl.v" );
2413- run (" read_verilog +/plugins/wildebeest/ff_models/dffehl.v" );
2414-
2415- if (part_name == " z1010" ) {
2416- run (" read_verilog "
2417- " +/plugins/wildebeest/architecture/z1010/models/tech_mae.v" );
2418- }
2415+ load_hardcoded_cell_models ();
24192416
24202417 // Black box them all
24212418 //
@@ -2735,6 +2732,10 @@ struct SynthFpgaPass : public ScriptPass {
27352732 run (" chtype -set $mul t:$__soft_mul" );
27362733
27372734 run (" stat" );
2735+
2736+ if (has_cell_type (yosys_get_design (), " \\ MAE" )) {
2737+ log_error (" Could not techmap DSP to a valid configuration.\n " );
2738+ }
27382739 }
27392740
27402741 // -------------------------
@@ -3547,30 +3548,6 @@ struct SynthFpgaPass : public ScriptPass {
35473548 analyze_undriven_nets (yosys_get_design ()->top_module (),
35483549 true /* connect undriven nets to undef */ );
35493550
3550- if (has_cell_type (yosys_get_design (), " \\ MAE" )) {
3551- log_error (" Could not techmap DSP to a valid configuration.\n " );
3552- }
3553-
3554- // Check for cell types that shouldn't be around at the end
3555- pool<RTLIL::IdString> cell_types_present;
3556- for (auto *mod : yosys_get_design ()->modules ()) {
3557- for (auto *cell : mod->cells ()) {
3558- cell_types_present.insert (cell->type );
3559- }
3560- }
3561- for (const auto &cell_type : G_config.illegal_final_state_cells ) {
3562- if (cell_type.empty ()) {
3563- continue ;
3564- }
3565- if ((cell_type[0 ] != ' $' && cell_type[0 ] != ' \\ ' )) {
3566- log_warning (" Skipping check for illegal final state cell '%s' because cell type does not begin with '$' or '\\ '.\n " , cell_type.c_str ());
3567- continue ;
3568- }
3569- if (cell_types_present.count (cell_type))
3570- log_error (" Synthesis error: illegal final state cell '%s' is still present at end of synthesis.\n " ,
3571- cell_type.c_str ());
3572- }
3573-
35743551 // tries to give public names instead of using $abc generic names.
35753552 // Right now this procedure blows up runtime for medium/big designs.
35763553 // This 'autoname' procedure needs to be re-written to be efficient.
0 commit comments