sim/vcd: fix variable identifiers to follow verilog rules

This commit is contained in:
Jacob Lifshay 2024-12-10 23:39:17 -08:00
parent ca759168ff
commit 564ccb30bc
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ

View file

@ -235,6 +235,17 @@ fn write_escaped<W: io::Write>(writer: &mut W, value: impl Display) -> io::Resul
write!(Wrapper(writer), "{value}")
}
fn is_unescaped_verilog_identifier(ident: &str) -> bool {
// we only allow ascii, so we can just check bytes
let Some((&first, rest)) = ident.as_bytes().split_first() else {
return false; // empty string is not an identifier
};
(first.is_ascii_alphabetic() || first == b'_')
&& rest
.iter()
.all(|&ch| ch.is_ascii_alphanumeric() || ch == b'_' || ch == b'$')
}
fn write_vcd_var<W: io::Write>(
writer: &mut W,
var_type: &str,
@ -244,7 +255,12 @@ fn write_vcd_var<W: io::Write>(
) -> io::Result<()> {
write!(writer, "$var {var_type} {size} ")?;
write_scalar_id(writer, id)?;
writeln!(writer, " {name} $end")
writer.write_all(b" ")?;
if !is_unescaped_verilog_identifier(name) {
writer.write_all(b"\\")?;
}
write_escaped(writer, name)?;
writer.write_all(b" $end\n")
}
impl WriteTrace for TraceUInt {