This commit is contained in:
		
							parent
							
								
									cb5855589f
								
							
						
					
					
						commit
						aaa2cb193e
					
				
					 2 changed files with 342 additions and 17 deletions
				
			
		
							
								
								
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -279,7 +279,7 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" | ||||||
| [[package]] | [[package]] | ||||||
| name = "fayalite" | name = "fayalite" | ||||||
| version = "0.2.0" | version = "0.2.0" | ||||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3939ce2360138c75c53972368069c8f882111571" | source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3d0f95cfe5a910f79177babf8fe12483f83e96f9" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "bitvec", |  "bitvec", | ||||||
|  "blake3", |  "blake3", | ||||||
|  | @ -300,7 +300,7 @@ dependencies = [ | ||||||
| [[package]] | [[package]] | ||||||
| name = "fayalite-proc-macros" | name = "fayalite-proc-macros" | ||||||
| version = "0.2.0" | version = "0.2.0" | ||||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3939ce2360138c75c53972368069c8f882111571" | source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3d0f95cfe5a910f79177babf8fe12483f83e96f9" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "fayalite-proc-macros-impl", |  "fayalite-proc-macros-impl", | ||||||
| ] | ] | ||||||
|  | @ -308,7 +308,7 @@ dependencies = [ | ||||||
| [[package]] | [[package]] | ||||||
| name = "fayalite-proc-macros-impl" | name = "fayalite-proc-macros-impl" | ||||||
| version = "0.2.0" | version = "0.2.0" | ||||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3939ce2360138c75c53972368069c8f882111571" | source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3d0f95cfe5a910f79177babf8fe12483f83e96f9" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "base16ct", |  "base16ct", | ||||||
|  "num-bigint", |  "num-bigint", | ||||||
|  | @ -323,7 +323,7 @@ dependencies = [ | ||||||
| [[package]] | [[package]] | ||||||
| name = "fayalite-visit-gen" | name = "fayalite-visit-gen" | ||||||
| version = "0.2.0" | version = "0.2.0" | ||||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3939ce2360138c75c53972368069c8f882111571" | source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#3d0f95cfe5a910f79177babf8fe12483f83e96f9" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "indexmap", |  "indexmap", | ||||||
|  "prettyplease", |  "prettyplease", | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| // SPDX-License-Identifier: LGPL-3.0-or-later
 | // SPDX-License-Identifier: LGPL-3.0-or-later
 | ||||||
| // See Notices.txt for copyright information
 | // See Notices.txt for copyright information
 | ||||||
| use crate::util::tree_reduce::tree_reduce; | use crate::util::tree_reduce::tree_reduce; | ||||||
| use fayalite::{prelude::*, util::ready_valid::ReadyValid}; | use fayalite::{module::wire_with_loc, prelude::*, util::ready_valid::ReadyValid}; | ||||||
| use std::{num::NonZeroUsize, ops::Range}; | use std::{num::NonZeroUsize, ops::Range}; | ||||||
| 
 | 
 | ||||||
| #[hdl_module] | #[hdl_module] | ||||||
|  | @ -17,7 +17,7 @@ pub fn unit_free_regs_tracker( | ||||||
|         m.input(Array[ReadyValid[UInt[reg_num_width]]][free_at_once.get()]); |         m.input(Array[ReadyValid[UInt[reg_num_width]]][free_at_once.get()]); | ||||||
|     #[hdl] |     #[hdl] | ||||||
|     let alloc_out: Array<ReadyValid<UInt>> = |     let alloc_out: Array<ReadyValid<UInt>> = | ||||||
|         m.input(Array[ReadyValid[UInt[reg_num_width]]][alloc_at_once.get()]); |         m.output(Array[ReadyValid[UInt[reg_num_width]]][alloc_at_once.get()]); | ||||||
|     assert!( |     assert!( | ||||||
|         reg_num_width <= isize::MAX.ilog2() as usize, |         reg_num_width <= isize::MAX.ilog2() as usize, | ||||||
|         "too many registers" |         "too many registers" | ||||||
|  | @ -47,7 +47,7 @@ pub fn unit_free_regs_tracker( | ||||||
|     }) = tree_reduce( |     }) = tree_reduce( | ||||||
|         (0..reg_count).map(|index| Summary { |         (0..reg_count).map(|index| Summary { | ||||||
|             range: index..index + 1, |             range: index..index + 1, | ||||||
|             count: allocated_reg[index] |             count: (!allocated_reg[index]) | ||||||
|                 .cast_to_static::<UInt<1>>() |                 .cast_to_static::<UInt<1>>() | ||||||
|                 .cast_to(count_ty), |                 .cast_to(count_ty), | ||||||
|             count_overflowed: false.to_expr(), |             count_overflowed: false.to_expr(), | ||||||
|  | @ -55,25 +55,35 @@ pub fn unit_free_regs_tracker( | ||||||
|         }), |         }), | ||||||
|         |l, r| { |         |l, r| { | ||||||
|             let range = l.range.start..r.range.end; |             let range = l.range.start..r.range.end; | ||||||
|             #[hdl] |             let reduced_count = wire_with_loc( | ||||||
|             let reduced_count = wire(count_ty); |                 &format!("reduced_count_{}_{}", range.start, range.end), | ||||||
|  |                 SourceLocation::caller(), | ||||||
|  |                 count_ty, | ||||||
|  |             ); | ||||||
|             connect_any(reduced_count, l.count + r.count); |             connect_any(reduced_count, l.count + r.count); | ||||||
|             #[hdl] |             let reduced_count_overflowed = wire_with_loc( | ||||||
|             let reduced_count_overflowed = wire(); |                 &format!("reduced_count_overflowed_{}_{}", range.start, range.end), | ||||||
|  |                 SourceLocation::caller(), | ||||||
|  |                 Bool, | ||||||
|  |             ); | ||||||
|             connect( |             connect( | ||||||
|                 reduced_count_overflowed, |                 reduced_count_overflowed, | ||||||
|                 (l.count + r.count).cmp_ne(reduced_count) | l.count_overflowed | r.count_overflowed, |                 (l.count + r.count).cmp_ne(reduced_count) | l.count_overflowed | r.count_overflowed, | ||||||
|             ); |             ); | ||||||
|             #[hdl] |             let reduced_alloc_nums = wire_with_loc( | ||||||
|             let reduced_alloc_nums = wire( |                 &format!("reduced_alloc_nums_{}_{}", range.start, range.end), | ||||||
|  |                 SourceLocation::caller(), | ||||||
|                 Array[UInt[Expr::ty(l.alloc_nums).element().width() + 1]][alloc_at_once.get()], |                 Array[UInt[Expr::ty(l.alloc_nums).element().width() + 1]][alloc_at_once.get()], | ||||||
|             ); |             ); | ||||||
|             for alloc_index in 0..alloc_at_once.get() { |             for alloc_index in 0..alloc_at_once.get() { | ||||||
|                 #[hdl] |                 #[hdl] | ||||||
|                 if l.count_overflowed | l.count.cmp_ge(alloc_at_once) { |                 if l.count_overflowed | l.count.cmp_gt(alloc_index) { | ||||||
|                     connect(reduced_alloc_nums[alloc_index], l.alloc_nums[alloc_index]); |                     connect(reduced_alloc_nums[alloc_index], l.alloc_nums[alloc_index]); | ||||||
|                 } else { |                 } else { | ||||||
|                     connect(reduced_alloc_nums[alloc_index], r.alloc_nums[alloc_index]); |                     connect( | ||||||
|  |                         reduced_alloc_nums[alloc_index], | ||||||
|  |                         r.alloc_nums[alloc_index.to_expr() - l.count] + l.range.len(), | ||||||
|  |                     ); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             Summary { |             Summary { | ||||||
|  | @ -93,7 +103,7 @@ pub fn unit_free_regs_tracker( | ||||||
|             connect(allocated_reg[alloc_num], true); |             connect(allocated_reg[alloc_num], true); | ||||||
|         } |         } | ||||||
|         #[hdl] |         #[hdl] | ||||||
|         if count_overflowed | count.cmp_ge(alloc_index) { |         if count_overflowed | count.cmp_gt(alloc_index) { | ||||||
|             connect( |             connect( | ||||||
|                 alloc_out[alloc_index].data, |                 alloc_out[alloc_index].data, | ||||||
|                 HdlSome(alloc_nums[alloc_index]), |                 HdlSome(alloc_nums[alloc_index]), | ||||||
|  | @ -107,4 +117,319 @@ pub fn unit_free_regs_tracker( | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TODO: add formal proof of unit_free_regs_tracker
 | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use super::*; | ||||||
|  |     use fayalite::{ | ||||||
|  |         cli::FormalMode, firrtl::ExportOptions, | ||||||
|  |         module::transform::simplify_enums::SimplifyEnumsKind, testing::assert_formal, | ||||||
|  |     }; | ||||||
|  |     use std::num::NonZero; | ||||||
|  | 
 | ||||||
|  |     fn test_unit_free_regs_tracker( | ||||||
|  |         free_at_once: NonZeroUsize, | ||||||
|  |         alloc_at_once: NonZeroUsize, | ||||||
|  |         reg_num_width: usize, | ||||||
|  |     ) { | ||||||
|  |         // enough time to completely allocate all regs, free whatever we please,
 | ||||||
|  |         // allocate one, then completely free the rest
 | ||||||
|  |         let history_len = (3 + 2 * (1 << reg_num_width)).max(5); | ||||||
|  |         assert_formal( | ||||||
|  |             format_args!( | ||||||
|  |                 "test_unit_free_regs_tracker_{free_at_once}_{alloc_at_once}_{reg_num_width}" | ||||||
|  |             ), | ||||||
|  |             unit_free_regs_tracker_test(free_at_once, alloc_at_once, reg_num_width, history_len), | ||||||
|  |             FormalMode::Prove, | ||||||
|  |             history_len as u64 + 2, | ||||||
|  |             None, | ||||||
|  |             ExportOptions { | ||||||
|  |                 simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts), | ||||||
|  |                 ..ExportOptions::default() | ||||||
|  |             }, | ||||||
|  |         ); | ||||||
|  |         #[hdl_module] | ||||||
|  |         fn unit_free_regs_tracker_test( | ||||||
|  |             free_at_once: NonZeroUsize, | ||||||
|  |             alloc_at_once: NonZeroUsize, | ||||||
|  |             reg_num_width: usize, | ||||||
|  |             history_len: usize, | ||||||
|  |         ) { | ||||||
|  |             #[hdl] | ||||||
|  |             let clk: Clock = m.input(); | ||||||
|  |             #[hdl] | ||||||
|  |             let cd = wire(); | ||||||
|  |             connect( | ||||||
|  |                 cd, | ||||||
|  |                 #[hdl] | ||||||
|  |                 ClockDomain { | ||||||
|  |                     clk, | ||||||
|  |                     rst: formal_reset().to_reset(), | ||||||
|  |                 }, | ||||||
|  |             ); | ||||||
|  |             #[hdl] | ||||||
|  |             let dut = instance(unit_free_regs_tracker( | ||||||
|  |                 free_at_once, | ||||||
|  |                 alloc_at_once, | ||||||
|  |                 reg_num_width, | ||||||
|  |             )); | ||||||
|  |             connect(dut.cd, cd); | ||||||
|  |             let reg_count = 1 << reg_num_width; | ||||||
|  |             let reg_num_ty = UInt[reg_num_width]; | ||||||
|  |             #[hdl] | ||||||
|  |             let free_reg = reg_builder().clock_domain(cd).reset(vec![true; reg_count]); | ||||||
|  |             for free_index in 0..free_at_once.get() { | ||||||
|  |                 #[hdl] | ||||||
|  |                 if any_seq(Bool) { | ||||||
|  |                     let data = any_seq(reg_num_ty); | ||||||
|  |                     connect(dut.free_in[free_index].data, HdlSome(data)); | ||||||
|  |                 } else { | ||||||
|  |                     connect( | ||||||
|  |                         dut.free_in[free_index].data, | ||||||
|  |                         HdlOption[reg_num_ty].HdlNone(), | ||||||
|  |                     ); | ||||||
|  |                 } | ||||||
|  |                 #[hdl] | ||||||
|  |                 if let HdlSome(free) = ReadyValid::firing_data(dut.free_in[free_index]) { | ||||||
|  |                     hdl_assume(clk, !free_reg[free], ""); | ||||||
|  |                     connect(free_reg[free], true); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             #[hdl] | ||||||
|  |             let free_before_alloc_array = wire(Array[Expr::ty(free_reg)][alloc_at_once.get() + 1]); | ||||||
|  |             connect(free_before_alloc_array[0], free_reg); | ||||||
|  |             #[hdl] | ||||||
|  |             let expected_alloc = wire(Array[HdlOption[reg_num_ty]][alloc_at_once.get()]); | ||||||
|  |             for alloc_index in 0..alloc_at_once.get() { | ||||||
|  |                 let free_before_alloc = free_before_alloc_array[alloc_index]; | ||||||
|  |                 let free_after_alloc = free_before_alloc_array[alloc_index + 1]; | ||||||
|  |                 connect(free_after_alloc, free_before_alloc); | ||||||
|  |                 connect(dut.alloc_out[alloc_index].ready, any_seq(Bool)); | ||||||
|  |                 connect(expected_alloc[alloc_index], HdlOption[reg_num_ty].HdlNone()); | ||||||
|  |                 for reg_index in (0..reg_count).rev() { | ||||||
|  |                     #[hdl] | ||||||
|  |                     if free_before_alloc[reg_index] { | ||||||
|  |                         connect( | ||||||
|  |                             expected_alloc[alloc_index], | ||||||
|  |                             HdlSome(reg_index.cast_to(reg_num_ty)), | ||||||
|  |                         ); | ||||||
|  |                     } | ||||||
|  |                     #[hdl] | ||||||
|  |                     if let HdlSome(alloc) = expected_alloc[alloc_index] { | ||||||
|  |                         #[hdl] | ||||||
|  |                         if alloc.cmp_eq(reg_index) { | ||||||
|  |                             connect(free_after_alloc[reg_index], false); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 #[hdl] | ||||||
|  |                 if let HdlSome(expected_alloc) = expected_alloc[alloc_index] { | ||||||
|  |                     #[hdl] | ||||||
|  |                     if let HdlSome(alloc) = dut.alloc_out[alloc_index].data { | ||||||
|  |                         hdl_assert(clk, expected_alloc.cmp_eq(alloc), ""); | ||||||
|  |                     } else { | ||||||
|  |                         hdl_assert(clk, false.to_expr(), ""); | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     hdl_assert(clk, HdlOption::is_none(dut.alloc_out[alloc_index].data), ""); | ||||||
|  |                 } | ||||||
|  |                 #[hdl] | ||||||
|  |                 if let HdlSome(alloc) = ReadyValid::firing_data(dut.alloc_out[alloc_index]) { | ||||||
|  |                     connect(free_reg[alloc], false); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             #[hdl] | ||||||
|  |             let free_fired_history_reg = reg_builder() | ||||||
|  |                 .clock_domain(cd) | ||||||
|  |                 .reset(repeat(!UInt[history_len].zero(), free_at_once.get())); | ||||||
|  |             for free_index in 0..free_at_once.get() { | ||||||
|  |                 connect_any( | ||||||
|  |                     free_fired_history_reg[free_index], | ||||||
|  |                     (free_fired_history_reg[free_index] << 1) | ||||||
|  |                         | ReadyValid::firing(dut.free_in[free_index]).cast_to(UInt[1]), | ||||||
|  |                 ); | ||||||
|  |                 hdl_assume(clk, free_fired_history_reg[free_index].any_one_bits(), ""); | ||||||
|  |             } | ||||||
|  |             #[hdl] | ||||||
|  |             let alloc_fired_history_reg = reg_builder() | ||||||
|  |                 .clock_domain(cd) | ||||||
|  |                 .reset(repeat(!UInt[history_len].zero(), alloc_at_once.get())); | ||||||
|  |             for alloc_index in 0..alloc_at_once.get() { | ||||||
|  |                 connect_any( | ||||||
|  |                     alloc_fired_history_reg[alloc_index], | ||||||
|  |                     (alloc_fired_history_reg[alloc_index] << 1) | ||||||
|  |                         | ReadyValid::firing(dut.alloc_out[alloc_index]).cast_to(UInt[1]), | ||||||
|  |                 ); | ||||||
|  |                 if alloc_index < reg_count { | ||||||
|  |                     hdl_assume(clk, alloc_fired_history_reg[alloc_index].any_one_bits(), ""); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             #[hdl] | ||||||
|  |             let any_free_history_reg = reg_builder() | ||||||
|  |                 .clock_domain(cd) | ||||||
|  |                 .reset(UInt[history_len].zero()); | ||||||
|  |             #[hdl] | ||||||
|  |             let any_allocated_history_reg = reg_builder() | ||||||
|  |                 .clock_domain(cd) | ||||||
|  |                 .reset(UInt[history_len].zero()); | ||||||
|  |             #[hdl] | ||||||
|  |             let any_free = wire(); | ||||||
|  |             connect(any_free, false); | ||||||
|  |             #[hdl] | ||||||
|  |             let any_allocated = wire(); | ||||||
|  |             connect(any_allocated, false); | ||||||
|  |             for reg_index in 0..reg_count { | ||||||
|  |                 #[hdl] | ||||||
|  |                 if free_reg[reg_index] { | ||||||
|  |                     connect(any_free, true); | ||||||
|  |                 } else { | ||||||
|  |                     connect(any_allocated, true); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             connect_any( | ||||||
|  |                 any_free_history_reg, | ||||||
|  |                 (any_free_history_reg << 1) | any_free.cast_to(UInt[1]), | ||||||
|  |             ); | ||||||
|  |             connect_any( | ||||||
|  |                 any_allocated_history_reg, | ||||||
|  |                 (any_allocated_history_reg << 1) | any_allocated.cast_to(UInt[1]), | ||||||
|  |             ); | ||||||
|  |             hdl_assume(clk, any_free_history_reg.any_zero_bits(), ""); | ||||||
|  |             hdl_assume(clk, any_allocated_history_reg.any_zero_bits(), ""); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_1_0() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(1).unwrap(), 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_1_1() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(1).unwrap(), 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_1_2() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(1).unwrap(), 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_1_3() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(1).unwrap(), 3); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_1_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(1).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_2_0() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(2).unwrap(), 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_2_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(2).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_3_0() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(3).unwrap(), 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_3_1() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(3).unwrap(), 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_3_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(3).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_4_0() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(4).unwrap(), 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_4_1() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(4).unwrap(), 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_4_2() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(4).unwrap(), 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_1_4_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(1).unwrap(), NonZero::new(4).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_2_1_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(2).unwrap(), NonZero::new(1).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_2_2_0() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(2).unwrap(), NonZero::new(2).unwrap(), 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_2_2_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(2).unwrap(), NonZero::new(2).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_3_1_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(3).unwrap(), NonZero::new(1).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_3_3_0() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(3).unwrap(), NonZero::new(3).unwrap(), 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_3_3_1() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(3).unwrap(), NonZero::new(3).unwrap(), 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_3_3_2() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(3).unwrap(), NonZero::new(3).unwrap(), 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_3_3_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(3).unwrap(), NonZero::new(3).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_4_1_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(4).unwrap(), NonZero::new(1).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_4_4_0() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(4).unwrap(), NonZero::new(4).unwrap(), 0); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_4_4_1() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(4).unwrap(), NonZero::new(4).unwrap(), 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_4_4_2() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(4).unwrap(), NonZero::new(4).unwrap(), 2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_unit_free_regs_tracker_4_4_4() { | ||||||
|  |         test_unit_free_regs_tracker(NonZero::new(4).unwrap(), NonZero::new(4).unwrap(), 4); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue