mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	
						commit
						5dcb899e76
					
				
					 13 changed files with 1242 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -65,6 +65,8 @@ int verific_verbose;
 | 
			
		|||
bool verific_import_pending;
 | 
			
		||||
string verific_error_msg;
 | 
			
		||||
 | 
			
		||||
vector<string> verific_incdirs, verific_libdirs;
 | 
			
		||||
 | 
			
		||||
void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefile, const char *msg, va_list args)
 | 
			
		||||
{
 | 
			
		||||
	string message_prefix = stringf("VERIFIC-%s [%s] ",
 | 
			
		||||
| 
						 | 
				
			
			@ -1658,6 +1660,8 @@ void verific_import(Design *design, std::string top)
 | 
			
		|||
	veri_file::Reset();
 | 
			
		||||
	vhdl_file::Reset();
 | 
			
		||||
	Libset::Reset();
 | 
			
		||||
	verific_incdirs.clear();
 | 
			
		||||
	verific_libdirs.clear();
 | 
			
		||||
	verific_import_pending = false;
 | 
			
		||||
 | 
			
		||||
	if (!verific_error_msg.empty())
 | 
			
		||||
| 
						 | 
				
			
			@ -1814,13 +1818,13 @@ struct VerificPass : public Pass {
 | 
			
		|||
 | 
			
		||||
		if (GetSize(args) > argidx && args[argidx] == "-vlog-incdir") {
 | 
			
		||||
			for (argidx++; argidx < GetSize(args); argidx++)
 | 
			
		||||
				veri_file::AddIncludeDir(args[argidx].c_str());
 | 
			
		||||
				verific_incdirs.push_back(args[argidx]);
 | 
			
		||||
			goto check_error;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (GetSize(args) > argidx && args[argidx] == "-vlog-libdir") {
 | 
			
		||||
			for (argidx++; argidx < GetSize(args); argidx++)
 | 
			
		||||
				veri_file::AddYDir(args[argidx].c_str());
 | 
			
		||||
				verific_libdirs.push_back(args[argidx]);
 | 
			
		||||
			goto check_error;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1886,6 +1890,11 @@ struct VerificPass : public Pass {
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto &dir : verific_incdirs)
 | 
			
		||||
				veri_file::AddIncludeDir(dir.c_str());
 | 
			
		||||
			for (auto &dir : verific_libdirs)
 | 
			
		||||
				veri_file::AddYDir(dir.c_str());
 | 
			
		||||
 | 
			
		||||
			while (argidx < GetSize(args))
 | 
			
		||||
				file_names.Insert(args[argidx++].c_str());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2139,6 +2148,8 @@ struct VerificPass : public Pass {
 | 
			
		|||
			veri_file::Reset();
 | 
			
		||||
			vhdl_file::Reset();
 | 
			
		||||
			Libset::Reset();
 | 
			
		||||
			verific_incdirs.clear();
 | 
			
		||||
			verific_libdirs.clear();
 | 
			
		||||
			verific_import_pending = false;
 | 
			
		||||
			goto check_error;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -2186,6 +2197,11 @@ struct ReadPass : public Pass {
 | 
			
		|||
		log("\n");
 | 
			
		||||
		log("Unset global Verilog/SystemVerilog defines.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    read -incdir <directory>\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("Add directory to global Verilog/SystemVerilog include directories.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -2263,6 +2279,20 @@ struct ReadPass : public Pass {
 | 
			
		|||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (args[1] == "-incdir") {
 | 
			
		||||
			if (use_verific) {
 | 
			
		||||
				args[0] = "verific";
 | 
			
		||||
				args[1] = "-vlog-incdir";
 | 
			
		||||
				Pass::call(design, args);
 | 
			
		||||
			}
 | 
			
		||||
			args[0] = "verilog_defaults";
 | 
			
		||||
			args[1] = "-add";
 | 
			
		||||
			for (int i = 2; i < GetSize(args); i++)
 | 
			
		||||
				args[i] = "-I" + args[i];
 | 
			
		||||
			Pass::call(design, args);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log_cmd_error("Missing or unsupported mode parameter.\n");
 | 
			
		||||
	}
 | 
			
		||||
} ReadPass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1517,9 +1517,11 @@ struct VerificSvaImporter
 | 
			
		|||
 | 
			
		||||
			Instance *consequent_inst = net_to_ast_driver(consequent_net);
 | 
			
		||||
 | 
			
		||||
			if (consequent_inst->Type() != PRIM_SVA_S_EVENTUALLY && consequent_inst->Type() != PRIM_SVA_EVENTUALLY) {
 | 
			
		||||
			if (consequent_inst == nullptr)
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			if (consequent_inst->Type() != PRIM_SVA_S_EVENTUALLY && consequent_inst->Type() != PRIM_SVA_EVENTUALLY)
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (mode_cover || mode_trigger)
 | 
			
		||||
				parser_error(consequent_inst);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@ OBJS += passes/techmap/insbuf.o
 | 
			
		|||
OBJS += passes/techmap/attrmvcp.o
 | 
			
		||||
OBJS += passes/techmap/attrmap.o
 | 
			
		||||
OBJS += passes/techmap/zinit.o
 | 
			
		||||
OBJS += passes/techmap/dff2dffs.o
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
GENFILES += passes/techmap/techmap.inc
 | 
			
		||||
| 
						 | 
				
			
			@ -57,4 +58,3 @@ yosys-filterlib$(EXE): passes/techmap/filterlib.o
 | 
			
		|||
	$(Q) mkdir -p $(dir $@)
 | 
			
		||||
	$(P) $(LD) -o yosys-filterlib$(EXE) $(LDFLAGS) $^ $(LDLIBS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,8 +279,9 @@ struct Dff2dffePass : public Pass {
 | 
			
		|||
		log("    -direct-match <pattern>\n");
 | 
			
		||||
		log("        like -direct for all DFF cell types matching the expression.\n");
 | 
			
		||||
		log("        this will use $__DFFE_* as <external_gate_type> matching the\n");
 | 
			
		||||
		log("        internal gate type $_DFF_*_, except for $_DFF_[NP]_, which is\n");
 | 
			
		||||
		log("        converted to $_DFFE_[NP]_.\n");
 | 
			
		||||
		log("        internal gate type $_DFF_*_, and $__DFFSE_* for those matching\n");
 | 
			
		||||
		log("        $_DFFS_*_, except for $_DFF_[NP]_, which is converted to \n");
 | 
			
		||||
		log("        $_DFFE_[NP]_.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
 | 
			
		||||
| 
						 | 
				
			
			@ -315,6 +316,15 @@ struct Dff2dffePass : public Pass {
 | 
			
		|||
				if (patmatch(pattern, "$_DFF_PN1_")) found_match = true, direct_dict["$_DFF_PN1_"] = "$__DFFE_PN1";
 | 
			
		||||
				if (patmatch(pattern, "$_DFF_PP0_")) found_match = true, direct_dict["$_DFF_PP0_"] = "$__DFFE_PP0";
 | 
			
		||||
				if (patmatch(pattern, "$_DFF_PP1_")) found_match = true, direct_dict["$_DFF_PP1_"] = "$__DFFE_PP1";
 | 
			
		||||
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_NN0_")) found_match = true, direct_dict["$__DFFS_NN0_"] = "$__DFFSE_NN0";
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_NN1_")) found_match = true, direct_dict["$__DFFS_NN1_"] = "$__DFFSE_NN1";
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_NP0_")) found_match = true, direct_dict["$__DFFS_NP0_"] = "$__DFFSE_NP0";
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_NP1_")) found_match = true, direct_dict["$__DFFS_NP1_"] = "$__DFFSE_NP1";
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_PN0_")) found_match = true, direct_dict["$__DFFS_PN0_"] = "$__DFFSE_PN0";
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_PN1_")) found_match = true, direct_dict["$__DFFS_PN1_"] = "$__DFFSE_PN1";
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_PP0_")) found_match = true, direct_dict["$__DFFS_PP0_"] = "$__DFFSE_PP0";
 | 
			
		||||
				if (patmatch(pattern, "$__DFFS_PP1_")) found_match = true, direct_dict["$__DFFS_PP1_"] = "$__DFFSE_PP1";
 | 
			
		||||
				if (!found_match)
 | 
			
		||||
					log_cmd_error("No cell types matched pattern '%s'.\n", pattern);
 | 
			
		||||
				continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										142
									
								
								passes/techmap/dff2dffs.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								passes/techmap/dff2dffs.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,142 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *  Copyright (C) 2018  David Shah <dave@ds0.me>
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 *  purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 *  copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "kernel/yosys.h"
 | 
			
		||||
#include "kernel/sigtools.h"
 | 
			
		||||
 | 
			
		||||
USING_YOSYS_NAMESPACE
 | 
			
		||||
PRIVATE_NAMESPACE_BEGIN
 | 
			
		||||
 | 
			
		||||
struct Dff2dffsPass : public Pass {
 | 
			
		||||
	Dff2dffsPass() : Pass("dff2dffs", "process sync set/reset with SR over CE priority") { }
 | 
			
		||||
	virtual void help()
 | 
			
		||||
	{
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    dff2dffs [options] [selection]\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("Merge synchronous set/reset $_MUX_ cells to create $__DFFS_[NP][NP][01], to be run before\n");
 | 
			
		||||
		log("dff2dffe for SR over CE priority.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
 | 
			
		||||
	{
 | 
			
		||||
		log_header(design, "Executing dff2dffs pass (merge synchronous set/reset into FF cells).\n");
 | 
			
		||||
 | 
			
		||||
		size_t argidx;
 | 
			
		||||
		for (argidx = 1; argidx < args.size(); argidx++)
 | 
			
		||||
		{
 | 
			
		||||
			// if (args[argidx] == "-singleton") {
 | 
			
		||||
			// 	singleton_mode = true;
 | 
			
		||||
			// 	continue;
 | 
			
		||||
			// }
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		pool<IdString> dff_types;
 | 
			
		||||
		dff_types.insert("$_DFF_N_");
 | 
			
		||||
		dff_types.insert("$_DFF_P_");
 | 
			
		||||
 | 
			
		||||
		for (auto module : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			log("Merging set/reset $_MUX_ cells into DFFs in %s.\n", log_id(module));
 | 
			
		||||
 | 
			
		||||
			SigMap sigmap(module);
 | 
			
		||||
			dict<SigBit, Cell*> sr_muxes;
 | 
			
		||||
			vector<Cell*> ff_cells;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
			{
 | 
			
		||||
				if (dff_types.count(cell->type)) {
 | 
			
		||||
					ff_cells.push_back(cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (cell->type != "$_MUX_")
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				SigBit bit_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
				SigBit bit_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
 | 
			
		||||
				if (bit_a.wire == nullptr || bit_b.wire == nullptr)
 | 
			
		||||
					sr_muxes[sigmap(cell->getPort("\\Y"))] = cell;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto cell : ff_cells)
 | 
			
		||||
			{
 | 
			
		||||
				SigSpec sig_d = cell->getPort("\\D");
 | 
			
		||||
 | 
			
		||||
				if (GetSize(sig_d) < 1)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				SigBit bit_d = sigmap(sig_d[0]);
 | 
			
		||||
 | 
			
		||||
				if (sr_muxes.count(bit_d) == 0)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				Cell *mux_cell = sr_muxes.at(bit_d);
 | 
			
		||||
				SigBit bit_a = sigmap(mux_cell->getPort("\\A"));
 | 
			
		||||
				SigBit bit_b = sigmap(mux_cell->getPort("\\B"));
 | 
			
		||||
				SigBit bit_s = sigmap(mux_cell->getPort("\\S"));
 | 
			
		||||
 | 
			
		||||
				log("  Merging %s (A=%s, B=%s, S=%s) into %s (%s).\n", log_id(mux_cell),
 | 
			
		||||
						log_signal(bit_a), log_signal(bit_b), log_signal(bit_s), log_id(cell), log_id(cell->type));
 | 
			
		||||
 | 
			
		||||
				SigBit sr_val, sr_sig;
 | 
			
		||||
				bool invert_sr;
 | 
			
		||||
				sr_sig = bit_s;
 | 
			
		||||
				if (bit_a.wire == nullptr) {
 | 
			
		||||
					bit_d = bit_b;
 | 
			
		||||
					sr_val = bit_a;
 | 
			
		||||
					invert_sr = true;
 | 
			
		||||
				} else {
 | 
			
		||||
					log_assert(bit_b.wire == nullptr);
 | 
			
		||||
					bit_d = bit_a;
 | 
			
		||||
					sr_val = bit_b;
 | 
			
		||||
					invert_sr = false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (sr_val == State::S1) {
 | 
			
		||||
					if (cell->type == "$_DFF_N_") {
 | 
			
		||||
						if (invert_sr) cell->type = "$__DFFS_NN1_";
 | 
			
		||||
						else cell->type = "$__DFFS_NP1_";
 | 
			
		||||
					} else {
 | 
			
		||||
						log_assert(cell->type == "$_DFF_P_");
 | 
			
		||||
						if (invert_sr) cell->type = "$__DFFS_PN1_";
 | 
			
		||||
						else cell->type = "$__DFFS_PP1_";
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					if (cell->type == "$_DFF_N_") {
 | 
			
		||||
						if (invert_sr) cell->type = "$__DFFS_NN0_";
 | 
			
		||||
						else cell->type = "$__DFFS_NP0_";
 | 
			
		||||
					} else {
 | 
			
		||||
						log_assert(cell->type == "$_DFF_P_");
 | 
			
		||||
						if (invert_sr) cell->type = "$__DFFS_PN0_";
 | 
			
		||||
						else cell->type = "$__DFFS_PP0_";
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				cell->setPort("\\R", sr_sig);
 | 
			
		||||
				cell->setPort("\\D", bit_d);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} Dff2dffsPass;
 | 
			
		||||
 | 
			
		||||
PRIVATE_NAMESPACE_END
 | 
			
		||||
							
								
								
									
										8
									
								
								techlibs/ecp5/Makefile.inc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								techlibs/ecp5/Makefile.inc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
 | 
			
		||||
OBJS += techlibs/ecp5/synth_ecp5.o
 | 
			
		||||
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/drams_map.v))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dram.txt))
 | 
			
		||||
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v))
 | 
			
		||||
							
								
								
									
										79
									
								
								techlibs/ecp5/arith_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								techlibs/ecp5/arith_map.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *  Copyright (C) 2018  David Shah <dave@ds0.me>
 | 
			
		||||
 *
 | 
			
		||||
 *  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.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
(* techmap_celltype = "$alu" *)
 | 
			
		||||
module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
 | 
			
		||||
	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] X, Y;
 | 
			
		||||
 | 
			
		||||
	input CI, BI;
 | 
			
		||||
	output [Y_WIDTH-1:0] CO;
 | 
			
		||||
 | 
			
		||||
	wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
 | 
			
		||||
 | 
			
		||||
	wire [Y_WIDTH-1:0] A_buf, B_buf;
 | 
			
		||||
	\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
 | 
			
		||||
	\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
 | 
			
		||||
 | 
			
		||||
	function integer round_up2;
 | 
			
		||||
		input integer N;
 | 
			
		||||
		begin
 | 
			
		||||
			round_up2 = ((N + 1) / 2) * 2;
 | 
			
		||||
		end
 | 
			
		||||
	endfunction
 | 
			
		||||
 | 
			
		||||
	localparam Y_WIDTH2 = round_up2(Y_WIDTH);
 | 
			
		||||
 | 
			
		||||
	wire [Y_WIDTH2-1:0] AA = A_buf;
 | 
			
		||||
	wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf;
 | 
			
		||||
	wire [Y_WIDTH2-1:0] C = {CO, CI};
 | 
			
		||||
	wire [Y_WIDTH2-1:0] FCO, Y1;
 | 
			
		||||
 | 
			
		||||
	genvar i;
 | 
			
		||||
	generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice
 | 
			
		||||
		CCU2C #(
 | 
			
		||||
			.INIT0(16'b0110011010101010),
 | 
			
		||||
			.INIT1(16'b0110011010101010),
 | 
			
		||||
			.INJECT1_0("NO"),
 | 
			
		||||
			.INJECT1_1("NO")
 | 
			
		||||
	   ) ccu2c_i (
 | 
			
		||||
			.CIN(C[i]),
 | 
			
		||||
			.A0(AA[i]), .B0(BB[i]), .C0(1'b0), .D0(1'b1),
 | 
			
		||||
			.A1(AA[i+1]), .B1(BB[i+1]), .C1(1'b0), .D1(1'b1),
 | 
			
		||||
			.S0(Y[i]), .S1(Y1[i]),
 | 
			
		||||
			.COUT(FCO[i])
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i]));
 | 
			
		||||
		if (i+1 < Y_WIDTH) begin
 | 
			
		||||
			assign CO[i+1] = FCO[i];
 | 
			
		||||
			assign Y[i+1] = Y1[i];
 | 
			
		||||
		end
 | 
			
		||||
	end endgenerate
 | 
			
		||||
 | 
			
		||||
	assign X = AA ^ BB;
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										135
									
								
								techlibs/ecp5/cells_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								techlibs/ecp5/cells_map.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,135 @@
 | 
			
		|||
module  \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("INV"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
module  \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
module  \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
 | 
			
		||||
 | 
			
		||||
`ifndef NO_LUT
 | 
			
		||||
module \$lut (A, Y);
 | 
			
		||||
    parameter WIDTH = 0;
 | 
			
		||||
    parameter LUT = 0;
 | 
			
		||||
 | 
			
		||||
    input [WIDTH-1:0] A;
 | 
			
		||||
    output Y;
 | 
			
		||||
 | 
			
		||||
    generate
 | 
			
		||||
        if (WIDTH == 1) begin
 | 
			
		||||
            LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y),
 | 
			
		||||
                .A(A[0]), .B(1'b0), .C(1'b0), .D(1'b0));
 | 
			
		||||
        end else
 | 
			
		||||
        if (WIDTH == 2) begin
 | 
			
		||||
            LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(1'b0), .D(1'b0));
 | 
			
		||||
        end else
 | 
			
		||||
        if (WIDTH == 3) begin
 | 
			
		||||
            LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(1'b0));
 | 
			
		||||
        end else
 | 
			
		||||
        if (WIDTH == 4) begin
 | 
			
		||||
            LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
        `ifndef NO_PFUMUX
 | 
			
		||||
        end else
 | 
			
		||||
        if (WIDTH == 5) begin
 | 
			
		||||
            wire f0, f1;
 | 
			
		||||
            LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(Y));
 | 
			
		||||
        end else
 | 
			
		||||
        if (WIDTH == 6) begin
 | 
			
		||||
            wire f0, f1, f2, f3, g0, g1;
 | 
			
		||||
            LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
 | 
			
		||||
            LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
 | 
			
		||||
            PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0));
 | 
			
		||||
            PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1));
 | 
			
		||||
            L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[5]), .Z(Y));
 | 
			
		||||
        end else
 | 
			
		||||
        if (WIDTH == 7) begin
 | 
			
		||||
            wire f0, f1, f2, f3, f4, f5, f6, f7, g0, g1, g2, g3, h0, h1;
 | 
			
		||||
            LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
 | 
			
		||||
            LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
 | 
			
		||||
            LUT4 #(.INIT(LUT[79:64])) lut4 (.Z(f4),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            LUT4 #(.INIT(LUT[95:80])) lut5 (.Z(f5),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
 | 
			
		||||
            LUT4 #(.INIT(LUT[111: 96])) lut6 (.Z(f6),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
            LUT4 #(.INIT(LUT[127:112])) lut7 (.Z(f7),
 | 
			
		||||
                .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
 | 
			
		||||
 | 
			
		||||
            PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0));
 | 
			
		||||
            PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1));
 | 
			
		||||
            PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[4]), .Z(g2));
 | 
			
		||||
            PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[4]), .Z(g3));
 | 
			
		||||
            L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[5]), .Z(h0));
 | 
			
		||||
            L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[5]), .Z(h1));
 | 
			
		||||
            L6MUX21 mux7  (.D0(h0), .D1(h1), .SD(A[6]), .Z(Y));
 | 
			
		||||
        `endif
 | 
			
		||||
        end else begin
 | 
			
		||||
            wire _TECHMAP_FAIL_ = 1;
 | 
			
		||||
        end
 | 
			
		||||
    endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
							
								
								
									
										448
									
								
								techlibs/ecp5/cells_sim.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										448
									
								
								techlibs/ecp5/cells_sim.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,448 @@
 | 
			
		|||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module LUT4(input A, B, C, D, output Z);
 | 
			
		||||
    parameter [15:0] INIT = 16'h0000;
 | 
			
		||||
    wire [7:0] s3 = D ?     INIT[15:8] :     INIT[7:0];
 | 
			
		||||
    wire [3:0] s2 = C ?       s3[ 7:4] :       s3[3:0];
 | 
			
		||||
    wire [1:0] s1 = B ?       s2[ 3:2] :       s2[1:0];
 | 
			
		||||
    assign Z =      A ?          s1[1] :         s1[0];
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module L6MUX21 (input D0, D1, SD, output Z);
 | 
			
		||||
	assign Z = SD ? D1 : D0;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1,
 | 
			
		||||
	           output S0, S1, COUT);
 | 
			
		||||
 | 
			
		||||
	parameter [15:0] INIT0 = 16'h0000;
 | 
			
		||||
	parameter [15:0] INIT1 = 16'h0000;
 | 
			
		||||
	parameter INJECT1_0 = "YES";
 | 
			
		||||
	parameter INJECT1_1 = "YES";
 | 
			
		||||
 | 
			
		||||
	// First half
 | 
			
		||||
	wire LUT4_0, LUT2_0;
 | 
			
		||||
	LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0));
 | 
			
		||||
	LUT2 #(.INIT(INIT0[3:0])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0));
 | 
			
		||||
 | 
			
		||||
	wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN;
 | 
			
		||||
	assign S0 = LUT4_0 ^ gated_cin_0;
 | 
			
		||||
 | 
			
		||||
	wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0;
 | 
			
		||||
	wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN);
 | 
			
		||||
 | 
			
		||||
	// Second half
 | 
			
		||||
	wire LUT4_1, LUT2_1;
 | 
			
		||||
	LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1));
 | 
			
		||||
	LUT2 #(.INIT(INIT1[3:0])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1));
 | 
			
		||||
 | 
			
		||||
	wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0;
 | 
			
		||||
	assign S1 = LUT4_1 ^ gated_cin_1;
 | 
			
		||||
 | 
			
		||||
	wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1;
 | 
			
		||||
	assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0);
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module TRELLIS_RAM16X2 (
 | 
			
		||||
	input DI0, DI1,
 | 
			
		||||
	input WAD0, WAD1, WAD2, WAD3,
 | 
			
		||||
	input WRE, WCK,
 | 
			
		||||
	input RAD0, RAD1, RAD2, RAD3,
 | 
			
		||||
	output DO0, DO1
 | 
			
		||||
);
 | 
			
		||||
  	parameter WCKMUX = "WCK";
 | 
			
		||||
	parameter WREMUX = "WRE";
 | 
			
		||||
	parameter INITVAL_0 = 16'h0000;
 | 
			
		||||
	parameter INITVAL_1 = 16'h0000;
 | 
			
		||||
 | 
			
		||||
	reg [1:0] mem[15:0];
 | 
			
		||||
 | 
			
		||||
	integer i;
 | 
			
		||||
	initial begin
 | 
			
		||||
		for (i = 0; i < 16; i = i + 1)
 | 
			
		||||
			mem[i] <= {INITVAL_1[i], INITVAL_0[i]};
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK;
 | 
			
		||||
 | 
			
		||||
	reg muxwre;
 | 
			
		||||
	always @(*)
 | 
			
		||||
		case (WREMUX)
 | 
			
		||||
			"1": muxwre = 1'b1;
 | 
			
		||||
			"0": muxwre = 1'b0;
 | 
			
		||||
			"INV": muxwre = ~WRE;
 | 
			
		||||
			default: muxwre = WRE;
 | 
			
		||||
		endcase
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	always @(posedge muxwck)
 | 
			
		||||
		if (muxwre)
 | 
			
		||||
			mem[{WAD3, WAD2, WAD1, WAD0}] <= {DI1, DI0};
 | 
			
		||||
 | 
			
		||||
	assign {DO1, DO0} = mem[{RAD3, RAD2, RAD1, RAD0}];
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module PFUMX (input ALUT, BLUT, C0, output Z);
 | 
			
		||||
	assign Z = C0 ? ALUT : BLUT;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module TRELLIS_DPR16X4 (
 | 
			
		||||
	input [3:0] DI,
 | 
			
		||||
	input [3:0] WAD,
 | 
			
		||||
	input WRE, WCK,
 | 
			
		||||
	input [3:0] RAD,
 | 
			
		||||
	output [3:0] DO
 | 
			
		||||
);
 | 
			
		||||
  	parameter WCKMUX = "WCK";
 | 
			
		||||
	parameter WREMUX = "WRE";
 | 
			
		||||
	parameter [63:0] INITVAL = 64'h0000000000000000;
 | 
			
		||||
 | 
			
		||||
	reg [3:0] mem[15:0];
 | 
			
		||||
 | 
			
		||||
	integer i;
 | 
			
		||||
	initial begin
 | 
			
		||||
		for (i = 0; i < 16; i = i + 1)
 | 
			
		||||
			mem[i] <= {INITVAL[i+3], INITVAL[i+2], INITVAL[i+1], INITVAL[i]};
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK;
 | 
			
		||||
 | 
			
		||||
	reg muxwre;
 | 
			
		||||
	always @(*)
 | 
			
		||||
		case (WREMUX)
 | 
			
		||||
			"1": muxwre = 1'b1;
 | 
			
		||||
			"0": muxwre = 1'b0;
 | 
			
		||||
			"INV": muxwre = ~WRE;
 | 
			
		||||
			default: muxwre = WRE;
 | 
			
		||||
		endcase
 | 
			
		||||
 | 
			
		||||
	always @(posedge muxwck)
 | 
			
		||||
		if (muxwre)
 | 
			
		||||
			mem[WAD] <= DI;
 | 
			
		||||
 | 
			
		||||
	assign DO = mem[RAD];
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module DPR16X4C (
 | 
			
		||||
		input [3:0] DI,
 | 
			
		||||
		input WCK, WRE,
 | 
			
		||||
		input [3:0] RAD,
 | 
			
		||||
		input [3:0] WAD,
 | 
			
		||||
		output [3:0] DO
 | 
			
		||||
);
 | 
			
		||||
	// For legacy Lattice compatibility, INITIVAL is a hex
 | 
			
		||||
	// string rather than a numeric parameter
 | 
			
		||||
	parameter INITVAL = "0x0000000000000000";
 | 
			
		||||
 | 
			
		||||
	function [63:0] convert_initval;
 | 
			
		||||
		input [143:0] hex_initval;
 | 
			
		||||
		reg done;
 | 
			
		||||
		reg [63:0] temp;
 | 
			
		||||
		reg [7:0] char;
 | 
			
		||||
		integer i;
 | 
			
		||||
		begin
 | 
			
		||||
			done = 1'b0;
 | 
			
		||||
			temp = 0;
 | 
			
		||||
			for (i = 0; i < 16; i = i + 1) begin
 | 
			
		||||
				if (!done) begin
 | 
			
		||||
					char = hex_initval[8*i +: 8];
 | 
			
		||||
					if (char == "x") begin
 | 
			
		||||
						done = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						if (char >= "0" && char <= "9")
 | 
			
		||||
							temp[4*i +: 4] = char - "0";
 | 
			
		||||
						else if (char >= "A" && char <= "F")
 | 
			
		||||
							temp[4*i +: 4] = 10 + char - "A";
 | 
			
		||||
						else if (char >= "a" && char <= "f")
 | 
			
		||||
							temp[4*i +: 4] = 10 + char - "a";
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			convert_initval = temp;
 | 
			
		||||
		end
 | 
			
		||||
	endfunction
 | 
			
		||||
 | 
			
		||||
	localparam conv_initval = convert_initval(INITVAL);
 | 
			
		||||
 | 
			
		||||
	reg [3:0] ram[0:15];
 | 
			
		||||
	integer i;
 | 
			
		||||
	initial begin
 | 
			
		||||
		for (i = 0; i < 15; i = i + 1) begin
 | 
			
		||||
			ram[i] <= conv_initval[4*i +: 4];
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	always @(posedge WCK)
 | 
			
		||||
		if (WRE)
 | 
			
		||||
			ram[WAD] <= DI;
 | 
			
		||||
 | 
			
		||||
	assign DO = ram[RAD];
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module LUT2(input A, B, output Z);
 | 
			
		||||
    parameter [3:0] INIT = 4'h0;
 | 
			
		||||
    wire [1:0] s1 = B ?     INIT[ 3:2] :     INIT[1:0];
 | 
			
		||||
    assign Z =      A ?          s1[1] :         s1[0];
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module TRELLIS_FF(input CLK, LSR, CE, DI, output reg Q);
 | 
			
		||||
	parameter GSR = "ENABLED";
 | 
			
		||||
	parameter [127:0] CEMUX = "1";
 | 
			
		||||
	parameter CLKMUX = "CLK";
 | 
			
		||||
	parameter LSRMUX = "LSR";
 | 
			
		||||
	parameter SRMODE = "LSR_OVER_CE";
 | 
			
		||||
	parameter REGSET = "RESET";
 | 
			
		||||
 | 
			
		||||
	reg muxce;
 | 
			
		||||
	always @(*)
 | 
			
		||||
		case (CEMUX)
 | 
			
		||||
			"1": muxce = 1'b1;
 | 
			
		||||
			"0": muxce = 1'b0;
 | 
			
		||||
			"INV": muxce = ~CE;
 | 
			
		||||
			default: muxce = CE;
 | 
			
		||||
		endcase
 | 
			
		||||
 | 
			
		||||
	wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
 | 
			
		||||
	wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
 | 
			
		||||
 | 
			
		||||
	localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0;
 | 
			
		||||
 | 
			
		||||
	initial Q = srval;
 | 
			
		||||
 | 
			
		||||
	generate
 | 
			
		||||
		if (SRMODE == "ASYNC") begin
 | 
			
		||||
			always @(posedge muxclk, posedge muxlsr)
 | 
			
		||||
				if (muxlsr)
 | 
			
		||||
					Q <= srval;
 | 
			
		||||
				else if (muxce)
 | 
			
		||||
					Q <= DI;
 | 
			
		||||
		end else begin
 | 
			
		||||
			always @(posedge muxclk)
 | 
			
		||||
				if (muxlsr)
 | 
			
		||||
					Q <= srval;
 | 
			
		||||
				else if (muxce)
 | 
			
		||||
					Q <= DI;
 | 
			
		||||
		end
 | 
			
		||||
	endgenerate
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module OBZ(input I, T, output O);
 | 
			
		||||
assign O = T ? 1'bz : I;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module IB(input I, output O);
 | 
			
		||||
assign O = I;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module TRELLIS_IO(
 | 
			
		||||
	inout B,
 | 
			
		||||
	input I,
 | 
			
		||||
	input T,
 | 
			
		||||
	output O
 | 
			
		||||
);
 | 
			
		||||
	parameter DIR = "INPUT";
 | 
			
		||||
 | 
			
		||||
	generate
 | 
			
		||||
		if (DIR == "INPUT") begin
 | 
			
		||||
			assign B = 1'bz;
 | 
			
		||||
			assign O = B;
 | 
			
		||||
		end else if (DIR == "OUTPUT") begin
 | 
			
		||||
			assign B = T ? 1'bz : I;
 | 
			
		||||
			assign O = 1'bx;
 | 
			
		||||
		end else if (DIR == "INOUT") begin
 | 
			
		||||
			assign B = T ? 1'bz : I;
 | 
			
		||||
			assign O = B;
 | 
			
		||||
		end else begin
 | 
			
		||||
			ERROR_UNKNOWN_IO_MODE error();
 | 
			
		||||
		end
 | 
			
		||||
	endgenerate
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module OB(input I, output O);
 | 
			
		||||
assign O = I;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module BB(input I, T, output O, inout B);
 | 
			
		||||
assign B = T ? 1'bz : I;
 | 
			
		||||
assign O = B;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module INV(input A, output Z);
 | 
			
		||||
	assign Z = !A;
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------
 | 
			
		||||
 | 
			
		||||
module TRELLIS_SLICE(
 | 
			
		||||
	input A0, B0, C0, D0,
 | 
			
		||||
	input A1, B1, C1, D1,
 | 
			
		||||
	input M0, M1,
 | 
			
		||||
	input FCI, FXA, FXB,
 | 
			
		||||
 | 
			
		||||
	input CLK, LSR, CE,
 | 
			
		||||
	input DI0, DI1,
 | 
			
		||||
 | 
			
		||||
	input WD0, WD1,
 | 
			
		||||
	input WAD0, WAD1, WAD2, WAD3,
 | 
			
		||||
	input WRE, WCK,
 | 
			
		||||
 | 
			
		||||
	output F0, Q0,
 | 
			
		||||
	output F1, Q1,
 | 
			
		||||
	output FCO, OFX0, OFX1,
 | 
			
		||||
 | 
			
		||||
	output WDO0, WDO1, WDO2, WDO3,
 | 
			
		||||
	output WADO0, WADO1, WADO2, WADO3
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
	parameter MODE = "LOGIC";
 | 
			
		||||
	parameter GSR = "ENABLED";
 | 
			
		||||
	parameter SRMODE = "LSR_OVER_CE";
 | 
			
		||||
	parameter [127:0] CEMUX = "1";
 | 
			
		||||
	parameter CLKMUX = "CLK";
 | 
			
		||||
	parameter LSRMUX = "LSR";
 | 
			
		||||
	parameter LUT0_INITVAL = 16'h0000;
 | 
			
		||||
	parameter LUT1_INITVAL = 16'h0000;
 | 
			
		||||
	parameter REG0_SD = "0";
 | 
			
		||||
	parameter REG1_SD = "0";
 | 
			
		||||
	parameter REG0_REGSET = "RESET";
 | 
			
		||||
	parameter REG1_REGSET = "RESET";
 | 
			
		||||
	parameter [127:0] CCU2_INJECT1_0 = "NO";
 | 
			
		||||
	parameter [127:0] CCU2_INJECT1_1 = "NO";
 | 
			
		||||
	parameter WREMUX = "WRE";
 | 
			
		||||
 | 
			
		||||
	function [15:0] permute_initval;
 | 
			
		||||
		input [15:0] initval;
 | 
			
		||||
		integer i;
 | 
			
		||||
		begin
 | 
			
		||||
			for (i = 0; i < 16; i = i + 1) begin
 | 
			
		||||
				permute_initval[{i[0], i[2], i[1], i[3]}] = initval[i];
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	endfunction
 | 
			
		||||
 | 
			
		||||
	generate
 | 
			
		||||
		if (MODE == "LOGIC") begin
 | 
			
		||||
			// LUTs
 | 
			
		||||
			LUT4 #(
 | 
			
		||||
				.INIT(LUT0_INITVAL)
 | 
			
		||||
			) lut4_0 (
 | 
			
		||||
				.A(A0), .B(B0), .C(C0), .D(D0),
 | 
			
		||||
				.Z(F0)
 | 
			
		||||
			);
 | 
			
		||||
			LUT4 #(
 | 
			
		||||
				.INIT(LUT1_INITVAL)
 | 
			
		||||
			) lut4_1 (
 | 
			
		||||
				.A(A1), .B(B1), .C(C1), .D(D1),
 | 
			
		||||
				.Z(F1)
 | 
			
		||||
			);
 | 
			
		||||
			// LUT expansion muxes
 | 
			
		||||
			PFUMX lut5_mux (.ALUT(F1), .BLUT(F0), .C0(M0), .Z(OFX0));
 | 
			
		||||
			L6MUX21 lutx_mux (.D0(FXA), .D1(FXB), .SD(M1), .Z(OFX1));
 | 
			
		||||
		end else if (MODE == "CCU2") begin
 | 
			
		||||
			CCU2C #(
 | 
			
		||||
				.INIT0(LUT0_INITVAL),
 | 
			
		||||
				.INIT1(LUT1_INITVAL),
 | 
			
		||||
				.INJECT1_0(CCU2_INJECT1_0),
 | 
			
		||||
				.INJECT1_1(CCU2_INJECT1_1)
 | 
			
		||||
		  ) ccu2c_i (
 | 
			
		||||
				.CIN(FCI),
 | 
			
		||||
				.A0(A0), .B0(B0), .C0(C0), .D0(D0),
 | 
			
		||||
				.A1(A1), .B1(B1), .C1(C1), .D1(D1),
 | 
			
		||||
				.S0(F0), .S1(F1),
 | 
			
		||||
				.COUT(FCO)
 | 
			
		||||
			);
 | 
			
		||||
		end else if (MODE == "RAMW") begin
 | 
			
		||||
			assign WDO0 = C1;
 | 
			
		||||
			assign WDO1 = A1;
 | 
			
		||||
			assign WDO2 = D1;
 | 
			
		||||
			assign WDO3 = B1;
 | 
			
		||||
			assign WADO0 = D0;
 | 
			
		||||
			assign WADO1 = B0;
 | 
			
		||||
			assign WADO2 = C0;
 | 
			
		||||
			assign WADO3 = A0;
 | 
			
		||||
		end else if (MODE == "DPRAM") begin
 | 
			
		||||
			TRELLIS_RAM16X2 #(
 | 
			
		||||
				.INITVAL_0(permute_initval(LUT0_INITVAL)),
 | 
			
		||||
				.INITVAL_1(permute_initval(LUT1_INITVAL)),
 | 
			
		||||
				.WREMUX(WREMUX)
 | 
			
		||||
			) ram_i (
 | 
			
		||||
				.DI0(WD0), .DI1(WD1),
 | 
			
		||||
				.WAD0(WAD0), .WAD1(WAD1), .WAD2(WAD2), .WAD3(WAD3),
 | 
			
		||||
				.WRE(WRE), .WCK(WCK),
 | 
			
		||||
				.RAD0(D0), .RAD1(B0), .RAD2(C0), .RAD3(A0),
 | 
			
		||||
				.DO0(F0), .DO1(F1)
 | 
			
		||||
			);
 | 
			
		||||
			// TODO: confirm RAD and INITVAL ordering
 | 
			
		||||
			// DPRAM mode contract?
 | 
			
		||||
			always @(*) begin
 | 
			
		||||
				assert(A0==A1);
 | 
			
		||||
				assert(B0==B1);
 | 
			
		||||
				assert(C0==C1);
 | 
			
		||||
				assert(D0==D1);
 | 
			
		||||
			end
 | 
			
		||||
		end else begin
 | 
			
		||||
			ERROR_UNKNOWN_SLICE_MODE error();
 | 
			
		||||
		end
 | 
			
		||||
	endgenerate
 | 
			
		||||
 | 
			
		||||
	// FF input selection muxes
 | 
			
		||||
	wire muxdi0 = (REG0_SD == "1") ? DI0 : M0;
 | 
			
		||||
	wire muxdi1 = (REG1_SD == "1") ? DI1 : M1;
 | 
			
		||||
	// Flipflops
 | 
			
		||||
	TRELLIS_FF #(
 | 
			
		||||
		.GSR(GSR),
 | 
			
		||||
		.CEMUX(CEMUX),
 | 
			
		||||
		.CLKMUX(CLKMUX),
 | 
			
		||||
		.LSRMUX(LSRMUX),
 | 
			
		||||
		.SRMODE(SRMODE),
 | 
			
		||||
		.REGSET(REG0_REGSET)
 | 
			
		||||
	) ff_0 (
 | 
			
		||||
		.CLK(CLK), .LSR(LSR), .CE(CE),
 | 
			
		||||
		.DI(muxdi0),
 | 
			
		||||
		.Q(Q0)
 | 
			
		||||
	);
 | 
			
		||||
	TRELLIS_FF #(
 | 
			
		||||
		.GSR(GSR),
 | 
			
		||||
		.CEMUX(CEMUX),
 | 
			
		||||
		.CLKMUX(CLKMUX),
 | 
			
		||||
		.LSRMUX(LSRMUX),
 | 
			
		||||
		.SRMODE(SRMODE),
 | 
			
		||||
		.REGSET(REG1_REGSET)
 | 
			
		||||
	) ff_1 (
 | 
			
		||||
		.CLK(CLK), .LSR(LSR), .CE(CE),
 | 
			
		||||
		.DI(muxdi1),
 | 
			
		||||
		.Q(Q1)
 | 
			
		||||
	);
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								techlibs/ecp5/dram.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								techlibs/ecp5/dram.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
bram $__TRELLIS_DPR16X4
 | 
			
		||||
  init 1
 | 
			
		||||
  abits 4
 | 
			
		||||
  dbits 4
 | 
			
		||||
  groups 2
 | 
			
		||||
  ports  1 1
 | 
			
		||||
  wrmode 0 1
 | 
			
		||||
  enable 0 1
 | 
			
		||||
  transp 0 0
 | 
			
		||||
  clocks 0 1
 | 
			
		||||
  clkpol 0 2
 | 
			
		||||
endbram
 | 
			
		||||
 | 
			
		||||
match $__TRELLIS_DPR16X4
 | 
			
		||||
  make_outreg
 | 
			
		||||
endmatch
 | 
			
		||||
							
								
								
									
										28
									
								
								techlibs/ecp5/drams_map.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								techlibs/ecp5/drams_map.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
module \$__TRELLIS_DPR16X4 (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
 | 
			
		||||
	parameter [63:0] INIT = 64'bx;
 | 
			
		||||
	parameter CLKPOL2 = 1;
 | 
			
		||||
	input CLK1;
 | 
			
		||||
 | 
			
		||||
	input [3:0] A1ADDR;
 | 
			
		||||
	output [3:0] A1DATA;
 | 
			
		||||
 | 
			
		||||
	input [3:0] B1ADDR;
 | 
			
		||||
	input [3:0] B1DATA;
 | 
			
		||||
	input B1EN;
 | 
			
		||||
 | 
			
		||||
	localparam WCKMUX = CLKPOL2 ? "WCK" : "INV";
 | 
			
		||||
 | 
			
		||||
	TRELLIS_DPR16X4 #(
 | 
			
		||||
		.INITVAL(INIT),
 | 
			
		||||
		.WCKMUX(WCKMUX),
 | 
			
		||||
		.WREMUX("WRE")
 | 
			
		||||
	) _TECHMAP_REPLACE_ (
 | 
			
		||||
		.RAD(A1ADDR),
 | 
			
		||||
		.DO(A1DATA),
 | 
			
		||||
 | 
			
		||||
		.WAD(B1ADDR),
 | 
			
		||||
		.DI(B1DATA),
 | 
			
		||||
		.WCK(CLK1),
 | 
			
		||||
		.WRE(B1EN)
 | 
			
		||||
	);
 | 
			
		||||
endmodule
 | 
			
		||||
							
								
								
									
										331
									
								
								techlibs/ecp5/synth_ecp5.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								techlibs/ecp5/synth_ecp5.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,331 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  yosys -- Yosys Open SYnthesis Suite
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *  Copyright (C) 2018 Clifford Wolf <dave@ds0.me>
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 *  purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 *  copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "kernel/register.h"
 | 
			
		||||
#include "kernel/celltypes.h"
 | 
			
		||||
#include "kernel/rtlil.h"
 | 
			
		||||
#include "kernel/log.h"
 | 
			
		||||
 | 
			
		||||
USING_YOSYS_NAMESPACE
 | 
			
		||||
PRIVATE_NAMESPACE_BEGIN
 | 
			
		||||
 | 
			
		||||
struct SynthEcp5Pass : public ScriptPass
 | 
			
		||||
{
 | 
			
		||||
	SynthEcp5Pass() : ScriptPass("synth_ecp5", "synthesis for ECP5 FPGAs") { }
 | 
			
		||||
 | 
			
		||||
	virtual void help() YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    synth_ecp5 [options]\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("This command runs synthesis for ECP5 FPGAs.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -top <module>\n");
 | 
			
		||||
		log("        use the specified module as top module\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -blif <file>\n");
 | 
			
		||||
		log("        write the design to the specified BLIF file. writing of an output file\n");
 | 
			
		||||
		log("        is omitted if this parameter is not specified.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -edif <file>\n");
 | 
			
		||||
		log("        write the design to the specified EDIF file. writing of an output file\n");
 | 
			
		||||
		log("        is omitted if this parameter is not specified.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -json <file>\n");
 | 
			
		||||
		log("        write the design to the specified JSON file. writing of an output file\n");
 | 
			
		||||
		log("        is omitted if this parameter is not specified.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -run <from_label>:<to_label>\n");
 | 
			
		||||
		log("        only run the commands between the labels (see below). an empty\n");
 | 
			
		||||
		log("        from label is synonymous to 'begin', and empty to label is\n");
 | 
			
		||||
		log("        synonymous to the end of the command list.\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -noflatten\n");
 | 
			
		||||
		log("        do not flatten design before synthesis\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -retime\n");
 | 
			
		||||
		log("        run 'abc' with -dff option\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -noccu2\n");
 | 
			
		||||
		log("        do not use CCU2 cells in output netlist\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -nodffe\n");
 | 
			
		||||
		log("        do not use flipflops with CE in output netlist\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -nobram\n");
 | 
			
		||||
		log("        do not use BRAM cells in output netlist\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -nodram\n");
 | 
			
		||||
		log("        do not use distributed RAM cells in output netlist\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -nomux\n");
 | 
			
		||||
		log("        do not use PFU muxes to implement LUTs larger than LUT4s\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -abc2\n");
 | 
			
		||||
		log("        run two passes of 'abc' for slightly improved logic density\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("    -vpr\n");
 | 
			
		||||
		log("        generate an output netlist (and BLIF file) suitable for VPR\n");
 | 
			
		||||
		log("        (this feature is experimental and incomplete)\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("The following commands are executed by this synthesis command:\n");
 | 
			
		||||
		help_script();
 | 
			
		||||
		log("\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	string top_opt, blif_file, edif_file, json_file;
 | 
			
		||||
	bool noccu2, nodffe, nobram, nodram, nomux, flatten, retime, abc2, vpr;
 | 
			
		||||
 | 
			
		||||
	virtual void clear_flags() YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		top_opt = "-auto-top";
 | 
			
		||||
		blif_file = "";
 | 
			
		||||
		edif_file = "";
 | 
			
		||||
		json_file = "";
 | 
			
		||||
		noccu2 = false;
 | 
			
		||||
		nodffe = false;
 | 
			
		||||
		nobram = false;
 | 
			
		||||
		nodram = false;
 | 
			
		||||
		nomux = false;
 | 
			
		||||
		flatten = true;
 | 
			
		||||
		retime = false;
 | 
			
		||||
		abc2 = false;
 | 
			
		||||
		vpr = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		string run_from, run_to;
 | 
			
		||||
		clear_flags();
 | 
			
		||||
 | 
			
		||||
		size_t argidx;
 | 
			
		||||
		for (argidx = 1; argidx < args.size(); argidx++)
 | 
			
		||||
		{
 | 
			
		||||
			if (args[argidx] == "-top" && argidx+1 < args.size()) {
 | 
			
		||||
				top_opt = "-top " + args[++argidx];
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-blif" && argidx+1 < args.size()) {
 | 
			
		||||
				blif_file = args[++argidx];
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-edif" && argidx+1 < args.size()) {
 | 
			
		||||
				edif_file = args[++argidx];
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-json" && argidx+1 < args.size()) {
 | 
			
		||||
				json_file = args[++argidx];
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-run" && argidx+1 < args.size()) {
 | 
			
		||||
				size_t pos = args[argidx+1].find(':');
 | 
			
		||||
				if (pos == std::string::npos)
 | 
			
		||||
					break;
 | 
			
		||||
				run_from = args[++argidx].substr(0, pos);
 | 
			
		||||
				run_to = args[argidx].substr(pos+1);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-flatten") {
 | 
			
		||||
				flatten = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-noflatten") {
 | 
			
		||||
				flatten = false;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-retime") {
 | 
			
		||||
				retime = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-noccu2") {
 | 
			
		||||
				noccu2 = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-nodffe") {
 | 
			
		||||
				nodffe = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-nobram") {
 | 
			
		||||
				nobram = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-nodram") {
 | 
			
		||||
				nodram = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-nomux") {
 | 
			
		||||
				nomux = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-abc2") {
 | 
			
		||||
				abc2 = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-vpr") {
 | 
			
		||||
				vpr = true;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		if (!design->full_selection())
 | 
			
		||||
			log_cmd_error("This comannd only operates on fully selected designs!\n");
 | 
			
		||||
 | 
			
		||||
		log_header(design, "Executing SYNTH_ECP5 pass.\n");
 | 
			
		||||
		log_push();
 | 
			
		||||
 | 
			
		||||
		run_script(design, run_from, run_to);
 | 
			
		||||
 | 
			
		||||
		log_pop();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	virtual void script() YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		if (check_label("begin"))
 | 
			
		||||
		{
 | 
			
		||||
			run("read_verilog -lib +/ecp5/cells_sim.v");
 | 
			
		||||
			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (flatten && check_label("flatten", "(unless -noflatten)"))
 | 
			
		||||
		{
 | 
			
		||||
			run("proc");
 | 
			
		||||
			run("flatten");
 | 
			
		||||
			run("tribuf -logic");
 | 
			
		||||
			run("deminout");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("coarse"))
 | 
			
		||||
		{
 | 
			
		||||
			run("synth -run coarse");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!nobram && check_label("bram", "(skip if -nobram)"))
 | 
			
		||||
		{
 | 
			
		||||
			//TODO
 | 
			
		||||
#if 0
 | 
			
		||||
			run("memory_bram -rules +/ecp5/brams.txt");
 | 
			
		||||
			run("techmap -map +/ecp5/brams_map.v");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!nodram && check_label("dram", "(skip if -nodram)"))
 | 
			
		||||
		{
 | 
			
		||||
			run("memory_bram -rules +/ecp5/dram.txt");
 | 
			
		||||
			run("techmap -map +/ecp5/drams_map.v");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("fine"))
 | 
			
		||||
		{
 | 
			
		||||
			run("opt -fast -mux_undef -undriven -fine");
 | 
			
		||||
			run("memory_map");
 | 
			
		||||
			run("opt -undriven -fine");
 | 
			
		||||
			if (noccu2)
 | 
			
		||||
				run("techmap");
 | 
			
		||||
			else
 | 
			
		||||
				run("techmap -map +/techmap.v -map +/ecp5/arith_map.v");
 | 
			
		||||
			if (retime || help_mode)
 | 
			
		||||
				run("abc -dff", "(only if -retime)");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map_ffs"))
 | 
			
		||||
		{
 | 
			
		||||
			run("dffsr2dff");
 | 
			
		||||
			run("dff2dffs");
 | 
			
		||||
			run("opt_clean");
 | 
			
		||||
			if (!nodffe)
 | 
			
		||||
				run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
 | 
			
		||||
			run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
 | 
			
		||||
			run("opt_expr -mux_undef");
 | 
			
		||||
			run("simplemap");
 | 
			
		||||
			// TODO
 | 
			
		||||
#if 0
 | 
			
		||||
			run("ecp5_ffinit");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map_luts"))
 | 
			
		||||
		{
 | 
			
		||||
			if (abc2 || help_mode) {
 | 
			
		||||
				run("abc", "      (only if -abc2)");
 | 
			
		||||
			}
 | 
			
		||||
			//TODO
 | 
			
		||||
#if 0
 | 
			
		||||
			run("techmap -map +/ecp5/latches_map.v");
 | 
			
		||||
#endif
 | 
			
		||||
			if (nomux)
 | 
			
		||||
				run("abc -lut 4");
 | 
			
		||||
			else
 | 
			
		||||
				run("abc -lut 4:7");
 | 
			
		||||
			run("clean");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map_cells"))
 | 
			
		||||
		{
 | 
			
		||||
			if (vpr)
 | 
			
		||||
				run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
 | 
			
		||||
			else
 | 
			
		||||
				run("techmap -map +/ecp5/cells_map.v", "(with -D NO_LUT in vpr mode)");
 | 
			
		||||
 | 
			
		||||
			run("clean");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("check"))
 | 
			
		||||
		{
 | 
			
		||||
			run("hierarchy -check");
 | 
			
		||||
			run("stat");
 | 
			
		||||
			run("check -noinit");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("blif"))
 | 
			
		||||
		{
 | 
			
		||||
			if (!blif_file.empty() || help_mode) {
 | 
			
		||||
				if (vpr || help_mode) {
 | 
			
		||||
					run(stringf("opt_clean -purge"),
 | 
			
		||||
							"                                 (vpr mode)");
 | 
			
		||||
					run(stringf("write_blif -attr -cname -conn -param %s",
 | 
			
		||||
							help_mode ? "<file-name>" : blif_file.c_str()),
 | 
			
		||||
							" (vpr mode)");
 | 
			
		||||
				}
 | 
			
		||||
				if (!vpr)
 | 
			
		||||
					run(stringf("write_blif -gates -attr -param %s",
 | 
			
		||||
							help_mode ? "<file-name>" : blif_file.c_str()),
 | 
			
		||||
							"       (non-vpr mode)");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("edif"))
 | 
			
		||||
		{
 | 
			
		||||
			if (!edif_file.empty() || help_mode)
 | 
			
		||||
				run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("json"))
 | 
			
		||||
		{
 | 
			
		||||
			if (!json_file.empty() || help_mode)
 | 
			
		||||
				run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} SynthEcp5Pass;
 | 
			
		||||
 | 
			
		||||
PRIVATE_NAMESPACE_END
 | 
			
		||||
| 
						 | 
				
			
			@ -657,7 +657,12 @@ module ICESTORM_LC (
 | 
			
		|||
	parameter [0:0] SET_NORESET  = 0;
 | 
			
		||||
	parameter [0:0] ASYNC_SR     = 0;
 | 
			
		||||
 | 
			
		||||
	assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && CIN) : 1'bx;
 | 
			
		||||
	parameter [0:0] CIN_CONST    = 0;
 | 
			
		||||
	parameter [0:0] CIN_SET      = 0;
 | 
			
		||||
 | 
			
		||||
	wire mux_cin = CIN_CONST ? CIN_SET : CIN;
 | 
			
		||||
 | 
			
		||||
	assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
 | 
			
		||||
 | 
			
		||||
	wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
 | 
			
		||||
	wire [3:0] lut_s2 = I2 ?   lut_s3[ 7:4] :   lut_s3[3:0];
 | 
			
		||||
| 
						 | 
				
			
			@ -1226,4 +1231,3 @@ module SB_IO_OD (
 | 
			
		|||
	endgenerate
 | 
			
		||||
`endif
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue