forked from libre-chip/fayalite
expand SimValue support
This commit is contained in:
parent
5028401a5a
commit
a40eaaa2da
13 changed files with 864 additions and 342 deletions
|
|
@ -7,13 +7,7 @@ use fayalite::{
|
|||
module::{instance_with_loc, reg_builder_with_loc},
|
||||
prelude::*,
|
||||
reset::ResetType,
|
||||
sim::{
|
||||
time::SimDuration,
|
||||
value::{SimValue, ToSimValue},
|
||||
vcd::VcdWriterDecls,
|
||||
Simulation,
|
||||
},
|
||||
ty::StaticType,
|
||||
sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation},
|
||||
util::RcWriter,
|
||||
};
|
||||
use std::num::NonZeroUsize;
|
||||
|
|
@ -391,113 +385,110 @@ fn test_enums() {
|
|||
let mut sim = Simulation::new(enums());
|
||||
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_bool(sim.io().en, false);
|
||||
sim.write_bool_or_int(sim.io().which_in, 0_hdl_u2);
|
||||
sim.write_bool_or_int(sim.io().data_in, 0_hdl_u4);
|
||||
sim.write(sim.io().cd.clk, false);
|
||||
sim.write(sim.io().cd.rst, true);
|
||||
sim.write(sim.io().en, false);
|
||||
sim.write(sim.io().which_in, 0_hdl_u2);
|
||||
sim.write(sim.io().data_in, 0_hdl_u4);
|
||||
sim.advance_time(SimDuration::from_micros(1));
|
||||
sim.write_clock(sim.io().cd.clk, true);
|
||||
sim.write(sim.io().cd.clk, true);
|
||||
sim.advance_time(SimDuration::from_nanos(100));
|
||||
sim.write_reset(sim.io().cd.rst, false);
|
||||
sim.write(sim.io().cd.rst, false);
|
||||
sim.advance_time(SimDuration::from_nanos(900));
|
||||
type BOutTy = HdlOption<(UInt<1>, Bool)>;
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[hdl(cmp_eq)]
|
||||
struct IO {
|
||||
en: bool,
|
||||
which_in: u8,
|
||||
data_in: u8,
|
||||
which_out: u8,
|
||||
data_out: u8,
|
||||
b_out: SimValue<BOutTy>,
|
||||
en: Bool,
|
||||
which_in: UInt<2>,
|
||||
data_in: UInt<4>,
|
||||
which_out: UInt<2>,
|
||||
data_out: UInt<4>,
|
||||
b_out: HdlOption<(UInt<1>, Bool)>,
|
||||
}
|
||||
let io_cycles = [
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
en: false,
|
||||
which_in: 0,
|
||||
data_in: 0,
|
||||
which_out: 0,
|
||||
data_out: 0,
|
||||
b_out: HdlNone().to_sim_value(StaticType::TYPE),
|
||||
which_in: 0_hdl_u2,
|
||||
data_in: 0_hdl_u4,
|
||||
which_out: 0_hdl_u2,
|
||||
data_out: 0_hdl_u4,
|
||||
b_out: HdlNone(),
|
||||
},
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
en: true,
|
||||
which_in: 1,
|
||||
data_in: 0,
|
||||
which_out: 0,
|
||||
data_out: 0,
|
||||
b_out: HdlNone().to_sim_value(StaticType::TYPE),
|
||||
which_in: 1_hdl_u2,
|
||||
data_in: 0_hdl_u4,
|
||||
which_out: 0_hdl_u2,
|
||||
data_out: 0_hdl_u4,
|
||||
b_out: HdlNone(),
|
||||
},
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
en: false,
|
||||
which_in: 0,
|
||||
data_in: 0,
|
||||
which_out: 1,
|
||||
data_out: 0,
|
||||
b_out: HdlSome((0_hdl_u1, false)).to_sim_value(StaticType::TYPE),
|
||||
which_in: 0_hdl_u2,
|
||||
data_in: 0_hdl_u4,
|
||||
which_out: 1_hdl_u2,
|
||||
data_out: 0_hdl_u4,
|
||||
b_out: HdlSome((0_hdl_u1, false)),
|
||||
},
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
en: true,
|
||||
which_in: 1,
|
||||
data_in: 0xF,
|
||||
which_out: 1,
|
||||
data_out: 0,
|
||||
b_out: HdlSome((0_hdl_u1, false)).to_sim_value(StaticType::TYPE),
|
||||
which_in: 1_hdl_u2,
|
||||
data_in: 0xF_hdl_u4,
|
||||
which_out: 1_hdl_u2,
|
||||
data_out: 0_hdl_u4,
|
||||
b_out: HdlSome((0_hdl_u1, false)),
|
||||
},
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
en: true,
|
||||
which_in: 1,
|
||||
data_in: 0xF,
|
||||
which_out: 1,
|
||||
data_out: 0x3,
|
||||
b_out: HdlSome((1_hdl_u1, true)).to_sim_value(StaticType::TYPE),
|
||||
which_in: 1_hdl_u2,
|
||||
data_in: 0xF_hdl_u4,
|
||||
which_out: 1_hdl_u2,
|
||||
data_out: 0x3_hdl_u4,
|
||||
b_out: HdlSome((1_hdl_u1, true)),
|
||||
},
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
en: true,
|
||||
which_in: 2,
|
||||
data_in: 0xF,
|
||||
which_out: 1,
|
||||
data_out: 0x3,
|
||||
b_out: HdlSome((1_hdl_u1, true)).to_sim_value(StaticType::TYPE),
|
||||
which_in: 2_hdl_u2,
|
||||
data_in: 0xF_hdl_u4,
|
||||
which_out: 1_hdl_u2,
|
||||
data_out: 0x3_hdl_u4,
|
||||
b_out: HdlSome((1_hdl_u1, true)),
|
||||
},
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
en: true,
|
||||
which_in: 2,
|
||||
data_in: 0xF,
|
||||
which_out: 2,
|
||||
data_out: 0xF,
|
||||
b_out: HdlNone().to_sim_value(StaticType::TYPE),
|
||||
which_in: 2_hdl_u2,
|
||||
data_in: 0xF_hdl_u4,
|
||||
which_out: 2_hdl_u2,
|
||||
data_out: 0xF_hdl_u4,
|
||||
b_out: HdlNone(),
|
||||
},
|
||||
];
|
||||
for (
|
||||
cycle,
|
||||
expected @ IO {
|
||||
for (cycle, expected) in io_cycles.into_iter().enumerate() {
|
||||
#[hdl(sim)]
|
||||
let IO {
|
||||
en,
|
||||
which_in,
|
||||
data_in,
|
||||
which_out: _,
|
||||
data_out: _,
|
||||
b_out: _,
|
||||
},
|
||||
) in io_cycles.into_iter().enumerate()
|
||||
{
|
||||
sim.write_bool(sim.io().en, en);
|
||||
sim.write_bool_or_int(sim.io().which_in, which_in.cast_to_static());
|
||||
sim.write_bool_or_int(sim.io().data_in, data_in.cast_to_static());
|
||||
let io = IO {
|
||||
} = expected;
|
||||
sim.write(sim.io().en, &en);
|
||||
sim.write(sim.io().which_in, &which_in);
|
||||
sim.write(sim.io().data_in, &data_in);
|
||||
let io = #[hdl(sim)]
|
||||
IO {
|
||||
en,
|
||||
which_in,
|
||||
data_in,
|
||||
which_out: sim
|
||||
.read_bool_or_int(sim.io().which_out)
|
||||
.to_bigint()
|
||||
.try_into()
|
||||
.expect("known to be in range"),
|
||||
data_out: sim
|
||||
.read_bool_or_int(sim.io().data_out)
|
||||
.to_bigint()
|
||||
.try_into()
|
||||
.expect("known to be in range"),
|
||||
which_out: sim.read(sim.io().which_out),
|
||||
data_out: sim.read(sim.io().data_out),
|
||||
b_out: sim.read(sim.io().b_out),
|
||||
};
|
||||
assert_eq!(
|
||||
|
|
@ -559,7 +550,7 @@ fn test_memories() {
|
|||
w_mask: (Bool, Bool),
|
||||
}
|
||||
let io_cycles = [
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: false,
|
||||
|
|
@ -569,7 +560,7 @@ fn test_memories() {
|
|||
w_data: (0u8, 0i8),
|
||||
w_mask: (false, false),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -579,7 +570,7 @@ fn test_memories() {
|
|||
w_data: (0x10u8, 0x20i8),
|
||||
w_mask: (true, true),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -589,7 +580,7 @@ fn test_memories() {
|
|||
w_data: (0x30u8, 0x40i8),
|
||||
w_mask: (false, true),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -599,7 +590,7 @@ fn test_memories() {
|
|||
w_data: (0x50u8, 0x60i8),
|
||||
w_mask: (true, false),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -609,7 +600,7 @@ fn test_memories() {
|
|||
w_data: (0x70u8, -0x80i8),
|
||||
w_mask: (false, false),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -619,7 +610,7 @@ fn test_memories() {
|
|||
w_data: (0x90u8, 0xA0u8 as i8),
|
||||
w_mask: (false, false),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -629,7 +620,7 @@ fn test_memories() {
|
|||
w_data: (0x90u8, 0xA0u8 as i8),
|
||||
w_mask: (true, true),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -639,7 +630,7 @@ fn test_memories() {
|
|||
w_data: (0xB0u8, 0xC0u8 as i8),
|
||||
w_mask: (true, true),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 0_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -649,7 +640,7 @@ fn test_memories() {
|
|||
w_data: (0xD0u8, 0xE0u8 as i8),
|
||||
w_mask: (true, true),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 1_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -659,7 +650,7 @@ fn test_memories() {
|
|||
w_data: (0xD0u8, 0xE0u8 as i8),
|
||||
w_mask: (true, true),
|
||||
},
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
IO {
|
||||
r_addr: 2_hdl_u4,
|
||||
r_en: true,
|
||||
|
|
@ -671,7 +662,7 @@ fn test_memories() {
|
|||
},
|
||||
];
|
||||
for (cycle, expected) in io_cycles.into_iter().enumerate() {
|
||||
#[hdl]
|
||||
#[hdl(sim)]
|
||||
let IO {
|
||||
r_addr,
|
||||
r_en,
|
||||
|
|
@ -681,13 +672,13 @@ fn test_memories() {
|
|||
w_data,
|
||||
w_mask,
|
||||
} = 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]
|
||||
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(sim)]
|
||||
IO {
|
||||
r_addr,
|
||||
r_en,
|
||||
|
|
@ -696,20 +687,19 @@ fn test_memories() {
|
|||
w_en,
|
||||
w_data,
|
||||
w_mask,
|
||||
})
|
||||
.to_sim_value(StaticType::TYPE);
|
||||
};
|
||||
assert_eq!(
|
||||
expected.to_sim_value(StaticType::TYPE),
|
||||
expected,
|
||||
io,
|
||||
"vcd:\n{}\ncycle: {cycle}",
|
||||
String::from_utf8(writer.take()).unwrap(),
|
||||
);
|
||||
sim.advance_time(SimDuration::from_micros(1));
|
||||
sim.write_clock(sim.io().r.clk, true);
|
||||
sim.write_clock(sim.io().w.clk, true);
|
||||
sim.write(sim.io().r.clk, true);
|
||||
sim.write(sim.io().w.clk, true);
|
||||
sim.advance_time(SimDuration::from_micros(1));
|
||||
sim.write_clock(sim.io().r.clk, false);
|
||||
sim.write_clock(sim.io().w.clk, false);
|
||||
sim.write(sim.io().r.clk, false);
|
||||
sim.write(sim.io().w.clk, false);
|
||||
}
|
||||
sim.flush_traces().unwrap();
|
||||
let vcd = String::from_utf8(writer.take()).unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue