use celox::Simulator;
#[path = "test_utils/mod.rs"]
#[macro_use]
mod test_utils;
all_backends! {
fn test_binary_encoder(sim) {
@setup { let top = r#"
module Top (
i_unary: input logic<8>,
o_bin : output logic<3>,
) {
inst u: binary_encoder #(UNARY_WIDTH: 8) (
i_en : 1'b1,
i_unary,
o_bin,
);
}
"#;
let code = format!("{}\n{top}", test_utils::veryl_std::source(&["binary_enc_dec", "binary_encoder.veryl"])); }
@build Simulator::builder(&code, "Top");
let i_unary = sim.signal("i_unary");
let o_bin = sim.signal("o_bin");
for bit_pos in 0u8..8 {
let onehot_val: u8 = 1 << bit_pos;
sim.modify(|io| io.set(i_unary, onehot_val)).unwrap();
let bin_out = sim.get_as::<u8>(o_bin);
assert_eq!(
bin_out, bit_pos,
"encoder({onehot_val:#010b}): expected={bit_pos}, got={bin_out}"
);
}
}
fn test_binary_decoder(sim) {
@setup { let top = r#"
module Top (
i_bin : input logic<3>,
o_unary: output logic<8>,
) {
inst u: binary_decoder #(BIN_WIDTH: 3) (
i_en: 1'b1,
i_bin,
o_unary,
);
}
"#;
let code = format!("{}\n{top}", test_utils::veryl_std::source(&["binary_enc_dec", "binary_decoder.veryl"])); }
@build Simulator::builder(&code, "Top");
let i_bin = sim.signal("i_bin");
let o_unary = sim.signal("o_unary");
for val in 0u8..8 {
sim.modify(|io| io.set(i_bin, val)).unwrap();
let unary_out = sim.get_as::<u8>(o_unary);
let expected: u8 = 1 << val;
assert_eq!(
unary_out, expected,
"decoder({val}): expected={expected:#010b}, got={unary_out:#010b}"
);
}
}
fn test_binary_codec_roundtrip(sim) {
@setup { let top = r#"
module Top (
i_unary: input logic<8>,
o_unary: output logic<8>,
o_bin : output logic<3>,
) {
inst u_enc: binary_encoder #(UNARY_WIDTH: 8) (
i_en : 1'b1,
i_unary,
o_bin,
);
inst u_dec: binary_decoder #(BIN_WIDTH: 3) (
i_en : 1'b1,
i_bin : o_bin,
o_unary,
);
}
"#;
let code = format!(
"{}\n{}\n{top}",
test_utils::veryl_std::source(&["binary_enc_dec", "binary_encoder.veryl"]),
test_utils::veryl_std::source(&["binary_enc_dec", "binary_decoder.veryl"]),
); }
@build Simulator::builder(&code, "Top");
let i_unary = sim.signal("i_unary");
let o_unary = sim.signal("o_unary");
for bit_pos in 0u8..8 {
let onehot_val: u8 = 1 << bit_pos;
sim.modify(|io| io.set(i_unary, onehot_val)).unwrap();
let roundtrip = sim.get_as::<u8>(o_unary);
assert_eq!(
roundtrip, onehot_val,
"roundtrip failed for bit {bit_pos}: input={onehot_val:#010b}, output={roundtrip:#010b}"
);
}
}
fn test_binary_encoder_disabled(sim) {
@setup { let top = r#"
module Top (
i_en : input logic,
i_unary: input logic<8>,
o_bin : output logic<3>,
) {
inst u: binary_encoder #(UNARY_WIDTH: 8) (
i_en,
i_unary,
o_bin,
);
}
"#;
let code = format!("{}\n{top}", test_utils::veryl_std::source(&["binary_enc_dec", "binary_encoder.veryl"])); }
@build Simulator::builder(&code, "Top");
let i_en = sim.signal("i_en");
let i_unary = sim.signal("i_unary");
let o_bin = sim.signal("o_bin");
sim.modify(|io| {
io.set(i_en, 0u8);
io.set(i_unary, 0b10000000u8);
})
.unwrap();
let bin_disabled = sim.get_as::<u8>(o_bin);
assert_eq!(bin_disabled, 0, "disabled encoder should output 0");
sim.modify(|io| io.set(i_en, 1u8)).unwrap();
let bin_enabled = sim.get_as::<u8>(o_bin);
assert_eq!(bin_enabled, 7, "enabled encoder should output 7 for bit 7");
}
}