mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	RIP $safe_pmux
This commit is contained in:
		
							parent
							
								
									28cf48e31f
								
							
						
					
					
						commit
						13f2f36884
					
				
					 16 changed files with 21 additions and 98 deletions
				
			
		|  | @ -98,7 +98,6 @@ struct CellTypes | ||||||
| 		cell_types.insert("$pmux"); | 		cell_types.insert("$pmux"); | ||||||
| 		cell_types.insert("$slice"); | 		cell_types.insert("$slice"); | ||||||
| 		cell_types.insert("$concat"); | 		cell_types.insert("$concat"); | ||||||
| 		cell_types.insert("$safe_pmux"); |  | ||||||
| 		cell_types.insert("$lut"); | 		cell_types.insert("$lut"); | ||||||
| 		cell_types.insert("$assert"); | 		cell_types.insert("$assert"); | ||||||
| 	} | 	} | ||||||
|  | @ -307,7 +306,7 @@ struct CellTypes | ||||||
| 
 | 
 | ||||||
| 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &sel) | 	static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &sel) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") { | 		if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") { | ||||||
| 			RTLIL::Const ret = arg1; | 			RTLIL::Const ret = arg1; | ||||||
| 			for (size_t i = 0; i < sel.bits.size(); i++) | 			for (size_t i = 0; i < sel.bits.size(); i++) | ||||||
| 				if (sel.bits[i] == RTLIL::State::S1) { | 				if (sel.bits[i] == RTLIL::State::S1) { | ||||||
|  |  | ||||||
|  | @ -104,7 +104,7 @@ struct ConstEval | ||||||
| 		if (cell->hasPort("\\B")) | 		if (cell->hasPort("\\B")) | ||||||
| 			sig_b = cell->getPort("\\B"); | 			sig_b = cell->getPort("\\B"); | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux" || cell->type == "$_MUX_") | 		if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_") | ||||||
| 		{ | 		{ | ||||||
| 			std::vector<RTLIL::SigSpec> y_candidates; | 			std::vector<RTLIL::SigSpec> y_candidates; | ||||||
| 			int count_maybe_set_s_bits = 0; | 			int count_maybe_set_s_bits = 0; | ||||||
|  | @ -125,10 +125,7 @@ struct ConstEval | ||||||
| 					count_set_s_bits++; | 					count_set_s_bits++; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$safe_pmux" && count_set_s_bits > 1) | 			if (count_set_s_bits == 0) | ||||||
| 				y_candidates.clear(); |  | ||||||
| 
 |  | ||||||
| 			if ((cell->type == "$safe_pmux" && count_maybe_set_s_bits > 1) || count_set_s_bits == 0) |  | ||||||
| 				y_candidates.push_back(sig_a); | 				y_candidates.push_back(sig_a); | ||||||
| 
 | 
 | ||||||
| 			std::vector<RTLIL::Const> y_values; | 			std::vector<RTLIL::Const> y_values; | ||||||
|  |  | ||||||
|  | @ -608,7 +608,7 @@ namespace { | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (cell->type == "$pmux" || cell->type == "$safe_pmux") { | 			if (cell->type == "$pmux") { | ||||||
| 				port("\\A", param("\\WIDTH")); | 				port("\\A", param("\\WIDTH")); | ||||||
| 				port("\\B", param("\\WIDTH") * param("\\S_WIDTH")); | 				port("\\B", param("\\WIDTH") * param("\\S_WIDTH")); | ||||||
| 				port("\\S", param("\\S_WIDTH")); | 				port("\\S", param("\\S_WIDTH")); | ||||||
|  | @ -1293,7 +1293,6 @@ DEF_METHOD(LogicOr,  1, "$logic_or") | ||||||
| 	} | 	} | ||||||
| DEF_METHOD(Mux,      "$mux",        0) | DEF_METHOD(Mux,      "$mux",        0) | ||||||
| DEF_METHOD(Pmux,     "$pmux",       1) | DEF_METHOD(Pmux,     "$pmux",       1) | ||||||
| DEF_METHOD(SafePmux, "$safe_pmux",  1) |  | ||||||
| #undef DEF_METHOD | #undef DEF_METHOD | ||||||
| 
 | 
 | ||||||
| #define DEF_METHOD_2(_func, _type, _P1, _P2) \ | #define DEF_METHOD_2(_func, _type, _P1, _P2) \ | ||||||
|  | @ -1637,10 +1636,10 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed) | ||||||
| 			type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") | 			type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:") | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	if (type == "$mux" || type == "$pmux" || type == "$safe_pmux") | 	if (type == "$mux" || type == "$pmux") | ||||||
| 	{ | 	{ | ||||||
| 		parameters["\\WIDTH"] = SIZE(connections_["\\Y"]); | 		parameters["\\WIDTH"] = SIZE(connections_["\\Y"]); | ||||||
| 		if (type == "$pmux" || type == "$safe_pmux") | 		if (type == "$pmux") | ||||||
| 			parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]); | 			parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]); | ||||||
| 		check(); | 		check(); | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
|  | @ -664,7 +664,6 @@ public: | ||||||
|                       |                       | ||||||
| 	RTLIL::Cell* addMux  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); | 	RTLIL::Cell* addMux  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); | ||||||
| 	RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); | 	RTLIL::Cell* addPmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); | ||||||
| 	RTLIL::Cell* addSafePmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y); |  | ||||||
|                       |                       | ||||||
| 	RTLIL::Cell* addSlice  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset); | 	RTLIL::Cell* addSlice  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset); | ||||||
| 	RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); | 	RTLIL::Cell* addConcat (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y); | ||||||
|  | @ -743,7 +742,6 @@ public: | ||||||
| 
 | 
 | ||||||
| 	RTLIL::SigSpec Mux      (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); | 	RTLIL::SigSpec Mux      (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); | ||||||
| 	RTLIL::SigSpec Pmux     (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); | 	RTLIL::SigSpec Pmux     (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); | ||||||
| 	RTLIL::SigSpec SafePmux (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s); |  | ||||||
| 
 | 
 | ||||||
| 	RTLIL::SigSpec InvGate  (RTLIL::IdString name, RTLIL::SigSpec sig_a); | 	RTLIL::SigSpec InvGate  (RTLIL::IdString name, RTLIL::SigSpec sig_a); | ||||||
| 	RTLIL::SigSpec AndGate  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); | 	RTLIL::SigSpec AndGate  (RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b); | ||||||
|  |  | ||||||
|  | @ -316,7 +316,7 @@ struct SatGen | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (cell->type == "$pmux" || cell->type == "$safe_pmux") | 		if (cell->type == "$pmux") | ||||||
| 		{ | 		{ | ||||||
| 			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); | 			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); | ||||||
| 			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); | 			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); | ||||||
|  | @ -330,8 +330,6 @@ struct SatGen | ||||||
| 				std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size()); | 				std::vector<int> part_of_b(b.begin()+i*a.size(), b.begin()+(i+1)*a.size()); | ||||||
| 				tmp = ez->vec_ite(s.at(i), part_of_b, tmp); | 				tmp = ez->vec_ite(s.at(i), part_of_b, tmp); | ||||||
| 			} | 			} | ||||||
| 			if (cell->type == "$safe_pmux") |  | ||||||
| 				tmp = ez->vec_ite(ez->onehot(s, true), tmp, a); |  | ||||||
| 			ez->assume(ez->vec_eq(tmp, yy)); | 			ez->assume(ez->vec_eq(tmp, yy)); | ||||||
| 
 | 
 | ||||||
| 			if (model_undef) | 			if (model_undef) | ||||||
|  | @ -370,12 +368,6 @@ struct SatGen | ||||||
| 
 | 
 | ||||||
| 				int maybe_a = ez->NOT(maybe_one_hot); | 				int maybe_a = ez->NOT(maybe_one_hot); | ||||||
| 
 | 
 | ||||||
| 				if (cell->type == "$safe_pmux") { |  | ||||||
| 					maybe_a = ez->OR(maybe_a, maybe_many_hot); |  | ||||||
| 					bits_set = ez->vec_ite(sure_many_hot, ez->vec_or(a, undef_a), bits_set); |  | ||||||
| 					bits_clr = ez->vec_ite(sure_many_hot, ez->vec_or(ez->vec_not(a), undef_a), bits_clr); |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				bits_set = ez->vec_ite(maybe_a, ez->vec_or(bits_set, ez->vec_or(bits_set, ez->vec_or(a, undef_a))), bits_set); | 				bits_set = ez->vec_ite(maybe_a, ez->vec_or(bits_set, ez->vec_or(bits_set, ez->vec_or(a, undef_a))), bits_set); | ||||||
| 				bits_clr = ez->vec_ite(maybe_a, ez->vec_or(bits_clr, ez->vec_or(bits_clr, ez->vec_or(ez->vec_not(a), undef_a))), bits_clr); | 				bits_clr = ez->vec_ite(maybe_a, ez->vec_or(bits_clr, ez->vec_or(bits_clr, ez->vec_or(ez->vec_not(a), undef_a))), bits_clr); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -302,7 +302,7 @@ cell name from the internal cell library: | ||||||
| \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont] | \begin{lstlisting}[xleftmargin=1cm, basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont] | ||||||
| $not $pos $bu0 $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor | $not $pos $bu0 $neg $and $or $xor $xnor $reduce_and $reduce_or $reduce_xor $reduce_xnor | ||||||
| $reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod | $reduce_bool $shl $shr $sshl $sshr $lt $le $eq $ne $eqx $nex $ge $gt $add $sub $mul $div $mod | ||||||
| $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $safe_pmux $lut $assert $sr $dff | $pow $logic_not $logic_and $logic_or $mux $pmux $slice $concat $lut $assert $sr $dff | ||||||
| $dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_INV_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ | $dffsr $adff $dlatch $dlatchsr $memrd $memwr $mem $fsm $_INV_ $_AND_ $_OR_ $_XOR_ $_MUX_ $_SR_NN_ | ||||||
| $_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_ | $_SR_NP_ $_SR_PN_ $_SR_PP_ $_DFF_N_ $_DFF_P_ $_DFF_NN0_ $_DFF_NN1_ $_DFF_NP0_ $_DFF_NP1_ $_DFF_PN0_ | ||||||
| $_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_ | $_DFF_PN1_ $_DFF_PP0_ $_DFF_PP1_ $_DFFSR_NNN_ $_DFFSR_NNP_ $_DFFSR_NPN_ $_DFFSR_NPP_ $_DFFSR_PNN_ | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ struct WreduceConfig | ||||||
| 		supported_cell_types << "$shl" << "$shr" << "$sshl" << "$sshr" << "$shift" << "$shiftx"; | 		supported_cell_types << "$shl" << "$shr" << "$sshl" << "$sshr" << "$shift" << "$shiftx"; | ||||||
| 		supported_cell_types << "$lt" << "$le" << "$eq" << "$ne" << "$eqx" << "$nex" << "$ge" << "$gt"; | 		supported_cell_types << "$lt" << "$le" << "$eq" << "$ne" << "$eqx" << "$nex" << "$ge" << "$gt"; | ||||||
| 		supported_cell_types << "$add" << "$sub"; // << "$mul" << "$div" << "$mod" << "$pow"
 | 		supported_cell_types << "$add" << "$sub"; // << "$mul" << "$div" << "$mod" << "$pow"
 | ||||||
| 		supported_cell_types << "$mux" << "$pmux" << "$safe_pmux"; | 		supported_cell_types << "$mux" << "$pmux"; | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -172,7 +172,7 @@ struct WreduceWorker | ||||||
| 		if (!cell->type.in(config->supported_cell_types)) | 		if (!cell->type.in(config->supported_cell_types)) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
| 		if (cell->type.in("$mux", "$pmux", "$safe_pmux")) | 		if (cell->type.in("$mux", "$pmux")) | ||||||
| 			return run_cell_mux(cell); | 			return run_cell_mux(cell); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig | ||||||
| 	std::set<sig2driver_entry_t> cellport_list; | 	std::set<sig2driver_entry_t> cellport_list; | ||||||
| 	sig2driver.find(sig, cellport_list); | 	sig2driver.find(sig, cellport_list); | ||||||
| 	for (auto &cellport : cellport_list) { | 	for (auto &cellport : cellport_list) { | ||||||
| 		if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux" && cellport.first->type != "$safe_pmux") || cellport.second != "\\Y") | 		if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux") || cellport.second != "\\Y") | ||||||
| 			return false; | 			return false; | ||||||
| 		RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A")); | 		RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A")); | ||||||
| 		RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B")); | 		RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B")); | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ struct FsmExpand | ||||||
| 
 | 
 | ||||||
| 	bool is_cell_merge_candidate(RTLIL::Cell *cell) | 	bool is_cell_merge_candidate(RTLIL::Cell *cell) | ||||||
| 	{ | 	{ | ||||||
| 		if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") | 		if (cell->type == "$mux" || cell->type == "$pmux") | ||||||
| 			if (cell->getPort("\\A").size() < 2) | 			if (cell->getPort("\\A").size() < 2) | ||||||
| 				return true; | 				return true; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -55,7 +55,7 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL | ||||||
| 	for (auto &cellport : cellport_list) | 	for (auto &cellport : cellport_list) | ||||||
| 	{ | 	{ | ||||||
| 		RTLIL::Cell *cell = module->cells_.at(cellport.first); | 		RTLIL::Cell *cell = module->cells_.at(cellport.first); | ||||||
| 		if ((cell->type != "$mux" && cell->type != "$pmux" && cell->type != "$safe_pmux") || cellport.second != "\\Y") { | 		if ((cell->type != "$mux" && cell->type != "$pmux") || cellport.second != "\\Y") { | ||||||
| 			log("  unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); | 			log("  unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str()); | ||||||
| 			return false; | 			return false; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -84,7 +84,7 @@ struct OptMuxtreeWorker | ||||||
| 		//	.const_activated
 | 		//	.const_activated
 | ||||||
| 		for (auto cell : module->cells()) | 		for (auto cell : module->cells()) | ||||||
| 		{ | 		{ | ||||||
| 			if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$safe_pmux") | 			if (cell->type == "$mux" || cell->type == "$pmux") | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigSpec sig_a = cell->getPort("\\A"); | 				RTLIL::SigSpec sig_a = cell->getPort("\\A"); | ||||||
| 				RTLIL::SigSpec sig_b = cell->getPort("\\B"); | 				RTLIL::SigSpec sig_b = cell->getPort("\\B"); | ||||||
|  |  | ||||||
|  | @ -312,7 +312,7 @@ struct OptReduceWorker | ||||||
| 			std::vector<RTLIL::Cell*> cells; | 			std::vector<RTLIL::Cell*> cells; | ||||||
| 
 | 
 | ||||||
| 			for (auto &it : module->cells_) | 			for (auto &it : module->cells_) | ||||||
| 				if ((it.second->type == "$mux" || it.second->type == "$pmux" || it.second->type == "$safe_pmux") && design->selected(module, it.second)) | 				if ((it.second->type == "$mux" || it.second->type == "$pmux") && design->selected(module, it.second)) | ||||||
| 					cells.push_back(it.second); | 					cells.push_back(it.second); | ||||||
| 
 | 
 | ||||||
| 			for (auto cell : cells) | 			for (auto cell : cells) | ||||||
|  |  | ||||||
|  | @ -224,7 +224,6 @@ struct OptShareWorker | ||||||
| 		if (mode_nomux) { | 		if (mode_nomux) { | ||||||
| 			ct.cell_types.erase("$mux"); | 			ct.cell_types.erase("$mux"); | ||||||
| 			ct.cell_types.erase("$pmux"); | 			ct.cell_types.erase("$pmux"); | ||||||
| 			ct.cell_types.erase("$safe_pmux"); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		log("Finding identical cells in module `%s'.\n", module->name.c_str()); | 		log("Finding identical cells in module `%s'.\n", module->name.c_str()); | ||||||
|  |  | ||||||
|  | @ -176,7 +176,6 @@ struct TestCellPass : public Pass { | ||||||
| 		// cell_types["$pmux"] = "A";
 | 		// cell_types["$pmux"] = "A";
 | ||||||
| 		// cell_types["$slice"] = "A";
 | 		// cell_types["$slice"] = "A";
 | ||||||
| 		// cell_types["$concat"] = "A";
 | 		// cell_types["$concat"] = "A";
 | ||||||
| 		// cell_types["$safe_pmux"] = "A";
 |  | ||||||
| 		// cell_types["$lut"] = "A";
 | 		// cell_types["$lut"] = "A";
 | ||||||
| 		// cell_types["$assert"] = "A";
 | 		// cell_types["$assert"] = "A";
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -938,39 +938,16 @@ input [S_WIDTH-1:0] S; | ||||||
| output reg [WIDTH-1:0] Y; | output reg [WIDTH-1:0] Y; | ||||||
| 
 | 
 | ||||||
| integer i; | integer i; | ||||||
|  | reg found_active_sel_bit; | ||||||
| 
 | 
 | ||||||
| always @* begin | always @* begin | ||||||
| 	Y = A; | 	Y = A; | ||||||
| 	for (i = 0; i < S_WIDTH; i = i+1) | 	found_active_sel_bit = 0; | ||||||
| 		if (S[i]) |  | ||||||
| 			Y = B >> (WIDTH*i); |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| // -------------------------------------------------------- |  | ||||||
| 
 |  | ||||||
| module \$safe_pmux (A, B, S, Y); |  | ||||||
| 
 |  | ||||||
| parameter WIDTH = 0; |  | ||||||
| parameter S_WIDTH = 0; |  | ||||||
| 
 |  | ||||||
| input [WIDTH-1:0] A; |  | ||||||
| input [WIDTH*S_WIDTH-1:0] B; |  | ||||||
| input [S_WIDTH-1:0] S; |  | ||||||
| output reg [WIDTH-1:0] Y; |  | ||||||
| 
 |  | ||||||
| integer i, j; |  | ||||||
| 
 |  | ||||||
| always @* begin |  | ||||||
| 	j = 0; |  | ||||||
| 	for (i = 0; i < S_WIDTH; i = i+1) | 	for (i = 0; i < S_WIDTH; i = i+1) | ||||||
| 		if (S[i]) begin | 		if (S[i]) begin | ||||||
| 			Y = B >> (WIDTH*i); | 			Y = found_active_sel_bit ? 'bx : B >> (WIDTH*i); | ||||||
| 			j = j + 1; | 			found_active_sel_bit = 1; | ||||||
| 		end | 		end | ||||||
| 	if (j != 1) |  | ||||||
| 		Y = A; |  | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
|  | @ -794,40 +794,3 @@ module \$pmux (A, B, S, Y); | ||||||
| 	assign Y = |S ? Y_B : A; | 	assign Y = |S ? Y_B : A; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module \$safe_pmux (A, B, S, Y); |  | ||||||
| 	parameter WIDTH = 1; |  | ||||||
| 	parameter S_WIDTH = 1; |  | ||||||
| 
 |  | ||||||
| 	input [WIDTH-1:0] A; |  | ||||||
| 	input [WIDTH*S_WIDTH-1:0] B; |  | ||||||
| 	input [S_WIDTH-1:0] S; |  | ||||||
| 	output [WIDTH-1:0] Y; |  | ||||||
| 
 |  | ||||||
| 	wire [S_WIDTH-1:0] status_found_first; |  | ||||||
| 	wire [S_WIDTH-1:0] status_found_second; |  | ||||||
| 
 |  | ||||||
| 	genvar i; |  | ||||||
| 	generate |  | ||||||
| 		for (i = 0; i < S_WIDTH; i = i + 1) begin:GEN1 |  | ||||||
| 			wire pre_first; |  | ||||||
| 			if (i > 0) begin:GEN2 |  | ||||||
| 				assign pre_first = status_found_first[i-1]; |  | ||||||
| 			end:GEN2 else begin:GEN3 |  | ||||||
| 				assign pre_first = 0; |  | ||||||
| 			end:GEN3 |  | ||||||
| 			assign status_found_first[i] = pre_first | S[i]; |  | ||||||
| 			assign status_found_second[i] = pre_first & S[i]; |  | ||||||
| 		end:GEN1 |  | ||||||
| 	endgenerate |  | ||||||
| 
 |  | ||||||
| 	\$pmux #( |  | ||||||
| 		.WIDTH(WIDTH), |  | ||||||
| 		.S_WIDTH(S_WIDTH) |  | ||||||
| 	) pmux_cell ( |  | ||||||
| 		.A(A), |  | ||||||
| 		.B(B), |  | ||||||
| 		.S(S & {S_WIDTH{~|status_found_second}}), |  | ||||||
| 		.Y(Y) |  | ||||||
| 	); |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue