change SimValue to contain and deref to a value and not just contain bits

This commit is contained in:
Jacob Lifshay 2025-03-27 23:44:36 -07:00
parent e0f978fbb6
commit 5028401a5a
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
19 changed files with 2065 additions and 820 deletions

View file

@ -3,10 +3,16 @@
use fayalite::{
int::UIntValue,
memory::{ReadStruct, ReadWriteStruct, WriteStruct},
module::{instance_with_loc, reg_builder_with_loc},
prelude::*,
reset::ResetType,
sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation, ToSimValue},
sim::{
time::SimDuration,
value::{SimValue, ToSimValue},
vcd::VcdWriterDecls,
Simulation,
},
ty::StaticType,
util::RcWriter,
};
@ -396,32 +402,14 @@ fn test_enums() {
sim.write_reset(sim.io().cd.rst, false);
sim.advance_time(SimDuration::from_nanos(900));
type BOutTy = HdlOption<(UInt<1>, Bool)>;
#[derive(Debug)]
#[derive(Debug, PartialEq)]
struct IO {
en: bool,
which_in: u8,
data_in: u8,
which_out: u8,
data_out: u8,
b_out: Expr<BOutTy>,
}
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)
}
b_out: SimValue<BOutTy>,
}
let io_cycles = [
IO {
@ -430,7 +418,7 @@ fn test_enums() {
data_in: 0,
which_out: 0,
data_out: 0,
b_out: HdlNone(),
b_out: HdlNone().to_sim_value(StaticType::TYPE),
},
IO {
en: true,
@ -438,7 +426,7 @@ fn test_enums() {
data_in: 0,
which_out: 0,
data_out: 0,
b_out: HdlNone(),
b_out: HdlNone().to_sim_value(StaticType::TYPE),
},
IO {
en: false,
@ -446,7 +434,7 @@ fn test_enums() {
data_in: 0,
which_out: 1,
data_out: 0,
b_out: HdlSome((0_hdl_u1, false)),
b_out: HdlSome((0_hdl_u1, false)).to_sim_value(StaticType::TYPE),
},
IO {
en: true,
@ -454,7 +442,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 1,
data_out: 0,
b_out: HdlSome((0_hdl_u1, false)),
b_out: HdlSome((0_hdl_u1, false)).to_sim_value(StaticType::TYPE),
},
IO {
en: true,
@ -462,7 +450,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 1,
data_out: 0x3,
b_out: HdlSome((1_hdl_u1, true)),
b_out: HdlSome((1_hdl_u1, true)).to_sim_value(StaticType::TYPE),
},
IO {
en: true,
@ -470,7 +458,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 1,
data_out: 0x3,
b_out: HdlSome((1_hdl_u1, true)),
b_out: HdlSome((1_hdl_u1, true)).to_sim_value(StaticType::TYPE),
},
IO {
en: true,
@ -478,7 +466,7 @@ fn test_enums() {
data_in: 0xF,
which_out: 2,
data_out: 0xF,
b_out: HdlNone(),
b_out: HdlNone().to_sim_value(StaticType::TYPE),
},
];
for (
@ -510,7 +498,7 @@ fn test_enums() {
.to_bigint()
.try_into()
.expect("known to be in range"),
b_out: sim.read(sim.io().b_out).to_expr(),
b_out: sim.read(sim.io().b_out),
};
assert_eq!(
expected,
@ -539,9 +527,9 @@ fn test_enums() {
#[hdl_module(outline_generated)]
pub fn memories() {
#[hdl]
let r: fayalite::memory::ReadStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input();
let r: ReadStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input();
#[hdl]
let w: fayalite::memory::WriteStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input();
let w: WriteStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input();
#[hdl]
let mut mem = memory_with_init([(0x01u8, 0x23i8); 16]);
mem.read_latency(0);
@ -560,120 +548,131 @@ fn test_memories() {
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)]
#[hdl(cmp_eq)]
struct IO {
r_addr: u8,
r_en: bool,
r_data: (u8, i8),
w_addr: u8,
w_en: bool,
w_data: (u8, i8),
w_mask: (bool, bool),
r_addr: UInt<4>,
r_en: Bool,
r_data: (UInt<8>, SInt<8>),
w_addr: UInt<4>,
w_en: Bool,
w_data: (UInt<8>, SInt<8>),
w_mask: (Bool, Bool),
}
let io_cycles = [
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: false,
r_data: (0, 0),
w_addr: 0,
r_data: (0u8, 0i8),
w_addr: 0_hdl_u4,
w_en: false,
w_data: (0, 0),
w_data: (0u8, 0i8),
w_mask: (false, false),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x1, 0x23),
w_addr: 0,
r_data: (0x1u8, 0x23i8),
w_addr: 0_hdl_u4,
w_en: true,
w_data: (0x10, 0x20),
w_data: (0x10u8, 0x20i8),
w_mask: (true, true),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x10, 0x20),
w_addr: 0,
r_data: (0x10u8, 0x20i8),
w_addr: 0_hdl_u4,
w_en: true,
w_data: (0x30, 0x40),
w_data: (0x30u8, 0x40i8),
w_mask: (false, true),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x10, 0x40),
w_addr: 0,
r_data: (0x10u8, 0x40i8),
w_addr: 0_hdl_u4,
w_en: true,
w_data: (0x50, 0x60),
w_data: (0x50u8, 0x60i8),
w_mask: (true, false),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x50, 0x40),
w_addr: 0,
r_data: (0x50u8, 0x40i8),
w_addr: 0_hdl_u4,
w_en: true,
w_data: (0x70, -0x80),
w_data: (0x70u8, -0x80i8),
w_mask: (false, false),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x50, 0x40),
w_addr: 0,
r_data: (0x50u8, 0x40i8),
w_addr: 0_hdl_u4,
w_en: false,
w_data: (0x90, 0xA0u8 as i8),
w_data: (0x90u8, 0xA0u8 as i8),
w_mask: (false, false),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x50, 0x40),
w_addr: 1,
r_data: (0x50u8, 0x40i8),
w_addr: 1_hdl_u4,
w_en: true,
w_data: (0x90, 0xA0u8 as i8),
w_data: (0x90u8, 0xA0u8 as i8),
w_mask: (true, true),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x50, 0x40),
w_addr: 2,
r_data: (0x50u8, 0x40i8),
w_addr: 2_hdl_u4,
w_en: true,
w_data: (0xB0, 0xC0u8 as i8),
w_data: (0xB0u8, 0xC0u8 as i8),
w_mask: (true, true),
},
#[hdl]
IO {
r_addr: 0,
r_addr: 0_hdl_u4,
r_en: true,
r_data: (0x50, 0x40),
w_addr: 2,
r_data: (0x50u8, 0x40i8),
w_addr: 2_hdl_u4,
w_en: false,
w_data: (0xD0, 0xE0u8 as i8),
w_data: (0xD0u8, 0xE0u8 as i8),
w_mask: (true, true),
},
#[hdl]
IO {
r_addr: 1,
r_addr: 1_hdl_u4,
r_en: true,
r_data: (0x90, 0xA0u8 as i8),
w_addr: 2,
r_data: (0x90u8, 0xA0u8 as i8),
w_addr: 2_hdl_u4,
w_en: false,
w_data: (0xD0, 0xE0u8 as i8),
w_data: (0xD0u8, 0xE0u8 as i8),
w_mask: (true, true),
},
#[hdl]
IO {
r_addr: 2,
r_addr: 2_hdl_u4,
r_en: true,
r_data: (0xB0, 0xC0u8 as i8),
w_addr: 2,
r_data: (0xB0u8, 0xC0u8 as i8),
w_addr: 2_hdl_u4,
w_en: false,
w_data: (0xD0, 0xE0u8 as i8),
w_data: (0xD0u8, 0xE0u8 as i8),
w_mask: (true, true),
},
];
for (
cycle,
expected @ IO {
for (cycle, expected) in io_cycles.into_iter().enumerate() {
#[hdl]
let IO {
r_addr,
r_en,
r_data: _,
@ -681,37 +680,26 @@ fn test_memories() {
w_en,
w_data,
w_mask,
},
) in io_cycles.into_iter().enumerate()
{
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);
sim.write_bool_or_int(sim.io().w.data.0, w_data.0);
sim.write_bool_or_int(sim.io().w.data.1, w_data.1);
sim.write_bool(sim.io().w.mask.0, w_mask.0);
sim.write_bool(sim.io().w.mask.1, w_mask.1);
let io = IO {
} = expected;
sim.write(sim.io().r.addr, r_addr);
sim.write(sim.io().r.en, r_en);
sim.write(sim.io().w.addr, w_addr);
sim.write(sim.io().w.en, w_en);
sim.write(sim.io().w.data, w_data);
sim.write(sim.io().w.mask, w_mask);
let io = (#[hdl]
IO {
r_addr,
r_en,
r_data: (
sim.read_bool_or_int(sim.io().r.data.0)
.to_bigint()
.try_into()
.expect("known to be in range"),
sim.read_bool_or_int(sim.io().r.data.1)
.to_bigint()
.try_into()
.expect("known to be in range"),
),
r_data: sim.read(sim.io().r.data),
w_addr,
w_en,
w_data,
w_mask,
};
})
.to_sim_value(StaticType::TYPE);
assert_eq!(
expected,
expected.to_sim_value(StaticType::TYPE),
io,
"vcd:\n{}\ncycle: {cycle}",
String::from_utf8(writer.take()).unwrap(),
@ -739,7 +727,7 @@ fn test_memories() {
#[hdl_module(outline_generated)]
pub fn memories2() {
#[hdl]
let rw: fayalite::memory::ReadWriteStruct<UInt<2>, ConstUsize<3>> = m.input();
let rw: ReadWriteStruct<UInt<2>, ConstUsize<3>> = m.input();
#[hdl]
let mut mem = memory_with_init([HdlSome(true); 5]);
mem.read_latency(1);
@ -1012,9 +1000,9 @@ fn test_memories2() {
#[hdl_module(outline_generated)]
pub fn memories3() {
#[hdl]
let r: fayalite::memory::ReadStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input();
let r: ReadStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input();
#[hdl]
let w: fayalite::memory::WriteStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input();
let w: WriteStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input();
#[hdl]
let mut mem: MemBuilder<Array<UInt<8>, 8>> = memory();
mem.depth(8);