From 2e7d685dc7571f4411c25aec7b78ddd7f8e8c04a Mon Sep 17 00:00:00 2001 From: Cesar Strauss Date: Sun, 8 Dec 2024 15:25:21 -0300 Subject: [PATCH 01/10] add module exercising formal verification of memories --- crates/fayalite/tests/formal.rs | 170 +++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 4 deletions(-) diff --git a/crates/fayalite/tests/formal.rs b/crates/fayalite/tests/formal.rs index 46b8292..65264dc 100644 --- a/crates/fayalite/tests/formal.rs +++ b/crates/fayalite/tests/formal.rs @@ -7,12 +7,13 @@ use fayalite::{ clock::{Clock, ClockDomain}, expr::{CastTo, HdlPartialEq}, firrtl::ExportOptions, - formal::{any_seq, formal_reset, hdl_assert, hdl_assume}, - hdl_module, - int::{Bool, UInt}, - module::{connect, connect_any, reg_builder, wire}, + formal::{any_const, any_seq, formal_reset, hdl_assert, hdl_assume}, + hdl, hdl_module, + int::{Bool, DynSize, Size, UInt, UIntType}, + module::{connect, connect_any, instance, memory, reg_builder, wire}, reset::ToReset, testing::assert_formal, + ty::StaticType, }; /// Test hidden state @@ -131,3 +132,164 @@ mod hidden_state { ); } } + +/// Formal verification of designs containing memories +/// +/// There is a trick for memories, described in the [Zipcpu blog]. +/// First, select a fixed but arbitrary memory address, monitoring all reads +/// and writes made to it. Then, assert that anything read from that location +/// matches the last stored value. +/// +/// A difficulty for induction is that the memory represents [hidden_state]. A +/// solution is to include an additional read port to the memory and assert +/// that the memory location effectively contains the last stored value. +/// This additional debug port is present only to assist the proof and is +/// unused (optimized out) in actual use. +/// +/// [Zipcpu blog]: +mod memory { + use super::*; + + /// Test a simple 8-bit SRAM model + #[test] + fn test_sram() { + #[hdl] + struct WritePort { + addr: UIntType, + data: UInt<8>, + en: Bool, + } + #[hdl] + struct ReadPort { + addr: UIntType, + #[hdl(flip)] + data: UInt<8>, + } + /// This debug port is only meant to assist the proof. + /// For normal use in a design, a wrapper could be provided, + /// omitting this port. + /// The implementation is forbidden to use any information + /// provided on this port in its internal workings. + #[hdl] + struct DebugPort { + selected: UIntType, + stored: UInt<8>, + wrote: Bool, + } + /// simple 1R1W SRAM model (one asynchronous read port and one + /// independent write port) with `n`-bit address width + #[hdl_module] + fn example_sram(n: usize) { + #[hdl] + let wr: WritePort = m.input(WritePort[n]); + #[hdl] + let rd: ReadPort = m.input(ReadPort[n]); + #[hdl] + let cd: ClockDomain = m.input(); + + // declare and connect the backing memory + #[hdl] + let mut mem = memory(); + mem.depth(1 << n); + let read_port = mem.new_read_port(); + let write_port = mem.new_write_port(); + connect(write_port.clk, cd.clk); + connect(write_port.addr, wr.addr); + connect(write_port.en, wr.en); + connect(write_port.data, wr.data); + connect(write_port.mask, true); + connect(read_port.clk, cd.clk); + connect(read_port.addr, rd.addr); + connect(read_port.en, true); + connect(rd.data, read_port.data); + + // To assist with induction, ensure that the chosen memory location + // really contains, always, the last value written to it. + #[hdl] + let dbg: DebugPort = m.input(DebugPort[n]); + let debug_port = mem.new_read_port(); + connect(debug_port.en, true); + connect(debug_port.clk, cd.clk); + connect(debug_port.addr, dbg.selected); + #[hdl] + if dbg.wrote { + hdl_assert(cd.clk, debug_port.data.cmp_eq(dbg.stored), ""); + // Try commenting out the assert above, induction will fail. + // Opening the trace, it can be seen that the memory contents + // and the stored value don't match, which is an unreachable + // state. By asserting the above, it will become invalid + // as well, so induction will skip this kind of situation. + } + } + + /// formal verification of the SRAM module, parametrized by the + /// address bit-width + #[hdl_module] + fn test_module(n: usize) { + #[hdl] + let clk: Clock = m.input(); + let cd = #[hdl] + ClockDomain { + clk, + rst: formal_reset().to_reset(), + }; + + // instantiate the SRAM model, connecting its inputs to + // a random sequence + #[hdl] + let rd: ReadPort = wire(ReadPort[n]); + connect(rd.addr, any_seq(UInt[n])); + #[hdl] + let wr: WritePort = wire(WritePort[n]); + connect(wr.addr, any_seq(UInt[n])); + connect(wr.data, any_seq(UInt::<8>::TYPE)); + connect(wr.en, any_seq(Bool)); + #[hdl] + let dut = instance(example_sram(n)); + connect(dut.cd, cd); + connect(dut.rd, rd); + connect(dut.wr, wr); + + // select a fixed but arbitrary test address + #[hdl] + let selected = wire(UInt[n]); + connect(selected, any_const(UInt[n])); + // store the last value written to that address + #[hdl] + let stored: UInt<8> = reg_builder().clock_domain(cd).reset(0u8); + // since memories are not initialized, track whether we wrote to the + // memory at least once + #[hdl] + let wrote: Bool = reg_builder().clock_domain(cd).reset(false); + // on a write, capture the last written value + #[hdl] + if wr.en & wr.addr.cmp_eq(selected) { + connect(stored, wr.data); + connect(wrote, true); + } + // on a read, assert that the read value is the same which was stored + #[hdl] + if rd.addr.cmp_eq(selected) & wrote { + hdl_assert(clk, rd.data.cmp_eq(stored), ""); + } + + // to assist induction, pass our state to the underlying instance + let dbg = #[hdl] + DebugPort { + selected, + stored, + wrote, + }; + connect(dut.dbg, dbg); + } + + assert_formal( + "sram", + test_module(8), + FormalMode::Prove, + 2, + None, + ExportOptions::default(), + ); + } +} From c756aeec704e3abcb54b023b6f215d25338701ca Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 12 Dec 2024 20:50:41 -0800 Subject: [PATCH 02/10] tests/sim: add test for memory rw port --- crates/fayalite/tests/sim.rs | 273 +++ .../fayalite/tests/sim/expected/memories2.txt | 1694 +++++++++++++++++ .../fayalite/tests/sim/expected/memories2.vcd | 363 ++++ 3 files changed, 2330 insertions(+) create mode 100644 crates/fayalite/tests/sim/expected/memories2.txt create mode 100644 crates/fayalite/tests/sim/expected/memories2.vcd diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index 2b8f276..3fc643c 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -694,4 +694,277 @@ fn test_memories() { } } +#[hdl_module(outline_generated)] +pub fn memories2() { + #[hdl] + let rw: fayalite::memory::ReadWriteStruct, ConstUsize<3>> = m.input(); + #[hdl] + let mut mem = memory_with_init([HdlSome(true); 5]); + mem.read_latency(1); + mem.write_latency(NonZeroUsize::new(1).unwrap()); + mem.read_under_write(ReadUnderWrite::New); + let rw_port = mem.new_rw_port(); + connect_any(rw_port.addr, rw.addr); + connect(rw_port.en, rw.en); + connect(rw_port.clk, rw.clk); + connect_any(rw.rdata, rw_port.rdata.cast_to_bits()); + connect(rw_port.wmode, rw.wmode); + connect(rw_port.wdata, HdlNone()); + #[hdl] + if rw.wdata[0] { + connect(rw_port.wdata, HdlSome(rw.wdata[1])); + } + connect(rw_port.wmask, rw.wmask); +} + +#[hdl] +#[test] +fn test_memories2() { + let _n = SourceLocation::normalize_files_for_tests(); + let mut sim = Simulation::new(memories2()); + let mut writer = RcWriter::default(); + sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); + sim.write_clock(sim.io().rw.clk, false); + #[derive(Debug, PartialEq, Eq)] + struct IO { + addr: u8, + en: bool, + rdata: u8, + wmode: bool, + wdata: u8, + wmask: bool, + } + let io_cycles = [ + IO { + addr: 0, + en: false, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 0, + en: true, + rdata: 0x3, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 0, + en: false, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 0, + en: true, + rdata: 0, + wmode: true, + wdata: 0, + wmask: true, + }, + IO { + addr: 0, + en: true, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 0, + en: true, + rdata: 0, + wmode: true, + wdata: 3, + wmask: false, + }, + IO { + addr: 1, + en: true, + rdata: 0, + wmode: true, + wdata: 1, + wmask: true, + }, + IO { + addr: 2, + en: true, + rdata: 0, + wmode: true, + wdata: 2, + wmask: true, + }, + IO { + addr: 3, + en: true, + rdata: 0, + wmode: true, + wdata: 3, + wmask: true, + }, + IO { + addr: 4, + en: true, + rdata: 0, + wmode: true, + wdata: 2, + wmask: true, + }, + IO { + addr: 5, + en: true, + rdata: 0, + wmode: true, + wdata: 1, + wmask: true, + }, + IO { + addr: 6, + en: true, + rdata: 0, + wmode: true, + wdata: 1, + wmask: true, + }, + IO { + addr: 7, + en: true, + rdata: 0, + wmode: true, + wdata: 1, + wmask: true, + }, + IO { + addr: 7, + en: true, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 6, + en: true, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 5, + en: true, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 4, + en: true, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 3, + en: true, + rdata: 3, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 2, + en: true, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 0, + en: true, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 1, + en: true, + rdata: 1, + wmode: false, + wdata: 0, + wmask: false, + }, + IO { + addr: 0, + en: false, + rdata: 0, + wmode: false, + wdata: 0, + wmask: false, + }, + ]; + for ( + cycle, + expected @ IO { + addr, + en, + rdata: _, + wmode, + wdata, + wmask, + }, + ) in io_cycles.into_iter().enumerate() + { + sim.write_bool_or_int(sim.io().rw.addr, addr.cast_to_static()); + sim.write_bool(sim.io().rw.en, en); + sim.write_bool(sim.io().rw.wmode, wmode); + sim.write_bool_or_int(sim.io().rw.wdata, wdata.cast_to_static()); + sim.write_bool(sim.io().rw.wmask, wmask); + sim.advance_time(SimDuration::from_nanos(250)); + sim.write_clock(sim.io().rw.clk, true); + sim.advance_time(SimDuration::from_nanos(250)); + let io = IO { + addr, + en, + rdata: sim + .read_bool_or_int(sim.io().rw.rdata) + .to_bigint() + .try_into() + .expect("known to be in range"), + wmode, + wdata, + wmask, + }; + assert_eq!( + expected, + io, + "cycle: {cycle}\nvcd:\n{}", + String::from_utf8(writer.take()).unwrap(), + ); + sim.advance_time(SimDuration::from_nanos(250)); + sim.write_clock(sim.io().rw.clk, false); + sim.advance_time(SimDuration::from_nanos(250)); + } + sim.flush_traces().unwrap(); + let vcd = String::from_utf8(writer.take()).unwrap(); + println!("####### VCD:\n{vcd}\n#######"); + if vcd != include_str!("sim/expected/memories2.vcd") { + panic!(); + } + let sim_debug = format!("{sim:#?}"); + println!("#######\n{sim_debug}\n#######"); + if sim_debug != include_str!("sim/expected/memories2.txt") { + panic!(); + } +} + // TODO: add more tests for memories diff --git a/crates/fayalite/tests/sim/expected/memories2.txt b/crates/fayalite/tests/sim/expected/memories2.txt new file mode 100644 index 0000000..5d90815 --- /dev/null +++ b/crates/fayalite/tests/sim/expected/memories2.txt @@ -0,0 +1,1694 @@ +Simulation { + state: State { + insns: Insns { + state_layout: StateLayout { + ty: TypeLayout { + small_slots: StatePartLayout { + len: 11, + debug_data: [ + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome, + }, + }, + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome, + }, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + big_slots: StatePartLayout { + len: 36, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.rdata", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wmode", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wdata", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wmask", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.rdata", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wmode", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wdata", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wmask", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: ".0", + ty: UInt<1>, + }, + SlotDebugData { + name: ".1", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + }, + ], + .. + }, + }, + memories: StatePartLayout { + len: 1, + debug_data: [ + (), + ], + layout_data: [ + MemoryData { + array_type: Array, + data: [ + // len = 0x5 + [0x0]: 0x3, + [0x1]: 0x3, + [0x2]: 0x3, + [0x3]: 0x3, + [0x4]: 0x3, + ], + }, + ], + .. + }, + }, + insns: [ + // at: module-XXXXXXXXXX.rs:13:1 + 0: Copy { + dest: StatePartIndex(13), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wmask", ty: Bool }, + src: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.wmask", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 1: SliceInt { + dest: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(5), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.wdata", ty: UInt<2> }, + start: 1, + len: 1, + }, + 2: Copy { + dest: StatePartIndex(30), // (0x0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + }, + 3: Const { + dest: StatePartIndex(28), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + value: 0x1, + }, + 4: Copy { + dest: StatePartIndex(26), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(28), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 5: Copy { + dest: StatePartIndex(27), // (0x0) SlotDebugData { name: ".1", ty: Bool }, + src: StatePartIndex(30), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + 6: Copy { + dest: StatePartIndex(31), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(27), // (0x0) SlotDebugData { name: ".1", ty: Bool }, + }, + 7: Shl { + dest: StatePartIndex(32), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(31), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + rhs: 1, + }, + 8: Or { + dest: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(26), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + rhs: StatePartIndex(32), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + }, + 9: CastToUInt { + dest: StatePartIndex(34), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + dest_width: 2, + }, + 10: Copy { + dest: StatePartIndex(35), // (0x1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bool)} }, + src: StatePartIndex(34), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + }, + 11: SliceInt { + dest: StatePartIndex(24), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(5), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.wdata", ty: UInt<2> }, + start: 0, + len: 1, + }, + 12: Copy { + dest: StatePartIndex(25), // (0x0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(24), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + }, + 13: Const { + dest: StatePartIndex(22), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + value: 0x0, + }, + 14: Copy { + dest: StatePartIndex(23), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bool)} }, + src: StatePartIndex(22), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + }, + // at: module-XXXXXXXXXX.rs:10:1 + 15: Copy { + dest: StatePartIndex(12), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + src: StatePartIndex(23), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bool)} }, + }, + // at: module-XXXXXXXXXX.rs:11:1 + 16: BranchIfZero { + target: 18, + value: StatePartIndex(25), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:12:1 + 17: Copy { + dest: StatePartIndex(12), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + src: StatePartIndex(35), // (0x1) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bool)} }, + }, + // at: module-XXXXXXXXXX.rs:9:1 + 18: Copy { + dest: StatePartIndex(11), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wmode", ty: Bool }, + src: StatePartIndex(4), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.wmode", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:7:1 + 19: Copy { + dest: StatePartIndex(9), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.clk", ty: Clock }, + src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.clk", ty: Clock }, + }, + // at: module-XXXXXXXXXX.rs:6:1 + 20: Copy { + dest: StatePartIndex(8), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.en", ty: Bool }, + src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.en", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:5:1 + 21: Copy { + dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.addr", ty: UInt<3> }, + src: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.addr", ty: UInt<3> }, + }, + // at: module-XXXXXXXXXX.rs:3:1 + 22: BranchIfSmallZero { + target: 26, + value: StatePartIndex(9), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 23: BranchIfSmallNonZero { + target: 26, + value: StatePartIndex(10), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 24: MemoryReadUInt { + dest: StatePartIndex(10), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.rdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, + // data: [ + // // len = 0x5 + // [0x0]: 0x0, + // [0x1]: 0x1, + // [0x2]: 0x0, + // [0x3]: 0x3, + // [0x4]: 0x0, + // ], + // }) (), + addr: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 2, + start: 0, + width: 2, + }, + 25: Branch { + target: 27, + }, + 26: Const { + dest: StatePartIndex(10), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.rdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + value: 0x0, + }, + 27: IsNonZeroDestIsSmall { + dest: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(11), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wmode", ty: Bool }, + }, + 28: CastBigToArrayIndex { + dest: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.addr", ty: UInt<3> }, + }, + 29: IsNonZeroDestIsSmall { + dest: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(8), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.en", ty: Bool }, + }, + 30: IsNonZeroDestIsSmall { + dest: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(9), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.clk", ty: Clock }, + }, + 31: AndSmall { + dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + rhs: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 32: Copy { + dest: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(12), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + }, + 33: SliceInt { + dest: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + start: 1, + len: 1, + }, + 34: Copy { + dest: StatePartIndex(19), // (0x0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + }, + // at: module-XXXXXXXXXX.rs:4:1 + 35: AndBigWithSmallImmediate { + dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} }, + lhs: StatePartIndex(12), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + rhs: 0x1, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 36: Copy { + dest: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(10), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.rdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + }, + 37: SliceInt { + dest: StatePartIndex(15), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + start: 1, + len: 1, + }, + 38: Copy { + dest: StatePartIndex(16), // (0x0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(15), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + }, + // at: module-XXXXXXXXXX.rs:8:1 + 39: Copy { + dest: StatePartIndex(3), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::rw.rdata", ty: UInt<2> }, + src: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + }, + // at: module-XXXXXXXXXX.rs:4:1 + 40: AndBigWithSmallImmediate { + dest: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} }, + lhs: StatePartIndex(10), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.rdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + rhs: 0x1, + }, + // at: module-XXXXXXXXXX.rs:3:1 + 41: BranchIfSmallZero { + target: 51, + value: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 42: CopySmall { + dest: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + }, + 43: CopySmall { + dest: StatePartIndex(9), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(5), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 44: Copy { + dest: StatePartIndex(20), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bool)} }, + src: StatePartIndex(12), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wdata", ty: Enum {HdlNone, HdlSome(Bool)} }, + }, + 45: Copy { + dest: StatePartIndex(21), // (0x0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(13), // (0x0) SlotDebugData { name: "InstantiatedModule(memories2: memories2).memories2::mem::rw0.wmask", ty: Bool }, + }, + 46: CopySmall { + dest: StatePartIndex(10), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 47: BranchIfSmallZero { + target: 51, + value: StatePartIndex(9), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 48: BranchIfSmallZero { + target: 51, + value: StatePartIndex(10), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 49: BranchIfZero { + target: 51, + value: StatePartIndex(21), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + 50: MemoryWriteUInt { + value: StatePartIndex(20), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bool)} }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, + // data: [ + // // len = 0x5 + // [0x0]: 0x0, + // [0x1]: 0x1, + // [0x2]: 0x0, + // [0x3]: 0x3, + // [0x4]: 0x0, + // ], + // }) (), + addr: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 2, + start: 0, + width: 2, + }, + 51: XorSmallImmediate { + dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + rhs: 0x1, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 52: Return, + ], + .. + }, + pc: 52, + memory_write_log: [], + memories: StatePart { + value: [ + MemoryData { + array_type: Array, + data: [ + // len = 0x5 + [0x0]: 0x0, + [0x1]: 0x1, + [0x2]: 0x0, + [0x3]: 0x3, + [0x4]: 0x0, + ], + }, + ], + }, + small_slots: StatePart { + value: [ + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + }, + big_slots: StatePart { + value: [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + ], + }, + }, + io: Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }, + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: UInt<2>, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: UInt<2>, + /* offset = 10 */ + wmask: Bool, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 7, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.rdata", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wmode", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wdata", + ty: UInt<2>, + }, + SlotDebugData { + name: "InstantiatedModule(memories2: memories2).memories2::rw.wmask", + ty: Bool, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(4), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(5), + }, + ty: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(6), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 7 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.rdata: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.wdata: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<2>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<2>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.wmask: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 6, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories2, + instantiated: Module { + name: memories2, + .. + }, + }.rw.wmode: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + }, + write: None, + }, + }, + made_initial_step: true, + needs_settle: false, + trace_decls: TraceModule { + name: "memories2", + children: [ + TraceModuleIO { + name: "rw", + child: TraceBundle { + name: "rw", + fields: [ + TraceUInt { + location: TraceScalarId(0), + name: "addr", + ty: UInt<3>, + flow: Source, + }, + TraceBool { + location: TraceScalarId(1), + name: "en", + flow: Source, + }, + TraceClock { + location: TraceScalarId(2), + name: "clk", + flow: Source, + }, + TraceUInt { + location: TraceScalarId(3), + name: "rdata", + ty: UInt<2>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(4), + name: "wmode", + flow: Source, + }, + TraceUInt { + location: TraceScalarId(5), + name: "wdata", + ty: UInt<2>, + flow: Source, + }, + TraceBool { + location: TraceScalarId(6), + name: "wmask", + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: UInt<2>, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: UInt<2>, + /* offset = 10 */ + wmask: Bool, + }, + flow: Source, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: UInt<2>, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: UInt<2>, + /* offset = 10 */ + wmask: Bool, + }, + flow: Source, + }, + TraceMem { + id: TraceMemoryId(0), + name: "mem", + stride: 2, + element_type: TraceEnumWithFields { + name: "mem", + discriminant: TraceEnumDiscriminant { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 5, + stride: 2, + start: 0, + len: 1, + }, + name: "$tag", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Duplex, + }, + non_empty_fields: [ + TraceBool { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 5, + stride: 2, + start: 1, + len: 1, + }, + name: "HdlSome", + flow: Duplex, + }, + ], + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Duplex, + }, + ports: [ + TraceMemPort { + name: "rw0", + bundle: TraceBundle { + name: "rw0", + fields: [ + TraceUInt { + location: TraceScalarId(7), + name: "addr", + ty: UInt<3>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(8), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(9), + name: "clk", + flow: Sink, + }, + TraceEnumWithFields { + name: "rdata", + discriminant: TraceEnumDiscriminant { + location: TraceScalarId(10), + name: "$tag", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Source, + }, + non_empty_fields: [ + TraceBool { + location: TraceScalarId(11), + name: "HdlSome", + flow: Source, + }, + ], + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Source, + }, + TraceBool { + location: TraceScalarId(12), + name: "wmode", + flow: Sink, + }, + TraceEnumWithFields { + name: "wdata", + discriminant: TraceEnumDiscriminant { + location: TraceScalarId(13), + name: "$tag", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Sink, + }, + non_empty_fields: [ + TraceBool { + location: TraceScalarId(14), + name: "HdlSome", + flow: Source, + }, + ], + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(15), + name: "wmask", + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 10 */ + wmask: Bool, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 10 */ + wmask: Bool, + }, + }, + ], + array_type: Array, + }, + ], + }, + traces: [ + SimTrace { + id: TraceScalarId(0), + kind: BigUInt { + index: StatePartIndex(0), + ty: UInt<3>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(1), + kind: BigBool { + index: StatePartIndex(1), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(2), + kind: BigClock { + index: StatePartIndex(2), + }, + state: 0x0, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(3), + kind: BigUInt { + index: StatePartIndex(3), + ty: UInt<2>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(4), + kind: BigBool { + index: StatePartIndex(4), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(5), + kind: BigUInt { + index: StatePartIndex(5), + ty: UInt<2>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(6), + kind: BigBool { + index: StatePartIndex(6), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(7), + kind: BigUInt { + index: StatePartIndex(7), + ty: UInt<3>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(8), + kind: BigBool { + index: StatePartIndex(8), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(9), + kind: BigClock { + index: StatePartIndex(9), + }, + state: 0x0, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(10), + kind: EnumDiscriminant { + index: StatePartIndex(0), + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(11), + kind: BigBool { + index: StatePartIndex(16), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(12), + kind: BigBool { + index: StatePartIndex(11), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(13), + kind: EnumDiscriminant { + index: StatePartIndex(1), + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(14), + kind: BigBool { + index: StatePartIndex(19), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(15), + kind: BigBool { + index: StatePartIndex(13), + }, + state: 0x0, + last_state: 0x0, + }, + ], + trace_memories: { + StatePartIndex(0): TraceMem { + id: TraceMemoryId(0), + name: "mem", + stride: 2, + element_type: TraceEnumWithFields { + name: "mem", + discriminant: TraceEnumDiscriminant { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 5, + stride: 2, + start: 0, + len: 1, + }, + name: "$tag", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Duplex, + }, + non_empty_fields: [ + TraceBool { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 5, + stride: 2, + start: 1, + len: 1, + }, + name: "HdlSome", + flow: Duplex, + }, + ], + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Duplex, + }, + ports: [ + TraceMemPort { + name: "rw0", + bundle: TraceBundle { + name: "rw0", + fields: [ + TraceUInt { + location: TraceScalarId(7), + name: "addr", + ty: UInt<3>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(8), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(9), + name: "clk", + flow: Sink, + }, + TraceEnumWithFields { + name: "rdata", + discriminant: TraceEnumDiscriminant { + location: TraceScalarId(10), + name: "$tag", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Source, + }, + non_empty_fields: [ + TraceBool { + location: TraceScalarId(11), + name: "HdlSome", + flow: Source, + }, + ], + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Source, + }, + TraceBool { + location: TraceScalarId(12), + name: "wmode", + flow: Sink, + }, + TraceEnumWithFields { + name: "wdata", + discriminant: TraceEnumDiscriminant { + location: TraceScalarId(13), + name: "$tag", + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Sink, + }, + non_empty_fields: [ + TraceBool { + location: TraceScalarId(14), + name: "HdlSome", + flow: Source, + }, + ], + ty: Enum { + HdlNone, + HdlSome(Bool), + }, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(15), + name: "wmask", + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 10 */ + wmask: Bool, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + rdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 7 */ + wmode: Bool, + /* offset = 8 */ + wdata: Enum { + HdlNone, + HdlSome(Bool), + }, + /* offset = 10 */ + wmask: Bool, + }, + }, + ], + array_type: Array, + }, + }, + trace_writers: [ + Running( + VcdWriter { + finished_init: true, + timescale: 1 ps, + .. + }, + ), + ], + instant: 22 μs, + clocks_triggered: [ + StatePartIndex(3), + ], + .. +} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/memories2.vcd b/crates/fayalite/tests/sim/expected/memories2.vcd new file mode 100644 index 0000000..bd48f24 --- /dev/null +++ b/crates/fayalite/tests/sim/expected/memories2.vcd @@ -0,0 +1,363 @@ +$timescale 1 ps $end +$scope module memories2 $end +$scope struct rw $end +$var wire 3 ! addr $end +$var wire 1 " en $end +$var wire 1 # clk $end +$var wire 2 $ rdata $end +$var wire 1 % wmode $end +$var wire 2 & wdata $end +$var wire 1 ' wmask $end +$upscope $end +$scope struct mem $end +$scope struct contents $end +$scope struct [0] $end +$scope struct mem $end +$var string 1 1 \$tag $end +$var reg 1 6 HdlSome $end +$upscope $end +$upscope $end +$scope struct [1] $end +$scope struct mem $end +$var string 1 2 \$tag $end +$var reg 1 7 HdlSome $end +$upscope $end +$upscope $end +$scope struct [2] $end +$scope struct mem $end +$var string 1 3 \$tag $end +$var reg 1 8 HdlSome $end +$upscope $end +$upscope $end +$scope struct [3] $end +$scope struct mem $end +$var string 1 4 \$tag $end +$var reg 1 9 HdlSome $end +$upscope $end +$upscope $end +$scope struct [4] $end +$scope struct mem $end +$var string 1 5 \$tag $end +$var reg 1 : HdlSome $end +$upscope $end +$upscope $end +$upscope $end +$scope struct rw0 $end +$var wire 3 ( addr $end +$var wire 1 ) en $end +$var wire 1 * clk $end +$scope struct rdata $end +$var string 1 + \$tag $end +$var wire 1 , HdlSome $end +$upscope $end +$var wire 1 - wmode $end +$scope struct wdata $end +$var string 1 . \$tag $end +$var wire 1 / HdlSome $end +$upscope $end +$var wire 1 0 wmask $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +$dumpvars +sHdlSome\x20(1) 1 +16 +sHdlSome\x20(1) 2 +17 +sHdlSome\x20(1) 3 +18 +sHdlSome\x20(1) 4 +19 +sHdlSome\x20(1) 5 +1: +b0 ! +0" +0# +b0 $ +0% +b0 & +0' +b0 ( +0) +0* +sHdlNone\x20(0) + +0, +0- +sHdlNone\x20(0) . +0/ +00 +$end +#250000 +1# +1* +#500000 +#750000 +0# +0* +#1000000 +1" +1) +#1250000 +1# +1* +b11 $ +sHdlSome\x20(1) + +1, +#1500000 +#1750000 +0# +0* +#2000000 +0" +0) +#2250000 +1# +1* +b0 $ +sHdlNone\x20(0) + +0, +#2500000 +#2750000 +0# +0* +#3000000 +1" +1% +1' +1) +1- +10 +#3250000 +sHdlNone\x20(0) 1 +06 +1# +1* +#3500000 +#3750000 +0# +0* +#4000000 +0% +0' +0- +00 +#4250000 +1# +1* +#4500000 +#4750000 +0# +0* +#5000000 +1% +b11 & +1- +sHdlSome\x20(1) . +1/ +#5250000 +1# +1* +#5500000 +#5750000 +0# +0* +#6000000 +b1 ! +b1 & +1' +b1 ( +0/ +10 +#6250000 +sHdlSome\x20(1) 2 +07 +1# +1* +#6500000 +#6750000 +0# +0* +#7000000 +b10 ! +b10 & +b10 ( +sHdlNone\x20(0) . +#7250000 +sHdlNone\x20(0) 3 +08 +1# +1* +#7500000 +#7750000 +0# +0* +#8000000 +b11 ! +b11 & +b11 ( +sHdlSome\x20(1) . +1/ +#8250000 +sHdlSome\x20(1) 4 +19 +1# +1* +#8500000 +#8750000 +0# +0* +#9000000 +b100 ! +b10 & +b100 ( +sHdlNone\x20(0) . +0/ +#9250000 +sHdlNone\x20(0) 5 +0: +1# +1* +#9500000 +#9750000 +0# +0* +#10000000 +b101 ! +b1 & +b101 ( +sHdlSome\x20(1) . +#10250000 +1# +1* +#10500000 +#10750000 +0# +0* +#11000000 +b110 ! +b110 ( +#11250000 +1# +1* +#11500000 +#11750000 +0# +0* +#12000000 +b111 ! +b111 ( +#12250000 +1# +1* +#12500000 +#12750000 +0# +0* +#13000000 +0% +b0 & +0' +0- +sHdlNone\x20(0) . +00 +#13250000 +1# +1* +#13500000 +#13750000 +0# +0* +#14000000 +b110 ! +b110 ( +#14250000 +1# +1* +#14500000 +#14750000 +0# +0* +#15000000 +b101 ! +b101 ( +#15250000 +1# +1* +#15500000 +#15750000 +0# +0* +#16000000 +b100 ! +b100 ( +#16250000 +1# +1* +#16500000 +#16750000 +0# +0* +#17000000 +b11 ! +b11 ( +#17250000 +1# +1* +b11 $ +sHdlSome\x20(1) + +1, +#17500000 +#17750000 +0# +0* +#18000000 +b10 ! +b10 ( +#18250000 +1# +1* +b0 $ +sHdlNone\x20(0) + +0, +#18500000 +#18750000 +0# +0* +#19000000 +b0 ! +b0 ( +#19250000 +1# +1* +#19500000 +#19750000 +0# +0* +#20000000 +b1 ! +b1 ( +#20250000 +1# +1* +b1 $ +sHdlSome\x20(1) + +#20500000 +#20750000 +0# +0* +#21000000 +b0 ! +0" +b0 ( +0) +#21250000 +1# +1* +b0 $ +sHdlNone\x20(0) + +#21500000 +#21750000 +0# +0* +#22000000 From 2af38de900547dd145b91e62a24a05e0fde86ded Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 13 Dec 2024 15:04:48 -0800 Subject: [PATCH 03/10] add more memory tests --- crates/fayalite/tests/sim.rs | 247 +- .../fayalite/tests/sim/expected/memories3.txt | 4882 +++++++++++++++++ .../fayalite/tests/sim/expected/memories3.vcd | 836 +++ 3 files changed, 5960 insertions(+), 5 deletions(-) create mode 100644 crates/fayalite/tests/sim/expected/memories3.txt create mode 100644 crates/fayalite/tests/sim/expected/memories3.vcd diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index 3fc643c..008d792 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -271,7 +271,7 @@ fn test_shift_register() { assert_eq!( *expected, sim.read_bool(sim.io().q), - "cycle: {cycle}\nvcd:\n{}", + "vcd:\n{}\ncycle: {cycle}", String::from_utf8(writer.take()).unwrap(), ); } @@ -473,7 +473,7 @@ fn test_enums() { assert_eq!( expected, io, - "cycle: {cycle}\nvcd:\n{}", + "vcd:\n{}\ncycle: {cycle}", String::from_utf8(writer.take()).unwrap(), ); sim.write_clock(sim.io().cd.clk, false); @@ -671,7 +671,7 @@ fn test_memories() { assert_eq!( expected, io, - "cycle: {cycle}\nvcd:\n{}", + "vcd:\n{}\ncycle: {cycle}", String::from_utf8(writer.take()).unwrap(), ); sim.advance_time(SimDuration::from_micros(1)); @@ -947,7 +947,7 @@ fn test_memories2() { assert_eq!( expected, io, - "cycle: {cycle}\nvcd:\n{}", + "vcd:\n{}\ncycle: {cycle}", String::from_utf8(writer.take()).unwrap(), ); sim.advance_time(SimDuration::from_nanos(250)); @@ -967,4 +967,241 @@ fn test_memories2() { } } -// TODO: add more tests for memories +#[hdl_module(outline_generated)] +pub fn memories3() { + #[hdl] + let r: fayalite::memory::ReadStruct, 8>, ConstUsize<3>> = m.input(); + #[hdl] + let w: fayalite::memory::WriteStruct, 8>, ConstUsize<3>> = m.input(); + #[hdl] + let mut mem: MemBuilder, 8>> = memory(); + mem.depth(8); + mem.read_latency(2); + mem.write_latency(NonZeroUsize::new(2).unwrap()); + mem.read_under_write(ReadUnderWrite::Old); + connect_any(mem.new_read_port(), r); + connect_any(mem.new_write_port(), w); +} + +#[hdl] +#[test] +fn test_memories3() { + let _n = SourceLocation::normalize_files_for_tests(); + let mut sim = Simulation::new(memories3()); + let mut writer = RcWriter::default(); + sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); + sim.write_clock(sim.io().r.clk, false); + sim.write_clock(sim.io().w.clk, false); + #[derive(Debug, PartialEq, Eq, Clone, Copy)] + struct IO { + r_addr: u8, + r_en: bool, + r_data: [u8; 8], + w_addr: u8, + w_en: bool, + w_data: [u8; 8], + w_mask: [bool; 8], + } + let io_cycles = [ + IO { + r_addr: 0, + r_en: false, + r_data: [0; 8], + w_addr: 0, + w_en: true, + w_data: [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0], + w_mask: [false, true, false, true, true, false, false, true], + }, + IO { + r_addr: 0, + r_en: true, + r_data: [0; 8], + w_addr: 1, + w_en: false, + w_data: [0; 8], + w_mask: [false; 8], + }, + IO { + r_addr: 0, + r_en: true, + r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0], + w_addr: 1, + w_en: false, + w_data: [0; 8], + w_mask: [false; 8], + }, + IO { + r_addr: 0, + r_en: true, + r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0], + w_addr: 0, + w_en: true, + w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], + w_mask: [true; 8], + }, + IO { + r_addr: 0, + r_en: true, + r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0], + w_addr: 0, + w_en: true, + w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], + w_mask: [true; 8], + }, + IO { + r_addr: 0, + r_en: true, + r_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], + w_addr: 0, + w_en: true, + w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], + w_mask: [true; 8], + }, + IO { + r_addr: 0, + r_en: false, + r_data: [0; 8], + w_addr: 1, + w_en: true, + w_data: [0x13, 0x57, 0x9B, 0xDF, 0x02, 0x46, 0x8A, 0xCE], + w_mask: [true; 8], + }, + IO { + r_addr: 0, + r_en: false, + r_data: [0; 8], + w_addr: 2, + w_en: true, + w_data: *b"testing!", + w_mask: [true; 8], + }, + IO { + r_addr: 0, + r_en: false, + r_data: [0; 8], + w_addr: 3, + w_en: true, + w_data: *b"more tst", + w_mask: [true; 8], + }, + IO { + r_addr: 0, + r_en: true, + r_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10], + w_addr: 0, + w_en: false, + w_data: [0; 8], + w_mask: [false; 8], + }, + IO { + r_addr: 1, + r_en: true, + r_data: [0x13, 0x57, 0x9B, 0xDF, 0x02, 0x46, 0x8A, 0xCE], + w_addr: 0, + w_en: false, + w_data: [0; 8], + w_mask: [false; 8], + }, + IO { + r_addr: 2, + r_en: true, + r_data: *b"testing!", + w_addr: 0, + w_en: false, + w_data: [0; 8], + w_mask: [false; 8], + }, + IO { + r_addr: 3, + r_en: true, + r_data: *b"more tst", + w_addr: 0, + w_en: false, + w_data: [0; 8], + w_mask: [false; 8], + }, + ]; + for cycle in 0..io_cycles.len() + 2 { + { + let IO { + r_addr, + r_en, + r_data: _, + w_addr, + w_en, + w_data, + w_mask, + } = io_cycles.get(cycle).copied().unwrap_or(IO { + r_addr: 0, + r_en: false, + r_data: [0; 8], + w_addr: 0, + w_en: false, + w_data: [0; 8], + w_mask: [false; 8], + }); + sim.write_bool_or_int(sim.io().r.addr, r_addr.cast_to_static()); + sim.write_bool(sim.io().r.en, r_en); + sim.write_bool_or_int(sim.io().w.addr, w_addr.cast_to_static()); + sim.write_bool(sim.io().w.en, w_en); + for (i, v) in w_data.into_iter().enumerate() { + sim.write_bool_or_int(sim.io().w.data[i], v); + } + for (i, v) in w_mask.into_iter().enumerate() { + sim.write_bool_or_int(sim.io().w.mask[i], v); + } + } + sim.advance_time(SimDuration::from_nanos(250)); + sim.write_clock(sim.io().r.clk, true); + sim.write_clock(sim.io().w.clk, true); + sim.advance_time(SimDuration::from_nanos(250)); + if let Some( + expected @ IO { + r_addr, + r_en, + r_data: _, + w_addr, + w_en, + w_data, + w_mask, + }, + ) = cycle.checked_sub(1).and_then(|i| io_cycles.get(i).copied()) + { + let io = IO { + r_addr, + r_en, + r_data: std::array::from_fn(|i| { + sim.read_bool_or_int(sim.io().r.data[i]) + .to_bigint() + .try_into() + .expect("known to be in range") + }), + w_addr, + w_en, + w_data, + w_mask, + }; + assert_eq!( + expected, + io, + "vcd:\n{}\ncycle: {cycle}", + String::from_utf8(writer.take()).unwrap(), + ); + } + sim.advance_time(SimDuration::from_nanos(250)); + sim.write_clock(sim.io().r.clk, false); + sim.write_clock(sim.io().w.clk, false); + sim.advance_time(SimDuration::from_nanos(250)); + } + sim.flush_traces().unwrap(); + let vcd = String::from_utf8(writer.take()).unwrap(); + println!("####### VCD:\n{vcd}\n#######"); + if vcd != include_str!("sim/expected/memories3.vcd") { + panic!(); + } + let sim_debug = format!("{sim:#?}"); + println!("#######\n{sim_debug}\n#######"); + if sim_debug != include_str!("sim/expected/memories3.txt") { + panic!(); + } +} diff --git a/crates/fayalite/tests/sim/expected/memories3.txt b/crates/fayalite/tests/sim/expected/memories3.txt new file mode 100644 index 0000000..7860bc5 --- /dev/null +++ b/crates/fayalite/tests/sim/expected/memories3.txt @@ -0,0 +1,4882 @@ +Simulation { + state: State { + insns: Insns { + state_layout: StateLayout { + ty: TypeLayout { + small_slots: StatePartLayout { + len: 14, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + big_slots: StatePartLayout { + len: 108, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[0]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[1]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[2]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[3]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[4]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[5]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[6]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[7]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[0]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[1]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[2]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[3]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[4]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[5]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[6]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[7]", + ty: Bool, + }, + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[0]", + ty: Bool, + }, + SlotDebugData { + name: "[1]", + ty: Bool, + }, + SlotDebugData { + name: "[2]", + ty: Bool, + }, + SlotDebugData { + name: "[3]", + ty: Bool, + }, + SlotDebugData { + name: "[4]", + ty: Bool, + }, + SlotDebugData { + name: "[5]", + ty: Bool, + }, + SlotDebugData { + name: "[6]", + ty: Bool, + }, + SlotDebugData { + name: "[7]", + ty: Bool, + }, + SlotDebugData { + name: "[0]", + ty: Bool, + }, + SlotDebugData { + name: "[1]", + ty: Bool, + }, + SlotDebugData { + name: "[2]", + ty: Bool, + }, + SlotDebugData { + name: "[3]", + ty: Bool, + }, + SlotDebugData { + name: "[4]", + ty: Bool, + }, + SlotDebugData { + name: "[5]", + ty: Bool, + }, + SlotDebugData { + name: "[6]", + ty: Bool, + }, + SlotDebugData { + name: "[7]", + ty: Bool, + }, + ], + .. + }, + }, + memories: StatePartLayout { + len: 1, + debug_data: [ + (), + ], + layout_data: [ + MemoryData { + array_type: Array, 8>, 8>, + data: [ + // len = 0x8 + [0x0]: 0x0000000000000000, + [0x1]: 0x0000000000000000, + [0x2]: 0x0000000000000000, + [0x3]: 0x0000000000000000, + [0x4]: 0x0000000000000000, + [0x5]: 0x0000000000000000, + [0x6]: 0x0000000000000000, + [0x7]: 0x0000000000000000, + ], + }, + ], + .. + }, + }, + insns: [ + // at: module-XXXXXXXXXX.rs:8:1 + 0: Copy { + dest: StatePartIndex(57), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.addr", ty: UInt<3> }, + src: StatePartIndex(11), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.addr", ty: UInt<3> }, + }, + 1: Copy { + dest: StatePartIndex(58), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.en", ty: Bool }, + src: StatePartIndex(12), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.en", ty: Bool }, + }, + 2: Copy { + dest: StatePartIndex(59), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.clk", ty: Clock }, + src: StatePartIndex(13), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.clk", ty: Clock }, + }, + 3: Copy { + dest: StatePartIndex(60), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[0]", ty: UInt<8> }, + src: StatePartIndex(14), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[0]", ty: UInt<8> }, + }, + 4: Copy { + dest: StatePartIndex(61), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[1]", ty: UInt<8> }, + src: StatePartIndex(15), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[1]", ty: UInt<8> }, + }, + 5: Copy { + dest: StatePartIndex(62), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[2]", ty: UInt<8> }, + src: StatePartIndex(16), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[2]", ty: UInt<8> }, + }, + 6: Copy { + dest: StatePartIndex(63), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[3]", ty: UInt<8> }, + src: StatePartIndex(17), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[3]", ty: UInt<8> }, + }, + 7: Copy { + dest: StatePartIndex(64), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[4]", ty: UInt<8> }, + src: StatePartIndex(18), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[4]", ty: UInt<8> }, + }, + 8: Copy { + dest: StatePartIndex(65), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[5]", ty: UInt<8> }, + src: StatePartIndex(19), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[5]", ty: UInt<8> }, + }, + 9: Copy { + dest: StatePartIndex(66), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[6]", ty: UInt<8> }, + src: StatePartIndex(20), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[6]", ty: UInt<8> }, + }, + 10: Copy { + dest: StatePartIndex(67), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[7]", ty: UInt<8> }, + src: StatePartIndex(21), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.data[7]", ty: UInt<8> }, + }, + 11: Copy { + dest: StatePartIndex(68), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[0]", ty: Bool }, + src: StatePartIndex(22), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[0]", ty: Bool }, + }, + 12: Copy { + dest: StatePartIndex(69), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[1]", ty: Bool }, + src: StatePartIndex(23), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[1]", ty: Bool }, + }, + 13: Copy { + dest: StatePartIndex(70), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[2]", ty: Bool }, + src: StatePartIndex(24), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[2]", ty: Bool }, + }, + 14: Copy { + dest: StatePartIndex(71), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[3]", ty: Bool }, + src: StatePartIndex(25), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[3]", ty: Bool }, + }, + 15: Copy { + dest: StatePartIndex(72), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[4]", ty: Bool }, + src: StatePartIndex(26), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[4]", ty: Bool }, + }, + 16: Copy { + dest: StatePartIndex(73), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[5]", ty: Bool }, + src: StatePartIndex(27), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[5]", ty: Bool }, + }, + 17: Copy { + dest: StatePartIndex(74), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[6]", ty: Bool }, + src: StatePartIndex(28), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[6]", ty: Bool }, + }, + 18: Copy { + dest: StatePartIndex(75), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[7]", ty: Bool }, + src: StatePartIndex(29), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::w.mask[7]", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:6:1 + 19: Copy { + dest: StatePartIndex(3), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[0]", ty: UInt<8> }, + src: StatePartIndex(33), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[0]", ty: UInt<8> }, + }, + 20: Copy { + dest: StatePartIndex(4), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[1]", ty: UInt<8> }, + src: StatePartIndex(34), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[1]", ty: UInt<8> }, + }, + 21: Copy { + dest: StatePartIndex(5), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[2]", ty: UInt<8> }, + src: StatePartIndex(35), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[2]", ty: UInt<8> }, + }, + 22: Copy { + dest: StatePartIndex(6), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[3]", ty: UInt<8> }, + src: StatePartIndex(36), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[3]", ty: UInt<8> }, + }, + 23: Copy { + dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[4]", ty: UInt<8> }, + src: StatePartIndex(37), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[4]", ty: UInt<8> }, + }, + 24: Copy { + dest: StatePartIndex(8), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[5]", ty: UInt<8> }, + src: StatePartIndex(38), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[5]", ty: UInt<8> }, + }, + 25: Copy { + dest: StatePartIndex(9), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[6]", ty: UInt<8> }, + src: StatePartIndex(39), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[6]", ty: UInt<8> }, + }, + 26: Copy { + dest: StatePartIndex(10), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.data[7]", ty: UInt<8> }, + src: StatePartIndex(40), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[7]", ty: UInt<8> }, + }, + 27: Copy { + dest: StatePartIndex(32), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.clk", ty: Clock }, + src: StatePartIndex(2), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.clk", ty: Clock }, + }, + 28: Copy { + dest: StatePartIndex(31), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.en", ty: Bool }, + src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.en", ty: Bool }, + }, + 29: Copy { + dest: StatePartIndex(30), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.addr", ty: UInt<3> }, + src: StatePartIndex(0), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::r.addr", ty: UInt<3> }, + }, + // at: module-XXXXXXXXXX.rs:4:1 + 30: CastBigToArrayIndex { + dest: StatePartIndex(9), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(57), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.addr", ty: UInt<3> }, + }, + 31: IsNonZeroDestIsSmall { + dest: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(58), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.en", ty: Bool }, + }, + 32: IsNonZeroDestIsSmall { + dest: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(59), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.clk", ty: Clock }, + }, + 33: AndSmall { + dest: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + rhs: StatePartIndex(5), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + }, + 34: CastBigToArrayIndex { + dest: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(30), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.addr", ty: UInt<3> }, + }, + 35: IsNonZeroDestIsSmall { + dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(31), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.en", ty: Bool }, + }, + 36: BranchIfSmallZero { + target: 46, + value: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 37: MemoryReadUInt { + dest: StatePartIndex(41), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 0, + width: 8, + }, + 38: MemoryReadUInt { + dest: StatePartIndex(42), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 8, + width: 8, + }, + 39: MemoryReadUInt { + dest: StatePartIndex(43), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 16, + width: 8, + }, + 40: MemoryReadUInt { + dest: StatePartIndex(44), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 24, + width: 8, + }, + 41: MemoryReadUInt { + dest: StatePartIndex(45), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 32, + width: 8, + }, + 42: MemoryReadUInt { + dest: StatePartIndex(46), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 40, + width: 8, + }, + 43: MemoryReadUInt { + dest: StatePartIndex(47), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 48, + width: 8, + }, + 44: MemoryReadUInt { + dest: StatePartIndex(48), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 56, + width: 8, + }, + 45: Branch { + target: 54, + }, + 46: Const { + dest: StatePartIndex(41), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + value: 0x0, + }, + 47: Const { + dest: StatePartIndex(42), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + value: 0x0, + }, + 48: Const { + dest: StatePartIndex(43), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + value: 0x0, + }, + 49: Const { + dest: StatePartIndex(44), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + value: 0x0, + }, + 50: Const { + dest: StatePartIndex(45), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + value: 0x0, + }, + 51: Const { + dest: StatePartIndex(46), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + value: 0x0, + }, + 52: Const { + dest: StatePartIndex(47), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + value: 0x0, + }, + 53: Const { + dest: StatePartIndex(48), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + value: 0x0, + }, + 54: IsNonZeroDestIsSmall { + dest: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(32), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.clk", ty: Clock }, + }, + 55: AndSmall { + dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + rhs: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + }, + 56: BranchIfSmallZero { + target: 73, + value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 57: Copy { + dest: StatePartIndex(33), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[0]", ty: UInt<8> }, + src: StatePartIndex(49), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + }, + 58: Copy { + dest: StatePartIndex(34), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[1]", ty: UInt<8> }, + src: StatePartIndex(50), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + }, + 59: Copy { + dest: StatePartIndex(35), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[2]", ty: UInt<8> }, + src: StatePartIndex(51), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + }, + 60: Copy { + dest: StatePartIndex(36), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[3]", ty: UInt<8> }, + src: StatePartIndex(52), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + }, + 61: Copy { + dest: StatePartIndex(37), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[4]", ty: UInt<8> }, + src: StatePartIndex(53), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + }, + 62: Copy { + dest: StatePartIndex(38), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[5]", ty: UInt<8> }, + src: StatePartIndex(54), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + }, + 63: Copy { + dest: StatePartIndex(39), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[6]", ty: UInt<8> }, + src: StatePartIndex(55), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + }, + 64: Copy { + dest: StatePartIndex(40), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::r0.data[7]", ty: UInt<8> }, + src: StatePartIndex(56), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + }, + 65: Copy { + dest: StatePartIndex(49), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + src: StatePartIndex(41), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + }, + 66: Copy { + dest: StatePartIndex(50), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + src: StatePartIndex(42), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + }, + 67: Copy { + dest: StatePartIndex(51), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + src: StatePartIndex(43), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + }, + 68: Copy { + dest: StatePartIndex(52), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + src: StatePartIndex(44), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + }, + 69: Copy { + dest: StatePartIndex(53), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + src: StatePartIndex(45), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + }, + 70: Copy { + dest: StatePartIndex(54), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + src: StatePartIndex(46), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + }, + 71: Copy { + dest: StatePartIndex(55), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + src: StatePartIndex(47), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + }, + 72: Copy { + dest: StatePartIndex(56), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + src: StatePartIndex(48), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + }, + 73: BranchIfSmallZero { + target: 127, + value: StatePartIndex(6), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 74: CopySmall { + dest: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(10), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + }, + 75: CopySmall { + dest: StatePartIndex(10), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(9), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + }, + 76: CopySmall { + dest: StatePartIndex(13), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(12), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 77: CopySmall { + dest: StatePartIndex(12), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(8), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 78: Copy { + dest: StatePartIndex(84), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + src: StatePartIndex(76), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + }, + 79: Copy { + dest: StatePartIndex(85), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + src: StatePartIndex(77), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + }, + 80: Copy { + dest: StatePartIndex(86), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + src: StatePartIndex(78), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + }, + 81: Copy { + dest: StatePartIndex(87), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + src: StatePartIndex(79), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + }, + 82: Copy { + dest: StatePartIndex(88), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + src: StatePartIndex(80), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + }, + 83: Copy { + dest: StatePartIndex(89), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + src: StatePartIndex(81), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + }, + 84: Copy { + dest: StatePartIndex(90), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + src: StatePartIndex(82), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + }, + 85: Copy { + dest: StatePartIndex(91), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + src: StatePartIndex(83), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + }, + 86: Copy { + dest: StatePartIndex(76), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + src: StatePartIndex(60), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[0]", ty: UInt<8> }, + }, + 87: Copy { + dest: StatePartIndex(77), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + src: StatePartIndex(61), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[1]", ty: UInt<8> }, + }, + 88: Copy { + dest: StatePartIndex(78), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + src: StatePartIndex(62), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[2]", ty: UInt<8> }, + }, + 89: Copy { + dest: StatePartIndex(79), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + src: StatePartIndex(63), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[3]", ty: UInt<8> }, + }, + 90: Copy { + dest: StatePartIndex(80), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + src: StatePartIndex(64), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[4]", ty: UInt<8> }, + }, + 91: Copy { + dest: StatePartIndex(81), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + src: StatePartIndex(65), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[5]", ty: UInt<8> }, + }, + 92: Copy { + dest: StatePartIndex(82), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + src: StatePartIndex(66), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[6]", ty: UInt<8> }, + }, + 93: Copy { + dest: StatePartIndex(83), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + src: StatePartIndex(67), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.data[7]", ty: UInt<8> }, + }, + 94: Copy { + dest: StatePartIndex(100), // (0x0) SlotDebugData { name: "[0]", ty: Bool }, + src: StatePartIndex(92), // (0x0) SlotDebugData { name: "[0]", ty: Bool }, + }, + 95: Copy { + dest: StatePartIndex(101), // (0x0) SlotDebugData { name: "[1]", ty: Bool }, + src: StatePartIndex(93), // (0x0) SlotDebugData { name: "[1]", ty: Bool }, + }, + 96: Copy { + dest: StatePartIndex(102), // (0x0) SlotDebugData { name: "[2]", ty: Bool }, + src: StatePartIndex(94), // (0x0) SlotDebugData { name: "[2]", ty: Bool }, + }, + 97: Copy { + dest: StatePartIndex(103), // (0x0) SlotDebugData { name: "[3]", ty: Bool }, + src: StatePartIndex(95), // (0x0) SlotDebugData { name: "[3]", ty: Bool }, + }, + 98: Copy { + dest: StatePartIndex(104), // (0x0) SlotDebugData { name: "[4]", ty: Bool }, + src: StatePartIndex(96), // (0x0) SlotDebugData { name: "[4]", ty: Bool }, + }, + 99: Copy { + dest: StatePartIndex(105), // (0x0) SlotDebugData { name: "[5]", ty: Bool }, + src: StatePartIndex(97), // (0x0) SlotDebugData { name: "[5]", ty: Bool }, + }, + 100: Copy { + dest: StatePartIndex(106), // (0x0) SlotDebugData { name: "[6]", ty: Bool }, + src: StatePartIndex(98), // (0x0) SlotDebugData { name: "[6]", ty: Bool }, + }, + 101: Copy { + dest: StatePartIndex(107), // (0x0) SlotDebugData { name: "[7]", ty: Bool }, + src: StatePartIndex(99), // (0x0) SlotDebugData { name: "[7]", ty: Bool }, + }, + 102: Copy { + dest: StatePartIndex(92), // (0x0) SlotDebugData { name: "[0]", ty: Bool }, + src: StatePartIndex(68), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[0]", ty: Bool }, + }, + 103: Copy { + dest: StatePartIndex(93), // (0x0) SlotDebugData { name: "[1]", ty: Bool }, + src: StatePartIndex(69), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[1]", ty: Bool }, + }, + 104: Copy { + dest: StatePartIndex(94), // (0x0) SlotDebugData { name: "[2]", ty: Bool }, + src: StatePartIndex(70), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[2]", ty: Bool }, + }, + 105: Copy { + dest: StatePartIndex(95), // (0x0) SlotDebugData { name: "[3]", ty: Bool }, + src: StatePartIndex(71), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[3]", ty: Bool }, + }, + 106: Copy { + dest: StatePartIndex(96), // (0x0) SlotDebugData { name: "[4]", ty: Bool }, + src: StatePartIndex(72), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[4]", ty: Bool }, + }, + 107: Copy { + dest: StatePartIndex(97), // (0x0) SlotDebugData { name: "[5]", ty: Bool }, + src: StatePartIndex(73), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[5]", ty: Bool }, + }, + 108: Copy { + dest: StatePartIndex(98), // (0x0) SlotDebugData { name: "[6]", ty: Bool }, + src: StatePartIndex(74), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[6]", ty: Bool }, + }, + 109: Copy { + dest: StatePartIndex(99), // (0x0) SlotDebugData { name: "[7]", ty: Bool }, + src: StatePartIndex(75), // (0x0) SlotDebugData { name: "InstantiatedModule(memories3: memories3).memories3::mem::w1.mask[7]", ty: Bool }, + }, + 110: BranchIfSmallZero { + target: 127, + value: StatePartIndex(13), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 111: BranchIfZero { + target: 113, + value: StatePartIndex(100), // (0x0) SlotDebugData { name: "[0]", ty: Bool }, + }, + 112: MemoryWriteUInt { + value: StatePartIndex(84), // (0x0) SlotDebugData { name: "[0]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 0, + width: 8, + }, + 113: BranchIfZero { + target: 115, + value: StatePartIndex(101), // (0x0) SlotDebugData { name: "[1]", ty: Bool }, + }, + 114: MemoryWriteUInt { + value: StatePartIndex(85), // (0x0) SlotDebugData { name: "[1]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 8, + width: 8, + }, + 115: BranchIfZero { + target: 117, + value: StatePartIndex(102), // (0x0) SlotDebugData { name: "[2]", ty: Bool }, + }, + 116: MemoryWriteUInt { + value: StatePartIndex(86), // (0x0) SlotDebugData { name: "[2]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 16, + width: 8, + }, + 117: BranchIfZero { + target: 119, + value: StatePartIndex(103), // (0x0) SlotDebugData { name: "[3]", ty: Bool }, + }, + 118: MemoryWriteUInt { + value: StatePartIndex(87), // (0x0) SlotDebugData { name: "[3]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 24, + width: 8, + }, + 119: BranchIfZero { + target: 121, + value: StatePartIndex(104), // (0x0) SlotDebugData { name: "[4]", ty: Bool }, + }, + 120: MemoryWriteUInt { + value: StatePartIndex(88), // (0x0) SlotDebugData { name: "[4]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 32, + width: 8, + }, + 121: BranchIfZero { + target: 123, + value: StatePartIndex(105), // (0x0) SlotDebugData { name: "[5]", ty: Bool }, + }, + 122: MemoryWriteUInt { + value: StatePartIndex(89), // (0x0) SlotDebugData { name: "[5]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 40, + width: 8, + }, + 123: BranchIfZero { + target: 125, + value: StatePartIndex(106), // (0x0) SlotDebugData { name: "[6]", ty: Bool }, + }, + 124: MemoryWriteUInt { + value: StatePartIndex(90), // (0x0) SlotDebugData { name: "[6]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 48, + width: 8, + }, + 125: BranchIfZero { + target: 127, + value: StatePartIndex(107), // (0x0) SlotDebugData { name: "[7]", ty: Bool }, + }, + 126: MemoryWriteUInt { + value: StatePartIndex(91), // (0x0) SlotDebugData { name: "[7]", ty: UInt<8> }, + memory: StatePartIndex(0), // (MemoryData { + // array_type: Array, 8>, 8>, + // data: [ + // // len = 0x8 + // [0x0]: 0x1032547698badcfe, + // [0x1]: 0xce8a4602df9b5713, + // [0x2]: 0x21676e6974736574, + // [0x3]: 0x7473742065726f6d, + // [0x4]: 0x0000000000000000, + // [0x5]: 0x0000000000000000, + // [0x6]: 0x0000000000000000, + // [0x7]: 0x0000000000000000, + // ], + // }) (), + addr: StatePartIndex(11), // (0x0 0) SlotDebugData { name: "", ty: UInt<3> }, + stride: 64, + start: 56, + width: 8, + }, + 127: XorSmallImmediate { + dest: StatePartIndex(0), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + rhs: 0x1, + }, + 128: XorSmallImmediate { + dest: StatePartIndex(5), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(7), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + rhs: 0x1, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 129: Return, + ], + .. + }, + pc: 129, + memory_write_log: [], + memories: StatePart { + value: [ + MemoryData { + array_type: Array, 8>, 8>, + data: [ + // len = 0x8 + [0x0]: 0x1032547698badcfe, + [0x1]: 0xce8a4602df9b5713, + [0x2]: 0x21676e6974736574, + [0x3]: 0x7473742065726f6d, + [0x4]: 0x0000000000000000, + [0x5]: 0x0000000000000000, + [0x6]: 0x0000000000000000, + [0x7]: 0x0000000000000000, + ], + }, + ], + }, + small_slots: StatePart { + value: [ + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + }, + big_slots: StatePart { + value: [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + }, + }, + io: Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }, + uninitialized_inputs: {}, + io_targets: { + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 11, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::r.data[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 11 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 0, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 2, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 8 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 3, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 4, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 5, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 6, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 7, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 8, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 9, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.data[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 10, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.r.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 1, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w: CompiledValue { + layout: CompiledTypeLayout { + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 19, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.addr", + ty: UInt<3>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.en", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.clk", + ty: Clock, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.data[7]", + ty: UInt<8>, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[0]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[1]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[2]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[3]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[4]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[5]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[6]", + ty: Bool, + }, + SlotDebugData { + name: "InstantiatedModule(memories3: memories3).memories3::w.mask[7]", + ty: Bool, + }, + ], + .. + }, + }, + body: Bundle { + fields: [ + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(0), + }, + ty: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(1), + }, + ty: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(2), + }, + ty: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(3), + }, + ty: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + }, + CompiledBundleField { + offset: TypeIndex { + small_slots: StatePartIndex(0), + big_slots: StatePartIndex(11), + }, + ty: CompiledTypeLayout { + ty: Array, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: Bool, + }, + SlotDebugData { + name: "[1]", + ty: Bool, + }, + SlotDebugData { + name: "[2]", + ty: Bool, + }, + SlotDebugData { + name: "[3]", + ty: Bool, + }, + SlotDebugData { + name: "[4]", + ty: Bool, + }, + SlotDebugData { + name: "[5]", + ty: Bool, + }, + SlotDebugData { + name: "[6]", + ty: Bool, + }, + SlotDebugData { + name: "[7]", + ty: Bool, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + }, + ], + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 11, len: 19 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.addr: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<3>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<3>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 11, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.clk: CompiledValue { + layout: CompiledTypeLayout { + ty: Clock, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Clock, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 13, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, 8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[1]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[2]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[3]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[4]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[5]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[6]", + ty: UInt<8>, + }, + SlotDebugData { + name: "[7]", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 14, len: 8 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 14, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 15, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 16, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 17, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 18, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 19, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 20, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.data[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: UInt<8>, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: UInt<8>, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 21, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.en: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 12, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask: CompiledValue { + layout: CompiledTypeLayout { + ty: Array, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 8, + debug_data: [ + SlotDebugData { + name: "[0]", + ty: Bool, + }, + SlotDebugData { + name: "[1]", + ty: Bool, + }, + SlotDebugData { + name: "[2]", + ty: Bool, + }, + SlotDebugData { + name: "[3]", + ty: Bool, + }, + SlotDebugData { + name: "[4]", + ty: Bool, + }, + SlotDebugData { + name: "[5]", + ty: Bool, + }, + SlotDebugData { + name: "[6]", + ty: Bool, + }, + SlotDebugData { + name: "[7]", + ty: Bool, + }, + ], + .. + }, + }, + body: Array { + element: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + }, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 22, len: 8 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[0]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 22, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[1]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 23, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[2]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 24, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[3]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 25, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[4]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 26, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[5]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 27, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[6]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 28, len: 1 }, + }, + write: None, + }, + Instance { + name: ::memories3, + instantiated: Module { + name: memories3, + .. + }, + }.w.mask[7]: CompiledValue { + layout: CompiledTypeLayout { + ty: Bool, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "", + ty: Bool, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 29, len: 1 }, + }, + write: None, + }, + }, + made_initial_step: true, + needs_settle: false, + trace_decls: TraceModule { + name: "memories3", + children: [ + TraceModuleIO { + name: "r", + child: TraceBundle { + name: "r", + fields: [ + TraceUInt { + location: TraceScalarId(0), + name: "addr", + ty: UInt<3>, + flow: Source, + }, + TraceBool { + location: TraceScalarId(1), + name: "en", + flow: Source, + }, + TraceClock { + location: TraceScalarId(2), + name: "clk", + flow: Source, + }, + TraceArray { + name: "data", + elements: [ + TraceUInt { + location: TraceScalarId(3), + name: "[0]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(4), + name: "[1]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(5), + name: "[2]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(6), + name: "[3]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(7), + name: "[4]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(8), + name: "[5]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(9), + name: "[6]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(10), + name: "[7]", + ty: UInt<8>, + flow: Sink, + }, + ], + ty: Array, 8>, + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, + }, + flow: Source, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, + }, + flow: Source, + }, + TraceModuleIO { + name: "w", + child: TraceBundle { + name: "w", + fields: [ + TraceUInt { + location: TraceScalarId(11), + name: "addr", + ty: UInt<3>, + flow: Source, + }, + TraceBool { + location: TraceScalarId(12), + name: "en", + flow: Source, + }, + TraceClock { + location: TraceScalarId(13), + name: "clk", + flow: Source, + }, + TraceArray { + name: "data", + elements: [ + TraceUInt { + location: TraceScalarId(14), + name: "[0]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(15), + name: "[1]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(16), + name: "[2]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(17), + name: "[3]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(18), + name: "[4]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(19), + name: "[5]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(20), + name: "[6]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(21), + name: "[7]", + ty: UInt<8>, + flow: Source, + }, + ], + ty: Array, 8>, + flow: Source, + }, + TraceArray { + name: "mask", + elements: [ + TraceBool { + location: TraceScalarId(22), + name: "[0]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(23), + name: "[1]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(24), + name: "[2]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(25), + name: "[3]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(26), + name: "[4]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(27), + name: "[5]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(28), + name: "[6]", + flow: Source, + }, + TraceBool { + location: TraceScalarId(29), + name: "[7]", + flow: Source, + }, + ], + ty: Array, + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + flow: Source, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + flow: Source, + }, + TraceMem { + id: TraceMemoryId(0), + name: "mem", + stride: 64, + element_type: TraceArray { + name: "mem", + elements: [ + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 0, + len: 8, + }, + name: "[0]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 8, + len: 8, + }, + name: "[1]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 16, + len: 8, + }, + name: "[2]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 24, + len: 8, + }, + name: "[3]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 32, + len: 8, + }, + name: "[4]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 40, + len: 8, + }, + name: "[5]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 48, + len: 8, + }, + name: "[6]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 56, + len: 8, + }, + name: "[7]", + ty: UInt<8>, + flow: Duplex, + }, + ], + ty: Array, 8>, + flow: Duplex, + }, + ports: [ + TraceMemPort { + name: "r0", + bundle: TraceBundle { + name: "r0", + fields: [ + TraceUInt { + location: TraceScalarId(30), + name: "addr", + ty: UInt<3>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(31), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(32), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceUInt { + location: TraceScalarId(33), + name: "[0]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(34), + name: "[1]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(35), + name: "[2]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(36), + name: "[3]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(37), + name: "[4]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(38), + name: "[5]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(39), + name: "[6]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(40), + name: "[7]", + ty: UInt<8>, + flow: Source, + }, + ], + ty: Array, 8>, + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, + }, + }, + TraceMemPort { + name: "w1", + bundle: TraceBundle { + name: "w1", + fields: [ + TraceUInt { + location: TraceScalarId(41), + name: "addr", + ty: UInt<3>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(42), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(43), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceUInt { + location: TraceScalarId(44), + name: "[0]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(45), + name: "[1]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(46), + name: "[2]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(47), + name: "[3]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(48), + name: "[4]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(49), + name: "[5]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(50), + name: "[6]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(51), + name: "[7]", + ty: UInt<8>, + flow: Sink, + }, + ], + ty: Array, 8>, + flow: Sink, + }, + TraceArray { + name: "mask", + elements: [ + TraceBool { + location: TraceScalarId(52), + name: "[0]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(53), + name: "[1]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(54), + name: "[2]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(55), + name: "[3]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(56), + name: "[4]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(57), + name: "[5]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(58), + name: "[6]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(59), + name: "[7]", + flow: Sink, + }, + ], + ty: Array, + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + }, + ], + array_type: Array, 8>, 8>, + }, + ], + }, + traces: [ + SimTrace { + id: TraceScalarId(0), + kind: BigUInt { + index: StatePartIndex(0), + ty: UInt<3>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(1), + kind: BigBool { + index: StatePartIndex(1), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(2), + kind: BigClock { + index: StatePartIndex(2), + }, + state: 0x0, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(3), + kind: BigUInt { + index: StatePartIndex(3), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(4), + kind: BigUInt { + index: StatePartIndex(4), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(5), + kind: BigUInt { + index: StatePartIndex(5), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(6), + kind: BigUInt { + index: StatePartIndex(6), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(7), + kind: BigUInt { + index: StatePartIndex(7), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(8), + kind: BigUInt { + index: StatePartIndex(8), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(9), + kind: BigUInt { + index: StatePartIndex(9), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(10), + kind: BigUInt { + index: StatePartIndex(10), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(11), + kind: BigUInt { + index: StatePartIndex(11), + ty: UInt<3>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(12), + kind: BigBool { + index: StatePartIndex(12), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(13), + kind: BigClock { + index: StatePartIndex(13), + }, + state: 0x0, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(14), + kind: BigUInt { + index: StatePartIndex(14), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(15), + kind: BigUInt { + index: StatePartIndex(15), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(16), + kind: BigUInt { + index: StatePartIndex(16), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(17), + kind: BigUInt { + index: StatePartIndex(17), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(18), + kind: BigUInt { + index: StatePartIndex(18), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(19), + kind: BigUInt { + index: StatePartIndex(19), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(20), + kind: BigUInt { + index: StatePartIndex(20), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(21), + kind: BigUInt { + index: StatePartIndex(21), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(22), + kind: BigBool { + index: StatePartIndex(22), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(23), + kind: BigBool { + index: StatePartIndex(23), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(24), + kind: BigBool { + index: StatePartIndex(24), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(25), + kind: BigBool { + index: StatePartIndex(25), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(26), + kind: BigBool { + index: StatePartIndex(26), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(27), + kind: BigBool { + index: StatePartIndex(27), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(28), + kind: BigBool { + index: StatePartIndex(28), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(29), + kind: BigBool { + index: StatePartIndex(29), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(30), + kind: BigUInt { + index: StatePartIndex(30), + ty: UInt<3>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(31), + kind: BigBool { + index: StatePartIndex(31), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(32), + kind: BigClock { + index: StatePartIndex(32), + }, + state: 0x0, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(33), + kind: BigUInt { + index: StatePartIndex(33), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(34), + kind: BigUInt { + index: StatePartIndex(34), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(35), + kind: BigUInt { + index: StatePartIndex(35), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(36), + kind: BigUInt { + index: StatePartIndex(36), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(37), + kind: BigUInt { + index: StatePartIndex(37), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(38), + kind: BigUInt { + index: StatePartIndex(38), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(39), + kind: BigUInt { + index: StatePartIndex(39), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(40), + kind: BigUInt { + index: StatePartIndex(40), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(41), + kind: BigUInt { + index: StatePartIndex(57), + ty: UInt<3>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(42), + kind: BigBool { + index: StatePartIndex(58), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(43), + kind: BigClock { + index: StatePartIndex(59), + }, + state: 0x0, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(44), + kind: BigUInt { + index: StatePartIndex(60), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(45), + kind: BigUInt { + index: StatePartIndex(61), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(46), + kind: BigUInt { + index: StatePartIndex(62), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(47), + kind: BigUInt { + index: StatePartIndex(63), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(48), + kind: BigUInt { + index: StatePartIndex(64), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(49), + kind: BigUInt { + index: StatePartIndex(65), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(50), + kind: BigUInt { + index: StatePartIndex(66), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(51), + kind: BigUInt { + index: StatePartIndex(67), + ty: UInt<8>, + }, + state: 0x00, + last_state: 0x00, + }, + SimTrace { + id: TraceScalarId(52), + kind: BigBool { + index: StatePartIndex(68), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(53), + kind: BigBool { + index: StatePartIndex(69), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(54), + kind: BigBool { + index: StatePartIndex(70), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(55), + kind: BigBool { + index: StatePartIndex(71), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(56), + kind: BigBool { + index: StatePartIndex(72), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(57), + kind: BigBool { + index: StatePartIndex(73), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(58), + kind: BigBool { + index: StatePartIndex(74), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(59), + kind: BigBool { + index: StatePartIndex(75), + }, + state: 0x0, + last_state: 0x0, + }, + ], + trace_memories: { + StatePartIndex(0): TraceMem { + id: TraceMemoryId(0), + name: "mem", + stride: 64, + element_type: TraceArray { + name: "mem", + elements: [ + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 0, + len: 8, + }, + name: "[0]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 8, + len: 8, + }, + name: "[1]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 16, + len: 8, + }, + name: "[2]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 24, + len: 8, + }, + name: "[3]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 32, + len: 8, + }, + name: "[4]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 40, + len: 8, + }, + name: "[5]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 48, + len: 8, + }, + name: "[6]", + ty: UInt<8>, + flow: Duplex, + }, + TraceUInt { + location: TraceMemoryLocation { + id: TraceMemoryId(0), + depth: 8, + stride: 64, + start: 56, + len: 8, + }, + name: "[7]", + ty: UInt<8>, + flow: Duplex, + }, + ], + ty: Array, 8>, + flow: Duplex, + }, + ports: [ + TraceMemPort { + name: "r0", + bundle: TraceBundle { + name: "r0", + fields: [ + TraceUInt { + location: TraceScalarId(30), + name: "addr", + ty: UInt<3>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(31), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(32), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceUInt { + location: TraceScalarId(33), + name: "[0]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(34), + name: "[1]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(35), + name: "[2]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(36), + name: "[3]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(37), + name: "[4]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(38), + name: "[5]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(39), + name: "[6]", + ty: UInt<8>, + flow: Source, + }, + TraceUInt { + location: TraceScalarId(40), + name: "[7]", + ty: UInt<8>, + flow: Source, + }, + ], + ty: Array, 8>, + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + #[hdl(flip)] /* offset = 5 */ + data: Array, 8>, + }, + }, + TraceMemPort { + name: "w1", + bundle: TraceBundle { + name: "w1", + fields: [ + TraceUInt { + location: TraceScalarId(41), + name: "addr", + ty: UInt<3>, + flow: Sink, + }, + TraceBool { + location: TraceScalarId(42), + name: "en", + flow: Sink, + }, + TraceClock { + location: TraceScalarId(43), + name: "clk", + flow: Sink, + }, + TraceArray { + name: "data", + elements: [ + TraceUInt { + location: TraceScalarId(44), + name: "[0]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(45), + name: "[1]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(46), + name: "[2]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(47), + name: "[3]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(48), + name: "[4]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(49), + name: "[5]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(50), + name: "[6]", + ty: UInt<8>, + flow: Sink, + }, + TraceUInt { + location: TraceScalarId(51), + name: "[7]", + ty: UInt<8>, + flow: Sink, + }, + ], + ty: Array, 8>, + flow: Sink, + }, + TraceArray { + name: "mask", + elements: [ + TraceBool { + location: TraceScalarId(52), + name: "[0]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(53), + name: "[1]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(54), + name: "[2]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(55), + name: "[3]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(56), + name: "[4]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(57), + name: "[5]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(58), + name: "[6]", + flow: Sink, + }, + TraceBool { + location: TraceScalarId(59), + name: "[7]", + flow: Sink, + }, + ], + ty: Array, + flow: Sink, + }, + ], + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + flow: Sink, + }, + ty: Bundle { + /* offset = 0 */ + addr: UInt<3>, + /* offset = 3 */ + en: Bool, + /* offset = 4 */ + clk: Clock, + /* offset = 5 */ + data: Array, 8>, + /* offset = 69 */ + mask: Array, + }, + }, + ], + array_type: Array, 8>, 8>, + }, + }, + trace_writers: [ + Running( + VcdWriter { + finished_init: true, + timescale: 1 ps, + .. + }, + ), + ], + instant: 15 μs, + clocks_triggered: [ + StatePartIndex(1), + StatePartIndex(6), + ], + .. +} \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/memories3.vcd b/crates/fayalite/tests/sim/expected/memories3.vcd new file mode 100644 index 0000000..328fcaa --- /dev/null +++ b/crates/fayalite/tests/sim/expected/memories3.vcd @@ -0,0 +1,836 @@ +$timescale 1 ps $end +$scope module memories3 $end +$scope struct r $end +$var wire 3 ! addr $end +$var wire 1 " en $end +$var wire 1 # clk $end +$scope struct data $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 +$upscope $end +$upscope $end +$scope struct w $end +$var wire 3 , addr $end +$var wire 1 - en $end +$var wire 1 . clk $end +$scope struct data $end +$var wire 8 / \[0] $end +$var wire 8 0 \[1] $end +$var wire 8 1 \[2] $end +$var wire 8 2 \[3] $end +$var wire 8 3 \[4] $end +$var wire 8 4 \[5] $end +$var wire 8 5 \[6] $end +$var wire 8 6 \[7] $end +$upscope $end +$scope struct mask $end +$var wire 1 7 \[0] $end +$var wire 1 8 \[1] $end +$var wire 1 9 \[2] $end +$var wire 1 : \[3] $end +$var wire 1 ; \[4] $end +$var wire 1 < \[5] $end +$var wire 1 = \[6] $end +$var wire 1 > \[7] $end +$upscope $end +$upscope $end +$scope struct mem $end +$scope struct contents $end +$scope struct [0] $end +$scope struct mem $end +$var reg 8 ] \[0] $end +$var reg 8 e \[1] $end +$var reg 8 m \[2] $end +$var reg 8 u \[3] $end +$var reg 8 } \[4] $end +$var reg 8 '" \[5] $end +$var reg 8 /" \[6] $end +$var reg 8 7" \[7] $end +$upscope $end +$upscope $end +$scope struct [1] $end +$scope struct mem $end +$var reg 8 ^ \[0] $end +$var reg 8 f \[1] $end +$var reg 8 n \[2] $end +$var reg 8 v \[3] $end +$var reg 8 ~ \[4] $end +$var reg 8 (" \[5] $end +$var reg 8 0" \[6] $end +$var reg 8 8" \[7] $end +$upscope $end +$upscope $end +$scope struct [2] $end +$scope struct mem $end +$var reg 8 _ \[0] $end +$var reg 8 g \[1] $end +$var reg 8 o \[2] $end +$var reg 8 w \[3] $end +$var reg 8 !" \[4] $end +$var reg 8 )" \[5] $end +$var reg 8 1" \[6] $end +$var reg 8 9" \[7] $end +$upscope $end +$upscope $end +$scope struct [3] $end +$scope struct mem $end +$var reg 8 ` \[0] $end +$var reg 8 h \[1] $end +$var reg 8 p \[2] $end +$var reg 8 x \[3] $end +$var reg 8 "" \[4] $end +$var reg 8 *" \[5] $end +$var reg 8 2" \[6] $end +$var reg 8 :" \[7] $end +$upscope $end +$upscope $end +$scope struct [4] $end +$scope struct mem $end +$var reg 8 a \[0] $end +$var reg 8 i \[1] $end +$var reg 8 q \[2] $end +$var reg 8 y \[3] $end +$var reg 8 #" \[4] $end +$var reg 8 +" \[5] $end +$var reg 8 3" \[6] $end +$var reg 8 ;" \[7] $end +$upscope $end +$upscope $end +$scope struct [5] $end +$scope struct mem $end +$var reg 8 b \[0] $end +$var reg 8 j \[1] $end +$var reg 8 r \[2] $end +$var reg 8 z \[3] $end +$var reg 8 $" \[4] $end +$var reg 8 ," \[5] $end +$var reg 8 4" \[6] $end +$var reg 8 <" \[7] $end +$upscope $end +$upscope $end +$scope struct [6] $end +$scope struct mem $end +$var reg 8 c \[0] $end +$var reg 8 k \[1] $end +$var reg 8 s \[2] $end +$var reg 8 { \[3] $end +$var reg 8 %" \[4] $end +$var reg 8 -" \[5] $end +$var reg 8 5" \[6] $end +$var reg 8 =" \[7] $end +$upscope $end +$upscope $end +$scope struct [7] $end +$scope struct mem $end +$var reg 8 d \[0] $end +$var reg 8 l \[1] $end +$var reg 8 t \[2] $end +$var reg 8 | \[3] $end +$var reg 8 &" \[4] $end +$var reg 8 ." \[5] $end +$var reg 8 6" \[6] $end +$var reg 8 >" \[7] $end +$upscope $end +$upscope $end +$upscope $end +$scope struct r0 $end +$var wire 3 ? addr $end +$var wire 1 @ en $end +$var wire 1 A clk $end +$scope struct data $end +$var wire 8 B \[0] $end +$var wire 8 C \[1] $end +$var wire 8 D \[2] $end +$var wire 8 E \[3] $end +$var wire 8 F \[4] $end +$var wire 8 G \[5] $end +$var wire 8 H \[6] $end +$var wire 8 I \[7] $end +$upscope $end +$upscope $end +$scope struct w1 $end +$var wire 3 J addr $end +$var wire 1 K en $end +$var wire 1 L clk $end +$scope struct data $end +$var wire 8 M \[0] $end +$var wire 8 N \[1] $end +$var wire 8 O \[2] $end +$var wire 8 P \[3] $end +$var wire 8 Q \[4] $end +$var wire 8 R \[5] $end +$var wire 8 S \[6] $end +$var wire 8 T \[7] $end +$upscope $end +$scope struct mask $end +$var wire 1 U \[0] $end +$var wire 1 V \[1] $end +$var wire 1 W \[2] $end +$var wire 1 X \[3] $end +$var wire 1 Y \[4] $end +$var wire 1 Z \[5] $end +$var wire 1 [ \[6] $end +$var wire 1 \ \[7] $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +$dumpvars +b0 ] +b0 e +b0 m +b0 u +b0 } +b0 '" +b0 /" +b0 7" +b0 ^ +b0 f +b0 n +b0 v +b0 ~ +b0 (" +b0 0" +b0 8" +b0 _ +b0 g +b0 o +b0 w +b0 !" +b0 )" +b0 1" +b0 9" +b0 ` +b0 h +b0 p +b0 x +b0 "" +b0 *" +b0 2" +b0 :" +b0 a +b0 i +b0 q +b0 y +b0 #" +b0 +" +b0 3" +b0 ;" +b0 b +b0 j +b0 r +b0 z +b0 $" +b0 ," +b0 4" +b0 <" +b0 c +b0 k +b0 s +b0 { +b0 %" +b0 -" +b0 5" +b0 =" +b0 d +b0 l +b0 t +b0 | +b0 &" +b0 ." +b0 6" +b0 >" +b0 ! +0" +0# +b0 $ +b0 % +b0 & +b0 ' +b0 ( +b0 ) +b0 * +b0 + +b0 , +1- +0. +b10010 / +b110100 0 +b1010110 1 +b1111000 2 +b10011010 3 +b10111100 4 +b11011110 5 +b11110000 6 +07 +18 +09 +1: +1; +0< +0= +1> +b0 ? +0@ +0A +b0 B +b0 C +b0 D +b0 E +b0 F +b0 G +b0 H +b0 I +b0 J +1K +0L +b10010 M +b110100 N +b1010110 O +b1111000 P +b10011010 Q +b10111100 R +b11011110 S +b11110000 T +0U +1V +0W +1X +1Y +0Z +0[ +1\ +$end +#250000 +1# +1. +1A +1L +#500000 +#750000 +0# +0. +0A +0L +#1000000 +1" +b1 , +0- +b0 / +b0 0 +b0 1 +b0 2 +b0 3 +b0 4 +b0 5 +b0 6 +08 +0: +0; +0> +1@ +b1 J +0K +b0 M +b0 N +b0 O +b0 P +b0 Q +b0 R +b0 S +b0 T +0V +0X +0Y +0\ +#1250000 +b0 ] +b110100 e +b0 m +b1111000 u +b10011010 } +b0 '" +b0 /" +b11110000 7" +1# +1. +1A +1L +#1500000 +#1750000 +0# +0. +0A +0L +#2000000 +#2250000 +1# +1. +1A +1L +#2500000 +#2750000 +0# +0. +0A +0L +#3000000 +b0 , +1- +b11111110 / +b11011100 0 +b10111010 1 +b10011000 2 +b1110110 3 +b1010100 4 +b110010 5 +b10000 6 +17 +18 +19 +1: +1; +1< +1= +1> +b0 J +1K +b11111110 M +b11011100 N +b10111010 O +b10011000 P +b1110110 Q +b1010100 R +b110010 S +b10000 T +1U +1V +1W +1X +1Y +1Z +1[ +1\ +#3250000 +1# +1. +1A +b110100 C +b1111000 E +b10011010 F +b11110000 I +1L +b110100 % +b1111000 ' +b10011010 ( +b11110000 + +#3500000 +#3750000 +0# +0. +0A +0L +#4000000 +#4250000 +b11111110 ] +b11011100 e +b10111010 m +b10011000 u +b1110110 } +b1010100 '" +b110010 /" +b10000 7" +1# +1. +1A +1L +#4500000 +#4750000 +0# +0. +0A +0L +#5000000 +#5250000 +b11111110 ] +b11011100 e +b10111010 m +b10011000 u +b1110110 } +b1010100 '" +b110010 /" +b10000 7" +1# +1. +1A +1L +#5500000 +#5750000 +0# +0. +0A +0L +#6000000 +0" +b1 , +b10011 / +b1010111 0 +b10011011 1 +b11011111 2 +b10 3 +b1000110 4 +b10001010 5 +b11001110 6 +0@ +b1 J +b10011 M +b1010111 N +b10011011 O +b11011111 P +b10 Q +b1000110 R +b10001010 S +b11001110 T +#6250000 +b11111110 ] +b11011100 e +b10111010 m +b10011000 u +b1110110 } +b1010100 '" +b110010 /" +b10000 7" +1# +1. +1A +b11111110 B +b11011100 C +b10111010 D +b10011000 E +b1110110 F +b1010100 G +b110010 H +b10000 I +1L +b11111110 $ +b11011100 % +b10111010 & +b10011000 ' +b1110110 ( +b1010100 ) +b110010 * +b10000 + +#6500000 +#6750000 +0# +0. +0A +0L +#7000000 +b10 , +b1110100 / +b1100101 0 +b1110011 1 +b1110100 2 +b1101001 3 +b1101110 4 +b1100111 5 +b100001 6 +b10 J +b1110100 M +b1100101 N +b1110011 O +b1110100 P +b1101001 Q +b1101110 R +b1100111 S +b100001 T +#7250000 +b10011 ^ +b1010111 f +b10011011 n +b11011111 v +b10 ~ +b1000110 (" +b10001010 0" +b11001110 8" +1# +1. +1A +b0 B +b0 C +b0 D +b0 E +b0 F +b0 G +b0 H +b0 I +1L +b0 $ +b0 % +b0 & +b0 ' +b0 ( +b0 ) +b0 * +b0 + +#7500000 +#7750000 +0# +0. +0A +0L +#8000000 +b11 , +b1101101 / +b1101111 0 +b1110010 1 +b1100101 2 +b100000 3 +b1110100 4 +b1110011 5 +b1110100 6 +b11 J +b1101101 M +b1101111 N +b1110010 O +b1100101 P +b100000 Q +b1110100 R +b1110011 S +b1110100 T +#8250000 +b1110100 _ +b1100101 g +b1110011 o +b1110100 w +b1101001 !" +b1101110 )" +b1100111 1" +b100001 9" +1# +1. +1A +1L +#8500000 +#8750000 +0# +0. +0A +0L +#9000000 +1" +b0 , +0- +b0 / +b0 0 +b0 1 +b0 2 +b0 3 +b0 4 +b0 5 +b0 6 +07 +08 +09 +0: +0; +0< +0= +0> +1@ +b0 J +0K +b0 M +b0 N +b0 O +b0 P +b0 Q +b0 R +b0 S +b0 T +0U +0V +0W +0X +0Y +0Z +0[ +0\ +#9250000 +b1101101 ` +b1101111 h +b1110010 p +b1100101 x +b100000 "" +b1110100 *" +b1110011 2" +b1110100 :" +1# +1. +1A +1L +#9500000 +#9750000 +0# +0. +0A +0L +#10000000 +b1 ! +b1 ? +#10250000 +1# +1. +1A +b11111110 B +b11011100 C +b10111010 D +b10011000 E +b1110110 F +b1010100 G +b110010 H +b10000 I +1L +b11111110 $ +b11011100 % +b10111010 & +b10011000 ' +b1110110 ( +b1010100 ) +b110010 * +b10000 + +#10500000 +#10750000 +0# +0. +0A +0L +#11000000 +b10 ! +b10 ? +#11250000 +1# +1. +1A +b10011 B +b1010111 C +b10011011 D +b11011111 E +b10 F +b1000110 G +b10001010 H +b11001110 I +1L +b10011 $ +b1010111 % +b10011011 & +b11011111 ' +b10 ( +b1000110 ) +b10001010 * +b11001110 + +#11500000 +#11750000 +0# +0. +0A +0L +#12000000 +b11 ! +b11 ? +#12250000 +1# +1. +1A +b1110100 B +b1100101 C +b1110011 D +b1110100 E +b1101001 F +b1101110 G +b1100111 H +b100001 I +1L +b1110100 $ +b1100101 % +b1110011 & +b1110100 ' +b1101001 ( +b1101110 ) +b1100111 * +b100001 + +#12500000 +#12750000 +0# +0. +0A +0L +#13000000 +b0 ! +0" +b0 ? +0@ +#13250000 +1# +1. +1A +b1101101 B +b1101111 C +b1110010 D +b1100101 E +b100000 F +b1110100 G +b1110011 H +b1110100 I +1L +b1101101 $ +b1101111 % +b1110010 & +b1100101 ' +b100000 ( +b1110100 ) +b1110011 * +b1110100 + +#13500000 +#13750000 +0# +0. +0A +0L +#14000000 +#14250000 +1# +1. +1A +b0 B +b0 C +b0 D +b0 E +b0 F +b0 G +b0 H +b0 I +1L +b0 $ +b0 % +b0 & +b0 ' +b0 ( +b0 ) +b0 * +b0 + +#14500000 +#14750000 +0# +0. +0A +0L +#15000000 From 21c73051ecd71151999af3c27a82bbe4a1abb7b2 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Wed, 18 Dec 2024 01:39:35 -0800 Subject: [PATCH 04/10] sim: add SimValue and reading/writing more than just a scalar --- crates/fayalite/src/bundle.rs | 125 +- crates/fayalite/src/sim.rs | 768 ++++++++++- crates/fayalite/tests/sim.rs | 39 +- crates/fayalite/tests/sim/expected/enums.txt | 1205 +++++++++++------- crates/fayalite/tests/sim/expected/enums.vcd | 42 +- 5 files changed, 1719 insertions(+), 460 deletions(-) diff --git a/crates/fayalite/src/bundle.rs b/crates/fayalite/src/bundle.rs index 843eb6c..995510e 100644 --- a/crates/fayalite/src/bundle.rs +++ b/crates/fayalite/src/bundle.rs @@ -4,12 +4,14 @@ use crate::{ expr::{ops::BundleLiteral, Expr, ToExpr}, intern::{Intern, Interned}, + sim::{SimValue, ToSimValue}, source_location::SourceLocation, ty::{ impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, StaticType, Type, TypeProperties, TypeWithDeref, }, }; +use bitvec::vec::BitVec; use hashbrown::HashMap; use std::{fmt, marker::PhantomData}; @@ -323,7 +325,7 @@ macro_rules! impl_tuple_builder_fields { } macro_rules! impl_tuples { - ([$({#[num = $num:literal, field = $field:ident] $var:ident: $T:ident})*] []) => { + ([$({#[num = $num:literal, field = $field:ident, ty = $ty_var:ident: $Ty:ident] $var:ident: $T:ident})*] []) => { impl_tuple_builder_fields! { {} [$({ @@ -423,6 +425,79 @@ macro_rules! impl_tuples { BundleLiteral::new(ty, field_values[..].intern()).to_expr() } } + impl<$($T: ToSimValue,)*> ToSimValue for ($($T,)*) { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + ToSimValue::::to_sim_value(self, Bundle::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn into_sim_value(self, ty: CanonicalType) -> SimValue + { + ToSimValue::::into_sim_value(self, Bundle::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + ToSimValue::::box_into_sim_value(self, Bundle::from_canonical(ty)).into_canonical() + } + } + impl<$($T: ToSimValue,)*> ToSimValue for ($($T,)*) { + #[track_caller] + fn to_sim_value(&self, ty: Bundle) -> SimValue { + let ($($var,)*) = self; + let [$($ty_var,)*] = *ty.fields() else { + panic!("bundle has wrong number of fields"); + }; + $(let $var = $var.to_sim_value($ty_var.ty);)* + ToSimValue::into_sim_value(($($var,)*), ty) + } + #[track_caller] + fn into_sim_value(self, ty: Bundle) -> SimValue { + #![allow(unused_mut)] + #![allow(clippy::unused_unit)] + let ($($var,)*) = self; + let [$($ty_var,)*] = *ty.fields() else { + panic!("bundle has wrong number of fields"); + }; + let mut bits: Option = None; + $(let $var = $var.into_sim_value($ty_var.ty); + assert_eq!($var.ty(), $ty_var.ty); + if !$var.bits().is_empty() { + if let Some(bits) = &mut bits { + bits.extend_from_bitslice($var.bits()); + } else { + let mut $var = $var.into_bits(); + $var.reserve(ty.type_properties().bit_width - $var.len()); + bits = Some($var); + } + } + )* + bits.unwrap_or_else(BitVec::new).into_sim_value(ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Bundle) -> SimValue { + Self::into_sim_value(*self, ty) + } + } + impl<$($T: ToSimValue<$Ty>, $Ty: Type,)*> ToSimValue<($($Ty,)*)> for ($($T,)*) { + #[track_caller] + fn to_sim_value(&self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { + let ($($var,)*) = self; + let ($($ty_var,)*) = ty; + $(let $var = $var.to_sim_value($ty_var).into_canonical();)* + SimValue::from_canonical(ToSimValue::into_sim_value(($($var,)*), ty.canonical())) + } + #[track_caller] + fn into_sim_value(self, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { + let ($($var,)*) = self; + let ($($ty_var,)*) = ty; + $(let $var = $var.into_sim_value($ty_var).into_canonical();)* + SimValue::from_canonical(ToSimValue::into_sim_value(($($var,)*), ty.canonical())) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: ($($Ty,)*)) -> SimValue<($($Ty,)*)> { + Self::into_sim_value(*self, ty) + } + } }; ([$($lhs:tt)*] [$rhs_first:tt $($rhs:tt)*]) => { impl_tuples!([$($lhs)*] []); @@ -432,18 +507,18 @@ macro_rules! impl_tuples { impl_tuples! { [] [ - {#[num = 0, field = field_0] v0: T0} - {#[num = 1, field = field_1] v1: T1} - {#[num = 2, field = field_2] v2: T2} - {#[num = 3, field = field_3] v3: T3} - {#[num = 4, field = field_4] v4: T4} - {#[num = 5, field = field_5] v5: T5} - {#[num = 6, field = field_6] v6: T6} - {#[num = 7, field = field_7] v7: T7} - {#[num = 8, field = field_8] v8: T8} - {#[num = 9, field = field_9] v9: T9} - {#[num = 10, field = field_10] v10: T10} - {#[num = 11, field = field_11] v11: T11} + {#[num = 0, field = field_0, ty = ty0: Ty0] v0: T0} + {#[num = 1, field = field_1, ty = ty1: Ty1] v1: T1} + {#[num = 2, field = field_2, ty = ty2: Ty2] v2: T2} + {#[num = 3, field = field_3, ty = ty3: Ty3] v3: T3} + {#[num = 4, field = field_4, ty = ty4: Ty4] v4: T4} + {#[num = 5, field = field_5, ty = ty5: Ty5] v5: T5} + {#[num = 6, field = field_6, ty = ty6: Ty6] v6: T6} + {#[num = 7, field = field_7, ty = ty7: Ty7] v7: T7} + {#[num = 8, field = field_8, ty = ty8: Ty8] v8: T8} + {#[num = 9, field = field_9, ty = ty9: Ty9] v9: T9} + {#[num = 10, field = field_10, ty = ty10: Ty10] v10: T10} + {#[num = 11, field = field_11, ty = ty11: Ty11] v11: T11} ] } @@ -528,3 +603,27 @@ impl ToExpr for PhantomData { BundleLiteral::new(PhantomData, Interned::default()).to_expr() } } + +impl ToSimValue for PhantomData { + #[track_caller] + fn to_sim_value(&self, ty: Self) -> SimValue { + ToSimValue::into_sim_value(BitVec::new(), ty) + } +} + +impl ToSimValue for PhantomData { + #[track_caller] + fn to_sim_value(&self, ty: Bundle) -> SimValue { + assert!(ty.fields().is_empty()); + ToSimValue::into_sim_value(BitVec::new(), ty) + } +} + +impl ToSimValue for PhantomData { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + let ty = Bundle::from_canonical(ty); + assert!(ty.fields().is_empty()); + ToSimValue::into_sim_value(BitVec::new(), ty).into_canonical() + } +} diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index a2b9648..10fbb92 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -14,7 +14,7 @@ use crate::{ }, ExprEnum, Flow, ToLiteralBits, }, - int::BoolOrIntType, + int::{BoolOrIntType, IntType, SIntValue, UIntValue}, intern::{Intern, Interned, Memoize}, memory::PortKind, module::{ @@ -42,7 +42,7 @@ use crate::{ use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView}; use hashbrown::{HashMap, HashSet}; use num_bigint::BigInt; -use num_traits::{Signed, ToPrimitive, Zero}; +use num_traits::{Signed, Zero}; use petgraph::{ data::FromElements, visit::{ @@ -50,7 +50,9 @@ use petgraph::{ IntoNodeIdentifiers, IntoNodeReferences, NodeRef, VisitMap, Visitable, }, }; -use std::{borrow::Cow, collections::BTreeSet, fmt, marker::PhantomData, mem, ops::IndexMut}; +use std::{ + borrow::Cow, collections::BTreeSet, fmt, marker::PhantomData, mem, ops::IndexMut, sync::Arc, +}; mod interpreter; pub mod time; @@ -5806,6 +5808,624 @@ impl SimTraceKind { } } +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct SimValue { + ty: T, + bits: BitVec, +} + +impl SimValue { + #[track_caller] + fn to_expr_impl(ty: CanonicalType, bits: &BitSlice) -> Expr { + match ty { + CanonicalType::UInt(_) => Expr::canonical(::bits_to_expr(Cow::Borrowed(bits))), + CanonicalType::SInt(_) => Expr::canonical(::bits_to_expr(Cow::Borrowed(bits))), + CanonicalType::Bool(_) => Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits))), + CanonicalType::Array(ty) => { + let element_bit_width = ty.element().bit_width(); + Expr::::canonical( + crate::expr::ops::ArrayLiteral::new( + ty.element(), + (0..ty.len()) + .map(|array_index| { + let start = element_bit_width * array_index; + let end = start + element_bit_width; + Self::to_expr_impl(ty.element(), &bits[start..end]) + }) + .collect(), + ) + .to_expr(), + ) + } + CanonicalType::Enum(ty) => { + let discriminant_bit_width = ty.discriminant_bit_width(); + let mut variant_index = [0; mem::size_of::()]; + variant_index.view_bits_mut::()[0..discriminant_bit_width] + .clone_from_bitslice(&bits[..discriminant_bit_width]); + let variant_index = usize::from_le_bytes(variant_index); + if let Some(variant) = ty.variants().get(variant_index) { + let data_bit_width = variant.ty.map_or(0, CanonicalType::bit_width); + Expr::canonical( + crate::expr::ops::EnumLiteral::new_by_index( + ty, + variant_index, + variant.ty.map(|ty| { + Self::to_expr_impl( + ty, + &bits[discriminant_bit_width + ..discriminant_bit_width + data_bit_width], + ) + }), + ) + .to_expr(), + ) + } else { + Expr::canonical(::bits_to_expr(Cow::Borrowed(bits)).cast_bits_to(ty)) + } + } + CanonicalType::Bundle(ty) => Expr::canonical( + crate::expr::ops::BundleLiteral::new( + ty, + ty.fields() + .iter() + .zip(ty.field_offsets().iter()) + .map(|(field, &field_offset)| { + Self::to_expr_impl( + field.ty, + &bits[field_offset..field_offset + field.ty.bit_width()], + ) + }) + .collect(), + ) + .to_expr(), + ), + CanonicalType::AsyncReset(ty) => { + Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits)).cast_to(ty)) + } + CanonicalType::SyncReset(ty) => { + Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits)).cast_to(ty)) + } + CanonicalType::Reset(_) => panic!( + "can't convert SimValue to Expr -- \ + can't deduce whether reset value should be sync or async" + ), + CanonicalType::Clock(ty) => { + Expr::canonical(Bool::bits_to_expr(Cow::Borrowed(bits)).cast_to(ty)) + } + } + } +} + +impl ToExpr for SimValue { + type Type = T; + + #[track_caller] + fn to_expr(&self) -> Expr { + Expr::from_canonical(SimValue::to_expr_impl(self.ty.canonical(), &self.bits)) + } +} + +impl ToSimValue for SimValue { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + assert_eq!(self.ty, ty); + self.clone() + } + + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + assert_eq!(self.ty, ty); + self + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + assert_eq!(self.ty, ty); + *self + } +} + +impl ToSimValue for BitVec { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + self.clone().into_sim_value(ty) + } + + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + assert_eq!(ty.canonical().bit_width(), self.len()); + SimValue { ty, bits: self } + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + Self::into_sim_value(*self, ty) + } +} + +impl ToSimValue for bitvec::boxed::BitBox { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + self.clone().into_sim_value(ty) + } + + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + assert_eq!(ty.canonical().bit_width(), self.len()); + SimValue { + ty, + bits: self.into_bitvec(), + } + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + Self::into_sim_value(*self, ty) + } +} + +impl ToSimValue for BitSlice { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + assert_eq!(ty.canonical().bit_width(), self.len()); + SimValue { + ty, + bits: self.to_bitvec(), + } + } +} + +impl SimValue { + pub fn ty(&self) -> T { + self.ty + } + pub fn bits(&self) -> &BitSlice { + &self.bits + } + pub fn into_bits(self) -> BitVec { + self.bits + } + #[track_caller] + pub fn from_canonical(v: SimValue) -> Self { + Self { + ty: T::from_canonical(v.ty), + bits: v.bits, + } + } + pub fn into_canonical(self) -> SimValue { + SimValue { + ty: self.ty.canonical(), + bits: self.bits, + } + } + #[track_caller] + pub fn from_dyn_int(v: SimValue) -> Self + where + T: IntType, + { + Self { + ty: T::from_dyn_int(v.ty), + bits: v.bits, + } + } + pub fn into_dyn_int(self) -> SimValue + where + T: IntType, + { + SimValue { + ty: self.ty.as_dyn_int(), + bits: self.bits, + } + } + #[track_caller] + pub fn from_bundle(v: SimValue) -> Self + where + T: BundleType, + { + Self { + ty: T::from_canonical(CanonicalType::Bundle(v.ty)), + bits: v.bits, + } + } + pub fn into_bundle(self) -> SimValue + where + T: BundleType, + { + SimValue { + ty: Bundle::from_canonical(self.ty.canonical()), + bits: self.bits, + } + } + #[track_caller] + pub fn from_enum(v: SimValue) -> Self + where + T: EnumType, + { + Self { + ty: T::from_canonical(CanonicalType::Enum(v.ty)), + bits: v.bits, + } + } + pub fn into_enum(self) -> SimValue + where + T: EnumType, + { + SimValue { + ty: Enum::from_canonical(self.ty.canonical()), + bits: self.bits, + } + } +} + +pub trait ToSimValue { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue; + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue + where + Self: Sized, + { + self.to_sim_value(ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + self.to_sim_value(ty) + } +} + +impl, T: Type> ToSimValue for &'_ This { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } +} + +impl, T: Type> ToSimValue for &'_ mut This { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } +} + +impl, T: Type> ToSimValue for Box { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: T) -> SimValue { + This::box_into_sim_value(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: T) -> SimValue { + This::box_into_sim_value(*self, ty) + } +} + +impl + Send + Sync + 'static, T: Type> ToSimValue + for Interned +{ + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + This::to_sim_value(self, ty) + } +} + +impl SimValue> { + #[track_caller] + pub fn from_array_elements< + I: IntoIterator, IntoIter: ExactSizeIterator>, + >( + elements: I, + ty: ArrayType, + ) -> Self { + let mut iter = elements.into_iter(); + assert_eq!(iter.len(), ty.len()); + let Some(first) = iter.next() else { + return SimValue { + ty, + bits: BitVec::new(), + }; + }; + let SimValue { + ty: element_ty, + mut bits, + } = first.into_sim_value(ty.element()); + assert_eq!(element_ty, ty.element()); + bits.reserve(ty.type_properties().bit_width - bits.len()); + for element in iter { + let SimValue { + ty: element_ty, + bits: element_bits, + } = element.into_sim_value(ty.element()); + assert_eq!(element_ty, ty.element()); + bits.extend_from_bitslice(&element_bits); + } + SimValue { ty, bits } + } +} + +impl, T: Type> ToSimValue> for [Element] { + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } +} + +impl> ToSimValue for [Element] { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } +} + +impl, T: Type, const N: usize> ToSimValue> for [Element; N] +where + ConstUsize: KnownSize, +{ + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements( as From>>::from(self), ty) + } +} + +impl, T: Type, const N: usize> ToSimValue> for [Element; N] +where + ConstUsize: KnownSize, +{ + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements( as From>>::from(self), ty) + } +} + +impl, const N: usize> ToSimValue + for [Element; N] +{ + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn into_sim_value(self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements( + as From>>::from(self), + ::from_canonical(ty), + ) + .into_canonical() + } +} + +impl, T: Type> ToSimValue> for Vec { + #[track_caller] + fn to_sim_value(&self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn into_sim_value(self, ty: Array) -> SimValue> { + SimValue::from_array_elements(self, ty) + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: Array) -> SimValue> { + SimValue::from_array_elements(*self, ty) + } +} + +impl> ToSimValue for Vec { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn into_sim_value(self, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(self, ::from_canonical(ty)).into_canonical() + } + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + SimValue::from_array_elements(*self, ::from_canonical(ty)).into_canonical() + } +} + +impl ToSimValue for Expr { + #[track_caller] + fn to_sim_value(&self, ty: T) -> SimValue { + assert_eq!(Expr::ty(*self), ty); + SimValue { + ty, + bits: self + .to_literal_bits() + .expect("must be a literal expression") + .to_bitvec(), + } + } +} + +macro_rules! impl_to_sim_value_for_bool_like { + ($ty:ident) => { + impl ToSimValue<$ty> for bool { + fn to_sim_value(&self, ty: $ty) -> SimValue<$ty> { + SimValue { + ty, + bits: BitVec::repeat(*self, 1), + } + } + } + }; +} + +impl_to_sim_value_for_bool_like!(Bool); +impl_to_sim_value_for_bool_like!(AsyncReset); +impl_to_sim_value_for_bool_like!(SyncReset); +impl_to_sim_value_for_bool_like!(Reset); +impl_to_sim_value_for_bool_like!(Clock); + +impl ToSimValue for bool { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + match ty { + CanonicalType::UInt(_) + | CanonicalType::SInt(_) + | CanonicalType::Array(_) + | CanonicalType::Enum(_) + | CanonicalType::Bundle(_) => { + panic!("can't create SimValue from bool: expected value of type: {ty:?}"); + } + CanonicalType::Bool(_) + | CanonicalType::AsyncReset(_) + | CanonicalType::SyncReset(_) + | CanonicalType::Reset(_) + | CanonicalType::Clock(_) => SimValue { + ty, + bits: BitVec::repeat(*self, 1), + }, + } + } +} + +macro_rules! impl_to_sim_value_for_primitive_int { + ($prim:ident) => { + impl ToSimValue<<$prim as ToExpr>::Type> for $prim { + #[track_caller] + fn to_sim_value( + &self, + ty: <$prim as ToExpr>::Type, + ) -> SimValue<<$prim as ToExpr>::Type> { + SimValue { + ty, + bits: <<$prim as ToExpr>::Type as BoolOrIntType>::le_bytes_to_bits_wrapping( + &self.to_le_bytes(), + ty.width(), + ), + } + } + } + + impl ToSimValue<<<$prim as ToExpr>::Type as IntType>::Dyn> for $prim { + #[track_caller] + fn to_sim_value( + &self, + ty: <<$prim as ToExpr>::Type as IntType>::Dyn, + ) -> SimValue<<<$prim as ToExpr>::Type as IntType>::Dyn> { + SimValue { + ty, + bits: <<$prim as ToExpr>::Type as BoolOrIntType>::le_bytes_to_bits_wrapping( + &self.to_le_bytes(), + ty.width(), + ), + } + } + } + + impl ToSimValue for $prim { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + let ty: <<$prim as ToExpr>::Type as IntType>::Dyn = Type::from_canonical(ty); + self.to_sim_value(ty).into_canonical() + } + } + }; +} + +impl_to_sim_value_for_primitive_int!(u8); +impl_to_sim_value_for_primitive_int!(u16); +impl_to_sim_value_for_primitive_int!(u32); +impl_to_sim_value_for_primitive_int!(u64); +impl_to_sim_value_for_primitive_int!(u128); +impl_to_sim_value_for_primitive_int!(usize); +impl_to_sim_value_for_primitive_int!(i8); +impl_to_sim_value_for_primitive_int!(i16); +impl_to_sim_value_for_primitive_int!(i32); +impl_to_sim_value_for_primitive_int!(i64); +impl_to_sim_value_for_primitive_int!(i128); +impl_to_sim_value_for_primitive_int!(isize); + +macro_rules! impl_to_sim_value_for_int_value { + ($IntValue:ident, $Int:ident, $IntType:ident) => { + impl ToSimValue<$IntType> for $IntValue { + fn to_sim_value(&self, ty: $IntType) -> SimValue<$IntType> { + self.bits().to_bitvec().into_sim_value(ty) + } + + fn into_sim_value(self, ty: $IntType) -> SimValue<$IntType> { + Arc::try_unwrap(self.into_bits()) + .unwrap_or_else(|v: Arc| v.to_bitvec()) + .into_sim_value(ty) + } + + fn box_into_sim_value( + self: Box, + ty: $IntType, + ) -> SimValue<$IntType> { + Self::into_sim_value(*self, ty) + } + } + + impl ToSimValue<$Int> for $IntValue { + fn to_sim_value(&self, ty: $Int) -> SimValue<$Int> { + self.bits().to_bitvec().into_sim_value(ty) + } + + fn into_sim_value(self, ty: $Int) -> SimValue<$Int> { + Arc::try_unwrap(self.into_bits()) + .unwrap_or_else(|v: Arc| v.to_bitvec()) + .into_sim_value(ty) + } + + fn box_into_sim_value(self: Box, ty: $Int) -> SimValue<$Int> { + Self::into_sim_value(*self, ty) + } + } + + impl ToSimValue for $IntValue { + #[track_caller] + fn to_sim_value(&self, ty: CanonicalType) -> SimValue { + ToSimValue::<$Int>::to_sim_value(self, $Int::from_canonical(ty)).into_canonical() + } + + #[track_caller] + fn into_sim_value(self, ty: CanonicalType) -> SimValue { + ToSimValue::<$Int>::into_sim_value(self, $Int::from_canonical(ty)).into_canonical() + } + + #[track_caller] + fn box_into_sim_value(self: Box, ty: CanonicalType) -> SimValue { + Self::into_sim_value(*self, ty) + } + } + }; +} + +impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType); +impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType); + struct SimulationImpl { state: interpreter::State, io: Expr, @@ -6263,8 +6883,11 @@ impl SimulationImpl { let value: BigInt = value.into(); match compiled_value.range.len() { TypeLen::A_SMALL_SLOT => { - self.state.small_slots[compiled_value.range.small_slots.start] = - value.to_u64().expect("value out of range"); + let mut small_value = value.iter_u64_digits().next().unwrap_or(0); + if value.is_negative() { + small_value = small_value.wrapping_neg(); + } + self.state.small_slots[compiled_value.range.small_slots.start] = small_value; } TypeLen::A_BIG_SLOT => { self.state.big_slots[compiled_value.range.big_slots.start] = value @@ -6272,6 +6895,130 @@ impl SimulationImpl { _ => unreachable!(), } } + #[track_caller] + fn read_write_sim_value_helper( + &mut self, + compiled_value: CompiledValue, + bits: &mut BitSlice, + read_write_big_scalar: impl Fn(bool, &mut BitSlice, &mut BigInt) + Copy, + read_write_small_scalar: impl Fn(bool, &mut BitSlice, &mut SmallUInt) + Copy, + ) { + match compiled_value.layout.body { + CompiledTypeLayoutBody::Scalar => { + let signed = match compiled_value.layout.ty { + CanonicalType::UInt(_) => false, + CanonicalType::SInt(_) => true, + CanonicalType::Bool(_) => false, + CanonicalType::Array(_) => unreachable!(), + CanonicalType::Enum(_) => false, + CanonicalType::Bundle(_) => unreachable!(), + CanonicalType::AsyncReset(_) => false, + CanonicalType::SyncReset(_) => false, + CanonicalType::Reset(_) => false, + CanonicalType::Clock(_) => false, + }; + match compiled_value.range.len() { + TypeLen::A_SMALL_SLOT => read_write_small_scalar( + signed, + bits, + &mut self.state.small_slots[compiled_value.range.small_slots.start], + ), + TypeLen::A_BIG_SLOT => read_write_big_scalar( + signed, + bits, + &mut self.state.big_slots[compiled_value.range.big_slots.start], + ), + _ => unreachable!(), + } + } + CompiledTypeLayoutBody::Array { element } => { + let ty = ::from_canonical(compiled_value.layout.ty); + let element_bit_width = ty.element().bit_width(); + for element_index in 0..ty.len() { + self.read_write_sim_value_helper( + CompiledValue { + layout: *element, + range: compiled_value + .range + .index_array(element.layout.len(), element_index), + write: None, + }, + &mut bits[element_index * element_bit_width..][..element_bit_width], + read_write_big_scalar, + read_write_small_scalar, + ); + } + } + CompiledTypeLayoutBody::Bundle { fields } => { + let ty = Bundle::from_canonical(compiled_value.layout.ty); + for ( + (field, offset), + CompiledBundleField { + offset: layout_offset, + ty: field_layout, + }, + ) in ty.fields().iter().zip(ty.field_offsets()).zip(fields) + { + self.read_write_sim_value_helper( + CompiledValue { + layout: field_layout, + range: compiled_value.range.slice(TypeIndexRange::new( + layout_offset, + field_layout.layout.len(), + )), + write: None, + }, + &mut bits[offset..][..field.ty.bit_width()], + read_write_big_scalar, + read_write_small_scalar, + ); + } + } + } + } + #[track_caller] + fn read(&mut self, io: Expr) -> SimValue { + let compiled_value = self.read_helper(io); + let mut bits = BitVec::repeat(false, compiled_value.layout.ty.bit_width()); + self.read_write_sim_value_helper( + compiled_value, + &mut bits, + |_signed, bits, value| ::copy_bits_from_bigint_wrapping(value, bits), + |_signed, bits, value| { + let bytes = value.to_le_bytes(); + let bitslice = BitSlice::::from_slice(&bytes); + bits.clone_from_bitslice(&bitslice[..bits.len()]); + }, + ); + SimValue { + ty: Expr::ty(io), + bits, + } + } + #[track_caller] + fn write(&mut self, io: Expr, value: SimValue) { + let compiled_value = self.write_helper(io); + assert_eq!(Expr::ty(io), value.ty()); + self.read_write_sim_value_helper( + compiled_value, + &mut value.into_bits(), + |signed, bits, value| { + if signed { + *value = SInt::bits_to_bigint(bits); + } else { + *value = UInt::bits_to_bigint(bits); + } + }, + |signed, bits, value| { + let mut small_value = [0; mem::size_of::()]; + if signed && bits.last().as_deref().copied() == Some(true) { + small_value.fill(u8::MAX); + } + small_value.view_bits_mut::()[0..bits.len()].clone_from_bitslice(bits); + *value = SmallUInt::from_le_bytes(small_value); + }, + ); + } fn close_all_trace_writers(&mut self) -> std::io::Result<()> { let trace_writers = mem::take(&mut self.trace_writers); let mut retval = Ok(()); @@ -6525,6 +7272,17 @@ impl Simulation { pub fn read_reset(&mut self, io: Expr) -> bool { self.sim_impl.read_bit(Expr::canonical(io)) } + #[track_caller] + pub fn read(&mut self, io: Expr) -> SimValue { + SimValue::from_canonical(self.sim_impl.read(Expr::canonical(io))) + } + #[track_caller] + pub fn write>(&mut self, io: Expr, value: V) { + self.sim_impl.write( + Expr::canonical(io), + value.into_sim_value(Expr::ty(io)).into_canonical(), + ); + } #[doc(hidden)] /// This is explicitly unstable and may be changed/removed at any time pub fn set_breakpoints_unstable(&mut self, pcs: HashSet, trace: bool) { diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index 008d792..bea7d93 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -5,7 +5,8 @@ use fayalite::{ int::UIntValue, prelude::*, reset::ResetType, - sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation}, + sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue}, + ty::StaticType, util::RcWriter, }; use std::num::NonZeroUsize; @@ -309,6 +310,8 @@ pub fn enums() { let which_out: UInt<2> = m.output(); #[hdl] let data_out: UInt<4> = m.output(); + #[hdl] + let b_out: HdlOption<(UInt<1>, Bool)> = m.output(); #[hdl] struct MyStruct { @@ -348,6 +351,8 @@ pub fn enums() { } } + connect(b_out, HdlNone()); + #[hdl] match the_reg { MyEnum::A => { @@ -357,6 +362,7 @@ pub fn enums() { MyEnum::B(v) => { connect(which_out, 1_hdl_u2); connect_any(data_out, v.0 | (v.1.cast_to_static::>() << 1)); + connect(b_out, HdlSome(v)); } MyEnum::C(v) => { connect(which_out, 2_hdl_u2); @@ -382,13 +388,33 @@ fn test_enums() { sim.advance_time(SimDuration::from_nanos(100)); sim.write_reset(sim.io().cd.rst, false); sim.advance_time(SimDuration::from_nanos(900)); - #[derive(Debug, PartialEq, Eq)] + type BOutTy = HdlOption<(UInt<1>, Bool)>; + #[derive(Debug)] struct IO { en: bool, which_in: u8, data_in: u8, which_out: u8, data_out: u8, + b_out: Expr, + } + impl PartialEq for IO { + fn eq(&self, other: &Self) -> bool { + let Self { + en, + which_in, + data_in, + which_out, + data_out, + b_out, + } = *self; + en == other.en + && which_in == other.which_in + && data_in == other.data_in + && which_out == other.which_out + && data_out == other.data_out + && b_out.to_sim_value(BOutTy::TYPE) == other.b_out.to_sim_value(BOutTy::TYPE) + } } let io_cycles = [ IO { @@ -397,6 +423,7 @@ fn test_enums() { data_in: 0, which_out: 0, data_out: 0, + b_out: HdlNone(), }, IO { en: true, @@ -404,6 +431,7 @@ fn test_enums() { data_in: 0, which_out: 0, data_out: 0, + b_out: HdlNone(), }, IO { en: false, @@ -411,6 +439,7 @@ fn test_enums() { data_in: 0, which_out: 1, data_out: 0, + b_out: HdlSome((0_hdl_u1, false)), }, IO { en: true, @@ -418,6 +447,7 @@ fn test_enums() { data_in: 0xF, which_out: 1, data_out: 0, + b_out: HdlSome((0_hdl_u1, false)), }, IO { en: true, @@ -425,6 +455,7 @@ fn test_enums() { data_in: 0xF, which_out: 1, data_out: 0x3, + b_out: HdlSome((1_hdl_u1, true)), }, IO { en: true, @@ -432,6 +463,7 @@ fn test_enums() { data_in: 0xF, which_out: 1, data_out: 0x3, + b_out: HdlSome((1_hdl_u1, true)), }, IO { en: true, @@ -439,6 +471,7 @@ fn test_enums() { data_in: 0xF, which_out: 2, data_out: 0xF, + b_out: HdlNone(), }, ]; for ( @@ -449,6 +482,7 @@ fn test_enums() { data_in, which_out: _, data_out: _, + b_out: _, }, ) in io_cycles.into_iter().enumerate() { @@ -469,6 +503,7 @@ fn test_enums() { .to_bigint() .try_into() .expect("known to be in range"), + b_out: sim.read(sim.io().b_out).to_expr(), }; assert_eq!( expected, diff --git a/crates/fayalite/tests/sim/expected/enums.txt b/crates/fayalite/tests/sim/expected/enums.txt index ebdcf7e..ebfae3e 100644 --- a/crates/fayalite/tests/sim/expected/enums.txt +++ b/crates/fayalite/tests/sim/expected/enums.txt @@ -4,8 +4,15 @@ Simulation { state_layout: StateLayout { ty: TypeLayout { small_slots: StatePartLayout { - len: 5, + len: 6, debug_data: [ + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome, + }, + }, SlotDebugData { name: "", ty: Bool, @@ -34,7 +41,7 @@ Simulation { .. }, big_slots: StatePartLayout { - len: 82, + len: 103, debug_data: [ SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.clk", @@ -64,6 +71,41 @@ Simulation { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4>, }, + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::b_out", + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + }, + SlotDebugData { + name: ".0", + ty: UInt<1>, + }, + SlotDebugData { + name: ".1", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: Bool, + }, SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum { @@ -344,6 +386,17 @@ Simulation { C(Bundle {a: Array, 2>, b: SInt<2>}), }, }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + }, SlotDebugData { name: "", ty: UInt<4>, @@ -364,6 +417,53 @@ Simulation { name: "", ty: UInt<4>, }, + SlotDebugData { + name: ".0", + ty: UInt<1>, + }, + SlotDebugData { + name: ".1.0", + ty: UInt<1>, + }, + SlotDebugData { + name: ".1.1", + ty: Bool, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: UInt<1>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<2>, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: UInt<3>, + }, + SlotDebugData { + name: "", + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + }, SlotDebugData { name: "", ty: UInt<2>, @@ -398,490 +498,601 @@ Simulation { insns: [ // at: module-XXXXXXXXXX.rs:1:1 0: Const { - dest: StatePartIndex(72), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, - value: 0x0, - }, - 1: SliceInt { - dest: StatePartIndex(61), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, - start: 2, - len: 2, - }, - 2: CastToSInt { - dest: StatePartIndex(62), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, - src: StatePartIndex(61), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - dest_width: 2, - }, - 3: Const { - dest: StatePartIndex(54), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - value: 0x2, - }, - 4: SliceInt { - dest: StatePartIndex(41), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, - start: 1, - len: 1, - }, - 5: Copy { - dest: StatePartIndex(42), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(41), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - }, - 6: Copy { - dest: StatePartIndex(60), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(42), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 7: SliceInt { - dest: StatePartIndex(38), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, - start: 0, - len: 1, - }, - 8: Copy { - dest: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(38), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - }, - 9: Copy { - dest: StatePartIndex(40), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 10: Copy { - dest: StatePartIndex(36), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - src: StatePartIndex(40), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - }, - 11: Copy { - dest: StatePartIndex(37), // (0x1) SlotDebugData { name: ".1", ty: Bool }, - src: StatePartIndex(42), // (0x1) SlotDebugData { name: "", ty: Bool }, - }, - 12: Copy { - dest: StatePartIndex(58), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, - src: StatePartIndex(40), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - }, - 13: Copy { - dest: StatePartIndex(59), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, - src: StatePartIndex(60), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - }, - 14: Copy { - dest: StatePartIndex(55), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, - src: StatePartIndex(58), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, - }, - 15: Copy { - dest: StatePartIndex(56), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, - src: StatePartIndex(59), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, - }, - 16: Copy { - dest: StatePartIndex(57), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, - src: StatePartIndex(62), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, - }, - 17: Copy { - dest: StatePartIndex(50), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, - src: StatePartIndex(54), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - }, - 18: Copy { - dest: StatePartIndex(51), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, - src: StatePartIndex(55), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, - }, - 19: Copy { - dest: StatePartIndex(52), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, - src: StatePartIndex(56), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, - }, - 20: Copy { - dest: StatePartIndex(53), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, - src: StatePartIndex(57), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, - }, - 21: Shl { - dest: StatePartIndex(63), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(52), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, - rhs: 1, - }, - 22: Or { - dest: StatePartIndex(64), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(51), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, - rhs: StatePartIndex(63), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - }, - 23: CastToUInt { - dest: StatePartIndex(65), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(53), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, - dest_width: 2, - }, - 24: Shl { - dest: StatePartIndex(66), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(65), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - rhs: 2, - }, - 25: Or { - dest: StatePartIndex(67), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(64), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - rhs: StatePartIndex(66), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - }, - 26: Shl { - dest: StatePartIndex(68), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, - lhs: StatePartIndex(67), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, - rhs: 2, - }, - 27: Or { - dest: StatePartIndex(69), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - lhs: StatePartIndex(50), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, - rhs: StatePartIndex(68), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, - }, - 28: CastToUInt { - dest: StatePartIndex(70), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - src: StatePartIndex(69), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - dest_width: 6, - }, - 29: Copy { - dest: StatePartIndex(71), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(70), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - }, - 30: Const { - dest: StatePartIndex(31), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + dest: StatePartIndex(90), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, value: 0x1, }, - 31: CmpEq { - dest: StatePartIndex(32), // (0x0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(3), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_in", ty: UInt<2> }, - rhs: StatePartIndex(31), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, - }, - 32: Copy { - dest: StatePartIndex(33), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, - src: StatePartIndex(31), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, - }, - 33: Copy { - dest: StatePartIndex(34), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, - src: StatePartIndex(36), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - }, - 34: Copy { - dest: StatePartIndex(35), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, - src: StatePartIndex(37), // (0x1) SlotDebugData { name: ".1", ty: Bool }, - }, - 35: Copy { - dest: StatePartIndex(43), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(35), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, - }, - 36: Shl { - dest: StatePartIndex(44), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(43), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - rhs: 1, - }, - 37: Or { - dest: StatePartIndex(45), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(34), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, - rhs: StatePartIndex(44), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - }, - 38: Shl { - dest: StatePartIndex(46), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(45), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - rhs: 2, - }, - 39: Or { - dest: StatePartIndex(47), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(33), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, - rhs: StatePartIndex(46), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - }, - 40: CastToUInt { - dest: StatePartIndex(48), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, - src: StatePartIndex(47), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, - dest_width: 6, - }, - 41: Copy { - dest: StatePartIndex(49), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(48), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, - }, - 42: Const { - dest: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + 1: Const { + dest: StatePartIndex(82), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, value: 0x0, }, - 43: CmpEq { - dest: StatePartIndex(30), // (0x0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(3), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_in", ty: UInt<2> }, - rhs: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + 2: Const { + dest: StatePartIndex(80), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, + value: 0x0, }, - 44: Copy { - dest: StatePartIndex(13), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, - src: StatePartIndex(7), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + 3: Copy { + dest: StatePartIndex(81), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(80), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, }, - 45: SliceInt { - dest: StatePartIndex(14), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(13), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + // at: module-XXXXXXXXXX.rs:16:1 + 4: Copy { + dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(81), // (0x0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 5: SliceInt { + dest: StatePartIndex(69), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, start: 2, len: 2, }, - 46: SliceInt { - dest: StatePartIndex(15), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(14), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - start: 0, - len: 1, + 6: CastToSInt { + dest: StatePartIndex(70), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + src: StatePartIndex(69), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + dest_width: 2, }, - 47: SliceInt { - dest: StatePartIndex(16), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(14), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + 7: Const { + dest: StatePartIndex(62), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + value: 0x2, + }, + 8: SliceInt { + dest: StatePartIndex(49), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, start: 1, len: 1, }, - 48: Copy { - dest: StatePartIndex(17), // (0x1) SlotDebugData { name: "", ty: Bool }, - src: StatePartIndex(16), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + 9: Copy { + dest: StatePartIndex(50), // (0x1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(49), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, - 49: Copy { - dest: StatePartIndex(11), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - src: StatePartIndex(15), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + 10: Copy { + dest: StatePartIndex(68), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(50), // (0x1) SlotDebugData { name: "", ty: Bool }, }, - 50: Copy { - dest: StatePartIndex(12), // (0x1) SlotDebugData { name: ".1", ty: Bool }, - src: StatePartIndex(17), // (0x1) SlotDebugData { name: "", ty: Bool }, + 11: SliceInt { + dest: StatePartIndex(46), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(4), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_in", ty: UInt<4> }, + start: 0, + len: 1, }, - 51: Copy { - dest: StatePartIndex(73), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(12), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + 12: Copy { + dest: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(46), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, - 52: Shl { - dest: StatePartIndex(74), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(73), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + 13: Copy { + dest: StatePartIndex(48), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(47), // (0x1) SlotDebugData { name: "", ty: Bool }, + }, + 14: Copy { + dest: StatePartIndex(44), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(48), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 15: Copy { + dest: StatePartIndex(45), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + src: StatePartIndex(50), // (0x1) SlotDebugData { name: "", ty: Bool }, + }, + 16: Copy { + dest: StatePartIndex(66), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + src: StatePartIndex(48), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 17: Copy { + dest: StatePartIndex(67), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + src: StatePartIndex(68), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 18: Copy { + dest: StatePartIndex(63), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + src: StatePartIndex(66), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + }, + 19: Copy { + dest: StatePartIndex(64), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + src: StatePartIndex(67), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + }, + 20: Copy { + dest: StatePartIndex(65), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + src: StatePartIndex(70), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + }, + 21: Copy { + dest: StatePartIndex(58), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, + src: StatePartIndex(62), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + }, + 22: Copy { + dest: StatePartIndex(59), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, + src: StatePartIndex(63), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + }, + 23: Copy { + dest: StatePartIndex(60), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, + src: StatePartIndex(64), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + }, + 24: Copy { + dest: StatePartIndex(61), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, + src: StatePartIndex(65), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + }, + 25: Shl { + dest: StatePartIndex(71), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(60), // (0x1) SlotDebugData { name: ".1.a[1]", ty: UInt<1> }, rhs: 1, }, - 53: Or { - dest: StatePartIndex(75), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(11), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, - rhs: StatePartIndex(74), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + 26: Or { + dest: StatePartIndex(72), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(59), // (0x1) SlotDebugData { name: ".1.a[0]", ty: UInt<1> }, + rhs: StatePartIndex(71), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, - 54: CastToUInt { - dest: StatePartIndex(76), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(75), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + 27: CastToUInt { + dest: StatePartIndex(73), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(61), // (-0x1) SlotDebugData { name: ".1.b", ty: SInt<2> }, + dest_width: 2, + }, + 28: Shl { + dest: StatePartIndex(74), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(73), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + rhs: 2, + }, + 29: Or { + dest: StatePartIndex(75), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(72), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + rhs: StatePartIndex(74), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + }, + 30: Shl { + dest: StatePartIndex(76), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, + lhs: StatePartIndex(75), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + rhs: 2, + }, + 31: Or { + dest: StatePartIndex(77), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + lhs: StatePartIndex(58), // (0x2) SlotDebugData { name: ".0", ty: UInt<2> }, + rhs: StatePartIndex(76), // (0x3c) SlotDebugData { name: "", ty: UInt<6> }, + }, + 32: CastToUInt { + dest: StatePartIndex(78), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + src: StatePartIndex(77), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + dest_width: 6, + }, + 33: Copy { + dest: StatePartIndex(79), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(78), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + }, + 34: Const { + dest: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + value: 0x1, + }, + 35: CmpEq { + dest: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(3), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_in", ty: UInt<2> }, + rhs: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + }, + 36: Copy { + dest: StatePartIndex(41), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, + src: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + }, + 37: Copy { + dest: StatePartIndex(42), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, + src: StatePartIndex(44), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + }, + 38: Copy { + dest: StatePartIndex(43), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + src: StatePartIndex(45), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + }, + 39: Copy { + dest: StatePartIndex(51), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(43), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + }, + 40: Shl { + dest: StatePartIndex(52), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(51), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + rhs: 1, + }, + 41: Or { + dest: StatePartIndex(53), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(42), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, + rhs: StatePartIndex(52), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + }, + 42: Shl { + dest: StatePartIndex(54), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(53), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + rhs: 2, + }, + 43: Or { + dest: StatePartIndex(55), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(41), // (0x1) SlotDebugData { name: ".0", ty: UInt<2> }, + rhs: StatePartIndex(54), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + }, + 44: CastToUInt { + dest: StatePartIndex(56), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, + src: StatePartIndex(55), // (0xd) SlotDebugData { name: "", ty: UInt<4> }, + dest_width: 6, + }, + 45: Copy { + dest: StatePartIndex(57), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(56), // (0xd) SlotDebugData { name: "", ty: UInt<6> }, + }, + 46: Const { + dest: StatePartIndex(37), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + value: 0x0, + }, + 47: CmpEq { + dest: StatePartIndex(38), // (0x0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(3), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_in", ty: UInt<2> }, + rhs: StatePartIndex(37), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + }, + 48: Copy { + dest: StatePartIndex(21), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + src: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + }, + 49: SliceInt { + dest: StatePartIndex(22), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(21), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + start: 2, + len: 2, + }, + 50: SliceInt { + dest: StatePartIndex(23), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(22), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + start: 0, + len: 1, + }, + 51: SliceInt { + dest: StatePartIndex(24), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(22), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + start: 1, + len: 1, + }, + 52: Copy { + dest: StatePartIndex(25), // (0x1) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(24), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 53: Copy { + dest: StatePartIndex(19), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(23), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 54: Copy { + dest: StatePartIndex(20), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + src: StatePartIndex(25), // (0x1) SlotDebugData { name: "", ty: Bool }, + }, + 55: Copy { + dest: StatePartIndex(83), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(20), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + }, + 56: Shl { + dest: StatePartIndex(84), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(83), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + rhs: 1, + }, + 57: Or { + dest: StatePartIndex(85), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(19), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + rhs: StatePartIndex(84), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + }, + 58: CastToUInt { + dest: StatePartIndex(86), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(85), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, dest_width: 4, }, - 55: SliceInt { - dest: StatePartIndex(23), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, - src: StatePartIndex(13), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, + 59: Copy { + dest: StatePartIndex(87), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(90), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + }, + 60: Copy { + dest: StatePartIndex(88), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, + src: StatePartIndex(19), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + }, + 61: Copy { + dest: StatePartIndex(89), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + src: StatePartIndex(20), // (0x1) SlotDebugData { name: ".1", ty: Bool }, + }, + 62: Copy { + dest: StatePartIndex(91), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(89), // (0x1) SlotDebugData { name: ".1.1", ty: Bool }, + }, + 63: Shl { + dest: StatePartIndex(92), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(91), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + rhs: 1, + }, + 64: Or { + dest: StatePartIndex(93), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(88), // (0x1) SlotDebugData { name: ".1.0", ty: UInt<1> }, + rhs: StatePartIndex(92), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + }, + 65: Shl { + dest: StatePartIndex(94), // (0x6) SlotDebugData { name: "", ty: UInt<3> }, + lhs: StatePartIndex(93), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + rhs: 1, + }, + 66: Or { + dest: StatePartIndex(95), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + lhs: StatePartIndex(87), // (0x1) SlotDebugData { name: ".0", ty: UInt<1> }, + rhs: StatePartIndex(94), // (0x6) SlotDebugData { name: "", ty: UInt<3> }, + }, + 67: CastToUInt { + dest: StatePartIndex(96), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(95), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + dest_width: 3, + }, + 68: Copy { + dest: StatePartIndex(97), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(96), // (0x7) SlotDebugData { name: "", ty: UInt<3> }, + }, + 69: SliceInt { + dest: StatePartIndex(31), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(21), // (0x3e) SlotDebugData { name: "", ty: UInt<6> }, start: 2, len: 4, }, - 56: SliceInt { - dest: StatePartIndex(24), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(23), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + 70: SliceInt { + dest: StatePartIndex(32), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(31), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, start: 0, len: 2, }, - 57: SliceInt { - dest: StatePartIndex(25), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(24), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + 71: SliceInt { + dest: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(32), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, start: 0, len: 1, }, - 58: SliceInt { - dest: StatePartIndex(26), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, - src: StatePartIndex(24), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + 72: SliceInt { + dest: StatePartIndex(34), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(32), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, start: 1, len: 1, }, - 59: Copy { - dest: StatePartIndex(21), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, - src: StatePartIndex(25), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + 73: Copy { + dest: StatePartIndex(29), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + src: StatePartIndex(33), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, - 60: Copy { - dest: StatePartIndex(22), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, - src: StatePartIndex(26), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, + 74: Copy { + dest: StatePartIndex(30), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + src: StatePartIndex(34), // (0x1) SlotDebugData { name: "", ty: UInt<1> }, }, - 61: SliceInt { - dest: StatePartIndex(27), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(23), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + 75: SliceInt { + dest: StatePartIndex(35), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(31), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, start: 2, len: 2, }, - 62: CastToSInt { - dest: StatePartIndex(28), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, - src: StatePartIndex(27), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + 76: CastToSInt { + dest: StatePartIndex(36), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + src: StatePartIndex(35), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, dest_width: 2, }, - 63: Copy { - dest: StatePartIndex(18), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, - src: StatePartIndex(21), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, + 77: Copy { + dest: StatePartIndex(26), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + src: StatePartIndex(29), // (0x1) SlotDebugData { name: "[0]", ty: UInt<1> }, }, - 64: Copy { - dest: StatePartIndex(19), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, - src: StatePartIndex(22), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, + 78: Copy { + dest: StatePartIndex(27), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + src: StatePartIndex(30), // (0x1) SlotDebugData { name: "[1]", ty: UInt<1> }, }, - 65: Copy { - dest: StatePartIndex(20), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, - src: StatePartIndex(28), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, + 79: Copy { + dest: StatePartIndex(28), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + src: StatePartIndex(36), // (-0x1) SlotDebugData { name: "", ty: SInt<2> }, }, - 66: Shl { - dest: StatePartIndex(77), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(19), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, + 80: Shl { + dest: StatePartIndex(98), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(27), // (0x1) SlotDebugData { name: ".a[1]", ty: UInt<1> }, rhs: 1, }, - 67: Or { - dest: StatePartIndex(78), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - lhs: StatePartIndex(18), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, - rhs: StatePartIndex(77), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + 81: Or { + dest: StatePartIndex(99), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + lhs: StatePartIndex(26), // (0x1) SlotDebugData { name: ".a[0]", ty: UInt<1> }, + rhs: StatePartIndex(98), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, }, - 68: CastToUInt { - dest: StatePartIndex(79), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - src: StatePartIndex(20), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, + 82: CastToUInt { + dest: StatePartIndex(100), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(28), // (-0x1) SlotDebugData { name: ".b", ty: SInt<2> }, dest_width: 2, }, - 69: Shl { - dest: StatePartIndex(80), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(79), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + 83: Shl { + dest: StatePartIndex(101), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(100), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, rhs: 2, }, - 70: Or { - dest: StatePartIndex(81), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, - lhs: StatePartIndex(78), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, - rhs: StatePartIndex(80), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, + 84: Or { + dest: StatePartIndex(102), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + lhs: StatePartIndex(99), // (0x3) SlotDebugData { name: "", ty: UInt<2> }, + rhs: StatePartIndex(101), // (0xc) SlotDebugData { name: "", ty: UInt<4> }, }, - // at: module-XXXXXXXXXX.rs:8:1 - 71: AndBigWithSmallImmediate { - dest: StatePartIndex(4), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, - lhs: StatePartIndex(7), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + // at: module-XXXXXXXXXX.rs:9:1 + 85: AndBigWithSmallImmediate { + dest: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + lhs: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, rhs: 0x3, }, - // at: module-XXXXXXXXXX.rs:15:1 - 72: BranchIfSmallNeImmediate { - target: 75, - lhs: StatePartIndex(4), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + // at: module-XXXXXXXXXX.rs:17:1 + 86: BranchIfSmallNeImmediate { + target: 89, + lhs: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, rhs: 0x0, }, - // at: module-XXXXXXXXXX.rs:16:1 - 73: Copy { - dest: StatePartIndex(5), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_out", ty: UInt<2> }, - src: StatePartIndex(29), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, - }, - // at: module-XXXXXXXXXX.rs:17:1 - 74: Copy { - dest: StatePartIndex(6), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4> }, - src: StatePartIndex(72), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, - }, - // at: module-XXXXXXXXXX.rs:15:1 - 75: BranchIfSmallNeImmediate { - target: 78, - lhs: StatePartIndex(4), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, - rhs: 0x1, - }, // at: module-XXXXXXXXXX.rs:18:1 - 76: Copy { + 87: Copy { dest: StatePartIndex(5), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_out", ty: UInt<2> }, - src: StatePartIndex(31), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(37), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, }, // at: module-XXXXXXXXXX.rs:19:1 - 77: Copy { + 88: Copy { dest: StatePartIndex(6), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4> }, - src: StatePartIndex(76), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(82), // (0x0) SlotDebugData { name: "", ty: UInt<4> }, }, - // at: module-XXXXXXXXXX.rs:15:1 - 78: BranchIfSmallNeImmediate { - target: 81, - lhs: StatePartIndex(4), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, - rhs: 0x2, + // at: module-XXXXXXXXXX.rs:17:1 + 89: BranchIfSmallNeImmediate { + target: 93, + lhs: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + rhs: 0x1, }, // at: module-XXXXXXXXXX.rs:20:1 - 79: Copy { + 90: Copy { dest: StatePartIndex(5), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_out", ty: UInt<2> }, - src: StatePartIndex(54), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(39), // (0x1) SlotDebugData { name: "", ty: UInt<2> }, }, // at: module-XXXXXXXXXX.rs:21:1 - 80: Copy { + 91: Copy { dest: StatePartIndex(6), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4> }, - src: StatePartIndex(81), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + src: StatePartIndex(86), // (0x3) SlotDebugData { name: "", ty: UInt<4> }, }, - // at: module-XXXXXXXXXX.rs:8:1 - 81: IsNonZeroDestIsSmall { - dest: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + // at: module-XXXXXXXXXX.rs:22:1 + 92: Copy { + dest: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + src: StatePartIndex(97), // (0x7) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + }, + // at: module-XXXXXXXXXX.rs:17:1 + 93: BranchIfSmallNeImmediate { + target: 96, + lhs: StatePartIndex(5), // (0x2 2) SlotDebugData { name: "", ty: Enum {A, B, C} }, + rhs: 0x2, + }, + // at: module-XXXXXXXXXX.rs:23:1 + 94: Copy { + dest: StatePartIndex(5), // (0x2) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::which_out", ty: UInt<2> }, + src: StatePartIndex(62), // (0x2) SlotDebugData { name: "", ty: UInt<2> }, + }, + // at: module-XXXXXXXXXX.rs:24:1 + 95: Copy { + dest: StatePartIndex(6), // (0xf) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::data_out", ty: UInt<4> }, + src: StatePartIndex(102), // (0xf) SlotDebugData { name: "", ty: UInt<4> }, + }, + // at: module-XXXXXXXXXX.rs:9:1 + 96: IsNonZeroDestIsSmall { + dest: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(1), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.rst", ty: SyncReset }, }, // at: module-XXXXXXXXXX.rs:1:1 - 82: Const { - dest: StatePartIndex(9), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, + 97: Const { + dest: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, value: 0x0, }, - 83: Copy { - dest: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(9), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, + 98: Copy { + dest: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(17), // (0x0) SlotDebugData { name: "", ty: UInt<6> }, }, - // at: module-XXXXXXXXXX.rs:9:1 - 84: BranchIfZero { - target: 92, + // at: module-XXXXXXXXXX.rs:10:1 + 99: BranchIfZero { + target: 107, value: StatePartIndex(2), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::en", ty: Bool }, }, - // at: module-XXXXXXXXXX.rs:10:1 - 85: BranchIfZero { - target: 87, - value: StatePartIndex(30), // (0x0) SlotDebugData { name: "", ty: Bool }, + // at: module-XXXXXXXXXX.rs:11:1 + 100: BranchIfZero { + target: 102, + value: StatePartIndex(38), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:12:1 + 101: Copy { + dest: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, }, // at: module-XXXXXXXXXX.rs:11:1 - 86: Copy { - dest: StatePartIndex(8), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - }, - // at: module-XXXXXXXXXX.rs:10:1 - 87: BranchIfNonZero { - target: 92, - value: StatePartIndex(30), // (0x0) SlotDebugData { name: "", ty: Bool }, - }, - // at: module-XXXXXXXXXX.rs:12:1 - 88: BranchIfZero { - target: 90, - value: StatePartIndex(32), // (0x0) SlotDebugData { name: "", ty: Bool }, + 102: BranchIfNonZero { + target: 107, + value: StatePartIndex(38), // (0x0) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:13:1 - 89: Copy { - dest: StatePartIndex(8), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(49), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - }, - // at: module-XXXXXXXXXX.rs:12:1 - 90: BranchIfNonZero { - target: 92, - value: StatePartIndex(32), // (0x0) SlotDebugData { name: "", ty: Bool }, + 103: BranchIfZero { + target: 105, + value: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Bool }, }, // at: module-XXXXXXXXXX.rs:14:1 - 91: Copy { - dest: StatePartIndex(8), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(71), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + 104: Copy { + dest: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(57), // (0xd) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, }, - // at: module-XXXXXXXXXX.rs:8:1 - 92: IsNonZeroDestIsSmall { - dest: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + // at: module-XXXXXXXXXX.rs:13:1 + 105: BranchIfNonZero { + target: 107, + value: StatePartIndex(40), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:15:1 + 106: Copy { + dest: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(79), // (0x3e) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + }, + // at: module-XXXXXXXXXX.rs:9:1 + 107: IsNonZeroDestIsSmall { + dest: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, src: StatePartIndex(0), // (0x1) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::cd.clk", ty: Clock }, }, - 93: AndSmall { + 108: AndSmall { + dest: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + rhs: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:1:1 + 109: Copy { + dest: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, + src: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + }, + 110: SliceInt { + dest: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + src: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: UInt<3> }, + start: 1, + len: 2, + }, + 111: SliceInt { + dest: StatePartIndex(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + start: 0, + len: 1, + }, + 112: SliceInt { + dest: StatePartIndex(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + src: StatePartIndex(11), // (0x0) SlotDebugData { name: "", ty: UInt<2> }, + start: 1, + len: 1, + }, + 113: Copy { + dest: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: Bool }, + src: StatePartIndex(13), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + }, + 114: Copy { + dest: StatePartIndex(8), // (0x0) SlotDebugData { name: ".0", ty: UInt<1> }, + src: StatePartIndex(12), // (0x0) SlotDebugData { name: "", ty: UInt<1> }, + }, + 115: Copy { + dest: StatePartIndex(9), // (0x0) SlotDebugData { name: ".1", ty: Bool }, + src: StatePartIndex(14), // (0x0) SlotDebugData { name: "", ty: Bool }, + }, + // at: module-XXXXXXXXXX.rs:8:1 + 116: AndBigWithSmallImmediate { + dest: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Enum {HdlNone, HdlSome} }, + lhs: StatePartIndex(7), // (0x0) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::b_out", ty: Enum {HdlNone, HdlSome(Bundle {0: UInt<1>, 1: Bool})} }, + rhs: 0x1, + }, + // at: module-XXXXXXXXXX.rs:9:1 + 117: BranchIfSmallZero { + target: 122, + value: StatePartIndex(2), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 118: BranchIfSmallNonZero { + target: 121, + value: StatePartIndex(4), // (0x0 0) SlotDebugData { name: "", ty: Bool }, + }, + 119: Copy { + dest: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(16), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + }, + 120: Branch { + target: 122, + }, + 121: Copy { + dest: StatePartIndex(15), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + src: StatePartIndex(18), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, + }, + 122: XorSmallImmediate { dest: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, - rhs: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 94: BranchIfSmallZero { - target: 99, - value: StatePartIndex(1), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 95: BranchIfSmallNonZero { - target: 98, - value: StatePartIndex(3), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - }, - 96: Copy { - dest: StatePartIndex(7), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(8), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg$next", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - }, - 97: Branch { - target: 99, - }, - 98: Copy { - dest: StatePartIndex(7), // (0x3e) SlotDebugData { name: "InstantiatedModule(enums: enums).enums::the_reg", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - src: StatePartIndex(10), // (0x0) SlotDebugData { name: "", ty: Enum {A, B(Bundle {0: UInt<1>, 1: Bool}), C(Bundle {a: Array, 2>, b: SInt<2>})} }, - }, - 99: XorSmallImmediate { - dest: StatePartIndex(0), // (0x0 0) SlotDebugData { name: "", ty: Bool }, - lhs: StatePartIndex(2), // (0x1 1) SlotDebugData { name: "", ty: Bool }, + lhs: StatePartIndex(3), // (0x1 1) SlotDebugData { name: "", ty: Bool }, rhs: 0x1, }, // at: module-XXXXXXXXXX.rs:1:1 - 100: Return, + 123: Return, ], .. }, - pc: 100, + pc: 123, memory_write_log: [], memories: StatePart { value: [], }, small_slots: StatePart { value: [ + 0, 0, 0, 1, @@ -898,6 +1109,14 @@ Simulation { 15, 2, 15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 62, 62, 0, @@ -964,10 +1183,23 @@ Simulation { 62, 62, 0, + 0, + 0, 1, 2, 3, 3, + 1, + 1, + 1, + 1, + 1, + 2, + 3, + 6, + 7, + 7, + 7, 2, 3, 3, @@ -985,6 +1217,46 @@ Simulation { }, uninitialized_inputs: {}, io_targets: { + Instance { + name: ::enums, + instantiated: Module { + name: enums, + .. + }, + }.b_out: CompiledValue { + layout: CompiledTypeLayout { + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + layout: TypeLayout { + small_slots: StatePartLayout { + len: 0, + debug_data: [], + .. + }, + big_slots: StatePartLayout { + len: 1, + debug_data: [ + SlotDebugData { + name: "InstantiatedModule(enums: enums).enums::b_out", + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + }, + ], + .. + }, + }, + body: Scalar, + }, + range: TypeIndexRange { + small_slots: StatePartIndexRange { start: 0, len: 0 }, + big_slots: StatePartIndexRange { start: 7, len: 1 }, + }, + write: None, + }, Instance { name: ::enums, instantiated: Module { @@ -1415,23 +1687,22 @@ Simulation { ty: UInt<4>, flow: Sink, }, - TraceReg { - name: "the_reg", + TraceModuleIO { + name: "b_out", child: TraceEnumWithFields { - name: "the_reg", + name: "b_out", discriminant: TraceEnumDiscriminant { location: TraceScalarId(7), name: "$tag", ty: Enum { - A, - B(Bundle {0: UInt<1>, 1: Bool}), - C(Bundle {a: Array, 2>, b: SInt<2>}), + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), }, - flow: Duplex, + flow: Sink, }, non_empty_fields: [ TraceBundle { - name: "B", + name: "HdlSome", fields: [ TraceUInt { location: TraceScalarId(8), @@ -1453,6 +1724,57 @@ Simulation { }, flow: Source, }, + ], + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + flow: Sink, + }, + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + flow: Sink, + }, + TraceReg { + name: "the_reg", + child: TraceEnumWithFields { + name: "the_reg", + discriminant: TraceEnumDiscriminant { + location: TraceScalarId(10), + name: "$tag", + ty: Enum { + A, + B(Bundle {0: UInt<1>, 1: Bool}), + C(Bundle {a: Array, 2>, b: SInt<2>}), + }, + flow: Duplex, + }, + non_empty_fields: [ + TraceBundle { + name: "B", + fields: [ + TraceUInt { + location: TraceScalarId(11), + name: "0", + ty: UInt<1>, + flow: Source, + }, + TraceBool { + location: TraceScalarId(12), + name: "1", + flow: Source, + }, + ], + ty: Bundle { + /* offset = 0 */ + 0: UInt<1>, + /* offset = 1 */ + 1: Bool, + }, + flow: Source, + }, TraceBundle { name: "C", fields: [ @@ -1460,13 +1782,13 @@ Simulation { name: "a", elements: [ TraceUInt { - location: TraceScalarId(10), + location: TraceScalarId(13), name: "[0]", ty: UInt<1>, flow: Source, }, TraceUInt { - location: TraceScalarId(11), + location: TraceScalarId(14), name: "[1]", ty: UInt<1>, flow: Source, @@ -1476,7 +1798,7 @@ Simulation { flow: Source, }, TraceSInt { - location: TraceScalarId(12), + location: TraceScalarId(15), name: "b", ty: SInt<2>, flow: Source, @@ -1570,7 +1892,36 @@ Simulation { SimTrace { id: TraceScalarId(7), kind: EnumDiscriminant { - index: StatePartIndex(4), + index: StatePartIndex(0), + ty: Enum { + HdlNone, + HdlSome(Bundle {0: UInt<1>, 1: Bool}), + }, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(8), + kind: BigUInt { + index: StatePartIndex(8), + ty: UInt<1>, + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(9), + kind: BigBool { + index: StatePartIndex(9), + }, + state: 0x0, + last_state: 0x0, + }, + SimTrace { + id: TraceScalarId(10), + kind: EnumDiscriminant { + index: StatePartIndex(5), ty: Enum { A, B(Bundle {0: UInt<1>, 1: Bool}), @@ -1580,32 +1931,6 @@ Simulation { state: 0x2, last_state: 0x2, }, - SimTrace { - id: TraceScalarId(8), - kind: BigUInt { - index: StatePartIndex(11), - ty: UInt<1>, - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(9), - kind: BigBool { - index: StatePartIndex(12), - }, - state: 0x1, - last_state: 0x1, - }, - SimTrace { - id: TraceScalarId(10), - kind: BigUInt { - index: StatePartIndex(18), - ty: UInt<1>, - }, - state: 0x1, - last_state: 0x1, - }, SimTrace { id: TraceScalarId(11), kind: BigUInt { @@ -1617,8 +1942,34 @@ Simulation { }, SimTrace { id: TraceScalarId(12), - kind: BigSInt { + kind: BigBool { index: StatePartIndex(20), + }, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(13), + kind: BigUInt { + index: StatePartIndex(26), + ty: UInt<1>, + }, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(14), + kind: BigUInt { + index: StatePartIndex(27), + ty: UInt<1>, + }, + state: 0x1, + last_state: 0x1, + }, + SimTrace { + id: TraceScalarId(15), + kind: BigSInt { + index: StatePartIndex(28), ty: SInt<2>, }, state: 0x3, @@ -1637,7 +1988,7 @@ Simulation { ], instant: 16 μs, clocks_triggered: [ - StatePartIndex(1), + StatePartIndex(2), ], .. } \ No newline at end of file diff --git a/crates/fayalite/tests/sim/expected/enums.vcd b/crates/fayalite/tests/sim/expected/enums.vcd index 48a493b..07cbd32 100644 --- a/crates/fayalite/tests/sim/expected/enums.vcd +++ b/crates/fayalite/tests/sim/expected/enums.vcd @@ -9,18 +9,25 @@ $var wire 2 $ which_in $end $var wire 4 % data_in $end $var wire 2 & which_out $end $var wire 4 ' data_out $end -$scope struct the_reg $end +$scope struct b_out $end $var string 1 ( \$tag $end +$scope struct HdlSome $end +$var wire 1 ) \0 $end +$var wire 1 * \1 $end +$upscope $end +$upscope $end +$scope struct the_reg $end +$var string 1 + \$tag $end $scope struct B $end -$var reg 1 ) \0 $end -$var reg 1 * \1 $end +$var reg 1 , \0 $end +$var reg 1 - \1 $end $upscope $end $scope struct C $end $scope struct a $end -$var reg 1 + \[0] $end -$var reg 1 , \[1] $end +$var reg 1 . \[0] $end +$var reg 1 / \[1] $end $upscope $end -$var reg 2 - b $end +$var reg 2 0 b $end $upscope $end $upscope $end $upscope $end @@ -33,12 +40,15 @@ b0 $ b0 % b0 & b0 ' -sA\x20(0) ( +sHdlNone\x20(0) ( 0) 0* -0+ +sA\x20(0) + 0, -b0 - +0- +0. +0/ +b0 0 $end #1000000 1! @@ -55,7 +65,8 @@ b1 $ #5000000 1! b1 & -sB\x20(1) ( +sHdlSome\x20(1) ( +sB\x20(1) + #6000000 0# b0 $ @@ -72,8 +83,10 @@ b1111 % b11 ' 1) 1* -1+ 1, +1- +1. +1/ #10000000 0! #11000000 @@ -85,8 +98,11 @@ b10 $ 1! b10 & b1111 ' -sC\x20(2) ( -b11 - +sHdlNone\x20(0) ( +0) +0* +sC\x20(2) + +b11 0 #14000000 0! #15000000 From 36bad529789f70e1732c6f43ef12a9bfd0e3afc7 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Wed, 18 Dec 2024 20:50:50 -0800 Subject: [PATCH 05/10] sim: fix sim.write to struct --- crates/fayalite/src/sim.rs | 86 +++++++++++++++++++++++++++--------- crates/fayalite/tests/sim.rs | 10 ++++- 2 files changed, 73 insertions(+), 23 deletions(-) diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 10fbb92..988afca 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -6429,7 +6429,7 @@ impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType); struct SimulationImpl { state: interpreter::State, io: Expr, - uninitialized_inputs: HashSet, + uninitialized_inputs: HashMap>, io_targets: HashMap>, made_initial_step: bool, needs_settle: bool, @@ -6483,37 +6483,52 @@ impl SimulationImpl { .field("clocks_triggered", clocks_triggered) .finish_non_exhaustive() } - fn parse_io(&mut self, target: Target, value: CompiledValue) { + /// returns `true` if `target` or any sub-targets are uninitialized inputs + fn parse_io(&mut self, target: Target, value: CompiledValue) -> bool { self.io_targets.insert(target, value); match value.layout.body { CompiledTypeLayoutBody::Scalar => match target.flow() { - Flow::Source => {} + Flow::Source => false, Flow::Sink => { - self.uninitialized_inputs.insert(target); + self.uninitialized_inputs.insert(target, vec![]); + true } Flow::Duplex => unreachable!(), }, CompiledTypeLayoutBody::Array { .. } => { let value = value.map_ty(Array::from_canonical); + let mut sub_targets = Vec::new(); for index in 0..value.layout.ty.len() { - self.parse_io( - target.join( - TargetPathElement::from(TargetPathArrayElement { index }) - .intern_sized(), - ), - value.element(index), + let sub_target = target.join( + TargetPathElement::from(TargetPathArrayElement { index }).intern_sized(), ); + if self.parse_io(sub_target, value.element(index)) { + sub_targets.push(sub_target); + } + } + if sub_targets.is_empty() { + false + } else { + self.uninitialized_inputs.insert(target, sub_targets); + true } } CompiledTypeLayoutBody::Bundle { .. } => { let value = value.map_ty(Bundle::from_canonical); + let mut sub_targets = Vec::new(); for BundleField { name, .. } in value.layout.ty.fields() { - self.parse_io( - target.join( - TargetPathElement::from(TargetPathBundleField { name }).intern_sized(), - ), - value.field_by_name(name), + let sub_target = target.join( + TargetPathElement::from(TargetPathBundleField { name }).intern_sized(), ); + if self.parse_io(sub_target, value.field_by_name(name)) { + sub_targets.push(sub_target); + } + } + if sub_targets.is_empty() { + false + } else { + self.uninitialized_inputs.insert(target, sub_targets); + true } } } @@ -6522,7 +6537,7 @@ impl SimulationImpl { let mut retval = Self { state: State::new(compiled.insns), io: compiled.io.to_expr(), - uninitialized_inputs: HashSet::new(), + uninitialized_inputs: HashMap::new(), io_targets: HashMap::new(), made_initial_step: false, needs_settle: true, @@ -6791,6 +6806,35 @@ impl SimulationImpl { }; panic!("simulator read/write expression must not have dynamic array indexes"); } + fn mark_target_as_initialized(&mut self, mut target: Target) { + fn remove_target_and_children( + uninitialized_inputs: &mut HashMap>, + target: Target, + ) { + let Some(children) = uninitialized_inputs.remove(&target) else { + return; + }; + for child in children { + remove_target_and_children(uninitialized_inputs, child); + } + } + remove_target_and_children(&mut self.uninitialized_inputs, target); + while let Some(target_child) = target.child() { + let parent = target_child.parent(); + for child in self + .uninitialized_inputs + .get(&*parent) + .map(|v| &**v) + .unwrap_or(&[]) + { + if self.uninitialized_inputs.contains_key(child) { + return; + } + } + target = *parent; + self.uninitialized_inputs.remove(&target); + } + } #[track_caller] fn read_helper(&mut self, io: Expr) -> CompiledValue { let Some(target) = io.target() else { @@ -6810,7 +6854,7 @@ impl SimulationImpl { self.settle(); } Flow::Sink => { - if self.uninitialized_inputs.contains(&*target) { + if self.uninitialized_inputs.contains_key(&*target) { panic!("can't read from an uninitialized input"); } } @@ -6833,7 +6877,7 @@ impl SimulationImpl { Flow::Duplex => unreachable!(), } if !self.made_initial_step { - self.uninitialized_inputs.remove(&*target); + self.mark_target_as_initialized(*target); } self.needs_settle = true; compiled_value @@ -7136,11 +7180,11 @@ pub struct Simulation { io: Expr, } -struct SortedSetDebug<'a, T>(&'a HashSet); +struct SortedSetDebug<'a, T, V>(&'a HashMap); -impl fmt::Debug for SortedSetDebug<'_, T> { +impl fmt::Debug for SortedSetDebug<'_, T, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut entries = Vec::from_iter(self.0.iter().map(|v| { + let mut entries = Vec::from_iter(self.0.iter().map(|(v, _)| { if f.alternate() { format!("{v:#?}") } else { diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index bea7d93..a249235 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -255,8 +255,14 @@ fn test_shift_register() { let mut sim = Simulation::new(shift_register()); let mut writer = RcWriter::default(); sim.add_trace_writer(VcdWriterDecls::new(writer.clone())); - sim.write_clock(sim.io().cd.clk, false); - sim.write_reset(sim.io().cd.rst, true); + sim.write( + sim.io().cd, + #[hdl] + ClockDomain { + clk: false.to_clock(), + rst: true.to_sync_reset(), + }, + ); sim.write_bool(sim.io().d, false); sim.advance_time(SimDuration::from_micros(1)); sim.write_clock(sim.io().cd.clk, true); From 9b06019bf54303e51989484a0cfa1641b0e9d543 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Wed, 18 Dec 2024 21:15:09 -0800 Subject: [PATCH 06/10] make sim::Compiler not print things to stdout unless you ask for it --- crates/fayalite/src/sim.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 988afca..cb6228d 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -1601,6 +1601,14 @@ impl MakeTraceDeclTarget { } } +struct DebugOpaque(T); + +impl fmt::Debug for DebugOpaque { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("<...>") + } +} + #[derive(Debug)] pub struct Compiler { insns: Insns, @@ -1622,6 +1630,7 @@ pub struct Compiler { registers: Vec, traces: SimTraces>>, memories: Vec, + dump_assignments_dot: Option>>, } impl Compiler { @@ -1647,8 +1656,14 @@ impl Compiler { registers: Vec::new(), traces: SimTraces(Vec::new()), memories: Vec::new(), + dump_assignments_dot: None, } } + #[doc(hidden)] + /// This is explicitly unstable and may be changed/removed at any time + pub fn dump_assignments_dot(&mut self, callback: Box) { + self.dump_assignments_dot = Some(DebugOpaque(callback)); + } fn new_sim_trace(&mut self, kind: SimTraceKind) -> TraceScalarId { let id = TraceScalarId(self.traces.0.len()); self.traces.0.push(SimTrace { @@ -4650,12 +4665,11 @@ impl Compiler { fn process_assignments(&mut self) { self.assignments .finalize(self.insns.state_layout().ty.clone().into()); - println!( - "{:#?}", - petgraph::dot::Dot::new(&petgraph::graph::DiGraph::<_, _, usize>::from_elements( - self.assignments.elements() - )) - ); + if let Some(DebugOpaque(dump_assignments_dot)) = &self.dump_assignments_dot { + let graph = + petgraph::graph::DiGraph::<_, _, usize>::from_elements(self.assignments.elements()); + dump_assignments_dot(&petgraph::dot::Dot::new(&graph)); + } let assignments_order: Vec<_> = match petgraph::algo::toposort(&self.assignments, None) { Ok(nodes) => nodes .into_iter() From 2ab84280627c5a7f5d9d07192cdd0edb36a25faa Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Sat, 28 Dec 2024 23:34:46 -0800 Subject: [PATCH 07/10] upgrade syn version --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e50abc..23cdc34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -543,9 +543,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -647,9 +647,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.66" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 2cfa586..54de3a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ quote = "1.0.36" serde = { version = "1.0.202", features = ["derive"] } serde_json = { version = "1.0.117", features = ["preserve_order"] } sha2 = "0.10.8" -syn = { version = "2.0.66", features = ["full", "fold", "visit", "extra-traits"] } +syn = { version = "2.0.93", features = ["full", "fold", "visit", "extra-traits"] } tempfile = "3.10.1" thiserror = "1.0.61" trybuild = "1.0" From 7005fa3330d6715008a3e3cd0b57c71108b465d2 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 27 Dec 2024 04:02:39 -0800 Subject: [PATCH 08/10] implement handling #[cfg] and #[cfg_attr] in proc macro inputs --- crates/fayalite-proc-macros-impl/src/lib.rs | 363 ++- .../src/process_cfg.rs | 2527 +++++++++++++++++ crates/fayalite/src/lib.rs | 50 + 3 files changed, 2929 insertions(+), 11 deletions(-) create mode 100644 crates/fayalite-proc-macros-impl/src/process_cfg.rs diff --git a/crates/fayalite-proc-macros-impl/src/lib.rs b/crates/fayalite-proc-macros-impl/src/lib.rs index 0ffd4d4..1b1b61f 100644 --- a/crates/fayalite-proc-macros-impl/src/lib.rs +++ b/crates/fayalite-proc-macros-impl/src/lib.rs @@ -3,14 +3,20 @@ #![cfg_attr(test, recursion_limit = "512")] use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens}; -use std::io::{ErrorKind, Write}; +use std::{ + collections::{hash_map::Entry, HashMap}, + io::{ErrorKind, Write}, +}; use syn::{ - bracketed, parenthesized, + bracketed, + ext::IdentExt, + parenthesized, parse::{Parse, ParseStream, Parser}, parse_quote, - punctuated::Pair, + punctuated::{Pair, Punctuated}, spanned::Spanned, - AttrStyle, Attribute, Error, Item, ItemFn, Token, + token::{Bracket, Paren}, + AttrStyle, Attribute, Error, Ident, Item, ItemFn, LitBool, LitStr, Meta, Token, }; mod fold; @@ -19,6 +25,7 @@ mod hdl_enum; mod hdl_type_alias; mod hdl_type_common; mod module; +mod process_cfg; pub(crate) trait CustomToken: Copy @@ -59,6 +66,11 @@ mod kw { }; } + custom_keyword!(__evaluated_cfgs); + custom_keyword!(all); + custom_keyword!(any); + custom_keyword!(cfg); + custom_keyword!(cfg_attr); custom_keyword!(clock_domain); custom_keyword!(connect_inexact); custom_keyword!(custom_bounds); @@ -75,6 +87,7 @@ mod kw { custom_keyword!(no_reset); custom_keyword!(no_runtime_generics); custom_keyword!(no_static); + custom_keyword!(not); custom_keyword!(outline_generated); custom_keyword!(output); custom_keyword!(reg_builder); @@ -901,15 +914,335 @@ fn hdl_module_impl(item: ItemFn) -> syn::Result { Ok(contents) } -pub fn hdl_module(attr: TokenStream, item: TokenStream) -> syn::Result { - let kw = kw::hdl_module::default(); - hdl_module_impl(syn::parse2(quote! { #[#kw(#attr)] #item })?) +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub(crate) enum CfgExpr { + Option { + ident: Ident, + value: Option<(Token![=], LitStr)>, + }, + All { + all: kw::all, + paren: Paren, + exprs: Punctuated, + }, + Any { + any: kw::any, + paren: Paren, + exprs: Punctuated, + }, + Not { + not: kw::not, + paren: Paren, + expr: Box, + trailing_comma: Option, + }, } -pub fn hdl_attr(attr: TokenStream, item: TokenStream) -> syn::Result { - let kw = kw::hdl::default(); - let item = quote! { #[#kw(#attr)] #item }; - let item = syn::parse2::(item)?; +impl Parse for CfgExpr { + fn parse(input: ParseStream) -> syn::Result { + match input.cursor().ident() { + Some((_, cursor)) if cursor.eof() => { + return Ok(CfgExpr::Option { + ident: input.call(Ident::parse_any)?, + value: None, + }); + } + _ => {} + } + if input.peek(Ident::peek_any) && input.peek2(Token![=]) { + return Ok(CfgExpr::Option { + ident: input.call(Ident::parse_any)?, + value: Some((input.parse()?, input.parse()?)), + }); + } + let contents; + if input.peek(kw::all) { + Ok(CfgExpr::All { + all: input.parse()?, + paren: parenthesized!(contents in input), + exprs: contents.call(Punctuated::parse_terminated)?, + }) + } else if input.peek(kw::any) { + Ok(CfgExpr::Any { + any: input.parse()?, + paren: parenthesized!(contents in input), + exprs: contents.call(Punctuated::parse_terminated)?, + }) + } else if input.peek(kw::not) { + Ok(CfgExpr::Not { + not: input.parse()?, + paren: parenthesized!(contents in input), + expr: contents.parse()?, + trailing_comma: contents.parse()?, + }) + } else { + Err(input.error("expected cfg-pattern")) + } + } +} + +impl ToTokens for CfgExpr { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + CfgExpr::Option { ident, value } => { + ident.to_tokens(tokens); + if let Some((eq, value)) = value { + eq.to_tokens(tokens); + value.to_tokens(tokens); + } + } + CfgExpr::All { all, paren, exprs } => { + all.to_tokens(tokens); + paren.surround(tokens, |tokens| exprs.to_tokens(tokens)); + } + CfgExpr::Any { any, paren, exprs } => { + any.to_tokens(tokens); + paren.surround(tokens, |tokens| exprs.to_tokens(tokens)); + } + CfgExpr::Not { + not, + paren, + expr, + trailing_comma, + } => { + not.to_tokens(tokens); + paren.surround(tokens, |tokens| { + expr.to_tokens(tokens); + trailing_comma.to_tokens(tokens); + }); + } + } + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub(crate) struct Cfg { + cfg: kw::cfg, + paren: Paren, + expr: CfgExpr, + trailing_comma: Option, +} + +impl Cfg { + fn parse_meta(meta: &Meta) -> syn::Result { + syn::parse2(meta.to_token_stream()) + } +} + +impl ToTokens for Cfg { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { + cfg, + paren, + expr, + trailing_comma, + } = self; + cfg.to_tokens(tokens); + paren.surround(tokens, |tokens| { + expr.to_tokens(tokens); + trailing_comma.to_tokens(tokens); + }); + } +} + +impl Parse for Cfg { + fn parse(input: ParseStream) -> syn::Result { + let contents; + Ok(Self { + cfg: input.parse()?, + paren: parenthesized!(contents in input), + expr: contents.parse()?, + trailing_comma: contents.parse()?, + }) + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub(crate) struct CfgAttr { + cfg_attr: kw::cfg_attr, + paren: Paren, + expr: CfgExpr, + comma: Token![,], + attrs: Punctuated, +} + +impl CfgAttr { + pub(crate) fn to_cfg(&self) -> Cfg { + Cfg { + cfg: kw::cfg(self.cfg_attr.span), + paren: self.paren, + expr: self.expr.clone(), + trailing_comma: None, + } + } + fn parse_meta(meta: &Meta) -> syn::Result { + syn::parse2(meta.to_token_stream()) + } +} + +impl Parse for CfgAttr { + fn parse(input: ParseStream) -> syn::Result { + let contents; + Ok(Self { + cfg_attr: input.parse()?, + paren: parenthesized!(contents in input), + expr: contents.parse()?, + comma: contents.parse()?, + attrs: contents.call(Punctuated::parse_terminated)?, + }) + } +} + +pub(crate) struct CfgAndValue { + cfg: Cfg, + eq_token: Token![=], + value: LitBool, +} + +impl Parse for CfgAndValue { + fn parse(input: ParseStream) -> syn::Result { + Ok(Self { + cfg: input.parse()?, + eq_token: input.parse()?, + value: input.parse()?, + }) + } +} + +pub(crate) struct Cfgs { + pub(crate) bracket: Bracket, + pub(crate) cfgs_map: HashMap, + pub(crate) cfgs_list: Vec, +} + +impl Default for Cfgs { + fn default() -> Self { + Self { + bracket: Default::default(), + cfgs_map: Default::default(), + cfgs_list: Default::default(), + } + } +} + +impl Cfgs { + fn insert_cfg(&mut self, cfg: Cfg, value: T) { + match self.cfgs_map.entry(cfg) { + Entry::Occupied(_) => {} + Entry::Vacant(entry) => { + self.cfgs_list.push(entry.key().clone()); + entry.insert(value); + } + } + } +} + +impl Parse for Cfgs { + fn parse(input: ParseStream) -> syn::Result { + let contents; + let bracket = bracketed!(contents in input); + let mut cfgs_map = HashMap::new(); + let mut cfgs_list = Vec::new(); + for CfgAndValue { + cfg, + eq_token, + value, + } in contents.call(Punctuated::::parse_terminated)? + { + let _ = eq_token; + match cfgs_map.entry(cfg) { + Entry::Occupied(_) => {} + Entry::Vacant(entry) => { + cfgs_list.push(entry.key().clone()); + entry.insert(value.value); + } + } + } + Ok(Self { + bracket, + cfgs_map, + cfgs_list, + }) + } +} + +impl Parse for Cfgs<()> { + fn parse(input: ParseStream) -> syn::Result { + let contents; + let bracket = bracketed!(contents in input); + let mut cfgs_map = HashMap::new(); + let mut cfgs_list = Vec::new(); + for cfg in contents.call(Punctuated::::parse_terminated)? { + match cfgs_map.entry(cfg) { + Entry::Occupied(_) => {} + Entry::Vacant(entry) => { + cfgs_list.push(entry.key().clone()); + entry.insert(()); + } + } + } + Ok(Self { + bracket, + cfgs_map, + cfgs_list, + }) + } +} + +impl ToTokens for Cfgs<()> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { + bracket, + cfgs_map: _, + cfgs_list, + } = self; + bracket.surround(tokens, |tokens| { + for cfg in cfgs_list { + cfg.to_tokens(tokens); + ::default().to_tokens(tokens); + } + }); + } +} + +fn hdl_main( + kw: impl CustomToken, + attr: TokenStream, + item: TokenStream, +) -> syn::Result { + let (evaluated_cfgs, attr): (_, TokenStream) = Parser::parse2( + |input: ParseStream| { + if input.peek(Bracket) && input.peek2(kw::__evaluated_cfgs) { + let cfgs = input.parse()?; + let _: kw::__evaluated_cfgs = input.parse()?; + Ok((Some(cfgs), input.parse()?)) + } else { + Ok((None, input.parse()?)) + } + }, + attr, + )?; + let cfgs = if let Some(cfgs) = evaluated_cfgs { + cfgs + } else { + let cfgs = process_cfg::collect_cfgs(syn::parse2(item.clone())?)?; + if cfgs.cfgs_list.is_empty() { + Cfgs::default() + } else { + let key = kw::__evaluated_cfgs::default(); + return Ok(quote! { + ::fayalite::__cfg_expansion_helper! { + [] + #cfgs + #[::fayalite::#kw:(#key #attr)] { #item } + } + }); + } + }; + let item = syn::parse2(quote! { #[#kw(#attr)] #item })?; + let Some(item) = process_cfg::process_cfgs(item, cfgs)? else { + return Ok(TokenStream::new()); + }; match item { Item::Enum(item) => hdl_enum::hdl_enum(item), Item::Struct(item) => hdl_bundle::hdl_bundle(item), @@ -921,3 +1254,11 @@ pub fn hdl_attr(attr: TokenStream, item: TokenStream) -> syn::Result syn::Result { + hdl_main(kw::hdl_module::default(), attr, item) +} + +pub fn hdl_attr(attr: TokenStream, item: TokenStream) -> syn::Result { + hdl_main(kw::hdl::default(), attr, item) +} diff --git a/crates/fayalite-proc-macros-impl/src/process_cfg.rs b/crates/fayalite-proc-macros-impl/src/process_cfg.rs new file mode 100644 index 0000000..5cff08f --- /dev/null +++ b/crates/fayalite-proc-macros-impl/src/process_cfg.rs @@ -0,0 +1,2527 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +use crate::{Cfg, CfgAttr, Cfgs, Errors}; +use proc_macro2::Ident; +use std::{collections::VecDeque, marker::PhantomData}; +use syn::{ + punctuated::{Pair, Punctuated}, + Token, +}; + +struct State { + cfgs: Cfgs, + errors: Errors, + _phantom: PhantomData

, +} + +impl State

{ + #[must_use] + fn eval_cfg(&mut self, cfg: Cfg) -> bool { + struct MyDispatch<'a> { + cfg: Cfg, + _phantom: PhantomData<&'a ()>, + } + impl<'a> PhaseDispatch for MyDispatch<'a> { + type Args = &'a mut State

; + type Output = bool; + + fn dispatch_collect( + self, + args: Self::Args, + ) -> Self::Output { + args.cfgs.insert_cfg(self.cfg, ()); + true + } + + fn dispatch_process( + self, + args: Self::Args, + ) -> Self::Output { + if let Some(&retval) = args.cfgs.cfgs_map.get(&self.cfg) { + retval + } else { + args.errors.error(self.cfg, "unrecognized cfg -- cfg wasn't evaluated when running `__cfg_expansion_helper!`"); + true + } + } + } + P::dispatch( + MyDispatch { + cfg, + _phantom: PhantomData, + }, + self, + ) + } + #[must_use] + fn eval_cfgs( + &mut self, + mut attrs: Vec, + ) -> Option, P>> { + let mut queue = VecDeque::from(attrs); + attrs = Vec::with_capacity(queue.len()); // cfg_attr is rare, and cfg can't increase length + while let Some(attr) = queue.pop_front() { + if attr.path().is_ident("cfg") { + if let Some(cfg) = self.errors.ok(Cfg::parse_meta(&attr.meta)) { + if !self.eval_cfg(cfg) { + return None; + } + continue; + } + } else if attr.path().is_ident("cfg_attr") { + if let Some(cfg_attr) = self.errors.ok(CfgAttr::parse_meta(&attr.meta)) { + if self.eval_cfg(cfg_attr.to_cfg()) { + // push onto queue since cfg_attr(, cfg_attr(, )) is valid + for meta in cfg_attr.attrs { + queue.push_front(syn::Attribute { + pound_token: attr.pound_token, + style: attr.style, + bracket_token: attr.bracket_token, + meta, + }); + } + } + continue; + } + } + attrs.push(attr); + } + Some(Output::new(attrs)) + } + fn process_qself_and_path( + &mut self, + qself: Option, + path: syn::Path, + ) -> Option<(Output, P>, Output)> { + let qself = if let Some(syn::QSelf { + lt_token, + ty, + position, + as_token, + gt_token, + }) = qself + { + ty.process(self)?.map(|ty| { + Some(syn::QSelf { + lt_token, + ty, + position, + as_token, + gt_token, + }) + }) + } else { + Output::new(None) + }; + let syn::Path { + leading_colon, + segments, + } = path; + // path segments don't get removed + let path = segments.process(self)?.map(|segments| syn::Path { + leading_colon, + segments, + }); + Some((qself, path)) + } +} + +trait PhaseDispatch { + type Args; + type Output; + fn dispatch_collect(self, args: Self::Args) + -> Self::Output; + fn dispatch_process(self, args: Self::Args) + -> Self::Output; +} + +trait Phase: Sized + 'static { + type Output; + type CfgsValue; + fn output_new(v: T) -> Output; + fn output_map U>(v: Output, f: F) -> Output; + fn output_zip(t: Output, u: Output) -> Output<(T, U), Self>; + fn dispatch(d: D, args: D::Args) -> D::Output; +} + +struct CollectCfgsPhase; + +impl Phase for CollectCfgsPhase { + type Output = (); + type CfgsValue = (); + + fn output_new(_v: T) -> Output { + Output(()) + } + + fn output_map U>(_v: Output, _f: F) -> Output { + Output(()) + } + + fn output_zip(_t: Output, _u: Output) -> Output<(T, U), Self> { + Output(()) + } + + fn dispatch(d: D, args: D::Args) -> D::Output { + d.dispatch_collect(args) + } +} + +struct ProcessCfgsPhase; + +impl Phase for ProcessCfgsPhase { + type Output = T; + type CfgsValue = bool; + + fn output_new(v: T) -> Output { + Output(v) + } + + fn output_map U>(v: Output, f: F) -> Output { + Output(f(v.0)) + } + + fn output_zip(t: Output, u: Output) -> Output<(T, U), Self> { + Output((t.0, u.0)) + } + + fn dispatch(d: D, args: D::Args) -> D::Output { + d.dispatch_process(args) + } +} + +struct Output(P::Output); + +trait OutputZip: Sized { + type Output; + fn zip(self) -> Output; + fn call R>(self, f: F) -> Output { + self.zip().map(f) + } +} + +impl OutputZip

for () { + type Output = (); + + fn zip(self) -> Output { + Output::new(()) + } +} + +impl OutputZip

for (Output,) { + type Output = (T,); + + fn zip(self) -> Output { + self.0.map(|v| (v,)) + } +} + +macro_rules! impl_zip { + ($first_arg:ident: $first_T:ident, $($arg:ident: $T:ident),* $(,)?) => { + impl_zip!(@step [], [($first_arg: $first_T) $(($arg: $T))*], (),); + }; + ( + @impl($first_arg:tt,), + $tuple_pat:tt, + ) => {}; + ( + @impl(($first_arg:ident: $first_T:ident), + $(($arg:ident: $T:ident),)*), + $tuple_pat:tt, + ) => { + impl<$first_T, $($T,)* P: Phase> OutputZip

for (Output<$first_T, P>, $(Output<$T, P>),*) { + type Output = ($first_T, $($T),*); + fn zip(self) -> Output<($first_T, $($T),*), P> { + let (tuples, $($arg),*) = self; + $(let tuples = P::output_zip(tuples, $arg);)* + tuples.map(|$tuple_pat| ($first_arg, $($arg),*)) + } + } + }; + ( + @step [$($cur:tt)*], + [], + $tuple_pat:tt, + ) => {}; + ( + @step [$($cur:tt)*], + [($next_arg:ident: $next_T:ident) $($rest:tt)*], + (), + ) => { + impl_zip!(@impl($($cur,)* ($next_arg: $next_T),), $next_arg,); + impl_zip!(@step [$($cur)* ($next_arg: $next_T)], [$($rest)*], $next_arg,); + }; + ( + @step [$($cur:tt)*], + [($next_arg:ident: $next_T:ident) $($rest:tt)*], + $tuple_pat:tt, + ) => { + impl_zip!(@impl($($cur,)* ($next_arg: $next_T),), ($tuple_pat, $next_arg),); + impl_zip!(@step [$($cur)* ($next_arg: $next_T)], [$($rest)*], ($tuple_pat, $next_arg),); + }; +} + +impl_zip!(t0: T0, t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8, t9: T9, t10: T10, t11: T11); + +impl Copy for Output where P::Output: Copy {} + +impl Clone for Output +where + P::Output: Clone, +{ + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl Output { + fn new(v: T) -> Self { + P::output_new(v) + } + fn map U>(self, f: F) -> Output { + P::output_map(self, f) + } +} + +trait Process: Sized { + #[must_use] + fn process(self, state: &mut State

) -> Option>; +} + +impl Process

for syn::Item { + fn process(self, _state: &mut State

) -> Option> { + // don't recurse into items + Some(Output::new(self)) + } +} + +impl Process

for Vec { + fn process(self, state: &mut State

) -> Option> { + state.eval_cfgs(self) + } +} + +impl, P: Phase> Process

for Box { + fn process(self, state: &mut State

) -> Option> { + Some(T::process(*self, state)?.map(Box::new)) + } +} + +trait ProcessVecElement { + const REMOVE_ELEMENTS: bool; +} + +impl ProcessVecElement for syn::Arm { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessVecElement for syn::Stmt { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessVecElement for syn::ForeignItem { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessVecElement for syn::ImplItem { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessVecElement for syn::Item { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessVecElement for syn::TraitItem { + const REMOVE_ELEMENTS: bool = true; +} + +impl + ProcessVecElement, P: Phase> Process

for Vec { + fn process(self, state: &mut State

) -> Option> { + let mut output = Output::new(Vec::new()); + for value in self { + if let Some(value) = value.process(state) { + output = (output, value).call(|(mut output, value)| { + output.push(value); + output + }); + } else if !T::REMOVE_ELEMENTS { + return None; + } + } + Some(output) + } +} + +trait ProcessOption { + /// if a configured-off value causes this value to be `None` instead of propagating the configuring-off + const REMOVE_VALUE: bool; +} + +impl ProcessOption for syn::Abi { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::Block { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::WhereClause { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::Expr { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::Type { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for Box { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::AngleBracketedGenericArguments { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::ImplRestriction { + const REMOVE_VALUE: bool = false; +} + +impl ProcessOption for syn::BoundLifetimes { + const REMOVE_VALUE: bool = false; +} + +impl ProcessOption for (Token![=], syn::Expr) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![=], syn::Type) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![if], Box) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![else], Box) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![&], Option) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Token![as], Ident) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Ident, Token![:]) { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Option, syn::Path, Token![for]) { + const REMOVE_VALUE: bool = false; +} + +impl ProcessOption for syn::BareVariadic { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::Variadic { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::LocalInit { + const REMOVE_VALUE: bool = false; +} + +impl ProcessOption for syn::Label { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for syn::PatRest { + const REMOVE_VALUE: bool = true; +} + +impl ProcessOption for (Box, Token![:]) { + const REMOVE_VALUE: bool = false; +} + +impl ProcessOption for (Token![@], Box) { + const REMOVE_VALUE: bool = false; +} + +impl ProcessOption for (syn::token::Brace, Vec) { + const REMOVE_VALUE: bool = false; +} + +impl + ProcessOption, P: Phase> Process

for Option { + fn process(self, state: &mut State

) -> Option> { + if let Some(this) = self { + match this.process(state) { + Some(v) => Some(v.map(Some)), + None => { + if T::REMOVE_VALUE { + Some(Output::new(None)) + } else { + None + } + } + } + } else { + Some(Output::new(None)) + } + } +} + +trait ProcessPunctuatedElement { + const REMOVE_ELEMENTS: bool; +} + +impl + ProcessPunctuatedElement, P: Phase, Punct: Default> Process

+ for Punctuated +{ + fn process(self, state: &mut State

) -> Option> { + let mut output = Output::new(Punctuated::::new()); + for pair in self.into_pairs() { + let (value, punct) = pair.into_tuple(); + if let Some(value) = value.process(state) { + output = (output, value).call(|(mut output, value)| { + output.extend([Pair::new(value, punct)]); + output + }); + } else if !T::REMOVE_ELEMENTS { + return None; + } + } + Some(output) + } +} + +impl ProcessPunctuatedElement for syn::PathSegment { + const REMOVE_ELEMENTS: bool = false; +} + +impl ProcessPunctuatedElement for syn::Type { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::Expr { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::Pat { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::CapturedParam { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::GenericArgument { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::GenericParam { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::Lifetime { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::WherePredicate { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::Variant { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::FnArg { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::BareFnArg { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::TypeParamBound { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::FieldValue { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::Field { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::FieldPat { + const REMOVE_ELEMENTS: bool = true; +} + +impl ProcessPunctuatedElement for syn::UseTree { + const REMOVE_ELEMENTS: bool = true; +} + +impl, U: Process

, P: Phase> Process

for (T, U) { + fn process(self, state: &mut State

) -> Option> { + let (t, u) = self; + let t = t.process(state)?; + let u = u.process(state)?; + Some((t, u).zip()) + } +} + +impl, U: Process

, V: Process

, P: Phase> Process

for (T, U, V) { + fn process(self, state: &mut State

) -> Option> { + let (t, u, v) = self; + let t = t.process(state)?; + let u = u.process(state)?; + let v = v.process(state)?; + Some((t, u, v).zip()) + } +} + +macro_rules! process_no_op { + ($ty:ty) => { + impl Process

for $ty { + fn process(self, _state: &mut State

) -> Option> { + Some(Output::new(self)) + } + } + + impl ProcessOption for $ty { + const REMOVE_VALUE: bool = false; + } + }; +} + +process_no_op!(Token![Self]); +process_no_op!(Token![abstract]); +process_no_op!(Token![as]); +process_no_op!(Token![async]); +process_no_op!(Token![auto]); +process_no_op!(Token![await]); +process_no_op!(Token![become]); +process_no_op!(Token![box]); +process_no_op!(Token![break]); +process_no_op!(Token![const]); +process_no_op!(Token![continue]); +process_no_op!(Token![crate]); +process_no_op!(Token![default]); +process_no_op!(Token![do]); +process_no_op!(Token![dyn]); +process_no_op!(Token![else]); +process_no_op!(Token![enum]); +process_no_op!(Token![extern]); +process_no_op!(Token![final]); +process_no_op!(Token![fn]); +process_no_op!(Token![for]); +process_no_op!(Token![if]); +process_no_op!(Token![impl]); +process_no_op!(Token![in]); +process_no_op!(Token![let]); +process_no_op!(Token![loop]); +process_no_op!(Token![macro]); +process_no_op!(Token![match]); +process_no_op!(Token![mod]); +process_no_op!(Token![move]); +process_no_op!(Token![mut]); +process_no_op!(Token![override]); +process_no_op!(Token![priv]); +process_no_op!(Token![pub]); +process_no_op!(Token![raw]); +process_no_op!(Token![ref]); +process_no_op!(Token![return]); +process_no_op!(Token![self]); +process_no_op!(Token![static]); +process_no_op!(Token![struct]); +process_no_op!(Token![super]); +process_no_op!(Token![trait]); +process_no_op!(Token![try]); +process_no_op!(Token![type]); +process_no_op!(Token![typeof]); +process_no_op!(Token![union]); +process_no_op!(Token![unsafe]); +process_no_op!(Token![unsized]); +process_no_op!(Token![use]); +process_no_op!(Token![virtual]); +process_no_op!(Token![where]); +process_no_op!(Token![while]); +process_no_op!(Token![yield]); + +process_no_op!(Token![!]); +process_no_op!(Token![!=]); +process_no_op!(Token![#]); +process_no_op!(Token![$]); +process_no_op!(Token![%]); +process_no_op!(Token![%=]); +process_no_op!(Token![&]); +process_no_op!(Token![&&]); +process_no_op!(Token![&=]); +process_no_op!(Token![*]); +process_no_op!(Token![*=]); +process_no_op!(Token![+]); +process_no_op!(Token![+=]); +process_no_op!(Token![,]); +process_no_op!(Token![-]); +process_no_op!(Token![-=]); +process_no_op!(Token![->]); +process_no_op!(Token![.]); +process_no_op!(Token![..]); +process_no_op!(Token![...]); +process_no_op!(Token![..=]); +process_no_op!(Token![/]); +process_no_op!(Token![/=]); +process_no_op!(Token![:]); +process_no_op!(Token![::]); +process_no_op!(Token![;]); +process_no_op!(Token![<]); +process_no_op!(Token![<-]); +process_no_op!(Token![<<]); +process_no_op!(Token![<<=]); +process_no_op!(Token![<=]); +process_no_op!(Token![=]); +process_no_op!(Token![==]); +process_no_op!(Token![=>]); +process_no_op!(Token![>]); +process_no_op!(Token![>=]); +process_no_op!(Token![>>]); +process_no_op!(Token![>>=]); +process_no_op!(Token![?]); +process_no_op!(Token![@]); +process_no_op!(Token![^]); +process_no_op!(Token![^=]); +process_no_op!(Token![_]); +process_no_op!(Token![|]); +process_no_op!(Token![|=]); +process_no_op!(Token![||]); +process_no_op!(Token![~]); + +process_no_op!(syn::token::Brace); +process_no_op!(syn::token::Bracket); +process_no_op!(syn::token::Paren); +process_no_op!(syn::token::Group); + +process_no_op!(Ident); +process_no_op!(syn::Index); +process_no_op!(syn::Lifetime); +process_no_op!(syn::LitBool); +process_no_op!(syn::LitByte); +process_no_op!(syn::LitByteStr); +process_no_op!(syn::LitChar); +process_no_op!(syn::LitCStr); +process_no_op!(syn::LitFloat); +process_no_op!(syn::LitInt); +process_no_op!(syn::LitStr); +process_no_op!(proc_macro2::TokenStream); +process_no_op!(proc_macro2::Literal); + +macro_rules! process_struct { + ($ty:path { + $($field:ident,)* + }) => { + impl Process

for $ty { + fn process(self, state: &mut State

) -> Option> { + let Self { + $($field,)* + } = self; + $(let $field = $field.process(state)?;)* + Some(($($field,)*).call(|($($field,)*)| Self { + $($field,)* + })) + } + } + }; + ($ty:path { + $($fields_before:ident,)* + #[qself] + $qself:ident, + $path:ident, + $($fields_after:ident,)* + }) => { + impl Process

for $ty { + fn process(self, state: &mut State

) -> Option> { + let Self { + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + } = self; + $(let $fields_before = $fields_before.process(state)?;)* + let ($qself, $path) = state.process_qself_and_path($qself, $path)?; + $(let $fields_after = $fields_after.process(state)?;)* + Some(( + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + ).call(|( + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + )| Self { + $($fields_before,)* + $qself, + $path, + $($fields_after,)* + })) + } + } + }; +} + +process_struct! { + syn::Abi { + extern_token, + name, + } +} + +process_struct! { + syn::AngleBracketedGenericArguments { + colon2_token, + lt_token, + args, + gt_token, + } +} + +process_struct! { + syn::Arm { + attrs, + pat, + guard, + fat_arrow_token, + body, + comma, + } +} + +process_struct! { + syn::AssocConst { + ident, + generics, + eq_token, + value, + } +} + +process_struct! { + syn::AssocType { + ident, + generics, + eq_token, + ty, + } +} + +process_struct! { + syn::BareFnArg { + attrs, + name, + ty, + } +} + +process_struct! { + syn::BareVariadic { + attrs, + name, + dots, + comma, + } +} + +process_struct! { + syn::Block { + brace_token, + stmts, + } +} + +process_struct! { + syn::BoundLifetimes { + for_token, + lt_token, + lifetimes, + gt_token, + } +} + +process_struct! { + syn::ConstParam { + attrs, + const_token, + ident, + colon_token, + ty, + eq_token, + default, + } +} + +process_struct! { + syn::Constraint { + ident, + generics, + colon_token, + bounds, + } +} + +process_struct! { + syn::DataEnum { + enum_token, + brace_token, + variants, + } +} + +process_struct! { + syn::DataStruct { + struct_token, + fields, + semi_token, + } +} + +process_struct! { + syn::DataUnion { + union_token, + fields, + } +} + +process_struct! { + syn::DeriveInput { + attrs, + vis, + ident, + generics, + data, + } +} + +process_struct! { + syn::ExprArray { + attrs, + bracket_token, + elems, + } +} + +process_struct! { + syn::ExprAssign { + attrs, + left, + eq_token, + right, + } +} + +process_struct! { + syn::ExprAsync { + attrs, + async_token, + capture, + block, + } +} + +process_struct! { + syn::ExprAwait { + attrs, + base, + dot_token, + await_token, + } +} + +process_struct! { + syn::ExprBinary { + attrs, + left, + op, + right, + } +} + +process_struct! { + syn::ExprBlock { + attrs, + label, + block, + } +} + +process_struct! { + syn::ExprBreak { + attrs, + break_token, + label, + expr, + } +} + +process_struct! { + syn::ExprCall { + attrs, + func, + paren_token, + args, + } +} + +process_struct! { + syn::ExprCast { + attrs, + expr, + as_token, + ty, + } +} + +process_struct! { + syn::ExprClosure { + attrs, + lifetimes, + constness, + movability, + asyncness, + capture, + or1_token, + inputs, + or2_token, + output, + body, + } +} + +process_struct! { + syn::ExprConst { + attrs, + const_token, + block, + } +} + +process_struct! { + syn::ExprContinue { + attrs, + continue_token, + label, + } +} + +process_struct! { + syn::ExprField { + attrs, + base, + dot_token, + member, + } +} + +process_struct! { + syn::ExprForLoop { + attrs, + label, + for_token, + pat, + in_token, + expr, + body, + } +} + +process_struct! { + syn::ExprGroup { + attrs, + group_token, + expr, + } +} + +process_struct! { + syn::ExprIf { + attrs, + if_token, + cond, + then_branch, + else_branch, + } +} + +process_struct! { + syn::ExprIndex { + attrs, + expr, + bracket_token, + index, + } +} + +process_struct! { + syn::ExprInfer { + attrs, + underscore_token, + } +} + +process_struct! { + syn::ExprLet { + attrs, + let_token, + pat, + eq_token, + expr, + } +} + +process_struct! { + syn::ExprLit { + attrs, + lit, + } +} + +process_struct! { + syn::ExprLoop { + attrs, + label, + loop_token, + body, + } +} + +process_struct! { + syn::ExprMacro { + attrs, + mac, + } +} + +process_struct! { + syn::ExprMatch { + attrs, + match_token, + expr, + brace_token, + arms, + } +} + +process_struct! { + syn::ExprMethodCall { + attrs, + receiver, + dot_token, + method, + turbofish, + paren_token, + args, + } +} + +process_struct! { + syn::ExprParen { + attrs, + paren_token, + expr, + } +} + +process_struct! { + syn::ExprPath { + attrs, + #[qself] + qself, + path, + } +} + +process_struct! { + syn::ExprRange { + attrs, + start, + limits, + end, + } +} + +process_struct! { + syn::ExprRawAddr { + attrs, + and_token, + raw, + mutability, + expr, + } +} + +process_struct! { + syn::ExprReference { + attrs, + and_token, + mutability, + expr, + } +} + +process_struct! { + syn::ExprRepeat { + attrs, + bracket_token, + expr, + semi_token, + len, + } +} + +process_struct! { + syn::ExprReturn { + attrs, + return_token, + expr, + } +} + +process_struct! { + syn::ExprStruct { + attrs, + #[qself] + qself, + path, + brace_token, + fields, + dot2_token, + rest, + } +} + +process_struct! { + syn::ExprTry { + attrs, + expr, + question_token, + } +} + +process_struct! { + syn::ExprTryBlock { + attrs, + try_token, + block, + } +} + +process_struct! { + syn::ExprTuple { + attrs, + paren_token, + elems, + } +} + +process_struct! { + syn::ExprUnary { + attrs, + op, + expr, + } +} + +process_struct! { + syn::ExprUnsafe { + attrs, + unsafe_token, + block, + } +} + +process_struct! { + syn::ExprWhile { + attrs, + label, + while_token, + cond, + body, + } +} + +process_struct! { + syn::ExprYield { + attrs, + yield_token, + expr, + } +} + +process_struct! { + syn::Field { + attrs, + vis, + mutability, + ident, + colon_token, + ty, + } +} + +process_struct! { + syn::FieldPat { + attrs, + member, + colon_token, + pat, + } +} + +process_struct! { + syn::FieldValue { + attrs, + member, + colon_token, + expr, + } +} + +process_struct! { + syn::FieldsNamed { + brace_token, + named, + } +} + +process_struct! { + syn::FieldsUnnamed { + paren_token, + unnamed, + } +} + +process_struct! { + syn::ForeignItemFn { + attrs, + vis, + sig, + semi_token, + } +} + +process_struct! { + syn::ForeignItemMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::ForeignItemStatic { + attrs, + vis, + static_token, + mutability, + ident, + colon_token, + ty, + semi_token, + } +} + +process_struct! { + syn::ForeignItemType { + attrs, + vis, + type_token, + ident, + generics, + semi_token, + } +} + +process_struct! { + syn::Generics { + lt_token, + params, + gt_token, + where_clause, + } +} + +process_struct! { + syn::ImplItemConst { + attrs, + vis, + defaultness, + const_token, + ident, + generics, + colon_token, + ty, + eq_token, + expr, + semi_token, + } +} + +process_struct! { + syn::ImplItemFn { + attrs, + vis, + defaultness, + sig, + block, + } +} + +process_struct! { + syn::ImplItemMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::ImplItemType { + attrs, + vis, + defaultness, + type_token, + ident, + generics, + eq_token, + ty, + semi_token, + } +} + +process_struct! { + syn::ItemConst { + attrs, + vis, + const_token, + ident, + generics, + colon_token, + ty, + eq_token, + expr, + semi_token, + } +} + +process_struct! { + syn::ItemEnum { + attrs, + vis, + enum_token, + ident, + generics, + brace_token, + variants, + } +} + +process_struct! { + syn::ItemExternCrate { + attrs, + vis, + extern_token, + crate_token, + ident, + rename, + semi_token, + } +} + +process_struct! { + syn::ItemFn { + attrs, + vis, + sig, + block, + } +} + +process_struct! { + syn::ItemForeignMod { + attrs, + unsafety, + abi, + brace_token, + items, + } +} + +process_struct! { + syn::ItemImpl { + attrs, + defaultness, + unsafety, + impl_token, + generics, + trait_, + self_ty, + brace_token, + items, + } +} + +process_struct! { + syn::ItemMacro { + attrs, + ident, + mac, + semi_token, + } +} + +process_struct! { + syn::ItemMod { + attrs, + vis, + unsafety, + mod_token, + ident, + content, + semi, + } +} + +process_struct! { + syn::ItemStatic { + attrs, + vis, + static_token, + mutability, + ident, + colon_token, + ty, + eq_token, + expr, + semi_token, + } +} + +process_struct! { + syn::ItemStruct { + attrs, + vis, + struct_token, + ident, + generics, + fields, + semi_token, + } +} + +process_struct! { + syn::ItemTrait { + attrs, + vis, + unsafety, + auto_token, + restriction, + trait_token, + ident, + generics, + colon_token, + supertraits, + brace_token, + items, + } +} + +process_struct! { + syn::ItemTraitAlias { + attrs, + vis, + trait_token, + ident, + generics, + eq_token, + bounds, + semi_token, + } +} + +process_struct! { + syn::ItemType { + attrs, + vis, + type_token, + ident, + generics, + eq_token, + ty, + semi_token, + } +} + +process_struct! { + syn::ItemUnion { + attrs, + vis, + union_token, + ident, + generics, + fields, + } +} + +process_struct! { + syn::ItemUse { + attrs, + vis, + use_token, + leading_colon, + tree, + semi_token, + } +} + +process_struct! { + syn::Label { + name, + colon_token, + } +} + +process_struct! { + syn::LifetimeParam { + attrs, + lifetime, + colon_token, + bounds, + } +} + +process_struct! { + syn::Local { + attrs, + let_token, + pat, + init, + semi_token, + } +} + +process_struct! { + syn::LocalInit { + eq_token, + expr, + diverge, + } +} + +process_struct! { + syn::Macro { + path, + bang_token, + delimiter, + tokens, + } +} + +process_struct! { + syn::MetaList { + path, + delimiter, + tokens, + } +} + +process_struct! { + syn::MetaNameValue { + path, + eq_token, + value, + } +} + +process_struct! { + syn::ParenthesizedGenericArguments { + paren_token, + inputs, + output, + } +} + +process_struct! { + syn::PatIdent { + attrs, + by_ref, + mutability, + ident, + subpat, + } +} + +process_struct! { + syn::PatOr { + attrs, + leading_vert, + cases, + } +} + +process_struct! { + syn::PatParen { + attrs, + paren_token, + pat, + } +} + +process_struct! { + syn::PatReference { + attrs, + and_token, + mutability, + pat, + } +} + +process_struct! { + syn::PatRest { + attrs, + dot2_token, + } +} + +process_struct! { + syn::PatSlice { + attrs, + bracket_token, + elems, + } +} + +process_struct! { + syn::PatStruct { + attrs, + #[qself] + qself, + path, + brace_token, + fields, + rest, + } +} + +process_struct! { + syn::PatTuple { + attrs, + paren_token, + elems, + } +} + +process_struct! { + syn::PatTupleStruct { + attrs, + #[qself] + qself, + path, + paren_token, + elems, + } +} + +process_struct! { + syn::PatType { + attrs, + pat, + colon_token, + ty, + } +} + +process_struct! { + syn::PatWild { + attrs, + underscore_token, + } +} + +process_struct! { + syn::Path { + leading_colon, + segments, + } +} + +process_struct! { + syn::PathSegment { + ident, + arguments, + } +} + +process_struct! { + syn::PreciseCapture { + use_token, + lt_token, + params, + gt_token, + } +} + +process_struct! { + syn::PredicateLifetime { + lifetime, + colon_token, + bounds, + } +} + +process_struct! { + syn::PredicateType { + lifetimes, + bounded_ty, + colon_token, + bounds, + } +} + +process_struct! { + syn::Receiver { + attrs, + reference, + mutability, + self_token, + colon_token, + ty, + } +} + +process_struct! { + syn::Signature { + constness, + asyncness, + unsafety, + abi, + fn_token, + ident, + generics, + paren_token, + inputs, + variadic, + output, + } +} + +process_struct! { + syn::StmtMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::TraitBound { + paren_token, + modifier, + lifetimes, + path, + } +} + +process_struct! { + syn::TraitItemConst { + attrs, + const_token, + ident, + generics, + colon_token, + ty, + default, + semi_token, + } +} + +process_struct! { + syn::TraitItemFn { + attrs, + sig, + default, + semi_token, + } +} + +process_struct! { + syn::TraitItemMacro { + attrs, + mac, + semi_token, + } +} + +process_struct! { + syn::TraitItemType { + attrs, + type_token, + ident, + generics, + colon_token, + bounds, + default, + semi_token, + } +} + +process_struct! { + syn::TypeArray { + bracket_token, + elem, + semi_token, + len, + } +} + +process_struct! { + syn::TypeBareFn { + lifetimes, + unsafety, + abi, + fn_token, + paren_token, + inputs, + variadic, + output, + } +} + +process_struct! { + syn::TypeGroup { + group_token, + elem, + } +} + +process_struct! { + syn::TypeImplTrait { + impl_token, + bounds, + } +} + +process_struct! { + syn::TypeInfer { + underscore_token, + } +} + +process_struct! { + syn::TypeMacro { + mac, + } +} + +process_struct! { + syn::TypeNever { + bang_token, + } +} + +process_struct! { + syn::TypeParam { + attrs, + ident, + colon_token, + bounds, + eq_token, + default, + } +} + +process_struct! { + syn::TypeParen { + paren_token, + elem, + } +} + +process_struct! { + syn::TypePath { + #[qself] + qself, + path, + } +} + +process_struct! { + syn::TypePtr { + star_token, + const_token, + mutability, + elem, + } +} + +process_struct! { + syn::TypeReference { + and_token, + lifetime, + mutability, + elem, + } +} + +process_struct! { + syn::TypeSlice { + bracket_token, + elem, + } +} + +process_struct! { + syn::TypeTraitObject { + dyn_token, + bounds, + } +} + +process_struct! { + syn::TypeTuple { + paren_token, + elems, + } +} + +process_struct! { + syn::UseGlob { + star_token, + } +} + +process_struct! { + syn::UseGroup { + brace_token, + items, + } +} + +process_struct! { + syn::UseName { + ident, + } +} + +process_struct! { + syn::UsePath { + ident, + colon2_token, + tree, + } +} + +process_struct! { + syn::UseRename { + ident, + as_token, + rename, + } +} + +process_struct! { + syn::Variadic { + attrs, + pat, + dots, + comma, + } +} + +process_struct! { + syn::Variant { + attrs, + ident, + fields, + discriminant, + } +} + +process_struct! { + syn::VisRestricted { + pub_token, + paren_token, + in_token, + path, + } +} + +process_struct! { + syn::WhereClause { + where_token, + predicates, + } +} + +macro_rules! process_enum { + ($path:path { + $($variant:ident$(($($field:ident),* $(,)?))?,)* + }) => { + impl Process

for $path { + fn process(self, state: &mut State

) -> Option> { + match self { + $(Self::$variant$(($($field),*))? => Some(($($($field.process(state)?,)*)?).call(|($($($field,)*)?)| Self::$variant$(($($field),*))?)),)* + } + } + } + }; + ($path:path { + $($variant:ident$(($($field:ident),* $(,)?))?,)* + #[no_op] + _, + }) => { + impl Process

for $path { + fn process(self, state: &mut State

) -> Option> { + #![allow(unused_variables)] + match self { + $(Self::$variant$(($($field),*))? => Some(($($($field.process(state)?,)*)?).call(|($($($field,)*)?)| Self::$variant$(($($field),*))?)),)* + _ => Some(Output::new(self)), + } + } + } + }; +} + +process_enum! { + syn::AttrStyle { + Outer, + Inner(f0), + } +} + +process_enum! { + syn::BinOp { + Add(f0), + Sub(f0), + Mul(f0), + Div(f0), + Rem(f0), + And(f0), + Or(f0), + BitXor(f0), + BitAnd(f0), + BitOr(f0), + Shl(f0), + Shr(f0), + Eq(f0), + Lt(f0), + Le(f0), + Ne(f0), + Ge(f0), + Gt(f0), + AddAssign(f0), + SubAssign(f0), + MulAssign(f0), + DivAssign(f0), + RemAssign(f0), + BitXorAssign(f0), + BitAndAssign(f0), + BitOrAssign(f0), + ShlAssign(f0), + ShrAssign(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::CapturedParam { + Lifetime(f0), + Ident(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::Data { + Struct(f0), + Enum(f0), + Union(f0), + } +} + +process_enum! { + syn::Expr { + Array(f0), + Assign(f0), + Async(f0), + Await(f0), + Binary(f0), + Block(f0), + Break(f0), + Call(f0), + Cast(f0), + Closure(f0), + Const(f0), + Continue(f0), + Field(f0), + ForLoop(f0), + Group(f0), + If(f0), + Index(f0), + Infer(f0), + Let(f0), + Lit(f0), + Loop(f0), + Macro(f0), + Match(f0), + MethodCall(f0), + Paren(f0), + Path(f0), + Range(f0), + RawAddr(f0), + Reference(f0), + Repeat(f0), + Return(f0), + Struct(f0), + Try(f0), + TryBlock(f0), + Tuple(f0), + Unary(f0), + Unsafe(f0), + Verbatim(f0), + While(f0), + Yield(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::FieldMutability { + None, + #[no_op] + _, + } +} + +process_enum! { + syn::Fields { + Named(f0), + Unnamed(f0), + Unit, + } +} + +process_enum! { + syn::FnArg { + Receiver(f0), + Typed(f0), + } +} + +process_enum! { + syn::ForeignItem { + Fn(f0), + Static(f0), + Type(f0), + Macro(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::GenericArgument { + Lifetime(f0), + Type(f0), + Const(f0), + AssocType(f0), + AssocConst(f0), + Constraint(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::GenericParam { + Lifetime(f0), + Type(f0), + Const(f0), + } +} + +process_enum! { + syn::ImplItem { + Const(f0), + Fn(f0), + Type(f0), + Macro(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::ImplRestriction { + #[no_op] + _, + } +} + +process_enum! { + syn::Lit { + Str(f0), + ByteStr(f0), + CStr(f0), + Byte(f0), + Char(f0), + Int(f0), + Float(f0), + Bool(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::MacroDelimiter { + Paren(f0), + Brace(f0), + Bracket(f0), + } +} + +process_enum! { + syn::Member { + Named(f0), + Unnamed(f0), + } +} + +process_enum! { + syn::Meta { + Path(f0), + List(f0), + NameValue(f0), + } +} + +process_enum! { + syn::Pat { + Const(f0), + Ident(f0), + Lit(f0), + Macro(f0), + Or(f0), + Paren(f0), + Path(f0), + Range(f0), + Reference(f0), + Rest(f0), + Slice(f0), + Struct(f0), + Tuple(f0), + TupleStruct(f0), + Type(f0), + Verbatim(f0), + Wild(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::PathArguments { + None, + AngleBracketed(f0), + Parenthesized(f0), + } +} + +process_enum! { + syn::PointerMutability { + Const(f0), + Mut(f0), + } +} + +process_enum! { + syn::RangeLimits { + HalfOpen(f0), + Closed(f0), + } +} + +process_enum! { + syn::ReturnType { + Default, + Type(f0, f1), + } +} + +process_enum! { + syn::StaticMutability { + Mut(f0), + None, + #[no_op] + _, + } +} + +process_enum! { + syn::Stmt { + Local(f0), + Item(f0), + Expr(f0, f1), + Macro(f0), + } +} + +process_enum! { + syn::TraitBoundModifier { + None, + Maybe(f0), + } +} + +process_enum! { + syn::TraitItem { + Const(f0), + Fn(f0), + Type(f0), + Macro(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::Type { + Array(f0), + BareFn(f0), + Group(f0), + ImplTrait(f0), + Infer(f0), + Macro(f0), + Never(f0), + Paren(f0), + Path(f0), + Ptr(f0), + Reference(f0), + Slice(f0), + TraitObject(f0), + Tuple(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::TypeParamBound { + Trait(f0), + Lifetime(f0), + PreciseCapture(f0), + Verbatim(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::UnOp { + Deref(f0), + Not(f0), + Neg(f0), + #[no_op] + _, + } +} + +process_enum! { + syn::UseTree { + Path(f0), + Name(f0), + Rename(f0), + Glob(f0), + Group(f0), + } +} + +process_enum! { + syn::Visibility { + Public(f0), + Restricted(f0), + Inherited, + } +} + +process_enum! { + syn::WherePredicate { + Lifetime(f0), + Type(f0), + #[no_op] + _, + } +} + +struct TopItem(syn::Item); + +impl Process

for TopItem { + fn process(self, state: &mut State

) -> Option> { + match self.0 { + syn::Item::Const(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Enum(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::ExternCrate(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Fn(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::ForeignMod(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Impl(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Macro(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Mod(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Static(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Struct(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Trait(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::TraitAlias(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Type(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Union(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + syn::Item::Use(item) => Some(item.process(state)?.map(Into::into).map(TopItem)), + _ => Some(Output::new(self)), + } + } +} + +pub(crate) fn process_cfgs(item: syn::Item, cfgs: Cfgs) -> syn::Result> { + let mut state = State:: { + cfgs, + errors: Errors::new(), + _phantom: PhantomData, + }; + let retval = TopItem(item).process(&mut state).map(|v| v.0 .0); + state.errors.finish()?; + Ok(retval) +} + +pub(crate) fn collect_cfgs(item: syn::Item) -> syn::Result> { + let mut state = State:: { + cfgs: Cfgs::default(), + errors: Errors::new(), + _phantom: PhantomData, + }; + let (None | Some(Output(()))) = TopItem(item).process(&mut state); + state.errors.finish()?; + Ok(state.cfgs) +} diff --git a/crates/fayalite/src/lib.rs b/crates/fayalite/src/lib.rs index fba7ada..5b5afb4 100644 --- a/crates/fayalite/src/lib.rs +++ b/crates/fayalite/src/lib.rs @@ -11,6 +11,56 @@ extern crate self as fayalite; #[doc(hidden)] pub use std as __std; +#[doc(hidden)] +#[macro_export] +macro_rules! __cfg_expansion_helper { + ( + [ + $($evaluated_cfgs:ident($($evaluated_exprs:tt)*) = $evaluated_results:ident,)* + ] + [ + $cfg:ident($($expr:tt)*), + $($unevaluated_cfgs:ident($($unevaluated_exprs:tt)*),)* + ] + #[$after_evaluation:path:($($after_evaluation_attr_args:tt)*)] {$($after_evaluation_args:tt)*} + ) => { + #[$cfg($($expr)*)] + $crate::__cfg_expansion_helper! { + [ + $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* + $cfg($($expr)*) = true, + ] + [ + $($unevaluated_cfgs($($unevaluated_exprs)*),)* + ] + #[$after_evaluation:($($after_evaluation_attr_args)*)] {$($after_evaluation_args)*} + } + #[$cfg(not($($expr)*))] + $crate::__cfg_expansion_helper! { + [ + $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* + $cfg($($expr)*) = false, + ] + [ + $($unevaluated_cfgs($($unevaluated_exprs)*),)* + ] + #[$after_evaluation:($($after_evaluation_attr_args)*)] {$($after_evaluation_args)*} + } + }; + ( + [ + $($evaluated_cfgs:ident($($evaluated_exprs:tt)*) = $evaluated_results:ident,)* + ] + [] + #[$after_evaluation:path:($($after_evaluation_attr_args:tt)*)] {$($after_evaluation_args:tt)*} + ) => { + #[$after_evaluation([ + $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* + ] $($after_evaluation_attr_args)*)] + $($after_evaluation_args)* + }; +} + #[doc(inline)] /// The `#[hdl_module]` attribute is applied to a Rust function so that that function creates /// a [`Module`][`::fayalite::module::Module`] when called. From b63676d0caff9387d4401f938c4489df85e7b185 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 27 Dec 2024 04:01:53 -0800 Subject: [PATCH 09/10] add test for cfgs --- crates/fayalite/build.rs | 3 ++ crates/fayalite/tests/module.rs | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/crates/fayalite/build.rs b/crates/fayalite/build.rs index 24d8f31..c6680d5 100644 --- a/crates/fayalite/build.rs +++ b/crates/fayalite/build.rs @@ -5,6 +5,9 @@ use std::{env, fs, path::Path}; fn main() { println!("cargo::rustc-check-cfg=cfg(todo)"); + println!("cargo::rustc-check-cfg=cfg(cfg_false_for_tests)"); + println!("cargo::rustc-check-cfg=cfg(cfg_true_for_tests)"); + println!("cargo::rustc-cfg=cfg_true_for_tests"); let path = "visit_types.json"; println!("cargo::rerun-if-changed={path}"); println!("cargo::rerun-if-changed=build.rs"); diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index 4cb3057..42cc528 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -4287,3 +4287,60 @@ circuit check_deduce_resets: ", }; } + +#[hdl_module(outline_generated)] +pub fn check_cfgs<#[cfg(cfg_false_for_tests)] A: Type, #[cfg(cfg_true_for_tests)] B: Type>( + #[cfg(cfg_false_for_tests)] a: A, + #[cfg(cfg_true_for_tests)] b: B, +) { + #[hdl] + struct S<#[cfg(cfg_false_for_tests)] A, #[cfg(cfg_true_for_tests)] B> { + #[cfg(cfg_false_for_tests)] + a: A, + #[cfg(cfg_true_for_tests)] + b: B, + } + #[hdl] + #[cfg(cfg_false_for_tests)] + let i_a: A = m.input(a); + #[hdl] + #[cfg(cfg_true_for_tests)] + let i_b: B = m.input(b); + #[hdl] + let w: S> = wire(); + #[cfg(cfg_false_for_tests)] + { + #[hdl] + let o_a: A = m.output(a); + connect(o_a, w.a.cast_bits_to(a)); + connect_any(w.a, i_a.cast_to_bits()); + } + #[cfg(cfg_true_for_tests)] + { + #[hdl] + let o_b: B = m.output(b); + connect(o_b, w.b.cast_bits_to(b)); + connect_any(w.b, i_b.cast_to_bits()); + } +} + +#[test] +fn test_cfgs() { + let _n = SourceLocation::normalize_files_for_tests(); + let m = check_cfgs(UInt[8]); + dbg!(m); + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + "/test/check_cfgs.fir": r"FIRRTL version 3.2.0 +circuit check_cfgs: + type Ty0 = {b: UInt<8>} + module check_cfgs: @[module-XXXXXXXXXX.rs 1:1] + input i_b: UInt<8> @[module-XXXXXXXXXX.rs 2:1] + output o_b: UInt<8> @[module-XXXXXXXXXX.rs 4:1] + wire w: Ty0 @[module-XXXXXXXXXX.rs 3:1] + connect o_b, w.b @[module-XXXXXXXXXX.rs 5:1] + connect w.b, i_b @[module-XXXXXXXXXX.rs 6:1] +", + }; +} From c16726cee63cd5afbf720dad14fcba7f738cf6b6 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Sun, 29 Dec 2024 00:48:15 -0800 Subject: [PATCH 10/10] fix #[hdl]/#[hdl_module] attributes getting the wrong hygiene when processing #[cfg]s --- crates/fayalite-proc-macros-impl/src/lib.rs | 27 +++++++++++++++------ crates/fayalite/src/lib.rs | 17 +++++++------ crates/fayalite/tests/module.rs | 15 ++++++------ 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/crates/fayalite-proc-macros-impl/src/lib.rs b/crates/fayalite-proc-macros-impl/src/lib.rs index 1b1b61f..6ba177b 100644 --- a/crates/fayalite-proc-macros-impl/src/lib.rs +++ b/crates/fayalite-proc-macros-impl/src/lib.rs @@ -1210,17 +1210,29 @@ fn hdl_main( attr: TokenStream, item: TokenStream, ) -> syn::Result { - let (evaluated_cfgs, attr): (_, TokenStream) = Parser::parse2( + fn parse_evaluated_cfgs_attr( + input: ParseStream, + parse_inner: impl FnOnce(ParseStream) -> syn::Result, + ) -> syn::Result { + let _: Token![#] = input.parse()?; + let bracket_content; + bracketed!(bracket_content in input); + let _: kw::__evaluated_cfgs = bracket_content.parse()?; + let paren_content; + parenthesized!(paren_content in bracket_content); + parse_inner(&paren_content) + } + let (evaluated_cfgs, item): (_, TokenStream) = Parser::parse2( |input: ParseStream| { - if input.peek(Bracket) && input.peek2(kw::__evaluated_cfgs) { - let cfgs = input.parse()?; - let _: kw::__evaluated_cfgs = input.parse()?; - Ok((Some(cfgs), input.parse()?)) + let peek = input.fork(); + if parse_evaluated_cfgs_attr(&peek, |_| Ok(())).is_ok() { + let evaluated_cfgs = parse_evaluated_cfgs_attr(input, Cfgs::::parse)?; + Ok((Some(evaluated_cfgs), input.parse()?)) } else { Ok((None, input.parse()?)) } }, - attr, + item, )?; let cfgs = if let Some(cfgs) = evaluated_cfgs { cfgs @@ -1229,12 +1241,11 @@ fn hdl_main( if cfgs.cfgs_list.is_empty() { Cfgs::default() } else { - let key = kw::__evaluated_cfgs::default(); return Ok(quote! { ::fayalite::__cfg_expansion_helper! { [] #cfgs - #[::fayalite::#kw:(#key #attr)] { #item } + {#[::fayalite::#kw(#attr)]} { #item } } }); } diff --git a/crates/fayalite/src/lib.rs b/crates/fayalite/src/lib.rs index 5b5afb4..88fe169 100644 --- a/crates/fayalite/src/lib.rs +++ b/crates/fayalite/src/lib.rs @@ -22,7 +22,8 @@ macro_rules! __cfg_expansion_helper { $cfg:ident($($expr:tt)*), $($unevaluated_cfgs:ident($($unevaluated_exprs:tt)*),)* ] - #[$after_evaluation:path:($($after_evaluation_attr_args:tt)*)] {$($after_evaluation_args:tt)*} + // pass as tt so we get right span for attribute + $after_evaluation_attr:tt $after_evaluation_body:tt ) => { #[$cfg($($expr)*)] $crate::__cfg_expansion_helper! { @@ -33,7 +34,7 @@ macro_rules! __cfg_expansion_helper { [ $($unevaluated_cfgs($($unevaluated_exprs)*),)* ] - #[$after_evaluation:($($after_evaluation_attr_args)*)] {$($after_evaluation_args)*} + $after_evaluation_attr $after_evaluation_body } #[$cfg(not($($expr)*))] $crate::__cfg_expansion_helper! { @@ -44,7 +45,7 @@ macro_rules! __cfg_expansion_helper { [ $($unevaluated_cfgs($($unevaluated_exprs)*),)* ] - #[$after_evaluation:($($after_evaluation_attr_args)*)] {$($after_evaluation_args)*} + $after_evaluation_attr $after_evaluation_body } }; ( @@ -52,12 +53,14 @@ macro_rules! __cfg_expansion_helper { $($evaluated_cfgs:ident($($evaluated_exprs:tt)*) = $evaluated_results:ident,)* ] [] - #[$after_evaluation:path:($($after_evaluation_attr_args:tt)*)] {$($after_evaluation_args:tt)*} + // don't use #[...] so we get right span for `#` and `[]` of attribute + {$($after_evaluation_attr:tt)*} {$($after_evaluation_body:tt)*} ) => { - #[$after_evaluation([ + $($after_evaluation_attr)* + #[__evaluated_cfgs([ $($evaluated_cfgs($($evaluated_exprs)*) = $evaluated_results,)* - ] $($after_evaluation_attr_args)*)] - $($after_evaluation_args)* + ])] + $($after_evaluation_body)* }; } diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index 42cc528..4e56df4 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -4288,7 +4288,8 @@ circuit check_deduce_resets: }; } -#[hdl_module(outline_generated)] +// intentionally not outline_generated to ensure we get correct macro hygiene +#[hdl_module] pub fn check_cfgs<#[cfg(cfg_false_for_tests)] A: Type, #[cfg(cfg_true_for_tests)] B: Type>( #[cfg(cfg_false_for_tests)] a: A, #[cfg(cfg_true_for_tests)] b: B, @@ -4335,12 +4336,12 @@ fn test_cfgs() { "/test/check_cfgs.fir": r"FIRRTL version 3.2.0 circuit check_cfgs: type Ty0 = {b: UInt<8>} - module check_cfgs: @[module-XXXXXXXXXX.rs 1:1] - input i_b: UInt<8> @[module-XXXXXXXXXX.rs 2:1] - output o_b: UInt<8> @[module-XXXXXXXXXX.rs 4:1] - wire w: Ty0 @[module-XXXXXXXXXX.rs 3:1] - connect o_b, w.b @[module-XXXXXXXXXX.rs 5:1] - connect w.b, i_b @[module-XXXXXXXXXX.rs 6:1] + module check_cfgs: @[the_test_file.rs 9962:1] + input i_b: UInt<8> @[the_test_file.rs 9979:20] + output o_b: UInt<8> @[the_test_file.rs 9992:24] + wire w: Ty0 @[the_test_file.rs 9981:25] + connect o_b, w.b @[the_test_file.rs 9993:9] + connect w.b, i_b @[the_test_file.rs 9994:9] ", }; }