mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	fmt,cxxrtl: add option to group digits in numbers.
The option is serialized to RTLIL as `_` (to match Python's option with the same symbol), and sets the `group` flag. This flag inserts an `_` symbol between each group of 3 digits (for decimal) or four digits (for binary, hex, and octal).
This commit is contained in:
		
							parent
							
								
									7b94599162
								
							
						
					
					
						commit
						00c5b60dfd
					
				
					 3 changed files with 42 additions and 5 deletions
				
			
		|  | @ -1042,6 +1042,7 @@ struct fmt_part { | ||||||
| 	} sign; // = MINUS;
 | 	} sign; // = MINUS;
 | ||||||
| 	bool hex_upper; // = false;
 | 	bool hex_upper; // = false;
 | ||||||
| 	bool show_base; // = false;
 | 	bool show_base; // = false;
 | ||||||
|  | 	bool group; // = false;
 | ||||||
| 
 | 
 | ||||||
| 	// VLOG_TIME type
 | 	// VLOG_TIME type
 | ||||||
| 	bool realtime; // = false;
 | 	bool realtime; // = false;
 | ||||||
|  | @ -1104,13 +1105,19 @@ struct fmt_part { | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (base == 2) { | 				if (base == 2) { | ||||||
|  | 					for (size_t index = 0; index < width; index++) { | ||||||
|  | 						if (group && index > 0 && index % 4 == 0) | ||||||
|  | 							buf += '_'; | ||||||
|  | 						buf += (val.bit(index) ? '1' : '0'); | ||||||
|  | 					} | ||||||
| 					if (show_base) | 					if (show_base) | ||||||
| 						buf += "0b"; | 						buf += "b0"; | ||||||
| 					for (size_t i = width; i > 0; i--) | 					std::reverse(buf.begin(), buf.end()); | ||||||
| 						buf += (val.bit(i - 1) ? '1' : '0'); |  | ||||||
| 				} else if (base == 8 || base == 16) { | 				} else if (base == 8 || base == 16) { | ||||||
| 					size_t step = (base == 16) ? 4 : 3; | 					size_t step = (base == 16) ? 4 : 3; | ||||||
| 					for (size_t index = 0; index < width; index += step) { | 					for (size_t index = 0; index < width; index += step) { | ||||||
|  | 						if (group && index > 0 && index % (4 * step) == 0) | ||||||
|  | 							buf += '_'; | ||||||
| 						uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2); | 						uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2); | ||||||
| 						if (step == 4) | 						if (step == 4) | ||||||
| 							value |= val.bit(index + 3) << 3; | 							value |= val.bit(index + 3) << 3; | ||||||
|  | @ -1126,7 +1133,10 @@ struct fmt_part { | ||||||
| 					if (val.is_zero()) | 					if (val.is_zero()) | ||||||
| 						buf += '0'; | 						buf += '0'; | ||||||
| 					value<(Bits > 4 ? Bits : 4)> xval = val.template zext<(Bits > 4 ? Bits : 4)>(); | 					value<(Bits > 4 ? Bits : 4)> xval = val.template zext<(Bits > 4 ? Bits : 4)>(); | ||||||
|  | 					size_t index = 0; | ||||||
| 					while (!xval.is_zero()) { | 					while (!xval.is_zero()) { | ||||||
|  | 						if (group && index > 0 && index % 3 == 0) | ||||||
|  | 							buf += '_'; | ||||||
| 						value<(Bits > 4 ? Bits : 4)> quotient, remainder; | 						value<(Bits > 4 ? Bits : 4)> quotient, remainder; | ||||||
| 						if (Bits >= 4) | 						if (Bits >= 4) | ||||||
| 							std::tie(quotient, remainder) = xval.udivmod(value<(Bits > 4 ? Bits : 4)>{10u}); | 							std::tie(quotient, remainder) = xval.udivmod(value<(Bits > 4 ? Bits : 4)>{10u}); | ||||||
|  | @ -1134,6 +1144,7 @@ struct fmt_part { | ||||||
| 							std::tie(quotient, remainder) = std::make_pair(value<(Bits > 4 ? Bits : 4)>{0u}, xval); | 							std::tie(quotient, remainder) = std::make_pair(value<(Bits > 4 ? Bits : 4)>{0u}, xval); | ||||||
| 						buf += '0' + remainder.template trunc<4>().template get<uint8_t>(); | 						buf += '0' + remainder.template trunc<4>().template get<uint8_t>(); | ||||||
| 						xval = quotient; | 						xval = quotient; | ||||||
|  | 						index++; | ||||||
| 					} | 					} | ||||||
| 					if (show_base) | 					if (show_base) | ||||||
| 						buf += "d0"; | 						buf += "d0"; | ||||||
|  |  | ||||||
|  | @ -156,6 +156,10 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { | ||||||
| 					part.show_base = true; | 					part.show_base = true; | ||||||
| 					++i; | 					++i; | ||||||
| 				} | 				} | ||||||
|  | 				if (fmt[i] == '_') { | ||||||
|  | 					part.group = true; | ||||||
|  | 					++i; | ||||||
|  | 				} | ||||||
| 
 | 
 | ||||||
| 				if (fmt[i] == 'u') | 				if (fmt[i] == 'u') | ||||||
| 					part.signed_ = false; | 					part.signed_ = false; | ||||||
|  | @ -241,6 +245,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { | ||||||
| 						case FmtPart::SPACE_MINUS: fmt += ' '; break; | 						case FmtPart::SPACE_MINUS: fmt += ' '; break; | ||||||
| 					} | 					} | ||||||
| 					fmt += part.show_base ? "#" : ""; | 					fmt += part.show_base ? "#" : ""; | ||||||
|  | 					fmt += part.group ? "_" : ""; | ||||||
| 					fmt += part.signed_ ? 's' : 'u'; | 					fmt += part.signed_ ? 's' : 'u'; | ||||||
| 				} else if (part.type == FmtPart::STRING) { | 				} else if (part.type == FmtPart::STRING) { | ||||||
| 					fmt += 'c'; | 					fmt += 'c'; | ||||||
|  | @ -683,6 +688,7 @@ void Fmt::emit_cxxrtl(std::ostream &os, std::string indent, std::function<void(c | ||||||
| 		os << ", "; | 		os << ", "; | ||||||
| 		os << part.hex_upper << ", "; | 		os << part.hex_upper << ", "; | ||||||
| 		os << part.show_base << ", "; | 		os << part.show_base << ", "; | ||||||
|  | 		os << part.group << ", "; | ||||||
| 		os << part.realtime; | 		os << part.realtime; | ||||||
| 		os << " }.render("; | 		os << " }.render("; | ||||||
| 		emit_sig(part.sig); | 		emit_sig(part.sig); | ||||||
|  | @ -737,12 +743,27 @@ std::string Fmt::render() const | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					if (part.base == 2) { | 					if (part.base == 2) { | ||||||
|  | 						for (size_t index = 0; index < (size_t)value.size(); index++) { | ||||||
|  | 							if (part.group && index > 0 && index % 4 == 0) | ||||||
|  | 								buf += '_'; | ||||||
|  | 							RTLIL::State bit = value[index]; | ||||||
|  | 							if (bit == State::Sx) | ||||||
|  | 								buf += 'x'; | ||||||
|  | 							else if (bit == State::Sz) | ||||||
|  | 								buf += 'z'; | ||||||
|  | 							else if (bit == State::S1) | ||||||
|  | 								buf += '1'; | ||||||
|  | 							else /* if (bit == State::S0) */ | ||||||
|  | 								buf += '0'; | ||||||
|  | 						} | ||||||
| 						if (part.show_base) | 						if (part.show_base) | ||||||
| 							buf += "0b"; | 							buf += "b0"; | ||||||
| 						buf = value.as_string(); | 						std::reverse(buf.begin(), buf.end()); | ||||||
| 					} else if (part.base == 8 || part.base == 16) { | 					} else if (part.base == 8 || part.base == 16) { | ||||||
| 						size_t step = (part.base == 16) ? 4 : 3; | 						size_t step = (part.base == 16) ? 4 : 3; | ||||||
| 						for (size_t index = 0; index < (size_t)value.size(); index += step) { | 						for (size_t index = 0; index < (size_t)value.size(); index += step) { | ||||||
|  | 							if (part.group && index > 0 && index % (4 * step) == 0) | ||||||
|  | 								buf += '_'; | ||||||
| 							RTLIL::Const subvalue = value.extract(index, min(step, value.size() - index)); | 							RTLIL::Const subvalue = value.extract(index, min(step, value.size() - index)); | ||||||
| 							bool has_x = false, all_x = true, has_z = false, all_z = true; | 							bool has_x = false, all_x = true, has_z = false, all_z = true; | ||||||
| 							for (State bit : subvalue) { | 							for (State bit : subvalue) { | ||||||
|  | @ -799,9 +820,13 @@ std::string Fmt::render() const | ||||||
| 							log_assert(absvalue.is_fully_def()); | 							log_assert(absvalue.is_fully_def()); | ||||||
| 							if (absvalue.is_fully_zero()) | 							if (absvalue.is_fully_zero()) | ||||||
| 								buf += '0'; | 								buf += '0'; | ||||||
|  | 							size_t index = 0; | ||||||
| 							while (!absvalue.is_fully_zero())	{ | 							while (!absvalue.is_fully_zero())	{ | ||||||
|  | 								if (part.group && index > 0 && index % 3 == 0) | ||||||
|  | 									buf += '_'; | ||||||
| 								buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int(); | 								buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int(); | ||||||
| 								absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size()); | 								absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size()); | ||||||
|  | 								index++; | ||||||
| 							} | 							} | ||||||
| 							if (part.show_base) | 							if (part.show_base) | ||||||
| 								buf += "d0"; | 								buf += "d0"; | ||||||
|  |  | ||||||
|  | @ -85,6 +85,7 @@ struct FmtPart { | ||||||
| 	} sign = MINUS; | 	} sign = MINUS; | ||||||
| 	bool hex_upper = false; | 	bool hex_upper = false; | ||||||
| 	bool show_base = false; | 	bool show_base = false; | ||||||
|  | 	bool group = false; | ||||||
| 
 | 
 | ||||||
| 	// VLOG_TIME type
 | 	// VLOG_TIME type
 | ||||||
| 	bool realtime = false; | 	bool realtime = false; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue