forked from libre-chip/fayalite
change SimValue to contain and deref to a value and not just contain bits
This commit is contained in:
parent
e0f978fbb6
commit
5028401a5a
19 changed files with 2065 additions and 820 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue