mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	fmt,cxxrtl: fix printing of non-decimal signed numbers.
Also fix interaction of `NUMERIC` justification with `show_base`.
This commit is contained in:
		
							parent
							
								
									00c5b60dfd
								
							
						
					
					
						commit
						ddf7b46955
					
				
					 2 changed files with 100 additions and 68 deletions
				
			
		| 
						 | 
					@ -1058,6 +1058,7 @@ struct fmt_part {
 | 
				
			||||||
		// We might want to replace some of these bit() calls with direct
 | 
							// We might want to replace some of these bit() calls with direct
 | 
				
			||||||
		// chunk access if it turns out to be slow enough to matter.
 | 
							// chunk access if it turns out to be slow enough to matter.
 | 
				
			||||||
		std::string buf;
 | 
							std::string buf;
 | 
				
			||||||
 | 
							std::string prefix;
 | 
				
			||||||
		switch (type) {
 | 
							switch (type) {
 | 
				
			||||||
			case LITERAL:
 | 
								case LITERAL:
 | 
				
			||||||
				return str;
 | 
									return str;
 | 
				
			||||||
| 
						 | 
					@ -1096,24 +1097,38 @@ struct fmt_part {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case INTEGER: {
 | 
								case INTEGER: {
 | 
				
			||||||
 | 
									bool negative = signed_ && val.is_neg();
 | 
				
			||||||
 | 
									if (negative) {
 | 
				
			||||||
 | 
										prefix = "-";
 | 
				
			||||||
 | 
										val = val.neg();
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										switch (sign) {
 | 
				
			||||||
 | 
											case MINUS:       break;
 | 
				
			||||||
 | 
											case PLUS_MINUS:  prefix = "+"; break;
 | 
				
			||||||
 | 
											case SPACE_MINUS: prefix = " "; break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				size_t width = Bits;
 | 
									size_t width = Bits;
 | 
				
			||||||
				if (base != 10) {
 | 
									if (base != 10) {
 | 
				
			||||||
					width = 0;
 | 
										width = 1;
 | 
				
			||||||
					for (size_t index = 0; index < Bits; index++)
 | 
										for (size_t index = 0; index < Bits; index++)
 | 
				
			||||||
						if (val.bit(index))
 | 
											if (val.bit(index))
 | 
				
			||||||
							width = index + 1;
 | 
												width = index + 1;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (base == 2) {
 | 
									if (base == 2) {
 | 
				
			||||||
 | 
										if (show_base)
 | 
				
			||||||
 | 
											prefix += "0b";
 | 
				
			||||||
					for (size_t index = 0; index < width; index++) {
 | 
										for (size_t index = 0; index < width; index++) {
 | 
				
			||||||
						if (group && index > 0 && index % 4 == 0)
 | 
											if (group && index > 0 && index % 4 == 0)
 | 
				
			||||||
							buf += '_';
 | 
												buf += '_';
 | 
				
			||||||
						buf += (val.bit(index) ? '1' : '0');
 | 
											buf += (val.bit(index) ? '1' : '0');
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if (show_base)
 | 
					 | 
				
			||||||
						buf += "b0";
 | 
					 | 
				
			||||||
					std::reverse(buf.begin(), buf.end());
 | 
										std::reverse(buf.begin(), buf.end());
 | 
				
			||||||
				} else if (base == 8 || base == 16) {
 | 
									} else if (base == 8 || base == 16) {
 | 
				
			||||||
 | 
										if (show_base)
 | 
				
			||||||
 | 
											prefix += (base == 16) ? (hex_upper ? "0X" : "0x") : "0o";
 | 
				
			||||||
					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)
 | 
											if (group && index > 0 && index % (4 * step) == 0)
 | 
				
			||||||
| 
						 | 
					@ -1123,13 +1138,10 @@ struct fmt_part {
 | 
				
			||||||
							value |= val.bit(index + 3) << 3;
 | 
												value |= val.bit(index + 3) << 3;
 | 
				
			||||||
						buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value];
 | 
											buf += (hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[value];
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if (show_base)
 | 
					 | 
				
			||||||
						buf += (base == 16) ? (hex_upper ? "X0" : "x0") : "o0";
 | 
					 | 
				
			||||||
					std::reverse(buf.begin(), buf.end());
 | 
										std::reverse(buf.begin(), buf.end());
 | 
				
			||||||
				} else if (base == 10) {
 | 
									} else if (base == 10) {
 | 
				
			||||||
					bool negative = signed_ && val.is_neg();
 | 
										if (show_base)
 | 
				
			||||||
					if (negative)
 | 
											prefix += "0d";
 | 
				
			||||||
						val = val.neg();
 | 
					 | 
				
			||||||
					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)>();
 | 
				
			||||||
| 
						 | 
					@ -1146,13 +1158,6 @@ struct fmt_part {
 | 
				
			||||||
						xval = quotient;
 | 
											xval = quotient;
 | 
				
			||||||
						index++;
 | 
											index++;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if (show_base)
 | 
					 | 
				
			||||||
						buf += "d0";
 | 
					 | 
				
			||||||
					switch (sign) {
 | 
					 | 
				
			||||||
						case MINUS:       buf += negative ? "-" : "";  break;
 | 
					 | 
				
			||||||
						case PLUS_MINUS:  buf += negative ? "-" : "+"; break;
 | 
					 | 
				
			||||||
						case SPACE_MINUS: buf += negative ? "-" : " "; break;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					std::reverse(buf.begin(), buf.end());
 | 
										std::reverse(buf.begin(), buf.end());
 | 
				
			||||||
				} else assert(false && "Unsupported base for fmt_part");
 | 
									} else assert(false && "Unsupported base for fmt_part");
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -1170,17 +1175,29 @@ struct fmt_part {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string str;
 | 
							std::string str;
 | 
				
			||||||
		assert(width == 0 || padding != '\0');
 | 
							assert(width == 0 || padding != '\0');
 | 
				
			||||||
		if (justify != LEFT && buf.size() < width) {
 | 
							if (prefix.size() + buf.size() < width) {
 | 
				
			||||||
			size_t pad_width = width - buf.size();
 | 
								size_t pad_width = width - prefix.size() - buf.size();
 | 
				
			||||||
			if (justify == NUMERIC && (buf.front() == '+' || buf.front() == '-' || buf.front() == ' ')) {
 | 
								switch (justify) {
 | 
				
			||||||
				str += buf.front();
 | 
									case LEFT:
 | 
				
			||||||
				buf.erase(0, 1);
 | 
										str += prefix;
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			str += std::string(pad_width, padding);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
					str += buf;
 | 
										str += buf;
 | 
				
			||||||
		if (justify == LEFT && buf.size() < width)
 | 
										str += std::string(pad_width, padding);
 | 
				
			||||||
			str += std::string(width - buf.size(), padding);
 | 
										break;
 | 
				
			||||||
 | 
									case RIGHT:
 | 
				
			||||||
 | 
										str += std::string(pad_width, padding);
 | 
				
			||||||
 | 
										str += prefix;
 | 
				
			||||||
 | 
										str += buf;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									case NUMERIC:
 | 
				
			||||||
 | 
										str += prefix;
 | 
				
			||||||
 | 
										str += std::string(pad_width, padding);
 | 
				
			||||||
 | 
										str += buf;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								str += prefix;
 | 
				
			||||||
 | 
								str += buf;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return str;
 | 
							return str;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										103
									
								
								kernel/fmt.cc
									
										
									
									
									
								
							
							
						
						
									
										103
									
								
								kernel/fmt.cc
									
										
									
									
									
								
							| 
						 | 
					@ -491,6 +491,8 @@ void Fmt::parse_verilog(const std::vector<VerilogFmtArg> &args, bool sformat_lik
 | 
				
			||||||
							if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS)
 | 
												if (part.type == FmtPart::INTEGER && part.base != 10 && part.sign != FmtPart::MINUS)
 | 
				
			||||||
								log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
 | 
													log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
												if (part.base != 10)
 | 
				
			||||||
 | 
													part.signed_ = false;
 | 
				
			||||||
							if (part.type == FmtPart::INTEGER && !has_leading_zero)
 | 
												if (part.type == FmtPart::INTEGER && !has_leading_zero)
 | 
				
			||||||
								apply_verilog_automatic_sizing_and_add(part);
 | 
													apply_verilog_automatic_sizing_and_add(part);
 | 
				
			||||||
							else
 | 
												else
 | 
				
			||||||
| 
						 | 
					@ -731,11 +733,34 @@ std::string Fmt::render() const
 | 
				
			||||||
			case FmtPart::STRING:
 | 
								case FmtPart::STRING:
 | 
				
			||||||
			case FmtPart::VLOG_TIME: {
 | 
								case FmtPart::VLOG_TIME: {
 | 
				
			||||||
				std::string buf;
 | 
									std::string buf;
 | 
				
			||||||
 | 
									std::string prefix;
 | 
				
			||||||
				if (part.type == FmtPart::INTEGER) {
 | 
									if (part.type == FmtPart::INTEGER) {
 | 
				
			||||||
					RTLIL::Const value = part.sig.as_const();
 | 
										RTLIL::Const value = part.sig.as_const();
 | 
				
			||||||
 | 
										bool has_x = false, all_x = true, has_z = false, all_z = true;
 | 
				
			||||||
 | 
										for (State bit : value) {
 | 
				
			||||||
 | 
											if (bit == State::Sx)
 | 
				
			||||||
 | 
												has_x = true;
 | 
				
			||||||
 | 
											else
 | 
				
			||||||
 | 
												all_x = false;
 | 
				
			||||||
 | 
											if (bit == State::Sz)
 | 
				
			||||||
 | 
												has_z = true;
 | 
				
			||||||
 | 
											else
 | 
				
			||||||
 | 
												all_z = false;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (!has_z && !has_x && part.signed_ && value[value.size() - 1]) {
 | 
				
			||||||
 | 
											prefix = "-";
 | 
				
			||||||
 | 
											value = RTLIL::const_neg(value, {}, part.signed_, {}, value.size() + 1);
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											switch (part.sign) {
 | 
				
			||||||
 | 
												case FmtPart::MINUS:       break;
 | 
				
			||||||
 | 
												case FmtPart::PLUS_MINUS:  prefix = "+"; break;
 | 
				
			||||||
 | 
												case FmtPart::SPACE_MINUS: prefix = " "; break;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (part.base != 10) {
 | 
										if (part.base != 10) {
 | 
				
			||||||
						size_t minimum_size = 0;
 | 
											size_t minimum_size = 1;
 | 
				
			||||||
						for (size_t index = 0; index < (size_t)value.size(); index++)
 | 
											for (size_t index = 0; index < (size_t)value.size(); index++)
 | 
				
			||||||
							if (value[index] != State::S0)
 | 
												if (value[index] != State::S0)
 | 
				
			||||||
								minimum_size = index + 1;
 | 
													minimum_size = index + 1;
 | 
				
			||||||
| 
						 | 
					@ -743,6 +768,8 @@ std::string Fmt::render() const
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (part.base == 2) {
 | 
										if (part.base == 2) {
 | 
				
			||||||
 | 
											if (part.show_base)
 | 
				
			||||||
 | 
												prefix += "0b";
 | 
				
			||||||
						for (size_t index = 0; index < (size_t)value.size(); index++) {
 | 
											for (size_t index = 0; index < (size_t)value.size(); index++) {
 | 
				
			||||||
							if (part.group && index > 0 && index % 4 == 0)
 | 
												if (part.group && index > 0 && index % 4 == 0)
 | 
				
			||||||
								buf += '_';
 | 
													buf += '_';
 | 
				
			||||||
| 
						 | 
					@ -756,10 +783,10 @@ std::string Fmt::render() const
 | 
				
			||||||
							else /* if (bit == State::S0) */
 | 
												else /* if (bit == State::S0) */
 | 
				
			||||||
								buf += '0';
 | 
													buf += '0';
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						if (part.show_base)
 | 
					 | 
				
			||||||
							buf += "b0";
 | 
					 | 
				
			||||||
						std::reverse(buf.begin(), buf.end());
 | 
											std::reverse(buf.begin(), buf.end());
 | 
				
			||||||
					} else if (part.base == 8 || part.base == 16) {
 | 
										} else if (part.base == 8 || part.base == 16) {
 | 
				
			||||||
 | 
											if (part.show_base)
 | 
				
			||||||
 | 
												prefix += (part.base == 16) ? (part.hex_upper ? "0X" : "0x") : "0o";
 | 
				
			||||||
						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)
 | 
												if (part.group && index > 0 && index % (4 * step) == 0)
 | 
				
			||||||
| 
						 | 
					@ -787,21 +814,10 @@ std::string Fmt::render() const
 | 
				
			||||||
							else
 | 
												else
 | 
				
			||||||
								buf += (part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[subvalue.as_int()];
 | 
													buf += (part.hex_upper ? "0123456789ABCDEF" : "0123456789abcdef")[subvalue.as_int()];
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						if (part.show_base)
 | 
					 | 
				
			||||||
							buf += (part.base == 16) ? (part.hex_upper ? "X0" : "x0") : "o0";
 | 
					 | 
				
			||||||
						std::reverse(buf.begin(), buf.end());
 | 
											std::reverse(buf.begin(), buf.end());
 | 
				
			||||||
					} else if (part.base == 10) {
 | 
										} else if (part.base == 10) {
 | 
				
			||||||
						bool has_x = false, all_x = true, has_z = false, all_z = true;
 | 
											if (part.show_base)
 | 
				
			||||||
						for (State bit : value) {
 | 
												prefix += "0d";
 | 
				
			||||||
							if (bit == State::Sx)
 | 
					 | 
				
			||||||
								has_x = true;
 | 
					 | 
				
			||||||
							else
 | 
					 | 
				
			||||||
								all_x = false;
 | 
					 | 
				
			||||||
							if (bit == State::Sz)
 | 
					 | 
				
			||||||
								has_z = true;
 | 
					 | 
				
			||||||
							else
 | 
					 | 
				
			||||||
								all_z = false;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						if (all_x)
 | 
											if (all_x)
 | 
				
			||||||
							buf += 'x';
 | 
												buf += 'x';
 | 
				
			||||||
						else if (all_z)
 | 
											else if (all_z)
 | 
				
			||||||
| 
						 | 
					@ -811,30 +827,17 @@ std::string Fmt::render() const
 | 
				
			||||||
						else if (has_z)
 | 
											else if (has_z)
 | 
				
			||||||
							buf += 'Z';
 | 
												buf += 'Z';
 | 
				
			||||||
						else {
 | 
											else {
 | 
				
			||||||
							bool negative = part.signed_ && value[value.size() - 1];
 | 
												log_assert(value.is_fully_def());
 | 
				
			||||||
							RTLIL::Const absvalue;
 | 
												if (value.is_fully_zero())
 | 
				
			||||||
							if (negative)
 | 
					 | 
				
			||||||
								absvalue = RTLIL::const_neg(value, {}, part.signed_, {}, value.size() + 1);
 | 
					 | 
				
			||||||
							else
 | 
					 | 
				
			||||||
								absvalue = value;
 | 
					 | 
				
			||||||
							log_assert(absvalue.is_fully_def());
 | 
					 | 
				
			||||||
							if (absvalue.is_fully_zero())
 | 
					 | 
				
			||||||
								buf += '0';
 | 
													buf += '0';
 | 
				
			||||||
							size_t index = 0;
 | 
												size_t index = 0;
 | 
				
			||||||
							while (!absvalue.is_fully_zero())	{
 | 
												while (!value.is_fully_zero())	{
 | 
				
			||||||
								if (part.group && index > 0 && index % 3 == 0)
 | 
													if (part.group && index > 0 && index % 3 == 0)
 | 
				
			||||||
									buf += '_';
 | 
														buf += '_';
 | 
				
			||||||
								buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int();
 | 
													buf += '0' + RTLIL::const_mod(value, 10, false, false, 4).as_int();
 | 
				
			||||||
								absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size());
 | 
													value = RTLIL::const_div(value, 10, false, false, value.size());
 | 
				
			||||||
								index++;
 | 
													index++;
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							if (part.show_base)
 | 
					 | 
				
			||||||
								buf += "d0";
 | 
					 | 
				
			||||||
							switch (part.sign) {
 | 
					 | 
				
			||||||
								case FmtPart::MINUS:       buf += negative ? "-" : "";  break;
 | 
					 | 
				
			||||||
								case FmtPart::PLUS_MINUS:  buf += negative ? "-" : "+"; break;
 | 
					 | 
				
			||||||
								case FmtPart::SPACE_MINUS: buf += negative ? "-" : " "; break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							std::reverse(buf.begin(), buf.end());
 | 
												std::reverse(buf.begin(), buf.end());
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					} else log_abort();
 | 
										} else log_abort();
 | 
				
			||||||
| 
						 | 
					@ -846,17 +849,29 @@ std::string Fmt::render() const
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				log_assert(part.width == 0 || part.padding != '\0');
 | 
									log_assert(part.width == 0 || part.padding != '\0');
 | 
				
			||||||
				if (part.justify != FmtPart::LEFT && buf.size() < part.width) {
 | 
									if (prefix.size() + buf.size() < part.width) {
 | 
				
			||||||
					size_t pad_width = part.width - buf.size();
 | 
										size_t pad_width = part.width - prefix.size() - buf.size();
 | 
				
			||||||
					if (part.justify == FmtPart::NUMERIC && (!buf.empty() && (buf.front() == '+' || buf.front() == '-' || buf.front() == ' '))) {
 | 
										switch (part.justify) {
 | 
				
			||||||
						str += buf.front();
 | 
											case FmtPart::LEFT:
 | 
				
			||||||
						buf.erase(0, 1);
 | 
												str += prefix;
 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					str += std::string(pad_width, part.padding);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
							str += buf;
 | 
												str += buf;
 | 
				
			||||||
				if (part.justify == FmtPart::LEFT && buf.size() < part.width)
 | 
												str += std::string(pad_width, part.padding);
 | 
				
			||||||
					str += std::string(part.width - buf.size(), part.padding);
 | 
												break;
 | 
				
			||||||
 | 
											case FmtPart::RIGHT:
 | 
				
			||||||
 | 
												str += std::string(pad_width, part.padding);
 | 
				
			||||||
 | 
												str += prefix;
 | 
				
			||||||
 | 
												str += buf;
 | 
				
			||||||
 | 
												break;
 | 
				
			||||||
 | 
											case FmtPart::NUMERIC:
 | 
				
			||||||
 | 
												str += prefix;
 | 
				
			||||||
 | 
												str += std::string(pad_width, part.padding);
 | 
				
			||||||
 | 
												str += buf;
 | 
				
			||||||
 | 
												break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										str += prefix;
 | 
				
			||||||
 | 
										str += buf;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue