mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Merge branch 'master' into eddie/fix1178
This commit is contained in:
		
						commit
						7129a03083
					
				
					 26 changed files with 1204 additions and 93 deletions
				
			
		| 
						 | 
				
			
			@ -13,6 +13,7 @@ Yosys 0.9 .. Yosys 0.9-dev
 | 
			
		|||
    - Added "synth_ice40 -abc9" (experimental)
 | 
			
		||||
    - Added "synth -abc9" (experimental)
 | 
			
		||||
    - Added "script -scriptwire
 | 
			
		||||
    - "synth_xilinx" to now infer wide multiplexers (-widemux <min> to enable)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Yosys 0.8 .. Yosys 0.8-dev
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -222,7 +222,7 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
 | 
			
		|||
				case RTLIL::S1: bin_digits.push_back('1'); break;
 | 
			
		||||
				case RTLIL::Sx: bin_digits.push_back('x'); break;
 | 
			
		||||
				case RTLIL::Sz: bin_digits.push_back('z'); break;
 | 
			
		||||
				case RTLIL::Sa: bin_digits.push_back('z'); break;
 | 
			
		||||
				case RTLIL::Sa: bin_digits.push_back('?'); break;
 | 
			
		||||
				case RTLIL::Sm: log_error("Found marker state in final netlist.");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -251,6 +251,12 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
 | 
			
		|||
					hex_digits.push_back('z');
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if (bit_3 == '?' || bit_2 == '?' || bit_1 == '?' || bit_0 == '?') {
 | 
			
		||||
					if (bit_3 != '?' || bit_2 != '?' || bit_1 != '?' || bit_0 != '?')
 | 
			
		||||
						goto dump_bin;
 | 
			
		||||
					hex_digits.push_back('?');
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				int val = 8*(bit_3 - '0') + 4*(bit_2 - '0') + 2*(bit_1 - '0') + (bit_0 - '0');
 | 
			
		||||
				hex_digits.push_back(val < 10 ? '0' + val : 'a' + val - 10);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +276,7 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o
 | 
			
		|||
				case RTLIL::S1: f << stringf("1"); break;
 | 
			
		||||
				case RTLIL::Sx: f << stringf("x"); break;
 | 
			
		||||
				case RTLIL::Sz: f << stringf("z"); break;
 | 
			
		||||
				case RTLIL::Sa: f << stringf("z"); break;
 | 
			
		||||
				case RTLIL::Sa: f << stringf("?"); break;
 | 
			
		||||
				case RTLIL::Sm: log_error("Found marker state in final netlist.");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1062,8 +1062,8 @@ struct AigerFrontend : public Frontend {
 | 
			
		|||
		if (module_name.empty()) {
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
			char fname[_MAX_FNAME];
 | 
			
		||||
			_splitpath(filename.c_str(), NULL /* drive */, NULL /* dir */, fname, NULL /* ext */)
 | 
			
		||||
				module_name = fname;
 | 
			
		||||
			_splitpath(filename.c_str(), NULL /* drive */, NULL /* dir */, fname, NULL /* ext */);
 | 
			
		||||
			module_name = fname;
 | 
			
		||||
#else
 | 
			
		||||
			char* bn = strdup(filename.c_str());
 | 
			
		||||
			module_name = RTLIL::escape_id(bn);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,6 +253,13 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
						SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
 | 
			
		||||
						Const rstval = cell->parameters["\\ARST_VALUE"];
 | 
			
		||||
 | 
			
		||||
						Wire *past_arst = module->addWire(NEW_ID);
 | 
			
		||||
						module->addFf(NEW_ID, arst, past_arst);
 | 
			
		||||
						if (cell->parameters["\\ARST_POLARITY"].as_bool())
 | 
			
		||||
							arst = module->LogicOr(NEW_ID, arst, past_arst);
 | 
			
		||||
						else
 | 
			
		||||
							arst = module->LogicAnd(NEW_ID, arst, past_arst);
 | 
			
		||||
 | 
			
		||||
						if (cell->parameters["\\ARST_POLARITY"].as_bool())
 | 
			
		||||
							module->addMux(NEW_ID, qval, rstval, arst, sig_q);
 | 
			
		||||
						else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@
 | 
			
		|||
						"&st; &if -g -K 6; &dch -f; &if {W}; &save; &load; "\
 | 
			
		||||
						"&st; &if -g -K 6; &synch2; &if {W}; &save; &load"
 | 
			
		||||
#else
 | 
			
		||||
#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps -l; &if {W} {D} -v; "/*"&mfs; "*/"&ps -l"
 | 
			
		||||
#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps -l; &if {W} {D} -v; &mfs; &ps -l"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -263,6 +263,25 @@ struct AttrmapPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				for (auto cell : module->selected_cells())
 | 
			
		||||
					attrmap_apply(stringf("%s.%s", log_id(module), log_id(cell)), actions, cell->attributes);
 | 
			
		||||
 | 
			
		||||
				for (auto proc : module->processes)
 | 
			
		||||
				{
 | 
			
		||||
					if (!design->selected(module, proc.second))
 | 
			
		||||
						continue;
 | 
			
		||||
					attrmap_apply(stringf("%s.%s", log_id(module), log_id(proc.first)), actions, proc.second->attributes);
 | 
			
		||||
 | 
			
		||||
					std::vector<RTLIL::CaseRule*> all_cases = {&proc.second->root_case};
 | 
			
		||||
					while (!all_cases.empty()) {
 | 
			
		||||
						RTLIL::CaseRule *cs = all_cases.back();
 | 
			
		||||
						all_cases.pop_back();
 | 
			
		||||
						attrmap_apply(stringf("%s.%s (case)", log_id(module), log_id(proc.first)), actions, cs->attributes);
 | 
			
		||||
 | 
			
		||||
						for (auto &sw : cs->switches) {
 | 
			
		||||
							attrmap_apply(stringf("%s.%s (switch)", log_id(module), log_id(proc.first)), actions, sw->attributes);
 | 
			
		||||
							all_cases.insert(all_cases.end(), sw->cases.begin(), sw->cases.end());
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -199,6 +199,9 @@ struct SynthEcp5Pass : public ScriptPass
 | 
			
		|||
		if (!design->full_selection())
 | 
			
		||||
			log_cmd_error("This command only operates on fully selected designs!\n");
 | 
			
		||||
 | 
			
		||||
		if (abc9 && retime)
 | 
			
		||||
				log_cmd_error("-retime option not currently compatible with -abc9!\n");
 | 
			
		||||
 | 
			
		||||
		log_header(design, "Executing SYNTH_ECP5 pass.\n");
 | 
			
		||||
		log_push();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,9 +67,6 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
		log("    -retime\n");
 | 
			
		||||
		log("        run 'abc' with -dff option\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -relut\n");
 | 
			
		||||
		log("        combine LUTs after synthesis\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -nocarry\n");
 | 
			
		||||
		log("        do not use SB_CARRY cells in output netlist\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +75,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
		log("\n");
 | 
			
		||||
		log("    -dffe_min_ce_use <min_ce_use>\n");
 | 
			
		||||
		log("        do not use SB_DFFE* cells if the resulting CE line would go to less\n");
 | 
			
		||||
		log("        than min_ce_use SB_DFFE*in output netlist\n");
 | 
			
		||||
		log("        than min_ce_use SB_DFFE* in output netlist\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -nobram\n");
 | 
			
		||||
		log("        do not use SB_RAM40_4K* cells in output netlist\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +103,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	string top_opt, blif_file, edif_file, json_file, abc, device_opt;
 | 
			
		||||
	bool nocarry, nodffe, nobram, dsp, flatten, retime, relut, noabc, abc2, vpr;
 | 
			
		||||
	bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr;
 | 
			
		||||
	int min_ce_use;
 | 
			
		||||
 | 
			
		||||
	void clear_flags() YS_OVERRIDE
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +119,6 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
		dsp = false;
 | 
			
		||||
		flatten = true;
 | 
			
		||||
		retime = false;
 | 
			
		||||
		relut = false;
 | 
			
		||||
		noabc = false;
 | 
			
		||||
		abc2 = false;
 | 
			
		||||
		vpr = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +171,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-relut") {
 | 
			
		||||
				relut = true;
 | 
			
		||||
				// removed, opt_lut is always run
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-nocarry") {
 | 
			
		||||
| 
						 | 
				
			
			@ -227,6 +223,9 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
		if (device_opt != "hx" && device_opt != "lp" && device_opt !="u")
 | 
			
		||||
			log_cmd_error("Invalid or no device specified: '%s'\n", device_opt.c_str());
 | 
			
		||||
 | 
			
		||||
		if (abc == "abc9" && retime)
 | 
			
		||||
			log_cmd_error("-retime option not currently compatible with -abc9!\n");
 | 
			
		||||
 | 
			
		||||
		log_header(design, "Executing SYNTH_ICE40 pass.\n");
 | 
			
		||||
		log_push();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -296,7 +295,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
				run("techmap");
 | 
			
		||||
			else
 | 
			
		||||
				run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
 | 
			
		||||
			if ((retime || help_mode) && abc != "abc9")
 | 
			
		||||
			if (retime || help_mode)
 | 
			
		||||
				run(abc + " -dff", "(only if -retime)");
 | 
			
		||||
			run("ice40_opt");
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -344,10 +343,8 @@ struct SynthIce40Pass : public ScriptPass
 | 
			
		|||
					run(abc + " -dress -lut 4", "(skip if -noabc)");
 | 
			
		||||
			}
 | 
			
		||||
			run("clean");
 | 
			
		||||
			if (relut || help_mode) {
 | 
			
		||||
				run("ice40_unlut", "                            (only if -relut)");
 | 
			
		||||
				run("opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3", "(only if -relut)");
 | 
			
		||||
			}
 | 
			
		||||
			run("ice40_unlut");
 | 
			
		||||
			run("opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map_cells"))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,8 @@ GENFILES += techlibs/xilinx/brams_init_36.vh
 | 
			
		|||
GENFILES += techlibs/xilinx/brams_init_32.vh
 | 
			
		||||
GENFILES += techlibs/xilinx/brams_init_18.vh
 | 
			
		||||
GENFILES += techlibs/xilinx/brams_init_16.vh
 | 
			
		||||
GENFILES += techlibs/xilinx/brams_init_9.vh
 | 
			
		||||
GENFILES += techlibs/xilinx/brams_init_8.vh
 | 
			
		||||
 | 
			
		||||
EXTRA_OBJS += techlibs/xilinx/brams_init.mk
 | 
			
		||||
.SECONDARY: techlibs/xilinx/brams_init.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -18,18 +20,24 @@ techlibs/xilinx/brams_init_36.vh: techlibs/xilinx/brams_init.mk
 | 
			
		|||
techlibs/xilinx/brams_init_32.vh: techlibs/xilinx/brams_init.mk
 | 
			
		||||
techlibs/xilinx/brams_init_18.vh: techlibs/xilinx/brams_init.mk
 | 
			
		||||
techlibs/xilinx/brams_init_16.vh: techlibs/xilinx/brams_init.mk
 | 
			
		||||
techlibs/xilinx/brams_init_9.vh: techlibs/xilinx/brams_init.mk
 | 
			
		||||
techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk
 | 
			
		||||
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams.txt))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/brams_bb.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_bb.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams.txt))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams.txt))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))
 | 
			
		||||
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.box))
 | 
			
		||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut))
 | 
			
		||||
| 
						 | 
				
			
			@ -39,4 +47,6 @@ $(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh))
 | 
			
		|||
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh))
 | 
			
		||||
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_18.vh))
 | 
			
		||||
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_16.vh))
 | 
			
		||||
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_9.vh))
 | 
			
		||||
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_8.vh))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,17 +3,22 @@
 | 
			
		|||
# NB: Inputs/Outputs must be ordered alphabetically
 | 
			
		||||
#     (with exceptions for carry in/out)
 | 
			
		||||
 | 
			
		||||
# F7BMUX slower than F7AMUX
 | 
			
		||||
# Average across F7[AB]MUX
 | 
			
		||||
# Inputs: I0 I1 S0
 | 
			
		||||
# Outputs: O
 | 
			
		||||
F7BMUX 1 1 3 1
 | 
			
		||||
217 223 296
 | 
			
		||||
F7MUX 1 1 3 1
 | 
			
		||||
204 208 286
 | 
			
		||||
 | 
			
		||||
# Inputs: I0 I1 S0
 | 
			
		||||
# Outputs: O
 | 
			
		||||
MUXF8 2 1 3 1
 | 
			
		||||
104 94 273
 | 
			
		||||
 | 
			
		||||
# Inputs: I0 I1 I2 I3 S0 S1
 | 
			
		||||
# Outputs: O
 | 
			
		||||
$__MUXF78 3 1 6 1
 | 
			
		||||
294 297 311 317 390 273
 | 
			
		||||
 | 
			
		||||
# CARRY4 + CARRY4_[ABCD]X
 | 
			
		||||
# Inputs: CYINIT DI0 DI1 DI2 DI3 S0 S1 S2 S3 CI
 | 
			
		||||
# Outputs:  O0 O1 O2 O3 CO0 CO1 CO2 CO3
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +26,7 @@ MUXF8 2 1 3 1
 | 
			
		|||
#        input/output and the entire bus has been
 | 
			
		||||
#        moved there overriding the otherwise
 | 
			
		||||
#        alphabetical ordering)
 | 
			
		||||
CARRY4 3 1 10 8
 | 
			
		||||
CARRY4 4 1 10 8
 | 
			
		||||
482 -   -   -   -   223 -   -   -   222
 | 
			
		||||
598 407 -   -   -   400 205 -   -   334
 | 
			
		||||
584 556 537 -   -   523 558 226 -   239
 | 
			
		||||
| 
						 | 
				
			
			@ -34,20 +39,20 @@ CARRY4 3 1 10 8
 | 
			
		|||
# SLICEM/A6LUT
 | 
			
		||||
# Inputs: A0 A1 A2 A3 A4 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 WCLK WE
 | 
			
		||||
# Outputs: DPO SPO
 | 
			
		||||
RAM32X1D 4 0 13 2
 | 
			
		||||
RAM32X1D 5 0 13 2
 | 
			
		||||
-   -   -   -   -   - 631 472 407 238 127 - -
 | 
			
		||||
631 472 407 238 127 - -   -   -   -   -   - -
 | 
			
		||||
 | 
			
		||||
# SLICEM/A6LUT
 | 
			
		||||
# Inputs: A0 A1 A2 A3 A4 A5 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 WCLK WE
 | 
			
		||||
# Outputs: DPO SPO
 | 
			
		||||
RAM64X1D 5 0 15 2
 | 
			
		||||
RAM64X1D 6 0 15 2
 | 
			
		||||
-   -   -   -   -   -   - 642 631 472 407 238 127 - -
 | 
			
		||||
642 631 472 407 238 127 - -   -   -   -   -   -   - -
 | 
			
		||||
 | 
			
		||||
# SLICEM/A6LUT + F7[AB]MUX
 | 
			
		||||
# Inputs: A0 A1 A2 A3 A4 A5 A6 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 DPRA6 WCLK WE
 | 
			
		||||
# Outputs: DPO SPO
 | 
			
		||||
RAM128X1D 6 0 17 2
 | 
			
		||||
RAM128X1D 7 0 17 2
 | 
			
		||||
-    -    -   -   -   -   -   - 1009 998 839 774 605 494 450 - -
 | 
			
		||||
1047 1036 877 812 643 532 478 - -    -   -   -   -   -   -   - -
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,17 @@
 | 
			
		|||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
with open("techlibs/xilinx/brams_init_9.vh", "w") as f:
 | 
			
		||||
    for i in range(4):
 | 
			
		||||
        init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
 | 
			
		||||
        for k in range(4, 256, 4):
 | 
			
		||||
            init_snippets[k] = "\n           " + init_snippets[k]
 | 
			
		||||
        print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
 | 
			
		||||
    for i in range(32):
 | 
			
		||||
        init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)]
 | 
			
		||||
        for k in range(4, 32, 4):
 | 
			
		||||
            init_snippets[k] = "\n          " + init_snippets[k]
 | 
			
		||||
        print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
 | 
			
		||||
 | 
			
		||||
with open("techlibs/xilinx/brams_init_18.vh", "w") as f:
 | 
			
		||||
    for i in range(8):
 | 
			
		||||
        init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +36,10 @@ with open("techlibs/xilinx/brams_init_36.vh", "w") as f:
 | 
			
		|||
            init_snippets[k] = "\n          " + init_snippets[k]
 | 
			
		||||
        print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
 | 
			
		||||
 | 
			
		||||
with open("techlibs/xilinx/brams_init_8.vh", "w") as f:
 | 
			
		||||
    for i in range(32):
 | 
			
		||||
        print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
 | 
			
		||||
 | 
			
		||||
with open("techlibs/xilinx/brams_init_16.vh", "w") as f:
 | 
			
		||||
    for i in range(64):
 | 
			
		||||
        print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,11 +93,8 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o
 | 
			
		|||
      \$__XILINX_SHREG_ #(.DEPTH(DEPTH-64), .INIT(INIT[DEPTH-64-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_2 (.C(C), .D(T3), .L(L[4:0]), .E(E), .Q(T4));
 | 
			
		||||
      if (&_TECHMAP_CONSTMSK_L_)
 | 
			
		||||
        assign Q = T4;
 | 
			
		||||
      else begin
 | 
			
		||||
        MUXF7 fpga_mux_0 (.O(T5), .I0(T0), .I1(T2), .S(L[5]));
 | 
			
		||||
        MUXF7 fpga_mux_1 (.O(T6), .I0(T4), .I1(1'b0 /* unused */), .S(L[5]));
 | 
			
		||||
        MUXF8 fpga_mux_2 (.O(Q), .I0(T5), .I1(T6), .S(L[6]));
 | 
			
		||||
      end
 | 
			
		||||
      else
 | 
			
		||||
        \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(1'bx), .S0(L[5]), .S1(L[6]), .O(Q));
 | 
			
		||||
    end else
 | 
			
		||||
    if (DEPTH > 97 && DEPTH < 128) begin
 | 
			
		||||
      wire T0, T1, T2, T3, T4, T5, T6, T7, T8;
 | 
			
		||||
| 
						 | 
				
			
			@ -107,11 +104,8 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o
 | 
			
		|||
      \$__XILINX_SHREG_ #(.DEPTH(DEPTH-96), .INIT(INIT[DEPTH-96-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_3 (.C(C), .D(T5), .L(L[4:0]), .E(E), .Q(T6));
 | 
			
		||||
      if (&_TECHMAP_CONSTMSK_L_)
 | 
			
		||||
        assign Q = T6;
 | 
			
		||||
      else begin
 | 
			
		||||
        MUXF7 fpga_mux_0 (.O(T7), .I0(T0), .I1(T2), .S(L[5]));
 | 
			
		||||
        MUXF7 fpga_mux_1 (.O(T8), .I0(T4), .I1(T6), .S(L[5]));
 | 
			
		||||
        MUXF8 fpga_mux_2 (.O(Q), .I0(T7), .I1(T8), .S(L[6]));
 | 
			
		||||
      end
 | 
			
		||||
      else
 | 
			
		||||
        \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(T6), .S0(L[5]), .S1(L[6]), .O(Q));
 | 
			
		||||
    end
 | 
			
		||||
    else if (DEPTH == 128) begin
 | 
			
		||||
      wire T0, T1, T2, T3, T4, T5, T6;
 | 
			
		||||
| 
						 | 
				
			
			@ -121,12 +115,8 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o
 | 
			
		|||
      SRLC32E #(.INIT(INIT_R[128-1:96]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_3 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T5), .Q(T6), .Q31(SO));
 | 
			
		||||
      if (&_TECHMAP_CONSTMSK_L_)
 | 
			
		||||
        assign Q = T6;
 | 
			
		||||
      else begin
 | 
			
		||||
        wire T7, T8;
 | 
			
		||||
        MUXF7 fpga_mux_0 (.O(T7), .I0(T0), .I1(T2), .S(L[5]));
 | 
			
		||||
        MUXF7 fpga_mux_1 (.O(T8), .I0(T4), .I1(T6), .S(L[5]));
 | 
			
		||||
        MUXF8 fpga_mux_2 (.O(Q), .I0(T7), .I1(T8), .S(L[6]));
 | 
			
		||||
      end
 | 
			
		||||
      else
 | 
			
		||||
        \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(T6), .S0(L[5]), .S1(L[6]), .O(Q));
 | 
			
		||||
    end
 | 
			
		||||
    // For fixed length, if just 1 over a convenient value, decompose
 | 
			
		||||
    else if (DEPTH <= 129 && &_TECHMAP_CONSTMSK_L_) begin
 | 
			
		||||
| 
						 | 
				
			
			@ -158,3 +148,220 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o
 | 
			
		|||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
`ifdef MIN_MUX_INPUTS
 | 
			
		||||
module \$__XILINX_SHIFTX (A, B, Y);
 | 
			
		||||
  parameter A_SIGNED = 0;
 | 
			
		||||
  parameter B_SIGNED = 0;
 | 
			
		||||
  parameter A_WIDTH = 1;
 | 
			
		||||
  parameter B_WIDTH = 1;
 | 
			
		||||
  parameter Y_WIDTH = 1;
 | 
			
		||||
 | 
			
		||||
  input [A_WIDTH-1:0] A;
 | 
			
		||||
  input [B_WIDTH-1:0] B;
 | 
			
		||||
  output [Y_WIDTH-1:0] Y;
 | 
			
		||||
 | 
			
		||||
  parameter [A_WIDTH-1:0] _TECHMAP_CONSTMSK_A_ = 0;
 | 
			
		||||
  parameter [A_WIDTH-1:0] _TECHMAP_CONSTVAL_A_ = 0;
 | 
			
		||||
  parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
 | 
			
		||||
  parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0;
 | 
			
		||||
 | 
			
		||||
  function integer A_WIDTH_trimmed;
 | 
			
		||||
    input integer start;
 | 
			
		||||
  begin
 | 
			
		||||
    A_WIDTH_trimmed = start;
 | 
			
		||||
    while (A_WIDTH_trimmed > 0 && _TECHMAP_CONSTMSK_A_[A_WIDTH_trimmed-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH_trimmed-1] === 1'bx)
 | 
			
		||||
      A_WIDTH_trimmed = A_WIDTH_trimmed - 1;
 | 
			
		||||
  end
 | 
			
		||||
  endfunction
 | 
			
		||||
 | 
			
		||||
  generate
 | 
			
		||||
    genvar i, j;
 | 
			
		||||
    // Bit-blast
 | 
			
		||||
    if (Y_WIDTH > 1) begin
 | 
			
		||||
      for (i = 0; i < Y_WIDTH; i++)
 | 
			
		||||
        \$__XILINX_SHIFTX  #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH-Y_WIDTH+1), .B_WIDTH(B_WIDTH), .Y_WIDTH(1'd1)) bitblast (.A(A[A_WIDTH-Y_WIDTH+i:i]), .B(B), .Y(Y[i]));
 | 
			
		||||
    end
 | 
			
		||||
    // If the LSB of B is constant zero (and Y_WIDTH is 1) then
 | 
			
		||||
    //   we can optimise by removing every other entry from A
 | 
			
		||||
    //   and popping the constant zero from B
 | 
			
		||||
    else if (_TECHMAP_CONSTMSK_B_[0] && !_TECHMAP_CONSTVAL_B_[0]) begin
 | 
			
		||||
      wire [(A_WIDTH+1)/2-1:0] A_i;
 | 
			
		||||
      for (i = 0; i < (A_WIDTH+1)/2; i++)
 | 
			
		||||
        assign A_i[i] = A[i*2];
 | 
			
		||||
      \$__XILINX_SHIFTX  #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH((A_WIDTH+1'd1)/2'd2), .B_WIDTH(B_WIDTH-1'd1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_i), .B(B[B_WIDTH-1:1]), .Y(Y));
 | 
			
		||||
    end
 | 
			
		||||
    // Trim off any leading 1'bx -es in A
 | 
			
		||||
    else if (_TECHMAP_CONSTMSK_A_[A_WIDTH-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH-1] === 1'bx) begin
 | 
			
		||||
      localparam A_WIDTH_new = A_WIDTH_trimmed(A_WIDTH-1);
 | 
			
		||||
      \$__XILINX_SHIFTX  #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH_new), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A[A_WIDTH_new-1:0]), .B(B), .Y(Y));
 | 
			
		||||
    end
 | 
			
		||||
    else if (A_WIDTH < `MIN_MUX_INPUTS) begin
 | 
			
		||||
      wire _TECHMAP_FAIL_ = 1;
 | 
			
		||||
    end
 | 
			
		||||
    else if (A_WIDTH == 2) begin
 | 
			
		||||
      MUXF7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y));
 | 
			
		||||
    end
 | 
			
		||||
    else if (A_WIDTH <= 4) begin
 | 
			
		||||
      wire [4-1:0] Ax;
 | 
			
		||||
      if (A_WIDTH == 4)
 | 
			
		||||
        assign Ax = A;
 | 
			
		||||
      else
 | 
			
		||||
        // Rather than extend with 1'bx which gets flattened to 1'b0
 | 
			
		||||
        // causing the "don't care" status to get lost, extend with
 | 
			
		||||
        // the same driver of F7B.I0 so that we can optimise F7B away
 | 
			
		||||
        // later
 | 
			
		||||
        assign Ax = {A[1], A};
 | 
			
		||||
      \$__XILINX_MUXF78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[2]), .I2(Ax[1]), .I3(Ax[3]), .S0(B[1]), .S1(B[0]), .O(Y));
 | 
			
		||||
    end
 | 
			
		||||
    // Note that the following decompositions are 'backwards' in that
 | 
			
		||||
    // the LSBs are placed on the hard resources, and the soft resources
 | 
			
		||||
    // are used for MSBs.
 | 
			
		||||
    // This has the effect of more effectively utilising the hard mux;
 | 
			
		||||
    // take for example a 5:1 multiplexer, currently this would map as:
 | 
			
		||||
    //
 | 
			
		||||
    //     A[0] \___  __                             A[0] \__  __
 | 
			
		||||
    //     A[4] /   \|  \       whereas the more     A[1] /  \|  \
 | 
			
		||||
    //     A[1] _____|   |      obvious mapping      A[2] \___|   |
 | 
			
		||||
    //     A[2] _____|   |--    of MSBs to hard      A[3] /   |   |__
 | 
			
		||||
    //     A[3]______|   |      resources would      A[4] ____|   |
 | 
			
		||||
    //               |__/       lead to:             1'bx ____|   |
 | 
			
		||||
    //                ||                                      |__/
 | 
			
		||||
    //                ||                                       ||
 | 
			
		||||
    //              B[1:0]                                   B[1:2]
 | 
			
		||||
    //
 | 
			
		||||
    // Expectation would be that the 'forward' mapping (right) is more
 | 
			
		||||
    // area efficient (consider a 9:1 multiplexer using 2x4:1 multiplexers
 | 
			
		||||
    // on its I0 and I1 inputs, and A[8] and 1'bx on its I2 and I3 inputs)
 | 
			
		||||
    // but that the 'backwards' mapping (left) is more delay efficient
 | 
			
		||||
    // since smaller LUTs are faster than wider ones.
 | 
			
		||||
    else if (A_WIDTH <= 8) begin
 | 
			
		||||
      wire [8-1:0] Ax = {{{8-A_WIDTH}{1'bx}}, A};
 | 
			
		||||
      wire T0 = B[2] ? Ax[4] : Ax[0];
 | 
			
		||||
      wire T1 = B[2] ? Ax[5] : Ax[1];
 | 
			
		||||
      wire T2 = B[2] ? Ax[6] : Ax[2];
 | 
			
		||||
      wire T3 = B[2] ? Ax[7] : Ax[3];
 | 
			
		||||
      \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y));
 | 
			
		||||
    end
 | 
			
		||||
    else if (A_WIDTH <= 16) begin
 | 
			
		||||
      wire [16-1:0] Ax = {{{16-A_WIDTH}{1'bx}}, A};
 | 
			
		||||
      wire T0 = B[2] ? B[3] ? Ax[12] : Ax[4]
 | 
			
		||||
                     : B[3] ? Ax[ 8] : Ax[0];
 | 
			
		||||
      wire T1 = B[2] ? B[3] ? Ax[13] : Ax[5]
 | 
			
		||||
                     : B[3] ? Ax[ 9] : Ax[1];
 | 
			
		||||
      wire T2 = B[2] ? B[3] ? Ax[14] : Ax[6]
 | 
			
		||||
                     : B[3] ? Ax[10] : Ax[2];
 | 
			
		||||
      wire T3 = B[2] ? B[3] ? Ax[15] : Ax[7]
 | 
			
		||||
                     : B[3] ? Ax[11] : Ax[3];
 | 
			
		||||
      \$__XILINX_MUXF78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y));
 | 
			
		||||
    end
 | 
			
		||||
    else begin
 | 
			
		||||
      localparam num_mux16 = (A_WIDTH+15) / 16;
 | 
			
		||||
      localparam clog2_num_mux16 = $clog2(num_mux16);
 | 
			
		||||
      wire [num_mux16-1:0] T;
 | 
			
		||||
      wire [num_mux16*16-1:0] Ax = {{(num_mux16*16-A_WIDTH){1'bx}}, A};
 | 
			
		||||
      for (i = 0; i < num_mux16; i++)
 | 
			
		||||
        \$__XILINX_SHIFTX  #(
 | 
			
		||||
          .A_SIGNED(A_SIGNED),
 | 
			
		||||
          .B_SIGNED(B_SIGNED),
 | 
			
		||||
          .A_WIDTH(16),
 | 
			
		||||
          .B_WIDTH(4),
 | 
			
		||||
          .Y_WIDTH(Y_WIDTH)
 | 
			
		||||
        ) fpga_mux (
 | 
			
		||||
          .A(Ax[i*16+:16]),
 | 
			
		||||
          .B(B[3:0]),
 | 
			
		||||
          .Y(T[i])
 | 
			
		||||
        );
 | 
			
		||||
      \$__XILINX_SHIFTX  #(
 | 
			
		||||
          .A_SIGNED(A_SIGNED),
 | 
			
		||||
          .B_SIGNED(B_SIGNED),
 | 
			
		||||
          .A_WIDTH(num_mux16),
 | 
			
		||||
          .B_WIDTH(clog2_num_mux16),
 | 
			
		||||
          .Y_WIDTH(Y_WIDTH)
 | 
			
		||||
      ) _TECHMAP_REPLACE_ (
 | 
			
		||||
          .A(T),
 | 
			
		||||
          .B(B[B_WIDTH-1-:clog2_num_mux16]),
 | 
			
		||||
          .Y(Y));
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* techmap_celltype = "$__XILINX_SHIFTX" *)
 | 
			
		||||
module _90__XILINX_SHIFTX (A, B, Y);
 | 
			
		||||
  parameter A_SIGNED = 0;
 | 
			
		||||
  parameter B_SIGNED = 0;
 | 
			
		||||
  parameter A_WIDTH = 1;
 | 
			
		||||
  parameter B_WIDTH = 1;
 | 
			
		||||
  parameter Y_WIDTH = 1;
 | 
			
		||||
 | 
			
		||||
  input [A_WIDTH-1:0] A;
 | 
			
		||||
  input [B_WIDTH-1:0] B;
 | 
			
		||||
  output [Y_WIDTH-1:0] Y;
 | 
			
		||||
 | 
			
		||||
  \$shiftx  #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module \$_MUX_ (A, B, S, Y);
 | 
			
		||||
  input A, B, S;
 | 
			
		||||
  output Y;
 | 
			
		||||
  generate
 | 
			
		||||
    if (`MIN_MUX_INPUTS == 2)
 | 
			
		||||
      \$__XILINX_SHIFTX  #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(2), .B_WIDTH(1), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({B,A}), .B(S), .Y(Y));
 | 
			
		||||
    else
 | 
			
		||||
      wire _TECHMAP_FAIL_ = 1;
 | 
			
		||||
  endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module \$_MUX4_ (A, B, C, D, S, T, Y);
 | 
			
		||||
  input A, B, C, D, S, T;
 | 
			
		||||
  output Y;
 | 
			
		||||
  \$__XILINX_SHIFTX  #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({D,C,B,A}), .B({T,S}), .Y(Y));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module \$_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y);
 | 
			
		||||
  input A, B, C, D, E, F, G, H, S, T, U;
 | 
			
		||||
  output Y;
 | 
			
		||||
  \$__XILINX_SHIFTX  #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(3), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({H,G,F,E,D,C,B,A}), .B({U,T,S}), .Y(Y));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y);
 | 
			
		||||
  input A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V;
 | 
			
		||||
  output Y;
 | 
			
		||||
  \$__XILINX_SHIFTX  #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(16), .B_WIDTH(4), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A}), .B({V,U,T,S}), .Y(Y));
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
`ifndef _ABC
 | 
			
		||||
module \$__XILINX_MUXF78 (O, I0, I1, I2, I3, S0, S1);
 | 
			
		||||
  output O;
 | 
			
		||||
  input I0, I1, I2, I3, S0, S1;
 | 
			
		||||
  wire T0, T1;
 | 
			
		||||
  parameter _TECHMAP_BITS_CONNMAP_ = 0;
 | 
			
		||||
  parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I0_ = 0;
 | 
			
		||||
  parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I1_ = 0;
 | 
			
		||||
  parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I2_ = 0;
 | 
			
		||||
  parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I3_ = 0;
 | 
			
		||||
  parameter _TECHMAP_CONSTMSK_S0_ = 0;
 | 
			
		||||
  parameter _TECHMAP_CONSTVAL_S0_ = 0;
 | 
			
		||||
  parameter _TECHMAP_CONSTMSK_S1_ = 0;
 | 
			
		||||
  parameter _TECHMAP_CONSTVAL_S1_ = 0;
 | 
			
		||||
  if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1)
 | 
			
		||||
    assign T0 = I1;
 | 
			
		||||
  else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_)
 | 
			
		||||
    assign T0 = I0;
 | 
			
		||||
  else
 | 
			
		||||
    MUXF7 mux7a (.I0(I0), .I1(I1), .S(S0), .O(T0));
 | 
			
		||||
  if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1)
 | 
			
		||||
    assign T1 = I3;
 | 
			
		||||
  else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_)
 | 
			
		||||
    assign T1 = I2;
 | 
			
		||||
  else
 | 
			
		||||
    MUXF7 mux7b (.I0(I2), .I1(I3), .S(S0), .O(T1));
 | 
			
		||||
  if (_TECHMAP_CONSTMSK_S1_ && _TECHMAP_CONSTVAL_S1_ === 1'b1)
 | 
			
		||||
    assign O = T1;
 | 
			
		||||
  else if (_TECHMAP_CONSTMSK_S1_ || (_TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_ && _TECHMAP_CONNMAP_I1_ === _TECHMAP_CONNMAP_I2_ && _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_))
 | 
			
		||||
    assign O = T0;
 | 
			
		||||
  else
 | 
			
		||||
    MUXF8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O));
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -169,11 +169,19 @@ module MUXF8(output O, input I0, I1, S);
 | 
			
		|||
  assign O = S ? I1 : I0;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
`ifdef _ABC
 | 
			
		||||
(* abc_box_id = 3, lib_whitebox *)
 | 
			
		||||
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
 | 
			
		||||
  assign O = S1 ? (S0 ? I3 : I2)
 | 
			
		||||
                : (S0 ? I1 : I0);
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
module XORCY(output O, input CI, LI);
 | 
			
		||||
  assign O = CI ^ LI;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 3, abc_carry="CI,CO", lib_whitebox *)
 | 
			
		||||
(* abc_box_id = 4, abc_carry="CI,CO", lib_whitebox *)
 | 
			
		||||
module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S);
 | 
			
		||||
  assign O = S ^ {CO[2:0], CI | CYINIT};
 | 
			
		||||
  assign CO[0] = S[0] ? CI | CYINIT : DI[0];
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +226,7 @@ module FDRE (output reg Q, input C, CE, D, R);
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDSE (output reg Q, input C, CE, D, S);
 | 
			
		||||
  parameter [0:0] INIT = 1'b0;
 | 
			
		||||
  parameter [0:0] INIT = 1'b1;
 | 
			
		||||
  parameter [0:0] IS_C_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_D_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_S_INVERTED = 1'b0;
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +252,7 @@ module FDCE (output reg Q, input C, CE, D, CLR);
 | 
			
		|||
endmodule
 | 
			
		||||
 | 
			
		||||
module FDPE (output reg Q, input C, CE, D, PRE);
 | 
			
		||||
  parameter [0:0] INIT = 1'b0;
 | 
			
		||||
  parameter [0:0] INIT = 1'b1;
 | 
			
		||||
  parameter [0:0] IS_C_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_D_INVERTED = 1'b0;
 | 
			
		||||
  parameter [0:0] IS_PRE_INVERTED = 1'b0;
 | 
			
		||||
| 
						 | 
				
			
			@ -281,7 +289,7 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE);
 | 
			
		|||
  always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 4, abc_scc_break="D,WE" *)
 | 
			
		||||
(* abc_box_id = 5, abc_scc_break="D,WE" *)
 | 
			
		||||
module RAM32X1D (
 | 
			
		||||
  output DPO, SPO,
 | 
			
		||||
  input  D, WCLK, WE,
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +307,7 @@ module RAM32X1D (
 | 
			
		|||
  always @(posedge clk) if (WE) mem[a] <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 5, abc_scc_break="D,WE" *)
 | 
			
		||||
(* abc_box_id = 6, abc_scc_break="D,WE" *)
 | 
			
		||||
module RAM64X1D (
 | 
			
		||||
  output DPO, SPO,
 | 
			
		||||
  input  D, WCLK, WE,
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +325,7 @@ module RAM64X1D (
 | 
			
		|||
  always @(posedge clk) if (WE) mem[a] <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
(* abc_box_id = 6, abc_scc_break="D,WE" *)
 | 
			
		||||
(* abc_box_id = 7, abc_scc_break="D,WE" *)
 | 
			
		||||
module RAM128X1D (
 | 
			
		||||
  output       DPO, SPO,
 | 
			
		||||
  input        D, WCLK, WE,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,10 +33,10 @@ module  \$_DFF_NP0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPL
 | 
			
		|||
module  \$_DFF_PN0_ (input D, C, R, output Q); FDCE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule
 | 
			
		||||
module  \$_DFF_PP0_ (input D, C, R, output Q); FDCE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$_DFF_NN1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
 | 
			
		||||
module  \$_DFF_NP1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
			
		||||
module  \$_DFF_PN1_ (input D, C, R, output Q); FDPE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
 | 
			
		||||
module  \$_DFF_PP1_ (input D, C, R, output Q); FDPE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
			
		||||
module  \$_DFF_NN1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
 | 
			
		||||
module  \$_DFF_NP1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
			
		||||
module  \$_DFF_PN1_ (input D, C, R, output Q); FDPE   #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
 | 
			
		||||
module  \$_DFF_PP1_ (input D, C, R, output Q); FDPE   #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
			
		||||
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										71
									
								
								techlibs/xilinx/mux_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								techlibs/xilinx/mux_map.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *                2019  Eddie Hung    <eddie@fpgeh.com>
 | 
			
		||||
 *
 | 
			
		||||
 *  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.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// The purpose of these mapping rules is to allow preserve all (sufficiently
 | 
			
		||||
// wide) $shiftx cells during 'techmap' so that they can be mapped to hard
 | 
			
		||||
// resources, rather than being bit-blasted to gates during 'techmap'
 | 
			
		||||
// execution
 | 
			
		||||
 | 
			
		||||
module \$shiftx (A, B, Y);
 | 
			
		||||
  parameter A_SIGNED = 0;
 | 
			
		||||
  parameter B_SIGNED = 0;
 | 
			
		||||
  parameter A_WIDTH = 1;
 | 
			
		||||
  parameter B_WIDTH = 1;
 | 
			
		||||
  parameter Y_WIDTH = 1;
 | 
			
		||||
 | 
			
		||||
  input [A_WIDTH-1:0] A;
 | 
			
		||||
  input [B_WIDTH-1:0] B;
 | 
			
		||||
  output [Y_WIDTH-1:0] Y;
 | 
			
		||||
 | 
			
		||||
  parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
 | 
			
		||||
  parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0;
 | 
			
		||||
 | 
			
		||||
  generate
 | 
			
		||||
    if (B_SIGNED) begin
 | 
			
		||||
      if (_TECHMAP_CONSTMSK_B_[B_WIDTH-1] && (_TECHMAP_CONSTVAL_B_[B_WIDTH-1] == 1'b0 || _TECHMAP_CONSTVAL_B_[B_WIDTH-1] === 1'bx))
 | 
			
		||||
        // Optimisation to remove B_SIGNED if sign bit of B is constant-0
 | 
			
		||||
        \$shiftx #(
 | 
			
		||||
          .A_SIGNED(A_SIGNED),
 | 
			
		||||
          .B_SIGNED(0),
 | 
			
		||||
          .A_WIDTH(A_WIDTH),
 | 
			
		||||
          .B_WIDTH(B_WIDTH-1'd1),
 | 
			
		||||
          .Y_WIDTH(Y_WIDTH)
 | 
			
		||||
        ) _TECHMAP_REPLACE_ (
 | 
			
		||||
          .A(A), .B(B[B_WIDTH-2:0]), .Y(Y)
 | 
			
		||||
        );
 | 
			
		||||
      else
 | 
			
		||||
        wire _TECHMAP_FAIL_ = 1;
 | 
			
		||||
    end
 | 
			
		||||
    else begin
 | 
			
		||||
      if (((A_WIDTH + Y_WIDTH - 1) / Y_WIDTH) < `MIN_MUX_INPUTS)
 | 
			
		||||
        wire _TECHMAP_FAIL_ = 1;
 | 
			
		||||
      else
 | 
			
		||||
        \$__XILINX_SHIFTX #(
 | 
			
		||||
          .A_SIGNED(A_SIGNED),
 | 
			
		||||
          .B_SIGNED(B_SIGNED),
 | 
			
		||||
          .A_WIDTH(A_WIDTH),
 | 
			
		||||
          .B_WIDTH(B_WIDTH),
 | 
			
		||||
          .Y_WIDTH(Y_WIDTH)
 | 
			
		||||
        ) _TECHMAP_REPLACE_ (
 | 
			
		||||
          .A(A), .B(B), .Y(Y)
 | 
			
		||||
        );
 | 
			
		||||
    end
 | 
			
		||||
  endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *            (C) 2019  Eddie Hung    <eddie@fpgeh.com>
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 *  purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
| 
						 | 
				
			
			@ -25,8 +26,8 @@
 | 
			
		|||
USING_YOSYS_NAMESPACE
 | 
			
		||||
PRIVATE_NAMESPACE_BEGIN
 | 
			
		||||
 | 
			
		||||
#define XC7_WIRE_DELAY "300" // Number with which ABC will map a 6-input gate
 | 
			
		||||
                             // to one LUT6 (instead of a LUT5 + LUT2)
 | 
			
		||||
#define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate
 | 
			
		||||
                           // to one LUT6 (instead of a LUT5 + LUT2)
 | 
			
		||||
 | 
			
		||||
struct SynthXilinxPass : public ScriptPass
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +78,11 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
		log("    -nowidelut\n");
 | 
			
		||||
		log("        do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -widemux <int>\n");
 | 
			
		||||
		log("        enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
 | 
			
		||||
		log("        above this number of inputs (minimum value 2, recommended value >= 5).\n");
 | 
			
		||||
		log("        default: 0 (no inference)\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");
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +105,7 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
 | 
			
		||||
	std::string top_opt, edif_file, blif_file, family;
 | 
			
		||||
	bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, abc9;
 | 
			
		||||
	int widemux;
 | 
			
		||||
 | 
			
		||||
	void clear_flags() YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -116,6 +123,7 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
		nocarry = false;
 | 
			
		||||
		nowidelut = false;
 | 
			
		||||
		abc9 = false;
 | 
			
		||||
		widemux = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
			
		||||
| 
						 | 
				
			
			@ -186,6 +194,10 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
				nosrl = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-widemux" && argidx+1 < args.size()) {
 | 
			
		||||
				widemux = std::stoi(args[++argidx]);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-abc9") {
 | 
			
		||||
				abc9 = true;
 | 
			
		||||
				continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -195,11 +207,17 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6s")
 | 
			
		||||
			log_cmd_error("Invalid Xilinx -family setting: %s\n", family.c_str());
 | 
			
		||||
			log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
 | 
			
		||||
 | 
			
		||||
		if (widemux != 0 && widemux < 2)
 | 
			
		||||
			log_cmd_error("-widemux value must be 0 or >= 2.\n");
 | 
			
		||||
 | 
			
		||||
		if (!design->full_selection())
 | 
			
		||||
			log_cmd_error("This command only operates on fully selected designs!\n");
 | 
			
		||||
 | 
			
		||||
		if (abc9 && retime)
 | 
			
		||||
			log_cmd_error("-retime option not currently compatible with -abc9!\n");
 | 
			
		||||
 | 
			
		||||
		log_header(design, "Executing SYNTH_XILINX pass.\n");
 | 
			
		||||
		log_push();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -212,39 +230,74 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
	{
 | 
			
		||||
		if (check_label("begin")) {
 | 
			
		||||
			if (vpr)
 | 
			
		||||
				run("read_verilog -lib -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
 | 
			
		||||
				run("read_verilog -lib -icells -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
 | 
			
		||||
			else
 | 
			
		||||
				run("read_verilog -lib -D _ABC +/xilinx/cells_sim.v");
 | 
			
		||||
				run("read_verilog -lib -icells -D _ABC +/xilinx/cells_sim.v");
 | 
			
		||||
 | 
			
		||||
			run("read_verilog -lib +/xilinx/cells_xtra.v");
 | 
			
		||||
 | 
			
		||||
			if (!nobram || help_mode)
 | 
			
		||||
				run("read_verilog -lib +/xilinx/brams_bb.v", "(skip if '-nobram')");
 | 
			
		||||
			if (help_mode) {
 | 
			
		||||
				run("read_verilog -lib +/xilinx/{family}_brams_bb.v");
 | 
			
		||||
			} else if (family == "xc6s") {
 | 
			
		||||
				run("read_verilog -lib +/xilinx/xc6s_brams_bb.v");
 | 
			
		||||
			} else if (family == "xc7") {
 | 
			
		||||
				run("read_verilog -lib +/xilinx/xc7_brams_bb.v");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			run(stringf("hierarchy -check %s", top_opt.c_str()));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("flatten", "(with '-flatten' only)")) {
 | 
			
		||||
			if (flatten || help_mode) {
 | 
			
		||||
				run("proc");
 | 
			
		||||
				run("flatten");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("coarse")) {
 | 
			
		||||
			run("synth -run coarse");
 | 
			
		||||
			run("proc");
 | 
			
		||||
			if (help_mode || flatten)
 | 
			
		||||
				run("flatten", "(if -flatten)");
 | 
			
		||||
			run("opt_expr");
 | 
			
		||||
			run("opt_clean");
 | 
			
		||||
			run("check");
 | 
			
		||||
			run("opt");
 | 
			
		||||
			if (help_mode)
 | 
			
		||||
				run("wreduce [-keepdc]", "(option for '-widemux')");
 | 
			
		||||
			else
 | 
			
		||||
				run("wreduce" + std::string(widemux > 0 ? " -keepdc" : ""));
 | 
			
		||||
			run("peepopt");
 | 
			
		||||
			run("opt_clean");
 | 
			
		||||
 | 
			
		||||
			if (widemux > 0 || help_mode)
 | 
			
		||||
				run("muxpack", "    ('-widemux' only)");
 | 
			
		||||
 | 
			
		||||
			// shregmap -tech xilinx can cope with $shiftx and $mux
 | 
			
		||||
			//   cells for identifying variable-length shift registers,
 | 
			
		||||
			//   so attempt to convert $pmux-es to the former
 | 
			
		||||
			if (!nosrl || help_mode)
 | 
			
		||||
				run("pmux2shiftx", "(skip if '-nosrl')");
 | 
			
		||||
			// Also: wide multiplexer inference benefits from this too
 | 
			
		||||
			if (!(nosrl && widemux == 0) || help_mode) {
 | 
			
		||||
				run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')");
 | 
			
		||||
				run("clean", "      (skip if '-nosrl' and '-widemux=0')");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			run("techmap -map +/cmp2lut.v -D LUT_WIDTH=6");
 | 
			
		||||
			run("alumacc");
 | 
			
		||||
			run("share");
 | 
			
		||||
			run("opt");
 | 
			
		||||
			run("fsm");
 | 
			
		||||
			run("opt -fast");
 | 
			
		||||
			run("memory -nomap");
 | 
			
		||||
			run("opt_clean");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("bram", "(skip if '-nobram')")) {
 | 
			
		||||
			if (!nobram || help_mode) {
 | 
			
		||||
				run("memory_bram -rules +/xilinx/brams.txt");
 | 
			
		||||
				run("techmap -map +/xilinx/brams_map.v");
 | 
			
		||||
			if (help_mode) {
 | 
			
		||||
				run("memory_bram -rules +/xilinx/{family}_brams.txt");
 | 
			
		||||
				run("techmap -map +/xilinx/{family}_brams_map.v");
 | 
			
		||||
			} else if (!nobram) {
 | 
			
		||||
				if (family == "xc6s") {
 | 
			
		||||
					run("memory_bram -rules +/xilinx/xc6s_brams.txt");
 | 
			
		||||
					run("techmap -map +/xilinx/xc6s_brams_map.v");
 | 
			
		||||
				} else if (family == "xc7") {
 | 
			
		||||
					run("memory_bram -rules +/xilinx/xc7_brams.txt");
 | 
			
		||||
					run("techmap -map +/xilinx/xc7_brams_map.v");
 | 
			
		||||
				} else {
 | 
			
		||||
					log_warning("Block RAM inference not yet supported for family %s.\n", family.c_str());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -256,50 +309,88 @@ struct SynthXilinxPass : public ScriptPass
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("fine")) {
 | 
			
		||||
			run("opt -fast -full");
 | 
			
		||||
			if (widemux > 0)
 | 
			
		||||
				run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
 | 
			
		||||
									    // performs less efficiently
 | 
			
		||||
			else
 | 
			
		||||
				run("opt -fast -full");
 | 
			
		||||
			run("memory_map");
 | 
			
		||||
			run("dffsr2dff");
 | 
			
		||||
			run("dff2dffe");
 | 
			
		||||
			if (help_mode) {
 | 
			
		||||
				run("simplemap t:$mux", "         ('-widemux' only)");
 | 
			
		||||
				run("muxcover <internal options>, ('-widemux' only)");
 | 
			
		||||
			}
 | 
			
		||||
			else if (widemux > 0) {
 | 
			
		||||
				run("simplemap t:$mux");
 | 
			
		||||
				constexpr int cost_mux2 = 100;
 | 
			
		||||
				std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2);
 | 
			
		||||
				switch (widemux) {
 | 
			
		||||
					case  2: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2+1, cost_mux2+2, cost_mux2+3); break;
 | 
			
		||||
					case  3:
 | 
			
		||||
					case  4: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-2, cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break;
 | 
			
		||||
					case  5:
 | 
			
		||||
					case  6:
 | 
			
		||||
					case  7:
 | 
			
		||||
					case  8: muxcover_args += stringf(" -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break;
 | 
			
		||||
					case  9:
 | 
			
		||||
					case 10:
 | 
			
		||||
					case 11:
 | 
			
		||||
					case 12:
 | 
			
		||||
					case 13:
 | 
			
		||||
					case 14:
 | 
			
		||||
					case 15:
 | 
			
		||||
					default: muxcover_args += stringf(" -mux16=%d", cost_mux2*(widemux-1)-1); break;
 | 
			
		||||
				}
 | 
			
		||||
				run("muxcover " + muxcover_args);
 | 
			
		||||
			}
 | 
			
		||||
			run("opt -full");
 | 
			
		||||
 | 
			
		||||
			if (!nosrl || help_mode) {
 | 
			
		||||
				// shregmap operates on bit-level flops, not word-level,
 | 
			
		||||
				//   so break those down here
 | 
			
		||||
				run("simplemap t:$dff t:$dffe", "(skip if '-nosrl')");
 | 
			
		||||
				run("simplemap t:$dff t:$dffe", "       (skip if '-nosrl')");
 | 
			
		||||
				// shregmap with '-tech xilinx' infers variable length shift regs
 | 
			
		||||
				run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			std::string techmap_files = " -map +/techmap.v";
 | 
			
		||||
			std::string techmap_args = " -map +/techmap.v";
 | 
			
		||||
			if (help_mode)
 | 
			
		||||
				techmap_files += " [-map +/xilinx/arith_map.v]";
 | 
			
		||||
				techmap_args += " [-map +/xilinx/mux_map.v]";
 | 
			
		||||
			else if (widemux > 0)
 | 
			
		||||
				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d -map +/xilinx/mux_map.v", widemux);
 | 
			
		||||
			if (help_mode)
 | 
			
		||||
				techmap_args += " [-map +/xilinx/arith_map.v]";
 | 
			
		||||
			else if (!nocarry) {
 | 
			
		||||
				techmap_files += " -map +/xilinx/arith_map.v";
 | 
			
		||||
				techmap_args += " -map +/xilinx/arith_map.v";
 | 
			
		||||
				if (vpr)
 | 
			
		||||
					techmap_files += " -D _EXPLICIT_CARRY";
 | 
			
		||||
					techmap_args += " -D _EXPLICIT_CARRY";
 | 
			
		||||
				else if (abc9)
 | 
			
		||||
					techmap_files += " -D _CLB_CARRY";
 | 
			
		||||
					techmap_args += " -D _CLB_CARRY";
 | 
			
		||||
			}
 | 
			
		||||
			run("techmap " + techmap_files);
 | 
			
		||||
			run("techmap " + techmap_args);
 | 
			
		||||
			run("opt -fast");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map_cells")) {
 | 
			
		||||
			run("techmap -map +/techmap.v -map +/xilinx/cells_map.v");
 | 
			
		||||
			std::string techmap_args = "-map +/techmap.v -D _ABC -map +/xilinx/cells_map.v";
 | 
			
		||||
			if (widemux > 0)
 | 
			
		||||
				techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
 | 
			
		||||
			run("techmap " + techmap_args);
 | 
			
		||||
			run("clean");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map_luts")) {
 | 
			
		||||
			run("opt_expr -mux_undef");
 | 
			
		||||
			if (help_mode)
 | 
			
		||||
				run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(skip if 'nowidelut', only for '-retime')");
 | 
			
		||||
				run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut', option for '-retime')");
 | 
			
		||||
			else if (abc9) {
 | 
			
		||||
				if (family != "xc7")
 | 
			
		||||
					log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n");
 | 
			
		||||
				if (nowidelut)
 | 
			
		||||
					run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : ""));
 | 
			
		||||
					run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY));
 | 
			
		||||
				else
 | 
			
		||||
					run("abc9 -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : ""));
 | 
			
		||||
					run("abc9 -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY));
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				if (nowidelut)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										84
									
								
								techlibs/xilinx/xc6s_brams.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								techlibs/xilinx/xc6s_brams.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
 | 
			
		||||
bram $__XILINX_RAMB8BWER_SDP
 | 
			
		||||
  init 1
 | 
			
		||||
  abits 8
 | 
			
		||||
  dbits 36
 | 
			
		||||
  groups 2
 | 
			
		||||
  ports  1 1
 | 
			
		||||
  wrmode 0 1
 | 
			
		||||
  enable 1 4
 | 
			
		||||
  transp 0 0
 | 
			
		||||
  clocks 2 3
 | 
			
		||||
  clkpol 2 3
 | 
			
		||||
endbram
 | 
			
		||||
 | 
			
		||||
bram $__XILINX_RAMB16BWER_TDP
 | 
			
		||||
  init 1
 | 
			
		||||
  abits  9     @a9d36
 | 
			
		||||
  dbits 36     @a9d36
 | 
			
		||||
  abits 10     @a10d18
 | 
			
		||||
  dbits 18     @a10d18
 | 
			
		||||
  abits 11     @a11d9
 | 
			
		||||
  dbits  9     @a11d9
 | 
			
		||||
  abits 12     @a12d4
 | 
			
		||||
  dbits  4     @a12d4
 | 
			
		||||
  abits 13     @a13d2
 | 
			
		||||
  dbits  2     @a13d2
 | 
			
		||||
  abits 14     @a14d1
 | 
			
		||||
  dbits  1     @a14d1
 | 
			
		||||
  groups 2
 | 
			
		||||
  ports  1 1
 | 
			
		||||
  wrmode 0 1
 | 
			
		||||
  enable 1 4   @a9d36
 | 
			
		||||
  enable 1 2   @a10d18
 | 
			
		||||
  enable 1 1   @a11d9 @a12d4 @a13d2 @a14d1
 | 
			
		||||
  transp 0 0
 | 
			
		||||
  clocks 2 3
 | 
			
		||||
  clkpol 2 3
 | 
			
		||||
endbram
 | 
			
		||||
 | 
			
		||||
bram $__XILINX_RAMB8BWER_TDP
 | 
			
		||||
  init 1
 | 
			
		||||
  abits  9     @a9d18
 | 
			
		||||
  dbits 18     @a9d18
 | 
			
		||||
  abits 10     @a10d9
 | 
			
		||||
  dbits  9     @a10d9
 | 
			
		||||
  abits 11     @a11d4
 | 
			
		||||
  dbits  4     @a11d4
 | 
			
		||||
  abits 12     @a12d2
 | 
			
		||||
  dbits  2     @a12d2
 | 
			
		||||
  abits 13     @a13d1
 | 
			
		||||
  dbits  1     @a13d1
 | 
			
		||||
  groups 2
 | 
			
		||||
  ports  1 1
 | 
			
		||||
  wrmode 0 1
 | 
			
		||||
  enable 1 2   @a9d18
 | 
			
		||||
  enable 1 1   @a10d9 @a11d4 @a12d2 @a13d1
 | 
			
		||||
  transp 0 0
 | 
			
		||||
  clocks 2 3
 | 
			
		||||
  clkpol 2 3
 | 
			
		||||
endbram
 | 
			
		||||
 | 
			
		||||
match $__XILINX_RAMB8BWER_SDP
 | 
			
		||||
  min bits 4096
 | 
			
		||||
  min efficiency 5
 | 
			
		||||
  shuffle_enable B
 | 
			
		||||
  make_transp
 | 
			
		||||
  or_next_if_better
 | 
			
		||||
endmatch
 | 
			
		||||
 | 
			
		||||
match $__XILINX_RAMB16BWER_TDP
 | 
			
		||||
  min bits 4096
 | 
			
		||||
  min efficiency 5
 | 
			
		||||
  shuffle_enable B
 | 
			
		||||
  make_transp
 | 
			
		||||
  or_next_if_better
 | 
			
		||||
endmatch
 | 
			
		||||
 | 
			
		||||
match $__XILINX_RAMB8BWER_TDP
 | 
			
		||||
  min bits 4096
 | 
			
		||||
  min efficiency 5
 | 
			
		||||
  shuffle_enable B
 | 
			
		||||
  make_transp
 | 
			
		||||
endmatch
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										211
									
								
								techlibs/xilinx/xc6s_brams_bb.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								techlibs/xilinx/xc6s_brams_bb.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,211 @@
 | 
			
		|||
module RAMB8BWER (
 | 
			
		||||
	input CLKAWRCLK,
 | 
			
		||||
	input CLKBRDCLK,
 | 
			
		||||
	input ENAWREN,
 | 
			
		||||
	input ENBRDEN,
 | 
			
		||||
	input REGCEA,
 | 
			
		||||
	input REGCEBREGCE,
 | 
			
		||||
	input RSTA,
 | 
			
		||||
	input RSTBRST,
 | 
			
		||||
 | 
			
		||||
	input [12:0] ADDRAWRADDR,
 | 
			
		||||
	input [12:0] ADDRBRDADDR,
 | 
			
		||||
	input [15:0] DIADI,
 | 
			
		||||
	input [15:0] DIBDI,
 | 
			
		||||
	input [1:0] DIPADIP,
 | 
			
		||||
	input [1:0] DIPBDIP,
 | 
			
		||||
	input [1:0] WEAWEL,
 | 
			
		||||
	input [1:0] WEBWEU,
 | 
			
		||||
 | 
			
		||||
	output [15:0] DOADO,
 | 
			
		||||
	output [15:0] DOBDO,
 | 
			
		||||
	output [1:0] DOPADOP,
 | 
			
		||||
	output [1:0] DOPBDOP
 | 
			
		||||
);
 | 
			
		||||
	parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter RAM_MODE = "TDP";
 | 
			
		||||
	parameter integer DOA_REG = 0;
 | 
			
		||||
	parameter integer DOB_REG = 0;
 | 
			
		||||
 | 
			
		||||
	parameter integer DATA_WIDTH_A = 0;
 | 
			
		||||
	parameter integer DATA_WIDTH_B = 0;
 | 
			
		||||
 | 
			
		||||
	parameter WRITE_MODE_A = "WRITE_FIRST";
 | 
			
		||||
	parameter WRITE_MODE_B = "WRITE_FIRST";
 | 
			
		||||
 | 
			
		||||
	parameter EN_RSTRAM_A = "TRUE";
 | 
			
		||||
	parameter EN_RSTRAM_B = "TRUE";
 | 
			
		||||
 | 
			
		||||
	parameter INIT_A = 18'h000000000;
 | 
			
		||||
	parameter INIT_B = 18'h000000000;
 | 
			
		||||
	parameter SRVAL_A = 18'h000000000;
 | 
			
		||||
	parameter SRVAL_B = 18'h000000000;
 | 
			
		||||
 | 
			
		||||
	parameter RST_PRIORITY_A = "CE";
 | 
			
		||||
	parameter RST_PRIORITY_B = "CE";
 | 
			
		||||
 | 
			
		||||
	parameter RSTTYPE = "SYNC";
 | 
			
		||||
 | 
			
		||||
	parameter SIM_COLLISION_CHECK = "ALL";
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module RAMB16BWER (
 | 
			
		||||
	input CLKA,
 | 
			
		||||
	input CLKB,
 | 
			
		||||
	input ENA,
 | 
			
		||||
	input ENB,
 | 
			
		||||
	input REGCEA,
 | 
			
		||||
	input REGCEB,
 | 
			
		||||
	input RSTA,
 | 
			
		||||
	input RSTB,
 | 
			
		||||
 | 
			
		||||
	input [13:0] ADDRA,
 | 
			
		||||
	input [13:0] ADDRB,
 | 
			
		||||
	input [31:0] DIA,
 | 
			
		||||
	input [31:0] DIB,
 | 
			
		||||
	input [3:0] DIPA,
 | 
			
		||||
	input [3:0] DIPB,
 | 
			
		||||
	input [3:0] WEA,
 | 
			
		||||
	input [3:0] WEB,
 | 
			
		||||
 | 
			
		||||
	output [31:0] DOA,
 | 
			
		||||
	output [31:0] DOB,
 | 
			
		||||
	output [3:0] DOPA,
 | 
			
		||||
	output [3:0] DOPB
 | 
			
		||||
);
 | 
			
		||||
	parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter integer DOA_REG = 0;
 | 
			
		||||
	parameter integer DOB_REG = 0;
 | 
			
		||||
 | 
			
		||||
	parameter integer DATA_WIDTH_A = 0;
 | 
			
		||||
	parameter integer DATA_WIDTH_B = 0;
 | 
			
		||||
 | 
			
		||||
	parameter WRITE_MODE_A = "WRITE_FIRST";
 | 
			
		||||
	parameter WRITE_MODE_B = "WRITE_FIRST";
 | 
			
		||||
 | 
			
		||||
	parameter EN_RSTRAM_A = "TRUE";
 | 
			
		||||
	parameter EN_RSTRAM_B = "TRUE";
 | 
			
		||||
 | 
			
		||||
	parameter INIT_A = 36'h000000000;
 | 
			
		||||
	parameter INIT_B = 36'h000000000;
 | 
			
		||||
	parameter SRVAL_A = 36'h000000000;
 | 
			
		||||
	parameter SRVAL_B = 36'h000000000;
 | 
			
		||||
 | 
			
		||||
	parameter RST_PRIORITY_A = "CE";
 | 
			
		||||
	parameter RST_PRIORITY_B = "CE";
 | 
			
		||||
 | 
			
		||||
	parameter RSTTYPE = "SYNC";
 | 
			
		||||
 | 
			
		||||
	parameter SIM_COLLISION_CHECK = "ALL";
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										255
									
								
								techlibs/xilinx/xc6s_brams_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								techlibs/xilinx/xc6s_brams_map.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,255 @@
 | 
			
		|||
module \$__XILINX_RAMB8BWER_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
 | 
			
		||||
	parameter CLKPOL2 = 1;
 | 
			
		||||
	parameter CLKPOL3 = 1;
 | 
			
		||||
	parameter [9215:0] INIT = 9216'bx;
 | 
			
		||||
 | 
			
		||||
	input CLK2;
 | 
			
		||||
	input CLK3;
 | 
			
		||||
 | 
			
		||||
	input [7:0] A1ADDR;
 | 
			
		||||
	output [35:0] A1DATA;
 | 
			
		||||
	input A1EN;
 | 
			
		||||
 | 
			
		||||
	input [7:0] B1ADDR;
 | 
			
		||||
	input [35:0] B1DATA;
 | 
			
		||||
	input [3:0] B1EN;
 | 
			
		||||
 | 
			
		||||
	wire [12:0] A1ADDR_13 = {A1ADDR, 5'b0};
 | 
			
		||||
	wire [12:0] B1ADDR_13 = {B1ADDR, 5'b0};
 | 
			
		||||
 | 
			
		||||
	wire [3:0] DIP, DOP;
 | 
			
		||||
	wire [31:0] DI, DO;
 | 
			
		||||
 | 
			
		||||
	assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
 | 
			
		||||
	assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
 | 
			
		||||
 | 
			
		||||
	RAMB8BWER #(
 | 
			
		||||
		.RAM_MODE("SDP"),
 | 
			
		||||
		.DATA_WIDTH_A(36),
 | 
			
		||||
		.DATA_WIDTH_B(36),
 | 
			
		||||
		.WRITE_MODE_A("READ_FIRST"),
 | 
			
		||||
		.WRITE_MODE_B("READ_FIRST"),
 | 
			
		||||
		`include "brams_init_9.vh"
 | 
			
		||||
	) _TECHMAP_REPLACE_ (
 | 
			
		||||
		.DOBDO(DO[31:16]),
 | 
			
		||||
		.DOADO(DO[15:0]),
 | 
			
		||||
		.DOPBDOP(DOP[3:2]),
 | 
			
		||||
		.DOPADOP(DOP[1:0]),
 | 
			
		||||
		.DIBDI(DI[31:16]),
 | 
			
		||||
		.DIADI(DI[15:0]),
 | 
			
		||||
		.DIPBDIP(DIP[3:2]),
 | 
			
		||||
		.DIPADIP(DIP[1:0]),
 | 
			
		||||
		.WEBWEU(B1EN[3:2]),
 | 
			
		||||
		.WEAWEL(B1EN[1:0]),
 | 
			
		||||
 | 
			
		||||
		.ADDRAWRADDR(B1ADDR_13),
 | 
			
		||||
		.CLKAWRCLK(CLK3 ^ !CLKPOL3),
 | 
			
		||||
		.ENAWREN(|1),
 | 
			
		||||
		.REGCEA(|0),
 | 
			
		||||
		.RSTA(|0),
 | 
			
		||||
 | 
			
		||||
		.ADDRBRDADDR(A1ADDR_13),
 | 
			
		||||
		.CLKBRDCLK(CLK2 ^ !CLKPOL2),
 | 
			
		||||
		.ENBRDEN(A1EN),
 | 
			
		||||
		.REGCEBREGCE(|1),
 | 
			
		||||
		.RSTB(|0)
 | 
			
		||||
	);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module \$__XILINX_RAMB16BWER_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
 | 
			
		||||
	parameter CFG_ABITS = 9;
 | 
			
		||||
	parameter CFG_DBITS = 36;
 | 
			
		||||
	parameter CFG_ENABLE_B = 4;
 | 
			
		||||
 | 
			
		||||
	parameter CLKPOL2 = 1;
 | 
			
		||||
	parameter CLKPOL3 = 1;
 | 
			
		||||
	parameter [18431:0] INIT = 18432'bx;
 | 
			
		||||
 | 
			
		||||
	input CLK2;
 | 
			
		||||
	input CLK3;
 | 
			
		||||
 | 
			
		||||
	input [CFG_ABITS-1:0] A1ADDR;
 | 
			
		||||
	output [CFG_DBITS-1:0] A1DATA;
 | 
			
		||||
	input A1EN;
 | 
			
		||||
 | 
			
		||||
	input [CFG_ABITS-1:0] B1ADDR;
 | 
			
		||||
	input [CFG_DBITS-1:0] B1DATA;
 | 
			
		||||
	input [CFG_ENABLE_B-1:0] B1EN;
 | 
			
		||||
 | 
			
		||||
	wire [13:0] A1ADDR_14 = A1ADDR << (14 - CFG_ABITS);
 | 
			
		||||
	wire [13:0] B1ADDR_14 = B1ADDR << (14 - CFG_ABITS);
 | 
			
		||||
	wire [3:0] B1EN_4 = {4{B1EN}};
 | 
			
		||||
 | 
			
		||||
	wire [3:0] DIP, DOP;
 | 
			
		||||
	wire [31:0] DI, DO;
 | 
			
		||||
 | 
			
		||||
	wire [31:0] DOB;
 | 
			
		||||
	wire [3:0] DOPB;
 | 
			
		||||
 | 
			
		||||
	assign A1DATA = { DOP[3], DO[31:24], DOP[2], DO[23:16], DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
 | 
			
		||||
	assign { DIP[3], DI[31:24], DIP[2], DI[23:16], DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
 | 
			
		||||
 | 
			
		||||
	generate if (CFG_DBITS > 8) begin
 | 
			
		||||
		RAMB16BWER #(
 | 
			
		||||
			.DATA_WIDTH_A(CFG_DBITS),
 | 
			
		||||
			.DATA_WIDTH_B(CFG_DBITS),
 | 
			
		||||
			.WRITE_MODE_A("READ_FIRST"),
 | 
			
		||||
			.WRITE_MODE_B("READ_FIRST"),
 | 
			
		||||
			`include "brams_init_18.vh"
 | 
			
		||||
		) _TECHMAP_REPLACE_ (
 | 
			
		||||
			.DIA(32'd0),
 | 
			
		||||
			.DIPA(4'd0),
 | 
			
		||||
			.DOA(DO[31:0]),
 | 
			
		||||
			.DOPA(DOP[3:0]),
 | 
			
		||||
			.ADDRA(A1ADDR_14),
 | 
			
		||||
			.CLKA(CLK2 ^ !CLKPOL2),
 | 
			
		||||
			.ENA(A1EN),
 | 
			
		||||
			.REGCEA(|1),
 | 
			
		||||
			.RSTA(|0),
 | 
			
		||||
			.WEA(4'b0),
 | 
			
		||||
 | 
			
		||||
			.DIB(DI),
 | 
			
		||||
			.DIPB(DIP),
 | 
			
		||||
			.DOB(DOB),
 | 
			
		||||
			.DOPB(DOPB),
 | 
			
		||||
			.ADDRB(B1ADDR_14),
 | 
			
		||||
			.CLKB(CLK3 ^ !CLKPOL3),
 | 
			
		||||
			.ENB(|1),
 | 
			
		||||
			.REGCEB(|0),
 | 
			
		||||
			.RSTB(|0),
 | 
			
		||||
			.WEB(B1EN_4)
 | 
			
		||||
		);
 | 
			
		||||
	end else begin
 | 
			
		||||
		RAMB16BWER #(
 | 
			
		||||
			.DATA_WIDTH_A(CFG_DBITS),
 | 
			
		||||
			.DATA_WIDTH_B(CFG_DBITS),
 | 
			
		||||
			.WRITE_MODE_A("READ_FIRST"),
 | 
			
		||||
			.WRITE_MODE_B("READ_FIRST"),
 | 
			
		||||
			`include "brams_init_16.vh"
 | 
			
		||||
		) _TECHMAP_REPLACE_ (
 | 
			
		||||
			.DIA(32'd0),
 | 
			
		||||
			.DIPA(4'd0),
 | 
			
		||||
			.DOA(DO[31:0]),
 | 
			
		||||
			.DOPA(DOP[3:0]),
 | 
			
		||||
			.ADDRA(A1ADDR_14),
 | 
			
		||||
			.CLKA(CLK2 ^ !CLKPOL2),
 | 
			
		||||
			.ENA(A1EN),
 | 
			
		||||
			.REGCEA(|1),
 | 
			
		||||
			.RSTA(|0),
 | 
			
		||||
			.WEA(4'b0),
 | 
			
		||||
 | 
			
		||||
			.DIB(DI),
 | 
			
		||||
			.DIPB(DIP),
 | 
			
		||||
			.DOB(DOB),
 | 
			
		||||
			.DOPB(DOPB),
 | 
			
		||||
			.ADDRB(B1ADDR_14),
 | 
			
		||||
			.CLKB(CLK3 ^ !CLKPOL3),
 | 
			
		||||
			.ENB(|1),
 | 
			
		||||
			.REGCEB(|0),
 | 
			
		||||
			.RSTB(|0),
 | 
			
		||||
			.WEB(B1EN_4)
 | 
			
		||||
		);
 | 
			
		||||
	end endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
module \$__XILINX_RAMB8BWER_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
 | 
			
		||||
	parameter CFG_ABITS = 9;
 | 
			
		||||
	parameter CFG_DBITS = 18;
 | 
			
		||||
	parameter CFG_ENABLE_B = 2;
 | 
			
		||||
 | 
			
		||||
	parameter CLKPOL2 = 1;
 | 
			
		||||
	parameter CLKPOL3 = 1;
 | 
			
		||||
	parameter [9215:0] INIT = 9216'bx;
 | 
			
		||||
 | 
			
		||||
	input CLK2;
 | 
			
		||||
	input CLK3;
 | 
			
		||||
 | 
			
		||||
	input [CFG_ABITS-1:0] A1ADDR;
 | 
			
		||||
	output [CFG_DBITS-1:0] A1DATA;
 | 
			
		||||
	input A1EN;
 | 
			
		||||
 | 
			
		||||
	input [CFG_ABITS-1:0] B1ADDR;
 | 
			
		||||
	input [CFG_DBITS-1:0] B1DATA;
 | 
			
		||||
	input [CFG_ENABLE_B-1:0] B1EN;
 | 
			
		||||
 | 
			
		||||
	wire [12:0] A1ADDR_13 = A1ADDR << (13 - CFG_ABITS);
 | 
			
		||||
	wire [12:0] B1ADDR_13 = B1ADDR << (13 - CFG_ABITS);
 | 
			
		||||
	wire [1:0] B1EN_2 = {2{B1EN}};
 | 
			
		||||
 | 
			
		||||
	wire [1:0] DIP, DOP;
 | 
			
		||||
	wire [15:0] DI, DO;
 | 
			
		||||
 | 
			
		||||
	wire [15:0] DOBDO;
 | 
			
		||||
	wire [1:0] DOPBDOP;
 | 
			
		||||
 | 
			
		||||
	assign A1DATA = { DOP[1], DO[15: 8], DOP[0], DO[ 7: 0] };
 | 
			
		||||
	assign { DIP[1], DI[15: 8], DIP[0], DI[ 7: 0] } = B1DATA;
 | 
			
		||||
 | 
			
		||||
	generate if (CFG_DBITS > 8) begin
 | 
			
		||||
		RAMB8BWER #(
 | 
			
		||||
			.RAM_MODE("TDP"),
 | 
			
		||||
			.DATA_WIDTH_A(CFG_DBITS),
 | 
			
		||||
			.DATA_WIDTH_B(CFG_DBITS),
 | 
			
		||||
			.WRITE_MODE_A("READ_FIRST"),
 | 
			
		||||
			.WRITE_MODE_B("READ_FIRST"),
 | 
			
		||||
			`include "brams_init_9.vh"
 | 
			
		||||
		) _TECHMAP_REPLACE_ (
 | 
			
		||||
			.DIADI(16'b0),
 | 
			
		||||
			.DIPADIP(2'b0),
 | 
			
		||||
			.DOADO(DO),
 | 
			
		||||
			.DOPADOP(DOP),
 | 
			
		||||
			.ADDRAWRADDR(A1ADDR_13),
 | 
			
		||||
			.CLKAWRCLK(CLK2 ^ !CLKPOL2),
 | 
			
		||||
			.ENAWREN(A1EN),
 | 
			
		||||
			.REGCEA(|1),
 | 
			
		||||
			.RSTA(|0),
 | 
			
		||||
			.WEAWEL(2'b0),
 | 
			
		||||
 | 
			
		||||
			.DIBDI(DI),
 | 
			
		||||
			.DIPBDIP(DIP),
 | 
			
		||||
			.DOBDO(DOBDO),
 | 
			
		||||
			.DOPBDOP(DOPBDOP),
 | 
			
		||||
			.ADDRBRDADDR(B1ADDR_13),
 | 
			
		||||
			.CLKBRDCLK(CLK3 ^ !CLKPOL3),
 | 
			
		||||
			.ENBRDEN(|1),
 | 
			
		||||
			.REGCEBREGCE(|0),
 | 
			
		||||
			.RSTB(|0),
 | 
			
		||||
			.WEBWEU(B1EN_2)
 | 
			
		||||
		);
 | 
			
		||||
	end else begin
 | 
			
		||||
		RAMB8BWER #(
 | 
			
		||||
			.RAM_MODE("TDP"),
 | 
			
		||||
			.DATA_WIDTH_A(CFG_DBITS),
 | 
			
		||||
			.DATA_WIDTH_B(CFG_DBITS),
 | 
			
		||||
			.WRITE_MODE_A("READ_FIRST"),
 | 
			
		||||
			.WRITE_MODE_B("READ_FIRST"),
 | 
			
		||||
			`include "brams_init_8.vh"
 | 
			
		||||
		) _TECHMAP_REPLACE_ (
 | 
			
		||||
			.DIADI(16'b0),
 | 
			
		||||
			.DIPADIP(2'b0),
 | 
			
		||||
			.DOADO(DO),
 | 
			
		||||
			.DOPADOP(DOP),
 | 
			
		||||
			.ADDRAWRADDR(A1ADDR_13),
 | 
			
		||||
			.CLKAWRCLK(CLK2 ^ !CLKPOL2),
 | 
			
		||||
			.ENAWREN(A1EN),
 | 
			
		||||
			.REGCEA(|1),
 | 
			
		||||
			.RSTA(|0),
 | 
			
		||||
			.WEAWEL(2'b0),
 | 
			
		||||
 | 
			
		||||
			.DIBDI(DI),
 | 
			
		||||
			.DIPBDIP(DIP),
 | 
			
		||||
			.DOBDO(DOBDO),
 | 
			
		||||
			.DOPBDOP(DOPBDOP),
 | 
			
		||||
			.ADDRBRDADDR(B1ADDR_13),
 | 
			
		||||
			.CLKBRDCLK(CLK3 ^ !CLKPOL3),
 | 
			
		||||
			.ENBRDEN(|1),
 | 
			
		||||
			.REGCEBREGCE(|0),
 | 
			
		||||
			.RSTB(|0),
 | 
			
		||||
			.WEBWEU(B1EN_2)
 | 
			
		||||
		);
 | 
			
		||||
	end endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										3
									
								
								tests/simple_abc9/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/simple_abc9/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
*.v
 | 
			
		||||
*.log
 | 
			
		||||
*.out
 | 
			
		||||
							
								
								
									
										11
									
								
								tests/various/async.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tests/various/async.sh
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
#!/bin/bash
 | 
			
		||||
set -ex
 | 
			
		||||
../../yosys -q -o async_syn.v -p 'synth; rename uut syn' async.v
 | 
			
		||||
../../yosys -q -o async_prp.v -p 'prep; rename uut prp' async.v
 | 
			
		||||
../../yosys -q -o async_a2s.v -p 'prep; async2sync; rename uut a2s' async.v
 | 
			
		||||
../../yosys -q -o async_ffl.v -p 'prep; clk2fflogic; rename uut ffl' async.v
 | 
			
		||||
iverilog -o async_sim -DTESTBENCH async.v async_???.v
 | 
			
		||||
vvp -N async_sim > async.out
 | 
			
		||||
tail async.out
 | 
			
		||||
grep PASS async.out
 | 
			
		||||
rm -f async_???.v async_sim async.out async.vcd
 | 
			
		||||
							
								
								
									
										108
									
								
								tests/various/async.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								tests/various/async.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,108 @@
 | 
			
		|||
`define MAXQ 2
 | 
			
		||||
module uut (
 | 
			
		||||
	input clk,
 | 
			
		||||
	input d, r, e,
 | 
			
		||||
	output [`MAXQ:0] q
 | 
			
		||||
);
 | 
			
		||||
	reg q0;
 | 
			
		||||
	always @(posedge clk) begin
 | 
			
		||||
		if (r)
 | 
			
		||||
			q0 <= 0;
 | 
			
		||||
		else if (e)
 | 
			
		||||
			q0 <= d;
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	reg q1;
 | 
			
		||||
	always @(posedge clk, posedge r) begin
 | 
			
		||||
		if (r)
 | 
			
		||||
			q1 <= 0;
 | 
			
		||||
		else if (e)
 | 
			
		||||
			q1 <= d;
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	reg q2;
 | 
			
		||||
	always @(posedge clk, negedge r) begin
 | 
			
		||||
		if (!r)
 | 
			
		||||
			q2 <= 0;
 | 
			
		||||
		else if (!e)
 | 
			
		||||
			q2 <= d;
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	assign q = {q2, q1, q0};
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
`ifdef TESTBENCH
 | 
			
		||||
module \$ff #(
 | 
			
		||||
	parameter integer WIDTH = 1
 | 
			
		||||
) (
 | 
			
		||||
	input [WIDTH-1:0] D,
 | 
			
		||||
	output reg [WIDTH-1:0] Q
 | 
			
		||||
);
 | 
			
		||||
	wire sysclk = testbench.sysclk;
 | 
			
		||||
	always @(posedge sysclk)
 | 
			
		||||
		Q <= D;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module testbench;
 | 
			
		||||
	reg sysclk;
 | 
			
		||||
	always #5 sysclk = (sysclk === 1'b0);
 | 
			
		||||
 | 
			
		||||
	reg clk;
 | 
			
		||||
	always @(posedge sysclk) clk = (clk === 1'b0);
 | 
			
		||||
 | 
			
		||||
	reg d, r, e;
 | 
			
		||||
 | 
			
		||||
	wire [`MAXQ:0] q_uut;
 | 
			
		||||
	uut uut (.clk(clk), .d(d), .r(r), .e(e), .q(q_uut));
 | 
			
		||||
 | 
			
		||||
	wire [`MAXQ:0] q_syn;
 | 
			
		||||
	syn syn (.clk(clk), .d(d), .r(r), .e(e), .q(q_syn));
 | 
			
		||||
 | 
			
		||||
	wire [`MAXQ:0] q_prp;
 | 
			
		||||
	prp prp (.clk(clk), .d(d), .r(r), .e(e), .q(q_prp));
 | 
			
		||||
 | 
			
		||||
	wire [`MAXQ:0] q_a2s;
 | 
			
		||||
	a2s a2s (.clk(clk), .d(d), .r(r), .e(e), .q(q_a2s));
 | 
			
		||||
 | 
			
		||||
	wire [`MAXQ:0] q_ffl;
 | 
			
		||||
	ffl ffl (.clk(clk), .d(d), .r(r), .e(e), .q(q_ffl));
 | 
			
		||||
 | 
			
		||||
	task printq;
 | 
			
		||||
		reg [5*8-1:0] msg;
 | 
			
		||||
		begin
 | 
			
		||||
			msg = "OK";
 | 
			
		||||
			if (q_uut !== q_syn) msg = "SYN";
 | 
			
		||||
			if (q_uut !== q_prp) msg = "PRP";
 | 
			
		||||
			if (q_uut !== q_a2s) msg = "A2S";
 | 
			
		||||
			if (q_uut !== q_ffl) msg = "FFL";
 | 
			
		||||
			$display("%6t %b %b %b %b %b %s", $time, q_uut, q_syn, q_prp, q_a2s, q_ffl, msg);
 | 
			
		||||
			if (msg != "OK") $finish;
 | 
			
		||||
		end
 | 
			
		||||
	endtask
 | 
			
		||||
 | 
			
		||||
	initial if(0) begin
 | 
			
		||||
		$dumpfile("async.vcd");
 | 
			
		||||
		$dumpvars(0, testbench);
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	initial begin
 | 
			
		||||
		@(posedge clk);
 | 
			
		||||
		d <= 0;
 | 
			
		||||
		r <= 0;
 | 
			
		||||
		e <= 0;
 | 
			
		||||
		@(posedge clk);
 | 
			
		||||
		e <= 1;
 | 
			
		||||
		@(posedge clk);
 | 
			
		||||
		e <= 0;
 | 
			
		||||
		repeat (10000) begin
 | 
			
		||||
			@(posedge clk);
 | 
			
		||||
			printq;
 | 
			
		||||
			d <= $random;
 | 
			
		||||
			r <= $random;
 | 
			
		||||
			e <= $random;
 | 
			
		||||
		end
 | 
			
		||||
		$display("PASS");
 | 
			
		||||
		$finish;
 | 
			
		||||
	end
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
| 
						 | 
				
			
			@ -4,11 +4,9 @@ for x in *.ys; do
 | 
			
		|||
	echo "Running $x.."
 | 
			
		||||
	../../yosys -ql ${x%.ys}.log $x
 | 
			
		||||
done
 | 
			
		||||
# Run any .sh files in this directory (with the exception of the file - run-test.sh
 | 
			
		||||
shell_tests=$(echo *.sh | sed -e 's/run-test.sh//')
 | 
			
		||||
if [ "$shell_tests" ]; then
 | 
			
		||||
    for s in $shell_tests; do
 | 
			
		||||
        echo "Running $s.."
 | 
			
		||||
        bash $s
 | 
			
		||||
    done
 | 
			
		||||
fi
 | 
			
		||||
for s in *.sh; do
 | 
			
		||||
	if [ "$s" != "run-test.sh" ]; then
 | 
			
		||||
		echo "Running $s.."
 | 
			
		||||
		bash $s
 | 
			
		||||
	fi
 | 
			
		||||
done
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue