forked from libre-chip/fayalite
		
	queue formal proof passes!
This commit is contained in:
		
							parent
							
								
									343805f80b
								
							
						
					
					
						commit
						0d54b9a2a9
					
				
					 6 changed files with 183 additions and 86 deletions
				
			
		| 
						 | 
				
			
			@ -516,7 +516,7 @@ impl FormalArgs {
 | 
			
		|||
        std::fs::write(&sby_file, self.sby_contents(&output)?)?;
 | 
			
		||||
        let mut cmd = process::Command::new(&self.sby);
 | 
			
		||||
        cmd.arg("-f");
 | 
			
		||||
        cmd.arg(sby_file);
 | 
			
		||||
        cmd.arg(sby_file.file_name().unwrap());
 | 
			
		||||
        cmd.args(&self.sby_extra_args);
 | 
			
		||||
        cmd.current_dir(&output.verilog.firrtl.output_dir);
 | 
			
		||||
        let status = self.verilog.firrtl.base.run_external_command(cmd)?;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
			
		||||
// See Notices.txt for copyright information
 | 
			
		||||
use crate::{
 | 
			
		||||
    intern::{Intern, Interned},
 | 
			
		||||
    int::BoolOrIntType,
 | 
			
		||||
    intern::{Intern, Interned, Memoize},
 | 
			
		||||
    prelude::*,
 | 
			
		||||
};
 | 
			
		||||
use std::sync::OnceLock;
 | 
			
		||||
| 
						 | 
				
			
			@ -172,12 +173,7 @@ pub fn formal_reset() -> Expr<SyncReset> {
 | 
			
		|||
        m.annotate_module(BlackBoxInlineAnnotation {
 | 
			
		||||
            path: "fayalite_formal_reset.v".intern(),
 | 
			
		||||
            text: r"module __fayalite_formal_reset(output rst);
 | 
			
		||||
    reg rst;
 | 
			
		||||
    (* gclk *)
 | 
			
		||||
    reg gclk;
 | 
			
		||||
    initial rst = 1;
 | 
			
		||||
    always @(posedge gclk)
 | 
			
		||||
        rst <= 0;
 | 
			
		||||
    assign rst = $initstate;
 | 
			
		||||
endmodule
 | 
			
		||||
"
 | 
			
		||||
            .intern(),
 | 
			
		||||
| 
						 | 
				
			
			@ -189,3 +185,63 @@ endmodule
 | 
			
		|||
    let formal_reset = instance(*MOD.get_or_init(formal_reset));
 | 
			
		||||
    formal_reset.rst
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! make_any_const_fn {
 | 
			
		||||
    ($ident:ident, $verilog_attribute:literal) => {
 | 
			
		||||
        #[hdl]
 | 
			
		||||
        pub fn $ident<T: BoolOrIntType>(ty: T) -> Expr<T> {
 | 
			
		||||
            #[hdl_module(extern)]
 | 
			
		||||
            pub(super) fn $ident<T: BoolOrIntType>(ty: T) {
 | 
			
		||||
                #[hdl]
 | 
			
		||||
                let out: T = m.output(ty);
 | 
			
		||||
                let width = ty.width();
 | 
			
		||||
                let verilog_bitslice = if width == 1 {
 | 
			
		||||
                    String::new()
 | 
			
		||||
                } else {
 | 
			
		||||
                    format!(" [{}:0]", width - 1)
 | 
			
		||||
                };
 | 
			
		||||
                m.annotate_module(BlackBoxInlineAnnotation {
 | 
			
		||||
                    path: Intern::intern_owned(format!(
 | 
			
		||||
                        "fayalite_{}_{width}.v",
 | 
			
		||||
                        stringify!($ident),
 | 
			
		||||
                    )),
 | 
			
		||||
                    text: Intern::intern_owned(format!(
 | 
			
		||||
                        r"module __fayalite_{}_{width}(output{verilog_bitslice} out);
 | 
			
		||||
    (* {} *)
 | 
			
		||||
    reg{verilog_bitslice} out;
 | 
			
		||||
endmodule
 | 
			
		||||
",
 | 
			
		||||
                        stringify!($ident),
 | 
			
		||||
                        $verilog_attribute,
 | 
			
		||||
                    )),
 | 
			
		||||
                });
 | 
			
		||||
                m.verilog_name(format!("__fayalite_{}_{width}", stringify!($ident)));
 | 
			
		||||
            }
 | 
			
		||||
            #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 | 
			
		||||
            struct TheMemoize<T>(T);
 | 
			
		||||
            impl<T: BoolOrIntType> Memoize for TheMemoize<T> {
 | 
			
		||||
                type Input = ();
 | 
			
		||||
                type InputOwned = ();
 | 
			
		||||
                type Output = Option<Interned<Module<$ident<T>>>>;
 | 
			
		||||
                fn inner(self, _input: &Self::Input) -> Self::Output {
 | 
			
		||||
                    if self.0.width() == 0 {
 | 
			
		||||
                        None
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Some($ident(self.0))
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            let Some(module) = TheMemoize(ty).get_owned(()) else {
 | 
			
		||||
                return 0_hdl_u0.cast_bits_to(ty);
 | 
			
		||||
            };
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let $ident = instance(module);
 | 
			
		||||
            $ident.out
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
make_any_const_fn!(any_const, "anyconst");
 | 
			
		||||
make_any_const_fn!(any_seq, "anyseq");
 | 
			
		||||
make_any_const_fn!(all_const, "allconst");
 | 
			
		||||
make_any_const_fn!(all_seq, "allseq");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,8 +14,9 @@ pub use crate::{
 | 
			
		|||
        ReduceBits, ToExpr,
 | 
			
		||||
    },
 | 
			
		||||
    formal::{
 | 
			
		||||
        formal_global_clock, formal_reset, hdl_assert, hdl_assert_with_enable, hdl_assume,
 | 
			
		||||
        hdl_assume_with_enable, hdl_cover, hdl_cover_with_enable, MakeFormalExpr,
 | 
			
		||||
        all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset, hdl_assert,
 | 
			
		||||
        hdl_assert_with_enable, hdl_assume, hdl_assume_with_enable, hdl_cover,
 | 
			
		||||
        hdl_cover_with_enable, MakeFormalExpr,
 | 
			
		||||
    },
 | 
			
		||||
    hdl, hdl_module,
 | 
			
		||||
    int::{Bool, DynSize, KnownSize, SInt, SIntType, Size, UInt, UIntType},
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,7 +68,6 @@ fn get_assert_formal_target_path(test_name: &dyn std::fmt::Display) -> PathBuf {
 | 
			
		|||
        },
 | 
			
		||||
    );
 | 
			
		||||
    let mut dir = String::with_capacity(64);
 | 
			
		||||
    write!(dir, "{simple_hash:08x}-").unwrap();
 | 
			
		||||
    for ch in Path::new(file)
 | 
			
		||||
        .file_stem()
 | 
			
		||||
        .unwrap_or_default()
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +83,7 @@ fn get_assert_formal_target_path(test_name: &dyn std::fmt::Display) -> PathBuf {
 | 
			
		|||
            _ => '_',
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    write!(dir, "-{simple_hash:08x}").unwrap();
 | 
			
		||||
    let index = *DIRS
 | 
			
		||||
        .lock()
 | 
			
		||||
        .unwrap()
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +91,7 @@ fn get_assert_formal_target_path(test_name: &dyn std::fmt::Display) -> PathBuf {
 | 
			
		|||
        .entry_ref(&dir)
 | 
			
		||||
        .and_modify(|v| *v += 1)
 | 
			
		||||
        .or_insert(0);
 | 
			
		||||
    write!(dir, ".{index}").unwrap();
 | 
			
		||||
    write!(dir, "-{index}").unwrap();
 | 
			
		||||
    get_cargo_target_dir()
 | 
			
		||||
        .join("fayalite_assert_formal")
 | 
			
		||||
        .join(dir)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,6 @@ impl<T: Type> ReadyValid<T> {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: needs testing
 | 
			
		||||
#[hdl_module]
 | 
			
		||||
pub fn queue<T: Type>(
 | 
			
		||||
    ty: T,
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +133,7 @@ pub fn queue<T: Type>(
 | 
			
		|||
    #[hdl]
 | 
			
		||||
    if inp_fire {
 | 
			
		||||
        #[hdl]
 | 
			
		||||
        if inp_index.cmp_eq(capacity) {
 | 
			
		||||
        if inp_index.cmp_eq(capacity.get() - 1) {
 | 
			
		||||
            connect_any(inp_index, 0_hdl_u0);
 | 
			
		||||
        } else {
 | 
			
		||||
            connect_any(inp_index, inp_index + 1_hdl_u1);
 | 
			
		||||
| 
						 | 
				
			
			@ -144,7 +143,7 @@ pub fn queue<T: Type>(
 | 
			
		|||
    #[hdl]
 | 
			
		||||
    if out_fire {
 | 
			
		||||
        #[hdl]
 | 
			
		||||
        if out_index.cmp_eq(capacity) {
 | 
			
		||||
        if out_index.cmp_eq(capacity.get() - 1) {
 | 
			
		||||
            connect_any(out_index, 0_hdl_u0);
 | 
			
		||||
        } else {
 | 
			
		||||
            connect_any(out_index, out_index + 1_hdl_u1);
 | 
			
		||||
| 
						 | 
				
			
			@ -153,10 +152,12 @@ pub fn queue<T: Type>(
 | 
			
		|||
 | 
			
		||||
    #[hdl]
 | 
			
		||||
    if indexes_equal {
 | 
			
		||||
        connect(
 | 
			
		||||
            count,
 | 
			
		||||
            maybe_full.cast_to_static::<UInt<1>>() << (count_ty.width() - 1),
 | 
			
		||||
        );
 | 
			
		||||
        #[hdl]
 | 
			
		||||
        if maybe_full {
 | 
			
		||||
            connect_any(count, capacity);
 | 
			
		||||
        } else {
 | 
			
		||||
            connect_any(count, 0_hdl_u0);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if capacity.is_power_of_two() {
 | 
			
		||||
            debug_assert_eq!(count_ty.width(), index_ty.width() + 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -182,6 +183,7 @@ mod tests {
 | 
			
		|||
    use crate::{
 | 
			
		||||
        cli::FormalMode, firrtl::ExportOptions,
 | 
			
		||||
        module::transform::simplify_enums::SimplifyEnumsKind, testing::assert_formal,
 | 
			
		||||
        ty::StaticType,
 | 
			
		||||
    };
 | 
			
		||||
    use std::num::NonZero;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -190,8 +192,8 @@ mod tests {
 | 
			
		|||
        assert_formal(
 | 
			
		||||
            format_args!("test_queue_{capacity}_{inp_ready_is_comb}_{out_valid_is_comb}"),
 | 
			
		||||
            queue_test(capacity, inp_ready_is_comb, out_valid_is_comb),
 | 
			
		||||
            FormalMode::BMC,
 | 
			
		||||
            20,
 | 
			
		||||
            FormalMode::Prove,
 | 
			
		||||
            14,
 | 
			
		||||
            None,
 | 
			
		||||
            ExportOptions {
 | 
			
		||||
                simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts),
 | 
			
		||||
| 
						 | 
				
			
			@ -200,12 +202,6 @@ mod tests {
 | 
			
		|||
        );
 | 
			
		||||
        #[hdl_module]
 | 
			
		||||
        fn queue_test(capacity: NonZeroUsize, inp_ready_is_comb: bool, out_valid_is_comb: bool) {
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let inp_data: HdlOption<UInt<8>> = m.input();
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let out_ready: Bool = m.input();
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let start_check: Bool = m.input();
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let clk: Clock = m.input();
 | 
			
		||||
            #[hdl]
 | 
			
		||||
| 
						 | 
				
			
			@ -219,6 +215,24 @@ mod tests {
 | 
			
		|||
                },
 | 
			
		||||
            );
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let inp_data: HdlOption<UInt<8>> = wire();
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if any_seq(Bool) {
 | 
			
		||||
                connect(inp_data, HdlSome(any_seq(UInt::<8>::TYPE)));
 | 
			
		||||
            } else {
 | 
			
		||||
                connect(inp_data, HdlNone());
 | 
			
		||||
            }
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let out_ready: Bool = wire();
 | 
			
		||||
            connect(out_ready, any_seq(Bool));
 | 
			
		||||
            let index_ty: UInt<32> = UInt::TYPE;
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let index_to_check = wire();
 | 
			
		||||
            connect(index_to_check, any_const(index_ty));
 | 
			
		||||
            let index_max = !index_ty.zero();
 | 
			
		||||
            // we saturate at index_max, so only check indexes where we properly maintain position
 | 
			
		||||
            hdl_assume(clk, index_to_check.cmp_ne(index_max), "");
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let dut = instance(queue(
 | 
			
		||||
                UInt[ConstUsize::<8>],
 | 
			
		||||
                capacity,
 | 
			
		||||
| 
						 | 
				
			
			@ -228,63 +242,97 @@ mod tests {
 | 
			
		|||
            connect(dut.cd, cd);
 | 
			
		||||
            connect(dut.inp.data, inp_data);
 | 
			
		||||
            connect(dut.out.ready, out_ready);
 | 
			
		||||
            hdl_assume(
 | 
			
		||||
                clk,
 | 
			
		||||
                index_to_check.cmp_ne(!Expr::ty(index_to_check).zero()),
 | 
			
		||||
                "",
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let count = reg_builder().clock_domain(cd).reset(0u32);
 | 
			
		||||
            let expected_count = reg_builder().clock_domain(cd).reset(0u32);
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let next_count = wire();
 | 
			
		||||
            connect(next_count, count);
 | 
			
		||||
            connect(count, next_count);
 | 
			
		||||
            let next_expected_count = wire();
 | 
			
		||||
            connect(next_expected_count, expected_count);
 | 
			
		||||
            connect(expected_count, next_expected_count);
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if ReadyValid::fire(dut.inp) & !ReadyValid::fire(dut.out) {
 | 
			
		||||
                connect_any(next_count, count + 1u8);
 | 
			
		||||
                connect_any(next_expected_count, expected_count + 1u8);
 | 
			
		||||
            } else if !ReadyValid::fire(dut.inp) & ReadyValid::fire(dut.out) {
 | 
			
		||||
                connect_any(next_count, count - 1u8);
 | 
			
		||||
                connect_any(next_expected_count, expected_count - 1u8);
 | 
			
		||||
            }
 | 
			
		||||
            hdl_assert(cd.clk, count.cmp_eq(dut.count), "");
 | 
			
		||||
            hdl_assert(cd.clk, expected_count.cmp_eq(dut.count), "");
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let started_check = reg_builder().clock_domain(cd).reset(false);
 | 
			
		||||
            let prev_out_ready = reg_builder().clock_domain(cd).reset(!0_hdl_u3);
 | 
			
		||||
            connect_any(
 | 
			
		||||
                prev_out_ready,
 | 
			
		||||
                (prev_out_ready << 1) | out_ready.cast_to(UInt[1]),
 | 
			
		||||
            );
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let steps_till_output = reg_builder().clock_domain(cd).reset(0u32);
 | 
			
		||||
            let prev_inp_valid = reg_builder().clock_domain(cd).reset(!0_hdl_u3);
 | 
			
		||||
            connect_any(
 | 
			
		||||
                prev_inp_valid,
 | 
			
		||||
                (prev_inp_valid << 1) | HdlOption::is_some(inp_data).cast_to(UInt[1]),
 | 
			
		||||
            );
 | 
			
		||||
            hdl_assume(clk, (prev_out_ready & prev_inp_valid).cmp_ne(0u8), "");
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let expected_output = reg_builder().clock_domain(cd).reset(HdlNone());
 | 
			
		||||
            let inp_index = reg_builder().clock_domain(cd).reset(index_ty.zero());
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if start_check & !started_check {
 | 
			
		||||
            let stored_inp_data = reg_builder().clock_domain(cd).reset(0u8);
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if let HdlSome(data) = ReadyValid::fire_data(dut.inp) {
 | 
			
		||||
                #[hdl]
 | 
			
		||||
                if let HdlSome(inp) = ReadyValid::fire_data(dut.inp) {
 | 
			
		||||
                    connect(started_check, true);
 | 
			
		||||
                    connect_any(
 | 
			
		||||
                        steps_till_output,
 | 
			
		||||
                        count + (!ReadyValid::fire(dut.out)).cast_to(UInt[1]),
 | 
			
		||||
                    );
 | 
			
		||||
                    connect(expected_output, HdlSome(inp));
 | 
			
		||||
                }
 | 
			
		||||
            } else if started_check & steps_till_output.cmp_ne(0u32) & ReadyValid::fire(dut.out) {
 | 
			
		||||
                connect_any(steps_till_output, steps_till_output - 1u32);
 | 
			
		||||
            }
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let stored_output = reg_builder().clock_domain(cd).reset(HdlNone());
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if let HdlSome(out) = ReadyValid::fire_data(dut.out) {
 | 
			
		||||
                #[hdl]
 | 
			
		||||
                if (start_check & !started_check) | (started_check & steps_till_output.cmp_ne(0u32))
 | 
			
		||||
                {
 | 
			
		||||
                    connect(stored_output, HdlSome(out));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if started_check & steps_till_output.cmp_eq(0u32) {
 | 
			
		||||
                #[hdl]
 | 
			
		||||
                if let HdlSome(expected_output) = expected_output {
 | 
			
		||||
                if inp_index.cmp_lt(index_max) {
 | 
			
		||||
                    connect_any(inp_index, inp_index + 1u8);
 | 
			
		||||
                    #[hdl]
 | 
			
		||||
                    if let HdlSome(stored_output) = stored_output {
 | 
			
		||||
                        hdl_assert(cd.clk, stored_output.cmp_eq(expected_output), "");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        hdl_assert(cd.clk, false.to_expr(), "");
 | 
			
		||||
                    if inp_index.cmp_eq(index_to_check) {
 | 
			
		||||
                        connect(stored_inp_data, data);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    hdl_assert(cd.clk, false.to_expr(), "");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if inp_index.cmp_lt(index_to_check) {
 | 
			
		||||
                hdl_assert(clk, stored_inp_data.cmp_eq(0u8), "");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let out_index = reg_builder().clock_domain(cd).reset(index_ty.zero());
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            let stored_out_data = reg_builder().clock_domain(cd).reset(0u8);
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if let HdlSome(data) = ReadyValid::fire_data(dut.out) {
 | 
			
		||||
                #[hdl]
 | 
			
		||||
                if out_index.cmp_lt(index_max) {
 | 
			
		||||
                    connect_any(out_index, out_index + 1u8);
 | 
			
		||||
                    #[hdl]
 | 
			
		||||
                    if out_index.cmp_eq(index_to_check) {
 | 
			
		||||
                        connect(stored_out_data, data);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if out_index.cmp_lt(index_to_check) {
 | 
			
		||||
                hdl_assert(clk, stored_out_data.cmp_eq(0u8), "");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            hdl_assert(clk, inp_index.cmp_ge(out_index), "");
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if inp_index.cmp_lt(index_max) & out_index.cmp_lt(index_max) {
 | 
			
		||||
                hdl_assert(clk, expected_count.cmp_eq(inp_index - out_index), "");
 | 
			
		||||
            } else {
 | 
			
		||||
                hdl_assert(clk, expected_count.cmp_ge(inp_index - out_index), "");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[hdl]
 | 
			
		||||
            if inp_index.cmp_gt(index_to_check) & out_index.cmp_gt(index_to_check) {
 | 
			
		||||
                hdl_assert(clk, stored_inp_data.cmp_eq(stored_out_data), "");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -328,49 +376,41 @@ mod tests {
 | 
			
		|||
        test_queue(NonZero::new(2).unwrap(), true, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_3_false_false() {
 | 
			
		||||
        test_queue(NonZero::new(3).unwrap(), false, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_3_false_true() {
 | 
			
		||||
        test_queue(NonZero::new(3).unwrap(), false, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_3_true_false() {
 | 
			
		||||
        test_queue(NonZero::new(3).unwrap(), true, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_3_true_true() {
 | 
			
		||||
        test_queue(NonZero::new(3).unwrap(), true, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_4_false_false() {
 | 
			
		||||
        test_queue(NonZero::new(4).unwrap(), false, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_4_false_true() {
 | 
			
		||||
        test_queue(NonZero::new(4).unwrap(), false, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_4_true_false() {
 | 
			
		||||
        test_queue(NonZero::new(4).unwrap(), true, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(todo)]
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_4_true_true() {
 | 
			
		||||
        test_queue(NonZero::new(4).unwrap(), true, true);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3394,7 +3394,7 @@ circuit check_formal: %[[
 | 
			
		|||
  {
 | 
			
		||||
    "class": "firrtl.transforms.BlackBoxInlineAnno",
 | 
			
		||||
    "name": "fayalite_formal_reset.v",
 | 
			
		||||
    "text": "module __fayalite_formal_reset(output rst);\n    reg rst;\n    (* gclk *)\n    reg gclk;\n    initial rst = 1;\n    always @(posedge gclk)\n        rst <= 0;\nendmodule\n",
 | 
			
		||||
    "text": "module __fayalite_formal_reset(output rst);\n    assign rst = $initstate;\nendmodule\n",
 | 
			
		||||
    "target": "~check_formal|formal_reset"
 | 
			
		||||
  }
 | 
			
		||||
]]
 | 
			
		||||
| 
						 | 
				
			
			@ -3407,20 +3407,20 @@ circuit check_formal: %[[
 | 
			
		|||
        input pred1: UInt<1> @[module-XXXXXXXXXX.rs 6:1]
 | 
			
		||||
        input pred2: UInt<1> @[module-XXXXXXXXXX.rs 7:1]
 | 
			
		||||
        input pred3: UInt<1> @[module-XXXXXXXXXX.rs 8:1]
 | 
			
		||||
        inst formal_reset of formal_reset @[formal.rs 189:24]
 | 
			
		||||
        inst formal_reset of formal_reset @[formal.rs 185:24]
 | 
			
		||||
        assert(clk, pred1, and(en1, not(formal_reset.rst)), "en check 1") @[module-XXXXXXXXXX.rs 9:1]
 | 
			
		||||
        inst formal_reset_1 of formal_reset @[formal.rs 189:24]
 | 
			
		||||
        inst formal_reset_1 of formal_reset @[formal.rs 185:24]
 | 
			
		||||
        assume(clk, pred2, and(en2, not(formal_reset_1.rst)), "en check 2") @[module-XXXXXXXXXX.rs 10:1]
 | 
			
		||||
        inst formal_reset_2 of formal_reset @[formal.rs 189:24]
 | 
			
		||||
        inst formal_reset_2 of formal_reset @[formal.rs 185:24]
 | 
			
		||||
        cover(clk, pred3, and(en3, not(formal_reset_2.rst)), "en check 3") @[module-XXXXXXXXXX.rs 11:1]
 | 
			
		||||
        inst formal_reset_3 of formal_reset @[formal.rs 189:24]
 | 
			
		||||
        inst formal_reset_3 of formal_reset @[formal.rs 185:24]
 | 
			
		||||
        assert(clk, pred1, and(UInt<1>(0h1), not(formal_reset_3.rst)), "check 1") @[module-XXXXXXXXXX.rs 12:1]
 | 
			
		||||
        inst formal_reset_4 of formal_reset @[formal.rs 189:24]
 | 
			
		||||
        inst formal_reset_4 of formal_reset @[formal.rs 185:24]
 | 
			
		||||
        assume(clk, pred2, and(UInt<1>(0h1), not(formal_reset_4.rst)), "check 2") @[module-XXXXXXXXXX.rs 13:1]
 | 
			
		||||
        inst formal_reset_5 of formal_reset @[formal.rs 189:24]
 | 
			
		||||
        inst formal_reset_5 of formal_reset @[formal.rs 185:24]
 | 
			
		||||
        cover(clk, pred3, and(UInt<1>(0h1), not(formal_reset_5.rst)), "check 3") @[module-XXXXXXXXXX.rs 14:1]
 | 
			
		||||
    extmodule formal_reset: @[formal.rs 168:5]
 | 
			
		||||
        output rst: UInt<1> @[formal.rs 171:32]
 | 
			
		||||
    extmodule formal_reset: @[formal.rs 169:5]
 | 
			
		||||
        output rst: UInt<1> @[formal.rs 172:32]
 | 
			
		||||
        defname = __fayalite_formal_reset
 | 
			
		||||
"#,
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue