@@ -64,9 +64,37 @@ pub fn selector(a: Wirex, b: Wirex, c: Wirex) -> Circuit {
6464 Circuit :: new ( vec ! [ g] , vec ! [ gate_1, gate_2, gate_3, gate_4] )
6565}
6666
67+ pub fn multiplexer ( a : Wires , s : Wires , w : usize ) -> Circuit {
68+ let n = 2_usize . pow ( w. try_into ( ) . unwrap ( ) ) ;
69+ assert_eq ! ( a. len( ) , n) ;
70+ assert_eq ! ( s. len( ) , w) ;
71+
72+ if w == 1 {
73+ return selector ( a[ 1 ] . clone ( ) , a[ 0 ] . clone ( ) , s[ 0 ] . clone ( ) ) ;
74+ }
75+
76+ let mut circuit = Circuit :: empty ( ) ;
77+
78+ let a1 = a[ 0 ..( n / 2 ) ] . to_vec ( ) ;
79+ let a2 = a[ ( n / 2 ) ..n] . to_vec ( ) ;
80+ let su = s[ 0 ..w-1 ] . to_vec ( ) ;
81+ let sv = s[ w-1 ] . clone ( ) ;
82+
83+ let b1 = circuit. extend ( multiplexer ( a1, su. clone ( ) , w-1 ) ) [ 0 ] . clone ( ) ;
84+ let b2 = circuit. extend ( multiplexer ( a2, su. clone ( ) , w-1 ) ) [ 0 ] . clone ( ) ;
85+
86+ let b = circuit. extend ( selector ( b2, b1, sv) ) [ 0 ] . clone ( ) ;
87+
88+ circuit. add_wire ( b) ;
89+
90+ circuit
91+ }
92+
6793#[ cfg( test) ]
6894mod tests {
69- use crate :: { bag:: * , circuits:: basic:: { full_adder, full_subtracter, half_adder, half_subtracter, selector} } ;
95+ use rand:: { rng, Rng } ;
96+
97+ use crate :: { bag:: * , circuits:: basic:: { full_adder, full_subtracter, half_adder, half_subtracter, multiplexer, selector} } ;
7098
7199 #[ test]
72100 fn test_half_adder ( ) {
@@ -232,5 +260,36 @@ mod tests {
232260 assert_eq ! ( d_wire. borrow( ) . get_value( ) , d) ;
233261 }
234262 }
263+
264+ #[ test]
265+ fn test_multiplexer ( ) {
266+ let w = 5 ;
267+ let n = 2_usize . pow ( w as u32 ) ;
268+ let a: Wires = ( 0 ..n) . map ( |_| { Rc :: new ( RefCell :: new ( Wire :: new ( ) ) ) } ) . collect ( ) ;
269+ let s: Wires = ( 0 ..w) . map ( |_| { Rc :: new ( RefCell :: new ( Wire :: new ( ) ) ) } ) . collect ( ) ;
270+
271+ for wire in a. clone ( ) {
272+ wire. borrow_mut ( ) . set ( rng ( ) . random ( ) ) ;
273+ }
274+
275+ let mut u = 0 ;
276+ for wire in s. iter ( ) . rev ( ) {
277+ let x = rng ( ) . random ( ) ;
278+ u = u + u + if x { 1 } else { 0 } ;
279+ wire. borrow_mut ( ) . set ( x) ;
280+ }
281+
282+ let circuit = multiplexer ( a. clone ( ) , s. clone ( ) , w) ;
283+ circuit. print_gate_type_counts ( ) ;
284+
285+ for mut gate in circuit. 1 {
286+ gate. evaluate ( ) ;
287+ }
288+
289+ let result = circuit. 0 [ 0 ] . clone ( ) . borrow ( ) . get_value ( ) ;
290+ let expected = a[ u] . clone ( ) . borrow ( ) . get_value ( ) ;
291+
292+ assert_eq ! ( result, expected) ;
293+ }
235294}
236295
0 commit comments