use celox::Simulation;
#[test]
fn test_simulation_step() {
let code = r#"
module Top (
clk: input clock,
rst: input reset,
cnt: output logic<8>
) {
var counter: logic<8>;
always_ff (clk, rst) {
if_reset {
counter = 8'd0;
} else {
counter = counter + 8'd1;
}
}
assign cnt = counter;
}
"#;
let mut vsim = Simulation::builder(code, "Top").build().unwrap();
vsim.add_clock("clk", 10, 0); let rst = vsim.signal("rst");
let cnt = vsim.signal("cnt");
vsim.modify(|io| io.set::<u8>(rst, 1)).unwrap();
vsim.step().unwrap();
assert_eq!(vsim.time(), 0);
let val0 = vsim.get(cnt);
vsim.step().unwrap();
assert_eq!(vsim.time(), 5);
vsim.step().unwrap();
assert_eq!(vsim.time(), 10);
let val10 = vsim.get(cnt);
assert!(val10 > val0);
}
#[test]
fn test_next_event_time() {
let code = r#"
module Top (
clk: input clock
) {
always_ff (clk) {}
}
"#;
let mut vsim = Simulation::builder(code, "Top").build().unwrap();
vsim.add_clock("clk", 100, 0);
assert_eq!(vsim.next_event_time(), Some(0));
vsim.step().unwrap();
assert_eq!(vsim.next_event_time(), Some(50));
vsim.step().unwrap();
assert_eq!(vsim.next_event_time(), Some(100));
}
#[test]
fn test_step_decorates_runtime_errors() {
let code = r#"
module Top (
clk: input clock,
start: input logic<8>,
count: input logic<8>,
q: output logic<8>
) {
always_ff (clk) {
q = 0;
for i in start..count step *= 2 {
q = i as 8;
}
}
}
"#;
let mut vsim = Simulation::builder(code, "Top").build().unwrap();
let start = vsim.signal("start");
let count = vsim.signal("count");
vsim.modify(|io| {
io.set(start, 0u8);
io.set(count, 4u8);
})
.unwrap();
vsim.add_clock("clk", 10, 0);
assert_eq!(
vsim.step().unwrap_err().to_string(),
"Non-progressing for loop in always_ff (loop variable `i`): i"
);
}