mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Fix FIRRTL to Verilog process instance subfield assignment.
Don't emit subfield assignments: bits(x, y, z) <= ... - but instead, add them to the reverse-wire-map where they'll be treated at the end of the module. Enable tests which were disabled due to incorrect treatment of subfields. Assume the `$firrtl2verilog` variable contains any additional switches to control verilog generation (i.e. `--no-dedup -X mverilog`)
This commit is contained in:
		
							parent
							
								
									c258b99040
								
							
						
					
					
						commit
						171c425cf9
					
				
					 4 changed files with 21 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -169,7 +169,6 @@ struct FirrtlWorker
 | 
			
		|||
		return *str == '\\' ? str + 1 : str;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	std::string cellname(RTLIL::Cell *cell)
 | 
			
		||||
	{
 | 
			
		||||
		return fid(cell->name).c_str();
 | 
			
		||||
| 
						 | 
				
			
			@ -219,29 +218,42 @@ struct FirrtlWorker
 | 
			
		|||
			if (it->second.size() > 0) {
 | 
			
		||||
				const SigSpec &secondSig = it->second;
 | 
			
		||||
				const std::string firstName = cell_name + "." + make_id(it->first);
 | 
			
		||||
				const std::string secondName = make_expr(secondSig);
 | 
			
		||||
				const std::string secondExpr = make_expr(secondSig);
 | 
			
		||||
				// Find the direction for this port.
 | 
			
		||||
				FDirection dir = getPortFDirection(it->first, instModule);
 | 
			
		||||
				std::string source, sink;
 | 
			
		||||
				std::string sourceExpr, sinkExpr;
 | 
			
		||||
				const SigSpec *sinkSig = nullptr;
 | 
			
		||||
				switch (dir) {
 | 
			
		||||
					case FD_INOUT:
 | 
			
		||||
						log_warning("Instance port connection %s.%s is INOUT; treating as OUT\n", cell_type.c_str(), log_signal(it->second));
 | 
			
		||||
					case FD_OUT:
 | 
			
		||||
						source = firstName;
 | 
			
		||||
						sink = secondName;
 | 
			
		||||
						sourceExpr = firstName;
 | 
			
		||||
						sinkExpr = secondExpr;
 | 
			
		||||
						sinkSig = &secondSig;
 | 
			
		||||
						break;
 | 
			
		||||
					case FD_NODIRECTION:
 | 
			
		||||
						log_warning("Instance port connection %s.%s is NODIRECTION; treating as IN\n", cell_type.c_str(), log_signal(it->second));
 | 
			
		||||
						/* FALL_THROUGH */
 | 
			
		||||
					case FD_IN:
 | 
			
		||||
						source = secondName;
 | 
			
		||||
						sink = firstName;
 | 
			
		||||
						sourceExpr = secondExpr;
 | 
			
		||||
						sinkExpr = firstName;
 | 
			
		||||
						break;
 | 
			
		||||
					default:
 | 
			
		||||
						log_error("Instance port %s.%s unrecognized connection direction 0x%x !\n", cell_type.c_str(), log_signal(it->second), dir);
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
				wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sink.c_str(), source.c_str()));
 | 
			
		||||
				// Check for subfield assignment.
 | 
			
		||||
				std::string bitsString = "bits(";
 | 
			
		||||
				if (sinkExpr.substr(0, bitsString.length()) == bitsString ) {
 | 
			
		||||
					if (sinkSig == nullptr)
 | 
			
		||||
						log_error("Unknown subfield %s.%s\n", cell_type.c_str(), sinkExpr.c_str());
 | 
			
		||||
					// Don't generate the assignment here.
 | 
			
		||||
					// Add the source and sink to the "reverse_wire_map" and we'll output the assignment
 | 
			
		||||
					//  as part of the coalesced subfield assignments for this wire.
 | 
			
		||||
					register_reverse_wire_map(sourceExpr, *sinkSig);
 | 
			
		||||
				} else {
 | 
			
		||||
					wire_exprs.push_back(stringf("\n%s%s <= %s", indent.c_str(), sinkExpr.c_str(), sourceExpr.c_str()));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		wire_exprs.push_back(stringf("\n"));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,6 @@ code_hdl_models_d_latch_gates.v	combinational loop
 | 
			
		|||
code_hdl_models_dff_async_reset.v	$adff
 | 
			
		||||
code_hdl_models_tff_async_reset.v	$adff
 | 
			
		||||
code_hdl_models_uart.v	$adff
 | 
			
		||||
code_specman_switch_fabric.v	subfield assignment (bits() <= ...)
 | 
			
		||||
code_tidbits_asyn_reset.v	$adff
 | 
			
		||||
code_tidbits_reg_seq_example.v	$adff
 | 
			
		||||
code_verilog_tutorial_always_example.v	empty module
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,6 @@ multiplier.v	inst id[0] of
 | 
			
		|||
muxtree.v	drops modules
 | 
			
		||||
omsp_dbg_uart.v	$adff
 | 
			
		||||
operators.v	$pow
 | 
			
		||||
paramods.v	subfield assignment (bits() <= ...)
 | 
			
		||||
partsel.v	drops modules
 | 
			
		||||
process.v	drops modules
 | 
			
		||||
realexpr.v	drops modules
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -175,7 +175,7 @@ do
 | 
			
		|||
			if [ -n "$firrtl2verilog" ]; then
 | 
			
		||||
			    if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then
 | 
			
		||||
				"$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt; memory; opt; fsm; opt -full -fine; pmuxtree" ${bn}_ref.v
 | 
			
		||||
				$firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v  -X verilog
 | 
			
		||||
				$firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v
 | 
			
		||||
				test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.fir.v
 | 
			
		||||
			    fi
 | 
			
		||||
			fi
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue