forked from libre-chip/fayalite
Compare commits
3 commits
fifo-proof
...
master
Author | SHA1 | Date | |
---|---|---|---|
Jacob Lifshay | d4ea826051 | ||
Jacob Lifshay | 404a2ee043 | ||
Jacob Lifshay | e3a2ccd41c |
|
@ -4773,6 +4773,9 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
self.insns.extend(insns.iter().copied(), *source_location);
|
self.insns.extend(insns.iter().copied(), *source_location);
|
||||||
}
|
}
|
||||||
|
for CondStackEntry { cond: _, end_label } in cond_stack {
|
||||||
|
self.insns.define_label_at_next_insn(end_label);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn process_clocks(&mut self) -> Interned<[StatePartIndex<StatePartKindSmallSlots>]> {
|
fn process_clocks(&mut self) -> Interned<[StatePartIndex<StatePartKindSmallSlots>]> {
|
||||||
mem::take(&mut self.clock_triggers)
|
mem::take(&mut self.clock_triggers)
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
enum_::{Enum, EnumType},
|
enum_::{Enum, EnumType},
|
||||||
expr::Flow,
|
expr::Flow,
|
||||||
int::UInt,
|
int::UInt,
|
||||||
|
intern::{Intern, Interned},
|
||||||
sim::{
|
sim::{
|
||||||
time::{SimDuration, SimInstant},
|
time::{SimDuration, SimInstant},
|
||||||
TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl,
|
TraceArray, TraceAsyncReset, TraceBool, TraceBundle, TraceClock, TraceDecl,
|
||||||
|
@ -15,12 +16,73 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bitvec::{order::Lsb0, slice::BitSlice};
|
use bitvec::{order::Lsb0, slice::BitSlice};
|
||||||
|
use hashbrown::{hash_map::Entry, HashMap};
|
||||||
use std::{
|
use std::{
|
||||||
fmt,
|
fmt::{self, Write as _},
|
||||||
io::{self, Write},
|
io, mem,
|
||||||
mem,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Scope {
|
||||||
|
last_inserted: HashMap<Interned<str>, usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct VerilogIdentifier {
|
||||||
|
unescaped_name: Interned<str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VerilogIdentifier {
|
||||||
|
fn needs_escape(self) -> bool {
|
||||||
|
// we only allow ascii, so we can just check bytes
|
||||||
|
let Some((&first, rest)) = self.unescaped_name.as_bytes().split_first() else {
|
||||||
|
unreachable!("Scope::new_identifier guarantees a non-empty name");
|
||||||
|
};
|
||||||
|
if !first.is_ascii_alphabetic() && first != b'_' {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
rest.iter()
|
||||||
|
.any(|&ch| !ch.is_ascii_alphanumeric() && ch != b'_' && ch != b'$')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for VerilogIdentifier {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
if self.needs_escape() {
|
||||||
|
f.write_str("\\")?;
|
||||||
|
}
|
||||||
|
write!(f, "{}", Escaped(self.unescaped_name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scope {
|
||||||
|
fn new_identifier(&mut self, unescaped_name: Interned<str>) -> VerilogIdentifier {
|
||||||
|
let next_disambiguator = match self.last_inserted.entry(unescaped_name) {
|
||||||
|
Entry::Vacant(entry) => {
|
||||||
|
entry.insert(1);
|
||||||
|
return VerilogIdentifier { unescaped_name };
|
||||||
|
}
|
||||||
|
Entry::Occupied(entry) => entry.get() + 1,
|
||||||
|
};
|
||||||
|
let mut disambiguated_name = String::from(&*unescaped_name);
|
||||||
|
for disambiguator in next_disambiguator.. {
|
||||||
|
disambiguated_name.truncate(unescaped_name.len());
|
||||||
|
write!(disambiguated_name, "_{disambiguator}").expect("can't fail");
|
||||||
|
if let Entry::Vacant(entry) = self.last_inserted.entry((*disambiguated_name).intern()) {
|
||||||
|
let retval = VerilogIdentifier {
|
||||||
|
unescaped_name: *entry.key(),
|
||||||
|
};
|
||||||
|
entry.insert(1);
|
||||||
|
// speed up future searches
|
||||||
|
self.last_inserted.insert(unescaped_name, disambiguator);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("too many names");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct VcdWriterDecls<W: io::Write + 'static> {
|
pub struct VcdWriterDecls<W: io::Write + 'static> {
|
||||||
writer: W,
|
writer: W,
|
||||||
timescale: SimDuration,
|
timescale: SimDuration,
|
||||||
|
@ -97,14 +159,20 @@ impl<W: io::Write> fmt::Debug for VcdWriterDecls<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// pass in scope to ensure it's not available in child scope
|
||||||
fn write_vcd_scope<W: io::Write, R>(
|
fn write_vcd_scope<W: io::Write, R>(
|
||||||
writer: &mut W,
|
writer: &mut W,
|
||||||
scope_type: &str,
|
scope_type: &str,
|
||||||
scope_name: &str,
|
scope_name: Interned<str>,
|
||||||
f: impl FnOnce(&mut W) -> io::Result<R>,
|
scope: &mut Scope,
|
||||||
|
f: impl FnOnce(&mut W, &mut Scope) -> io::Result<R>,
|
||||||
) -> io::Result<R> {
|
) -> io::Result<R> {
|
||||||
writeln!(writer, "$scope {scope_type} {scope_name} $end")?;
|
writeln!(
|
||||||
let retval = f(writer)?;
|
writer,
|
||||||
|
"$scope {scope_type} {} $end",
|
||||||
|
scope.new_identifier(scope_name),
|
||||||
|
)?;
|
||||||
|
let retval = f(writer, &mut Scope::default())?;
|
||||||
writeln!(writer, "$upscope $end")?;
|
writeln!(writer, "$upscope $end")?;
|
||||||
Ok(retval)
|
Ok(retval)
|
||||||
}
|
}
|
||||||
|
@ -143,24 +211,28 @@ trait_arg! {
|
||||||
|
|
||||||
struct ArgModule<'a> {
|
struct ArgModule<'a> {
|
||||||
properties: &'a mut VcdWriterProperties,
|
properties: &'a mut VcdWriterProperties,
|
||||||
|
scope: &'a mut Scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArgModule<'a> {
|
impl<'a> ArgModule<'a> {
|
||||||
fn reborrow(&mut self) -> ArgModule<'_> {
|
fn reborrow(&mut self) -> ArgModule<'_> {
|
||||||
ArgModule {
|
ArgModule {
|
||||||
properties: self.properties,
|
properties: self.properties,
|
||||||
|
scope: self.scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ArgModuleBody<'a> {
|
struct ArgModuleBody<'a> {
|
||||||
properties: &'a mut VcdWriterProperties,
|
properties: &'a mut VcdWriterProperties,
|
||||||
|
scope: &'a mut Scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArgModuleBody<'a> {
|
impl<'a> ArgModuleBody<'a> {
|
||||||
fn reborrow(&mut self) -> ArgModuleBody<'_> {
|
fn reborrow(&mut self) -> ArgModuleBody<'_> {
|
||||||
ArgModuleBody {
|
ArgModuleBody {
|
||||||
properties: self.properties,
|
properties: self.properties,
|
||||||
|
scope: self.scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,6 +242,7 @@ struct ArgInType<'a> {
|
||||||
sink_var_type: &'static str,
|
sink_var_type: &'static str,
|
||||||
duplex_var_type: &'static str,
|
duplex_var_type: &'static str,
|
||||||
properties: &'a mut VcdWriterProperties,
|
properties: &'a mut VcdWriterProperties,
|
||||||
|
scope: &'a mut Scope,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ArgInType<'a> {
|
impl<'a> ArgInType<'a> {
|
||||||
|
@ -179,6 +252,7 @@ impl<'a> ArgInType<'a> {
|
||||||
sink_var_type: self.sink_var_type,
|
sink_var_type: self.sink_var_type,
|
||||||
duplex_var_type: self.duplex_var_type,
|
duplex_var_type: self.duplex_var_type,
|
||||||
properties: self.properties,
|
properties: self.properties,
|
||||||
|
scope: self.scope,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,55 +300,42 @@ fn write_vcd_id<W: io::Write>(writer: &mut W, mut id: usize) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_escaped<W: io::Write>(writer: &mut W, value: impl fmt::Display) -> io::Result<()> {
|
struct Escaped<T: fmt::Display>(T);
|
||||||
// escaping rules from function GTKWave uses to decode VCD strings:
|
|
||||||
// https://github.com/gtkwave/gtkwave/blob/491f24d7e8619cfc1fcc65704ee5c967d1083c18/lib/libfst/fstapi.c#L7090
|
impl<T: fmt::Display> fmt::Display for Escaped<T> {
|
||||||
struct Wrapper<W>(W);
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
impl<W: io::Write> io::Write for Wrapper<W> {
|
// escaping rules from function GTKWave uses to decode VCD strings:
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
// https://github.com/gtkwave/gtkwave/blob/491f24d7e8619cfc1fcc65704ee5c967d1083c18/lib/libfst/fstapi.c#L7090
|
||||||
if buf.is_empty() {
|
struct Wrapper<W>(W);
|
||||||
return self.0.write(buf);
|
impl<W: fmt::Write> fmt::Write for Wrapper<W> {
|
||||||
}
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
let mut retval = 0;
|
for byte in s.bytes() {
|
||||||
for &byte in buf {
|
match byte {
|
||||||
match byte {
|
b'\\' | b'\'' | b'"' | b'?' => {
|
||||||
b'\\' | b'\'' | b'"' | b'?' => self.0.write_all(&[b'\\', byte])?,
|
self.0.write_str("\\")?;
|
||||||
b'\n' => self.0.write_all(br"\n")?,
|
self.0.write_char(byte as char)?;
|
||||||
b'\r' => self.0.write_all(br"\r")?,
|
}
|
||||||
b'\t' => self.0.write_all(br"\t")?,
|
b'\n' => self.0.write_str(r"\n")?,
|
||||||
0x7 => self.0.write_all(br"\a")?,
|
b'\r' => self.0.write_str(r"\r")?,
|
||||||
0x8 => self.0.write_all(br"\b")?,
|
b'\t' => self.0.write_str(r"\t")?,
|
||||||
0xC => self.0.write_all(br"\f")?,
|
0x7 => self.0.write_str(r"\a")?,
|
||||||
0xB => self.0.write_all(br"\v")?,
|
0x8 => self.0.write_str(r"\b")?,
|
||||||
_ => {
|
0xC => self.0.write_str(r"\f")?,
|
||||||
if byte.is_ascii_graphic() {
|
0xB => self.0.write_str(r"\v")?,
|
||||||
self.0.write_all(&[byte])?;
|
_ => {
|
||||||
} else {
|
if byte.is_ascii_graphic() {
|
||||||
write!(self.0, r"\x{byte:02x}")?;
|
self.0.write_char(byte as char)?;
|
||||||
|
} else {
|
||||||
|
write!(self.0, r"\x{byte:02x}")?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
retval += 1;
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok(retval)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
|
||||||
self.0.flush()
|
|
||||||
}
|
}
|
||||||
|
write!(Wrapper(f), "{}", self.0)
|
||||||
}
|
}
|
||||||
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>(
|
fn write_vcd_var<W: io::Write>(
|
||||||
|
@ -284,7 +345,7 @@ fn write_vcd_var<W: io::Write>(
|
||||||
var_type: &str,
|
var_type: &str,
|
||||||
size: usize,
|
size: usize,
|
||||||
location: TraceLocation,
|
location: TraceLocation,
|
||||||
name: &str,
|
name: VerilogIdentifier,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let id = match location {
|
let id = match location {
|
||||||
TraceLocation::Scalar(id) => id.as_usize(),
|
TraceLocation::Scalar(id) => id.as_usize(),
|
||||||
|
@ -319,12 +380,7 @@ fn write_vcd_var<W: io::Write>(
|
||||||
};
|
};
|
||||||
write!(writer, "$var {var_type} {size} ")?;
|
write!(writer, "$var {var_type} {size} ")?;
|
||||||
write_vcd_id(writer, id)?;
|
write_vcd_id(writer, id)?;
|
||||||
writer.write_all(b" ")?;
|
writeln!(writer, " {name} $end")
|
||||||
if !is_unescaped_verilog_identifier(name) {
|
|
||||||
writer.write_all(b"\\")?;
|
|
||||||
}
|
|
||||||
write_escaped(writer, name)?;
|
|
||||||
writer.write_all(b" $end\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteTrace for TraceUInt {
|
impl WriteTrace for TraceUInt {
|
||||||
|
@ -334,6 +390,7 @@ impl WriteTrace for TraceUInt {
|
||||||
sink_var_type,
|
sink_var_type,
|
||||||
duplex_var_type,
|
duplex_var_type,
|
||||||
properties,
|
properties,
|
||||||
|
scope,
|
||||||
} = arg.in_type();
|
} = arg.in_type();
|
||||||
let Self {
|
let Self {
|
||||||
location,
|
location,
|
||||||
|
@ -356,7 +413,7 @@ impl WriteTrace for TraceUInt {
|
||||||
var_type,
|
var_type,
|
||||||
ty.width(),
|
ty.width(),
|
||||||
location,
|
location,
|
||||||
&name,
|
scope.new_identifier(name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,6 +478,7 @@ impl WriteTrace for TraceEnumDiscriminant {
|
||||||
sink_var_type: _,
|
sink_var_type: _,
|
||||||
duplex_var_type: _,
|
duplex_var_type: _,
|
||||||
properties,
|
properties,
|
||||||
|
scope,
|
||||||
} = arg.in_type();
|
} = arg.in_type();
|
||||||
let Self {
|
let Self {
|
||||||
location,
|
location,
|
||||||
|
@ -435,7 +493,7 @@ impl WriteTrace for TraceEnumDiscriminant {
|
||||||
"string",
|
"string",
|
||||||
1,
|
1,
|
||||||
location,
|
location,
|
||||||
&name,
|
scope.new_identifier(name),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,11 +565,11 @@ impl WriteTrace for TraceScope {
|
||||||
|
|
||||||
impl WriteTrace for TraceModule {
|
impl WriteTrace for TraceModule {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModule { properties } = arg.module();
|
let ArgModule { properties, scope } = arg.module();
|
||||||
let Self { name, children } = self;
|
let Self { name, children } = self;
|
||||||
write_vcd_scope(writer, "module", &name, |writer| {
|
write_vcd_scope(writer, "module", name, scope, |writer, scope| {
|
||||||
for child in children {
|
for child in children {
|
||||||
child.write_trace(writer, ArgModuleBody { properties })?;
|
child.write_trace(writer, ArgModuleBody { properties, scope })?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -520,7 +578,7 @@ impl WriteTrace for TraceModule {
|
||||||
|
|
||||||
impl WriteTrace for TraceInstance {
|
impl WriteTrace for TraceInstance {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModuleBody { properties } = arg.module_body();
|
let ArgModuleBody { properties, scope } = arg.module_body();
|
||||||
let Self {
|
let Self {
|
||||||
name: _,
|
name: _,
|
||||||
instance_io,
|
instance_io,
|
||||||
|
@ -534,15 +592,16 @@ impl WriteTrace for TraceInstance {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
|
scope,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
module.write_trace(writer, ArgModule { properties })
|
module.write_trace(writer, ArgModule { properties, scope })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WriteTrace for TraceMem {
|
impl WriteTrace for TraceMem {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModuleBody { properties } = arg.module_body();
|
let ArgModuleBody { properties, scope } = arg.module_body();
|
||||||
let Self {
|
let Self {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
@ -551,27 +610,41 @@ impl WriteTrace for TraceMem {
|
||||||
ports,
|
ports,
|
||||||
array_type,
|
array_type,
|
||||||
} = self;
|
} = self;
|
||||||
write_vcd_scope(writer, "struct", &*name, |writer| {
|
write_vcd_scope(writer, "struct", name, scope, |writer, scope| {
|
||||||
write_vcd_scope(writer, "struct", "contents", |writer| {
|
write_vcd_scope(
|
||||||
for element_index in 0..array_type.len() {
|
writer,
|
||||||
write_vcd_scope(writer, "struct", &format!("[{element_index}]"), |writer| {
|
"struct",
|
||||||
properties.memory_properties[id.as_usize()].element_index = element_index;
|
"contents".intern(),
|
||||||
properties.memory_properties[id.as_usize()].element_part_index = 0;
|
scope,
|
||||||
element_type.write_trace(
|
|writer, scope| {
|
||||||
|
for element_index in 0..array_type.len() {
|
||||||
|
write_vcd_scope(
|
||||||
writer,
|
writer,
|
||||||
ArgInType {
|
"struct",
|
||||||
source_var_type: "reg",
|
Intern::intern_owned(format!("[{element_index}]")),
|
||||||
sink_var_type: "reg",
|
scope,
|
||||||
duplex_var_type: "reg",
|
|writer, scope| {
|
||||||
properties,
|
properties.memory_properties[id.as_usize()].element_index =
|
||||||
|
element_index;
|
||||||
|
properties.memory_properties[id.as_usize()].element_part_index = 0;
|
||||||
|
element_type.write_trace(
|
||||||
|
writer,
|
||||||
|
ArgInType {
|
||||||
|
source_var_type: "reg",
|
||||||
|
sink_var_type: "reg",
|
||||||
|
duplex_var_type: "reg",
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
},
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)?;
|
||||||
})?;
|
}
|
||||||
}
|
Ok(())
|
||||||
Ok(())
|
},
|
||||||
})?;
|
)?;
|
||||||
for port in ports {
|
for port in ports {
|
||||||
port.write_trace(writer, ArgModuleBody { properties })?;
|
port.write_trace(writer, ArgModuleBody { properties, scope })?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -580,7 +653,7 @@ impl WriteTrace for TraceMem {
|
||||||
|
|
||||||
impl WriteTrace for TraceMemPort {
|
impl WriteTrace for TraceMemPort {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModuleBody { properties } = arg.module_body();
|
let ArgModuleBody { properties, scope } = arg.module_body();
|
||||||
let Self {
|
let Self {
|
||||||
name: _,
|
name: _,
|
||||||
bundle,
|
bundle,
|
||||||
|
@ -593,6 +666,7 @@ impl WriteTrace for TraceMemPort {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -600,7 +674,7 @@ impl WriteTrace for TraceMemPort {
|
||||||
|
|
||||||
impl WriteTrace for TraceWire {
|
impl WriteTrace for TraceWire {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModuleBody { properties } = arg.module_body();
|
let ArgModuleBody { properties, scope } = arg.module_body();
|
||||||
let Self {
|
let Self {
|
||||||
name: _,
|
name: _,
|
||||||
child,
|
child,
|
||||||
|
@ -613,6 +687,7 @@ impl WriteTrace for TraceWire {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -620,7 +695,7 @@ impl WriteTrace for TraceWire {
|
||||||
|
|
||||||
impl WriteTrace for TraceReg {
|
impl WriteTrace for TraceReg {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModuleBody { properties } = arg.module_body();
|
let ArgModuleBody { properties, scope } = arg.module_body();
|
||||||
let Self {
|
let Self {
|
||||||
name: _,
|
name: _,
|
||||||
child,
|
child,
|
||||||
|
@ -633,6 +708,7 @@ impl WriteTrace for TraceReg {
|
||||||
sink_var_type: "reg",
|
sink_var_type: "reg",
|
||||||
duplex_var_type: "reg",
|
duplex_var_type: "reg",
|
||||||
properties,
|
properties,
|
||||||
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -640,7 +716,7 @@ impl WriteTrace for TraceReg {
|
||||||
|
|
||||||
impl WriteTrace for TraceModuleIO {
|
impl WriteTrace for TraceModuleIO {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let ArgModuleBody { properties } = arg.module_body();
|
let ArgModuleBody { properties, scope } = arg.module_body();
|
||||||
let Self {
|
let Self {
|
||||||
name: _,
|
name: _,
|
||||||
child,
|
child,
|
||||||
|
@ -654,6 +730,7 @@ impl WriteTrace for TraceModuleIO {
|
||||||
sink_var_type: "wire",
|
sink_var_type: "wire",
|
||||||
duplex_var_type: "wire",
|
duplex_var_type: "wire",
|
||||||
properties,
|
properties,
|
||||||
|
scope,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -661,16 +738,31 @@ impl WriteTrace for TraceModuleIO {
|
||||||
|
|
||||||
impl WriteTrace for TraceBundle {
|
impl WriteTrace for TraceBundle {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let mut arg = arg.in_type();
|
let ArgInType {
|
||||||
|
source_var_type,
|
||||||
|
sink_var_type,
|
||||||
|
duplex_var_type,
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
} = arg.in_type();
|
||||||
let Self {
|
let Self {
|
||||||
name,
|
name,
|
||||||
fields,
|
fields,
|
||||||
ty: _,
|
ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
} = self;
|
} = self;
|
||||||
write_vcd_scope(writer, "struct", &name, |writer| {
|
write_vcd_scope(writer, "struct", name, scope, |writer, scope| {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
field.write_trace(writer, arg.reborrow())?;
|
field.write_trace(
|
||||||
|
writer,
|
||||||
|
ArgInType {
|
||||||
|
source_var_type,
|
||||||
|
sink_var_type,
|
||||||
|
duplex_var_type,
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -679,16 +771,31 @@ impl WriteTrace for TraceBundle {
|
||||||
|
|
||||||
impl WriteTrace for TraceArray {
|
impl WriteTrace for TraceArray {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let mut arg = arg.in_type();
|
let ArgInType {
|
||||||
|
source_var_type,
|
||||||
|
sink_var_type,
|
||||||
|
duplex_var_type,
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
} = arg.in_type();
|
||||||
let Self {
|
let Self {
|
||||||
name,
|
name,
|
||||||
elements,
|
elements,
|
||||||
ty: _,
|
ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
} = self;
|
} = self;
|
||||||
write_vcd_scope(writer, "struct", &name, |writer| {
|
write_vcd_scope(writer, "struct", name, scope, |writer, scope| {
|
||||||
for element in elements {
|
for element in elements {
|
||||||
element.write_trace(writer, arg.reborrow())?;
|
element.write_trace(
|
||||||
|
writer,
|
||||||
|
ArgInType {
|
||||||
|
source_var_type,
|
||||||
|
sink_var_type,
|
||||||
|
duplex_var_type,
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -697,7 +804,13 @@ impl WriteTrace for TraceArray {
|
||||||
|
|
||||||
impl WriteTrace for TraceEnumWithFields {
|
impl WriteTrace for TraceEnumWithFields {
|
||||||
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
fn write_trace<W: io::Write, A: Arg>(self, writer: &mut W, mut arg: A) -> io::Result<()> {
|
||||||
let mut arg = arg.in_type();
|
let ArgInType {
|
||||||
|
source_var_type,
|
||||||
|
sink_var_type,
|
||||||
|
duplex_var_type,
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
} = arg.in_type();
|
||||||
let Self {
|
let Self {
|
||||||
name,
|
name,
|
||||||
discriminant,
|
discriminant,
|
||||||
|
@ -705,10 +818,28 @@ impl WriteTrace for TraceEnumWithFields {
|
||||||
ty: _,
|
ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
} = self;
|
} = self;
|
||||||
write_vcd_scope(writer, "struct", &name, |writer| {
|
write_vcd_scope(writer, "struct", name, scope, |writer, scope| {
|
||||||
discriminant.write_trace(writer, arg.reborrow())?;
|
discriminant.write_trace(
|
||||||
|
writer,
|
||||||
|
ArgInType {
|
||||||
|
source_var_type,
|
||||||
|
sink_var_type,
|
||||||
|
duplex_var_type,
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
for field in non_empty_fields {
|
for field in non_empty_fields {
|
||||||
field.write_trace(writer, arg.reborrow())?;
|
field.write_trace(
|
||||||
|
writer,
|
||||||
|
ArgInType {
|
||||||
|
source_var_type,
|
||||||
|
sink_var_type,
|
||||||
|
duplex_var_type,
|
||||||
|
properties,
|
||||||
|
scope,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -744,6 +875,7 @@ impl<W: io::Write> TraceWriterDecls for VcdWriterDecls<W> {
|
||||||
&mut writer,
|
&mut writer,
|
||||||
ArgModule {
|
ArgModule {
|
||||||
properties: &mut properties,
|
properties: &mut properties,
|
||||||
|
scope: &mut Scope::default(),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
writeln!(writer, "$enddefinitions $end")?;
|
writeln!(writer, "$enddefinitions $end")?;
|
||||||
|
@ -798,9 +930,7 @@ fn write_string_value_change(
|
||||||
value: impl fmt::Display,
|
value: impl fmt::Display,
|
||||||
id: usize,
|
id: usize,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
writer.write_all(b"s")?;
|
write!(writer, "s{} ", Escaped(value))?;
|
||||||
write_escaped(writer, value)?;
|
|
||||||
writer.write_all(b" ")?;
|
|
||||||
write_vcd_id(writer, id)?;
|
write_vcd_id(writer, id)?;
|
||||||
writer.write_all(b"\n")
|
writer.write_all(b"\n")
|
||||||
}
|
}
|
||||||
|
@ -946,3 +1076,49 @@ impl<W: io::Write> fmt::Debug for VcdWriter<W> {
|
||||||
.finish_non_exhaustive()
|
.finish_non_exhaustive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_scope() {
|
||||||
|
let mut scope = Scope::default();
|
||||||
|
assert_eq!(&*scope.new_identifier("foo".intern()).unescaped_name, "foo");
|
||||||
|
assert_eq!(
|
||||||
|
&*scope.new_identifier("foo_0".intern()).unescaped_name,
|
||||||
|
"foo_0"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
&*scope.new_identifier("foo_1".intern()).unescaped_name,
|
||||||
|
"foo_1"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
&*scope.new_identifier("foo_3".intern()).unescaped_name,
|
||||||
|
"foo_3"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
&*scope.new_identifier("foo".intern()).unescaped_name,
|
||||||
|
"foo_2"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
&*scope.new_identifier("foo".intern()).unescaped_name,
|
||||||
|
"foo_4"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
&*scope.new_identifier("foo_0".intern()).unescaped_name,
|
||||||
|
"foo_0_2"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
&*scope.new_identifier("foo_1".intern()).unescaped_name,
|
||||||
|
"foo_1_2"
|
||||||
|
);
|
||||||
|
for i in 5..1000u64 {
|
||||||
|
// verify it actually picks the next available identifier with no skips or duplicates
|
||||||
|
assert_eq!(
|
||||||
|
*scope.new_identifier("foo".intern()).unescaped_name,
|
||||||
|
format!("foo_{i}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1246,3 +1246,200 @@ fn test_memories3() {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[hdl_module(outline_generated)]
|
||||||
|
pub fn duplicate_names() {
|
||||||
|
#[hdl]
|
||||||
|
let w = wire();
|
||||||
|
connect(w, 5u8);
|
||||||
|
#[hdl]
|
||||||
|
let w = wire();
|
||||||
|
connect(w, 6u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_duplicate_names() {
|
||||||
|
let _n = SourceLocation::normalize_files_for_tests();
|
||||||
|
let mut sim = Simulation::new(duplicate_names());
|
||||||
|
let mut writer = RcWriter::default();
|
||||||
|
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
|
||||||
|
sim.advance_time(SimDuration::from_micros(1));
|
||||||
|
sim.flush_traces().unwrap();
|
||||||
|
let vcd = String::from_utf8(writer.take()).unwrap();
|
||||||
|
println!("####### VCD:\n{vcd}\n#######");
|
||||||
|
if vcd != include_str!("sim/expected/duplicate_names.vcd") {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
let sim_debug = format!("{sim:#?}");
|
||||||
|
println!("#######\n{sim_debug}\n#######");
|
||||||
|
if sim_debug != include_str!("sim/expected/duplicate_names.txt") {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl_module(outline_generated)]
|
||||||
|
pub fn array_rw() {
|
||||||
|
#[hdl]
|
||||||
|
let array_in: Array<UInt<8>, 16> = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let array_out: Array<UInt<8>, 16> = m.output();
|
||||||
|
#[hdl]
|
||||||
|
let read_index: UInt<8> = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let read_data: UInt<8> = m.output();
|
||||||
|
#[hdl]
|
||||||
|
let write_index: UInt<8> = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let write_data: UInt<8> = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let write_en: Bool = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let array_wire = wire();
|
||||||
|
connect(array_wire, array_in);
|
||||||
|
connect(array_out, array_wire);
|
||||||
|
#[hdl]
|
||||||
|
if write_en {
|
||||||
|
connect(array_wire[write_index], write_data);
|
||||||
|
}
|
||||||
|
connect(read_data, array_wire[read_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_array_rw() {
|
||||||
|
let _n = SourceLocation::normalize_files_for_tests();
|
||||||
|
let mut sim = Simulation::new(array_rw());
|
||||||
|
let mut writer = RcWriter::default();
|
||||||
|
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
struct State {
|
||||||
|
array_in: [u8; 16],
|
||||||
|
array_out: [u8; 16],
|
||||||
|
read_index: u8,
|
||||||
|
read_data: u8,
|
||||||
|
write_index: u8,
|
||||||
|
write_data: u8,
|
||||||
|
write_en: bool,
|
||||||
|
}
|
||||||
|
let mut states = Vec::new();
|
||||||
|
let array_in = [
|
||||||
|
0xFFu8, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, //
|
||||||
|
0x00u8, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE,
|
||||||
|
];
|
||||||
|
for i in 0..=16 {
|
||||||
|
states.push(State {
|
||||||
|
array_in,
|
||||||
|
array_out: array_in,
|
||||||
|
read_index: i,
|
||||||
|
read_data: array_in.get(i as usize).copied().unwrap_or(0),
|
||||||
|
write_index: 0,
|
||||||
|
write_data: 0,
|
||||||
|
write_en: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for i in 0..=16u8 {
|
||||||
|
let mut array_out = array_in;
|
||||||
|
let write_data = i.wrapping_mul(i);
|
||||||
|
if let Some(v) = array_out.get_mut(i as usize) {
|
||||||
|
*v = write_data;
|
||||||
|
}
|
||||||
|
states.push(State {
|
||||||
|
array_in,
|
||||||
|
array_out,
|
||||||
|
read_index: 0,
|
||||||
|
read_data: array_out[0],
|
||||||
|
write_index: i,
|
||||||
|
write_data,
|
||||||
|
write_en: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (cycle, expected) in states.into_iter().enumerate() {
|
||||||
|
let State {
|
||||||
|
array_in,
|
||||||
|
array_out: _,
|
||||||
|
read_index,
|
||||||
|
read_data: _,
|
||||||
|
write_index,
|
||||||
|
write_data,
|
||||||
|
write_en,
|
||||||
|
} = expected;
|
||||||
|
sim.write(sim.io().array_in, array_in);
|
||||||
|
sim.write(sim.io().read_index, read_index);
|
||||||
|
sim.write(sim.io().write_index, write_index);
|
||||||
|
sim.write(sim.io().write_data, write_data);
|
||||||
|
sim.write(sim.io().write_en, write_en);
|
||||||
|
sim.advance_time(SimDuration::from_micros(1));
|
||||||
|
let array_out = std::array::from_fn(|index| {
|
||||||
|
sim.read_bool_or_int(sim.io().array_out[index])
|
||||||
|
.to_bigint()
|
||||||
|
.try_into()
|
||||||
|
.expect("known to be in range")
|
||||||
|
});
|
||||||
|
let read_data = sim
|
||||||
|
.read_bool_or_int(sim.io().read_data)
|
||||||
|
.to_bigint()
|
||||||
|
.try_into()
|
||||||
|
.expect("known to be in range");
|
||||||
|
let state = State {
|
||||||
|
array_in,
|
||||||
|
array_out,
|
||||||
|
read_index,
|
||||||
|
read_data,
|
||||||
|
write_index,
|
||||||
|
write_data,
|
||||||
|
write_en,
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
state,
|
||||||
|
expected,
|
||||||
|
"vcd:\n{}\ncycle: {cycle}",
|
||||||
|
String::from_utf8(writer.take()).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
sim.flush_traces().unwrap();
|
||||||
|
let vcd = String::from_utf8(writer.take()).unwrap();
|
||||||
|
println!("####### VCD:\n{vcd}\n#######");
|
||||||
|
if vcd != include_str!("sim/expected/array_rw.vcd") {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
let sim_debug = format!("{sim:#?}");
|
||||||
|
println!("#######\n{sim_debug}\n#######");
|
||||||
|
if sim_debug != include_str!("sim/expected/array_rw.txt") {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl_module(outline_generated)]
|
||||||
|
pub fn conditional_assignment_last() {
|
||||||
|
#[hdl]
|
||||||
|
let i: Bool = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let w = wire();
|
||||||
|
connect(w, true);
|
||||||
|
#[hdl]
|
||||||
|
if i {
|
||||||
|
connect(w, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_conditional_assignment_last() {
|
||||||
|
let _n = SourceLocation::normalize_files_for_tests();
|
||||||
|
let mut sim = Simulation::new(conditional_assignment_last());
|
||||||
|
let mut writer = RcWriter::default();
|
||||||
|
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
|
||||||
|
sim.write(sim.io().i, false);
|
||||||
|
sim.advance_time(SimDuration::from_micros(1));
|
||||||
|
sim.write(sim.io().i, true);
|
||||||
|
sim.advance_time(SimDuration::from_micros(1));
|
||||||
|
sim.flush_traces().unwrap();
|
||||||
|
let vcd = String::from_utf8(writer.take()).unwrap();
|
||||||
|
println!("####### VCD:\n{vcd}\n#######");
|
||||||
|
if vcd != include_str!("sim/expected/conditional_assignment_last.vcd") {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
let sim_debug = format!("{sim:#?}");
|
||||||
|
println!("#######\n{sim_debug}\n#######");
|
||||||
|
if sim_debug != include_str!("sim/expected/conditional_assignment_last.txt") {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2859
crates/fayalite/tests/sim/expected/array_rw.txt
Normal file
2859
crates/fayalite/tests/sim/expected/array_rw.txt
Normal file
File diff suppressed because it is too large
Load diff
283
crates/fayalite/tests/sim/expected/array_rw.vcd
Normal file
283
crates/fayalite/tests/sim/expected/array_rw.vcd
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
$timescale 1 ps $end
|
||||||
|
$scope module array_rw $end
|
||||||
|
$scope struct array_in $end
|
||||||
|
$var wire 8 ! \[0] $end
|
||||||
|
$var wire 8 " \[1] $end
|
||||||
|
$var wire 8 # \[2] $end
|
||||||
|
$var wire 8 $ \[3] $end
|
||||||
|
$var wire 8 % \[4] $end
|
||||||
|
$var wire 8 & \[5] $end
|
||||||
|
$var wire 8 ' \[6] $end
|
||||||
|
$var wire 8 ( \[7] $end
|
||||||
|
$var wire 8 ) \[8] $end
|
||||||
|
$var wire 8 * \[9] $end
|
||||||
|
$var wire 8 + \[10] $end
|
||||||
|
$var wire 8 , \[11] $end
|
||||||
|
$var wire 8 - \[12] $end
|
||||||
|
$var wire 8 . \[13] $end
|
||||||
|
$var wire 8 / \[14] $end
|
||||||
|
$var wire 8 0 \[15] $end
|
||||||
|
$upscope $end
|
||||||
|
$scope struct array_out $end
|
||||||
|
$var wire 8 1 \[0] $end
|
||||||
|
$var wire 8 2 \[1] $end
|
||||||
|
$var wire 8 3 \[2] $end
|
||||||
|
$var wire 8 4 \[3] $end
|
||||||
|
$var wire 8 5 \[4] $end
|
||||||
|
$var wire 8 6 \[5] $end
|
||||||
|
$var wire 8 7 \[6] $end
|
||||||
|
$var wire 8 8 \[7] $end
|
||||||
|
$var wire 8 9 \[8] $end
|
||||||
|
$var wire 8 : \[9] $end
|
||||||
|
$var wire 8 ; \[10] $end
|
||||||
|
$var wire 8 < \[11] $end
|
||||||
|
$var wire 8 = \[12] $end
|
||||||
|
$var wire 8 > \[13] $end
|
||||||
|
$var wire 8 ? \[14] $end
|
||||||
|
$var wire 8 @ \[15] $end
|
||||||
|
$upscope $end
|
||||||
|
$var wire 8 A read_index $end
|
||||||
|
$var wire 8 B read_data $end
|
||||||
|
$var wire 8 C write_index $end
|
||||||
|
$var wire 8 D write_data $end
|
||||||
|
$var wire 1 E write_en $end
|
||||||
|
$scope struct array_wire $end
|
||||||
|
$var wire 8 F \[0] $end
|
||||||
|
$var wire 8 G \[1] $end
|
||||||
|
$var wire 8 H \[2] $end
|
||||||
|
$var wire 8 I \[3] $end
|
||||||
|
$var wire 8 J \[4] $end
|
||||||
|
$var wire 8 K \[5] $end
|
||||||
|
$var wire 8 L \[6] $end
|
||||||
|
$var wire 8 M \[7] $end
|
||||||
|
$var wire 8 N \[8] $end
|
||||||
|
$var wire 8 O \[9] $end
|
||||||
|
$var wire 8 P \[10] $end
|
||||||
|
$var wire 8 Q \[11] $end
|
||||||
|
$var wire 8 R \[12] $end
|
||||||
|
$var wire 8 S \[13] $end
|
||||||
|
$var wire 8 T \[14] $end
|
||||||
|
$var wire 8 U \[15] $end
|
||||||
|
$upscope $end
|
||||||
|
$upscope $end
|
||||||
|
$enddefinitions $end
|
||||||
|
$dumpvars
|
||||||
|
b11111111 !
|
||||||
|
b1111111 "
|
||||||
|
b111111 #
|
||||||
|
b11111 $
|
||||||
|
b1111 %
|
||||||
|
b111 &
|
||||||
|
b11 '
|
||||||
|
b1 (
|
||||||
|
b0 )
|
||||||
|
b10000000 *
|
||||||
|
b11000000 +
|
||||||
|
b11100000 ,
|
||||||
|
b11110000 -
|
||||||
|
b11111000 .
|
||||||
|
b11111100 /
|
||||||
|
b11111110 0
|
||||||
|
b11111111 1
|
||||||
|
b1111111 2
|
||||||
|
b111111 3
|
||||||
|
b11111 4
|
||||||
|
b1111 5
|
||||||
|
b111 6
|
||||||
|
b11 7
|
||||||
|
b1 8
|
||||||
|
b0 9
|
||||||
|
b10000000 :
|
||||||
|
b11000000 ;
|
||||||
|
b11100000 <
|
||||||
|
b11110000 =
|
||||||
|
b11111000 >
|
||||||
|
b11111100 ?
|
||||||
|
b11111110 @
|
||||||
|
b0 A
|
||||||
|
b11111111 B
|
||||||
|
b0 C
|
||||||
|
b0 D
|
||||||
|
0E
|
||||||
|
b11111111 F
|
||||||
|
b1111111 G
|
||||||
|
b111111 H
|
||||||
|
b11111 I
|
||||||
|
b1111 J
|
||||||
|
b111 K
|
||||||
|
b11 L
|
||||||
|
b1 M
|
||||||
|
b0 N
|
||||||
|
b10000000 O
|
||||||
|
b11000000 P
|
||||||
|
b11100000 Q
|
||||||
|
b11110000 R
|
||||||
|
b11111000 S
|
||||||
|
b11111100 T
|
||||||
|
b11111110 U
|
||||||
|
$end
|
||||||
|
#1000000
|
||||||
|
b1 A
|
||||||
|
b1111111 B
|
||||||
|
#2000000
|
||||||
|
b10 A
|
||||||
|
b111111 B
|
||||||
|
#3000000
|
||||||
|
b11 A
|
||||||
|
b11111 B
|
||||||
|
#4000000
|
||||||
|
b100 A
|
||||||
|
b1111 B
|
||||||
|
#5000000
|
||||||
|
b101 A
|
||||||
|
b111 B
|
||||||
|
#6000000
|
||||||
|
b110 A
|
||||||
|
b11 B
|
||||||
|
#7000000
|
||||||
|
b111 A
|
||||||
|
b1 B
|
||||||
|
#8000000
|
||||||
|
b1000 A
|
||||||
|
b0 B
|
||||||
|
#9000000
|
||||||
|
b1001 A
|
||||||
|
b10000000 B
|
||||||
|
#10000000
|
||||||
|
b1010 A
|
||||||
|
b11000000 B
|
||||||
|
#11000000
|
||||||
|
b1011 A
|
||||||
|
b11100000 B
|
||||||
|
#12000000
|
||||||
|
b1100 A
|
||||||
|
b11110000 B
|
||||||
|
#13000000
|
||||||
|
b1101 A
|
||||||
|
b11111000 B
|
||||||
|
#14000000
|
||||||
|
b1110 A
|
||||||
|
b11111100 B
|
||||||
|
#15000000
|
||||||
|
b1111 A
|
||||||
|
b11111110 B
|
||||||
|
#16000000
|
||||||
|
b10000 A
|
||||||
|
b0 B
|
||||||
|
#17000000
|
||||||
|
b0 1
|
||||||
|
b0 A
|
||||||
|
1E
|
||||||
|
b0 F
|
||||||
|
#18000000
|
||||||
|
b11111111 1
|
||||||
|
b1 2
|
||||||
|
b11111111 B
|
||||||
|
b1 C
|
||||||
|
b1 D
|
||||||
|
b11111111 F
|
||||||
|
b1 G
|
||||||
|
#19000000
|
||||||
|
b1111111 2
|
||||||
|
b100 3
|
||||||
|
b10 C
|
||||||
|
b100 D
|
||||||
|
b1111111 G
|
||||||
|
b100 H
|
||||||
|
#20000000
|
||||||
|
b111111 3
|
||||||
|
b1001 4
|
||||||
|
b11 C
|
||||||
|
b1001 D
|
||||||
|
b111111 H
|
||||||
|
b1001 I
|
||||||
|
#21000000
|
||||||
|
b11111 4
|
||||||
|
b10000 5
|
||||||
|
b100 C
|
||||||
|
b10000 D
|
||||||
|
b11111 I
|
||||||
|
b10000 J
|
||||||
|
#22000000
|
||||||
|
b1111 5
|
||||||
|
b11001 6
|
||||||
|
b101 C
|
||||||
|
b11001 D
|
||||||
|
b1111 J
|
||||||
|
b11001 K
|
||||||
|
#23000000
|
||||||
|
b111 6
|
||||||
|
b100100 7
|
||||||
|
b110 C
|
||||||
|
b100100 D
|
||||||
|
b111 K
|
||||||
|
b100100 L
|
||||||
|
#24000000
|
||||||
|
b11 7
|
||||||
|
b110001 8
|
||||||
|
b111 C
|
||||||
|
b110001 D
|
||||||
|
b11 L
|
||||||
|
b110001 M
|
||||||
|
#25000000
|
||||||
|
b1 8
|
||||||
|
b1000000 9
|
||||||
|
b1000 C
|
||||||
|
b1000000 D
|
||||||
|
b1 M
|
||||||
|
b1000000 N
|
||||||
|
#26000000
|
||||||
|
b0 9
|
||||||
|
b1010001 :
|
||||||
|
b1001 C
|
||||||
|
b1010001 D
|
||||||
|
b0 N
|
||||||
|
b1010001 O
|
||||||
|
#27000000
|
||||||
|
b10000000 :
|
||||||
|
b1100100 ;
|
||||||
|
b1010 C
|
||||||
|
b1100100 D
|
||||||
|
b10000000 O
|
||||||
|
b1100100 P
|
||||||
|
#28000000
|
||||||
|
b11000000 ;
|
||||||
|
b1111001 <
|
||||||
|
b1011 C
|
||||||
|
b1111001 D
|
||||||
|
b11000000 P
|
||||||
|
b1111001 Q
|
||||||
|
#29000000
|
||||||
|
b11100000 <
|
||||||
|
b10010000 =
|
||||||
|
b1100 C
|
||||||
|
b10010000 D
|
||||||
|
b11100000 Q
|
||||||
|
b10010000 R
|
||||||
|
#30000000
|
||||||
|
b11110000 =
|
||||||
|
b10101001 >
|
||||||
|
b1101 C
|
||||||
|
b10101001 D
|
||||||
|
b11110000 R
|
||||||
|
b10101001 S
|
||||||
|
#31000000
|
||||||
|
b11111000 >
|
||||||
|
b11000100 ?
|
||||||
|
b1110 C
|
||||||
|
b11000100 D
|
||||||
|
b11111000 S
|
||||||
|
b11000100 T
|
||||||
|
#32000000
|
||||||
|
b11111100 ?
|
||||||
|
b11100001 @
|
||||||
|
b1111 C
|
||||||
|
b11100001 D
|
||||||
|
b11111100 T
|
||||||
|
b11100001 U
|
||||||
|
#33000000
|
||||||
|
b11111110 @
|
||||||
|
b10000 C
|
||||||
|
b0 D
|
||||||
|
b11111110 U
|
||||||
|
#34000000
|
|
@ -0,0 +1,189 @@
|
||||||
|
Simulation {
|
||||||
|
state: State {
|
||||||
|
insns: Insns {
|
||||||
|
state_layout: StateLayout {
|
||||||
|
ty: TypeLayout {
|
||||||
|
small_slots: StatePartLayout<SmallSlots> {
|
||||||
|
len: 0,
|
||||||
|
debug_data: [],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
big_slots: StatePartLayout<BigSlots> {
|
||||||
|
len: 4,
|
||||||
|
debug_data: [
|
||||||
|
SlotDebugData {
|
||||||
|
name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::i",
|
||||||
|
ty: Bool,
|
||||||
|
},
|
||||||
|
SlotDebugData {
|
||||||
|
name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::w",
|
||||||
|
ty: Bool,
|
||||||
|
},
|
||||||
|
SlotDebugData {
|
||||||
|
name: "",
|
||||||
|
ty: Bool,
|
||||||
|
},
|
||||||
|
SlotDebugData {
|
||||||
|
name: "",
|
||||||
|
ty: Bool,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
},
|
||||||
|
memories: StatePartLayout<Memories> {
|
||||||
|
len: 0,
|
||||||
|
debug_data: [],
|
||||||
|
layout_data: [],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
},
|
||||||
|
insns: [
|
||||||
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
|
0: Const {
|
||||||
|
dest: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
|
value: 0x0,
|
||||||
|
},
|
||||||
|
1: Const {
|
||||||
|
dest: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool },
|
||||||
|
value: 0x1,
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:4:1
|
||||||
|
2: Copy {
|
||||||
|
dest: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::w", ty: Bool },
|
||||||
|
src: StatePartIndex<BigSlots>(2), // (0x1) SlotDebugData { name: "", ty: Bool },
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:5:1
|
||||||
|
3: BranchIfZero {
|
||||||
|
target: 5,
|
||||||
|
value: StatePartIndex<BigSlots>(0), // (0x1) SlotDebugData { name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::i", ty: Bool },
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:6:1
|
||||||
|
4: Copy {
|
||||||
|
dest: StatePartIndex<BigSlots>(1), // (0x0) SlotDebugData { name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::w", ty: Bool },
|
||||||
|
src: StatePartIndex<BigSlots>(3), // (0x0) SlotDebugData { name: "", ty: Bool },
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
|
5: Return,
|
||||||
|
],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
pc: 5,
|
||||||
|
memory_write_log: [],
|
||||||
|
memories: StatePart {
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
|
small_slots: StatePart {
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
|
big_slots: StatePart {
|
||||||
|
value: [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
io: Instance {
|
||||||
|
name: <simulator>::conditional_assignment_last,
|
||||||
|
instantiated: Module {
|
||||||
|
name: conditional_assignment_last,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uninitialized_inputs: {},
|
||||||
|
io_targets: {
|
||||||
|
Instance {
|
||||||
|
name: <simulator>::conditional_assignment_last,
|
||||||
|
instantiated: Module {
|
||||||
|
name: conditional_assignment_last,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
}.i: CompiledValue {
|
||||||
|
layout: CompiledTypeLayout {
|
||||||
|
ty: Bool,
|
||||||
|
layout: TypeLayout {
|
||||||
|
small_slots: StatePartLayout<SmallSlots> {
|
||||||
|
len: 0,
|
||||||
|
debug_data: [],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
big_slots: StatePartLayout<BigSlots> {
|
||||||
|
len: 1,
|
||||||
|
debug_data: [
|
||||||
|
SlotDebugData {
|
||||||
|
name: "InstantiatedModule(conditional_assignment_last: conditional_assignment_last).conditional_assignment_last::i",
|
||||||
|
ty: Bool,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: Scalar,
|
||||||
|
},
|
||||||
|
range: TypeIndexRange {
|
||||||
|
small_slots: StatePartIndexRange<SmallSlots> { start: 0, len: 0 },
|
||||||
|
big_slots: StatePartIndexRange<BigSlots> { start: 0, len: 1 },
|
||||||
|
},
|
||||||
|
write: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
made_initial_step: true,
|
||||||
|
needs_settle: false,
|
||||||
|
trace_decls: TraceModule {
|
||||||
|
name: "conditional_assignment_last",
|
||||||
|
children: [
|
||||||
|
TraceModuleIO {
|
||||||
|
name: "i",
|
||||||
|
child: TraceBool {
|
||||||
|
location: TraceScalarId(0),
|
||||||
|
name: "i",
|
||||||
|
flow: Source,
|
||||||
|
},
|
||||||
|
ty: Bool,
|
||||||
|
flow: Source,
|
||||||
|
},
|
||||||
|
TraceWire {
|
||||||
|
name: "w",
|
||||||
|
child: TraceBool {
|
||||||
|
location: TraceScalarId(1),
|
||||||
|
name: "w",
|
||||||
|
flow: Duplex,
|
||||||
|
},
|
||||||
|
ty: Bool,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
traces: [
|
||||||
|
SimTrace {
|
||||||
|
id: TraceScalarId(0),
|
||||||
|
kind: BigBool {
|
||||||
|
index: StatePartIndex<BigSlots>(0),
|
||||||
|
},
|
||||||
|
state: 0x1,
|
||||||
|
last_state: 0x0,
|
||||||
|
},
|
||||||
|
SimTrace {
|
||||||
|
id: TraceScalarId(1),
|
||||||
|
kind: BigBool {
|
||||||
|
index: StatePartIndex<BigSlots>(1),
|
||||||
|
},
|
||||||
|
state: 0x0,
|
||||||
|
last_state: 0x1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trace_memories: {},
|
||||||
|
trace_writers: [
|
||||||
|
Running(
|
||||||
|
VcdWriter {
|
||||||
|
finished_init: true,
|
||||||
|
timescale: 1 ps,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
instant: 2 μs,
|
||||||
|
clocks_triggered: [],
|
||||||
|
..
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
$timescale 1 ps $end
|
||||||
|
$scope module conditional_assignment_last $end
|
||||||
|
$var wire 1 ! i $end
|
||||||
|
$var wire 1 " w $end
|
||||||
|
$upscope $end
|
||||||
|
$enddefinitions $end
|
||||||
|
$dumpvars
|
||||||
|
0!
|
||||||
|
1"
|
||||||
|
$end
|
||||||
|
#1000000
|
||||||
|
1!
|
||||||
|
0"
|
||||||
|
#2000000
|
153
crates/fayalite/tests/sim/expected/duplicate_names.txt
Normal file
153
crates/fayalite/tests/sim/expected/duplicate_names.txt
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
Simulation {
|
||||||
|
state: State {
|
||||||
|
insns: Insns {
|
||||||
|
state_layout: StateLayout {
|
||||||
|
ty: TypeLayout {
|
||||||
|
small_slots: StatePartLayout<SmallSlots> {
|
||||||
|
len: 0,
|
||||||
|
debug_data: [],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
big_slots: StatePartLayout<BigSlots> {
|
||||||
|
len: 4,
|
||||||
|
debug_data: [
|
||||||
|
SlotDebugData {
|
||||||
|
name: "InstantiatedModule(duplicate_names: duplicate_names).duplicate_names::w",
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
SlotDebugData {
|
||||||
|
name: "",
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
SlotDebugData {
|
||||||
|
name: "InstantiatedModule(duplicate_names: duplicate_names).duplicate_names::w",
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
SlotDebugData {
|
||||||
|
name: "",
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
},
|
||||||
|
memories: StatePartLayout<Memories> {
|
||||||
|
len: 0,
|
||||||
|
debug_data: [],
|
||||||
|
layout_data: [],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
},
|
||||||
|
insns: [
|
||||||
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
|
0: Const {
|
||||||
|
dest: StatePartIndex<BigSlots>(3), // (0x6) SlotDebugData { name: "", ty: UInt<8> },
|
||||||
|
value: 0x6,
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:5:1
|
||||||
|
1: Copy {
|
||||||
|
dest: StatePartIndex<BigSlots>(2), // (0x6) SlotDebugData { name: "InstantiatedModule(duplicate_names: duplicate_names).duplicate_names::w", ty: UInt<8> },
|
||||||
|
src: StatePartIndex<BigSlots>(3), // (0x6) SlotDebugData { name: "", ty: UInt<8> },
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
|
2: Const {
|
||||||
|
dest: StatePartIndex<BigSlots>(1), // (0x5) SlotDebugData { name: "", ty: UInt<8> },
|
||||||
|
value: 0x5,
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:3:1
|
||||||
|
3: Copy {
|
||||||
|
dest: StatePartIndex<BigSlots>(0), // (0x5) SlotDebugData { name: "InstantiatedModule(duplicate_names: duplicate_names).duplicate_names::w", ty: UInt<8> },
|
||||||
|
src: StatePartIndex<BigSlots>(1), // (0x5) SlotDebugData { name: "", ty: UInt<8> },
|
||||||
|
},
|
||||||
|
// at: module-XXXXXXXXXX.rs:1:1
|
||||||
|
4: Return,
|
||||||
|
],
|
||||||
|
..
|
||||||
|
},
|
||||||
|
pc: 4,
|
||||||
|
memory_write_log: [],
|
||||||
|
memories: StatePart {
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
|
small_slots: StatePart {
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
|
big_slots: StatePart {
|
||||||
|
value: [
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
6,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
io: Instance {
|
||||||
|
name: <simulator>::duplicate_names,
|
||||||
|
instantiated: Module {
|
||||||
|
name: duplicate_names,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uninitialized_inputs: {},
|
||||||
|
io_targets: {},
|
||||||
|
made_initial_step: true,
|
||||||
|
needs_settle: false,
|
||||||
|
trace_decls: TraceModule {
|
||||||
|
name: "duplicate_names",
|
||||||
|
children: [
|
||||||
|
TraceWire {
|
||||||
|
name: "w",
|
||||||
|
child: TraceUInt {
|
||||||
|
location: TraceScalarId(0),
|
||||||
|
name: "w",
|
||||||
|
ty: UInt<8>,
|
||||||
|
flow: Duplex,
|
||||||
|
},
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
TraceWire {
|
||||||
|
name: "w",
|
||||||
|
child: TraceUInt {
|
||||||
|
location: TraceScalarId(1),
|
||||||
|
name: "w",
|
||||||
|
ty: UInt<8>,
|
||||||
|
flow: Duplex,
|
||||||
|
},
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
traces: [
|
||||||
|
SimTrace {
|
||||||
|
id: TraceScalarId(0),
|
||||||
|
kind: BigUInt {
|
||||||
|
index: StatePartIndex<BigSlots>(0),
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
state: 0x05,
|
||||||
|
last_state: 0x05,
|
||||||
|
},
|
||||||
|
SimTrace {
|
||||||
|
id: TraceScalarId(1),
|
||||||
|
kind: BigUInt {
|
||||||
|
index: StatePartIndex<BigSlots>(2),
|
||||||
|
ty: UInt<8>,
|
||||||
|
},
|
||||||
|
state: 0x06,
|
||||||
|
last_state: 0x06,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
trace_memories: {},
|
||||||
|
trace_writers: [
|
||||||
|
Running(
|
||||||
|
VcdWriter {
|
||||||
|
finished_init: true,
|
||||||
|
timescale: 1 ps,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
instant: 1 μs,
|
||||||
|
clocks_triggered: [],
|
||||||
|
..
|
||||||
|
}
|
11
crates/fayalite/tests/sim/expected/duplicate_names.vcd
Normal file
11
crates/fayalite/tests/sim/expected/duplicate_names.vcd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
$timescale 1 ps $end
|
||||||
|
$scope module duplicate_names $end
|
||||||
|
$var wire 8 ! w $end
|
||||||
|
$var wire 8 " w_2 $end
|
||||||
|
$upscope $end
|
||||||
|
$enddefinitions $end
|
||||||
|
$dumpvars
|
||||||
|
b101 !
|
||||||
|
b110 "
|
||||||
|
$end
|
||||||
|
#1000000
|
|
@ -24,97 +24,97 @@ $upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$scope struct contents $end
|
$scope struct contents $end
|
||||||
$scope struct [0] $end
|
$scope struct \[0] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 9 \0 $end
|
$var reg 8 9 \0 $end
|
||||||
$var reg 8 I \1 $end
|
$var reg 8 I \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [1] $end
|
$scope struct \[1] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 : \0 $end
|
$var reg 8 : \0 $end
|
||||||
$var reg 8 J \1 $end
|
$var reg 8 J \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [2] $end
|
$scope struct \[2] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ; \0 $end
|
$var reg 8 ; \0 $end
|
||||||
$var reg 8 K \1 $end
|
$var reg 8 K \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [3] $end
|
$scope struct \[3] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 < \0 $end
|
$var reg 8 < \0 $end
|
||||||
$var reg 8 L \1 $end
|
$var reg 8 L \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [4] $end
|
$scope struct \[4] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 = \0 $end
|
$var reg 8 = \0 $end
|
||||||
$var reg 8 M \1 $end
|
$var reg 8 M \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [5] $end
|
$scope struct \[5] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 > \0 $end
|
$var reg 8 > \0 $end
|
||||||
$var reg 8 N \1 $end
|
$var reg 8 N \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [6] $end
|
$scope struct \[6] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ? \0 $end
|
$var reg 8 ? \0 $end
|
||||||
$var reg 8 O \1 $end
|
$var reg 8 O \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [7] $end
|
$scope struct \[7] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 @ \0 $end
|
$var reg 8 @ \0 $end
|
||||||
$var reg 8 P \1 $end
|
$var reg 8 P \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [8] $end
|
$scope struct \[8] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 A \0 $end
|
$var reg 8 A \0 $end
|
||||||
$var reg 8 Q \1 $end
|
$var reg 8 Q \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [9] $end
|
$scope struct \[9] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 B \0 $end
|
$var reg 8 B \0 $end
|
||||||
$var reg 8 R \1 $end
|
$var reg 8 R \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [10] $end
|
$scope struct \[10] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 C \0 $end
|
$var reg 8 C \0 $end
|
||||||
$var reg 8 S \1 $end
|
$var reg 8 S \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [11] $end
|
$scope struct \[11] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 D \0 $end
|
$var reg 8 D \0 $end
|
||||||
$var reg 8 T \1 $end
|
$var reg 8 T \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [12] $end
|
$scope struct \[12] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 E \0 $end
|
$var reg 8 E \0 $end
|
||||||
$var reg 8 U \1 $end
|
$var reg 8 U \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [13] $end
|
$scope struct \[13] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 F \0 $end
|
$var reg 8 F \0 $end
|
||||||
$var reg 8 V \1 $end
|
$var reg 8 V \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [14] $end
|
$scope struct \[14] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 G \0 $end
|
$var reg 8 G \0 $end
|
||||||
$var reg 8 W \1 $end
|
$var reg 8 W \1 $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [15] $end
|
$scope struct \[15] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 H \0 $end
|
$var reg 8 H \0 $end
|
||||||
$var reg 8 X \1 $end
|
$var reg 8 X \1 $end
|
||||||
|
|
|
@ -11,31 +11,31 @@ $var wire 1 ' wmask $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$scope struct contents $end
|
$scope struct contents $end
|
||||||
$scope struct [0] $end
|
$scope struct \[0] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 1 \$tag $end
|
$var string 1 1 \$tag $end
|
||||||
$var reg 1 6 HdlSome $end
|
$var reg 1 6 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [1] $end
|
$scope struct \[1] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 2 \$tag $end
|
$var string 1 2 \$tag $end
|
||||||
$var reg 1 7 HdlSome $end
|
$var reg 1 7 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [2] $end
|
$scope struct \[2] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 3 \$tag $end
|
$var string 1 3 \$tag $end
|
||||||
$var reg 1 8 HdlSome $end
|
$var reg 1 8 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [3] $end
|
$scope struct \[3] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 4 \$tag $end
|
$var string 1 4 \$tag $end
|
||||||
$var reg 1 9 HdlSome $end
|
$var reg 1 9 HdlSome $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [4] $end
|
$scope struct \[4] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var string 1 5 \$tag $end
|
$var string 1 5 \$tag $end
|
||||||
$var reg 1 : HdlSome $end
|
$var reg 1 : HdlSome $end
|
||||||
|
|
|
@ -42,7 +42,7 @@ $upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$scope struct contents $end
|
$scope struct contents $end
|
||||||
$scope struct [0] $end
|
$scope struct \[0] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ] \[0] $end
|
$var reg 8 ] \[0] $end
|
||||||
$var reg 8 e \[1] $end
|
$var reg 8 e \[1] $end
|
||||||
|
@ -54,7 +54,7 @@ $var reg 8 /" \[6] $end
|
||||||
$var reg 8 7" \[7] $end
|
$var reg 8 7" \[7] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [1] $end
|
$scope struct \[1] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ^ \[0] $end
|
$var reg 8 ^ \[0] $end
|
||||||
$var reg 8 f \[1] $end
|
$var reg 8 f \[1] $end
|
||||||
|
@ -66,7 +66,7 @@ $var reg 8 0" \[6] $end
|
||||||
$var reg 8 8" \[7] $end
|
$var reg 8 8" \[7] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [2] $end
|
$scope struct \[2] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 _ \[0] $end
|
$var reg 8 _ \[0] $end
|
||||||
$var reg 8 g \[1] $end
|
$var reg 8 g \[1] $end
|
||||||
|
@ -78,7 +78,7 @@ $var reg 8 1" \[6] $end
|
||||||
$var reg 8 9" \[7] $end
|
$var reg 8 9" \[7] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [3] $end
|
$scope struct \[3] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 ` \[0] $end
|
$var reg 8 ` \[0] $end
|
||||||
$var reg 8 h \[1] $end
|
$var reg 8 h \[1] $end
|
||||||
|
@ -90,7 +90,7 @@ $var reg 8 2" \[6] $end
|
||||||
$var reg 8 :" \[7] $end
|
$var reg 8 :" \[7] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [4] $end
|
$scope struct \[4] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 a \[0] $end
|
$var reg 8 a \[0] $end
|
||||||
$var reg 8 i \[1] $end
|
$var reg 8 i \[1] $end
|
||||||
|
@ -102,7 +102,7 @@ $var reg 8 3" \[6] $end
|
||||||
$var reg 8 ;" \[7] $end
|
$var reg 8 ;" \[7] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [5] $end
|
$scope struct \[5] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 b \[0] $end
|
$var reg 8 b \[0] $end
|
||||||
$var reg 8 j \[1] $end
|
$var reg 8 j \[1] $end
|
||||||
|
@ -114,7 +114,7 @@ $var reg 8 4" \[6] $end
|
||||||
$var reg 8 <" \[7] $end
|
$var reg 8 <" \[7] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [6] $end
|
$scope struct \[6] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 c \[0] $end
|
$var reg 8 c \[0] $end
|
||||||
$var reg 8 k \[1] $end
|
$var reg 8 k \[1] $end
|
||||||
|
@ -126,7 +126,7 @@ $var reg 8 5" \[6] $end
|
||||||
$var reg 8 =" \[7] $end
|
$var reg 8 =" \[7] $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$upscope $end
|
$upscope $end
|
||||||
$scope struct [7] $end
|
$scope struct \[7] $end
|
||||||
$scope struct mem $end
|
$scope struct mem $end
|
||||||
$var reg 8 d \[0] $end
|
$var reg 8 d \[0] $end
|
||||||
$var reg 8 l \[1] $end
|
$var reg 8 l \[1] $end
|
||||||
|
|
Loading…
Reference in a new issue