def test_replace_only_dst_wire(self): a, b, c, d = pyrtl.input_list('a/1 b/1 c/1 d/1') w1 = a & b w1.name = 'w1' w2 = c | d w2.name = 'w2' w3 = w1 ^ w2 w3.name = 'w3' o = pyrtl.Output(1, 'o') o <<= w3 w4 = pyrtl.WireVector(1, 'w4') src_nets, dst_nets = pyrtl.working_block().net_connections() w1_src_net = src_nets[w1] w1_dst_net = dst_nets[w1][0] self.assertEqual(w1_src_net.args, (a, b)) self.assertEqual(w1_src_net.dests, (w1, )) self.assertEqual(w1_dst_net.args, (w1, w2)) self.assertEqual(w1_dst_net.dests, (w3, )) self.assertNotIn(w4, src_nets) pyrtl.transform.replace_wire_fast(w1, w1, w4, src_nets, dst_nets) self.assertNotIn(w1, dst_nets) # The maps have been updated... self.assertEqual(src_nets[w1], w1_src_net) w4_dst_net = dst_nets[w4][ 0] # ...but the net can't be, so new versions were created self.assertEqual(w4_dst_net.args, (w4, w2)) self.assertEqual(w4_dst_net.dests, w1_dst_net.dests)
def test_replace_input(self): def f(wire): if wire.name == 'a': w = pyrtl.clone_wire(wire, 'w2') else: w = pyrtl.clone_wire(wire, 'w3') return wire, w a, b = pyrtl.input_list('a/1 b/1') w1 = a & b o = pyrtl.Output(1, 'o') o <<= w1 src_nets, dst_nets = pyrtl.working_block().net_connections() self.assertEqual(src_nets[w1], pyrtl.LogicNet('&', None, (a, b), (w1, ))) self.assertIn(a, dst_nets) self.assertIn(b, dst_nets) transform.wire_transform(f, select_types=pyrtl.Input, exclude_types=tuple()) w2 = pyrtl.working_block().get_wirevector_by_name('w2') w3 = pyrtl.working_block().get_wirevector_by_name('w3') src_nets, dst_nets = pyrtl.working_block().net_connections() self.assertEqual(src_nets[w1], pyrtl.LogicNet('&', None, (w2, w3), (w1, ))) self.assertNotIn(a, dst_nets) self.assertNotIn(b, dst_nets)
def test_two_way_fanout_large_design(self): i, j = pyrtl.input_list('i/1 j/2') o, p, q, r = pyrtl.output_list('o p q r') o <<= ~i p <<= i * j q <<= i & 0 r <<= i - 3 self.assertEqual(pyrtl.fanout(i), 4) pyrtl.two_way_fanout() self.check_all_leq_two()
def test_single_output(self): i, j = pyrtl.input_list('i/4 j/4') o = pyrtl.Output(8, 'o') o <<= i * j self.assertEqual(len(pyrtl.working_block().logic), 2) # Includes intermediary 'w' wire self.assertEqual(len(pyrtl.working_block().wirevector_set), 4) pyrtl.direct_connect_outputs() self.assertEqual(len(pyrtl.working_block().logic), 1) self.assertEqual(pyrtl.working_block().wirevector_set, {i, j, o})
def test_several_outputs(self): i, j = pyrtl.input_list('i/2 j/2') o, p, q = pyrtl.output_list('o p q') o <<= i * j w = i + 2 p <<= w q <<= ~w self.assertEqual(len(pyrtl.working_block().logic), 9) self.assertEqual(len(pyrtl.working_block().logic_subset(op='w')), 3) pyrtl.direct_connect_outputs() self.assertEqual(len(pyrtl.working_block().logic), 6) self.assertEqual(len(pyrtl.working_block().logic_subset(op='w')), 0)
def test_replace_output(self): def f(wire): w = pyrtl.clone_wire(wire, 'w2') return w, wire a, b = pyrtl.input_list('a/1 b/1') w1 = a & b o = pyrtl.Output(1, 'o') o <<= w1 src_nets, dst_nets = pyrtl.working_block().net_connections() self.assertEqual(dst_nets[w1], [pyrtl.LogicNet('w', None, (w1, ), (o, ))]) self.assertIn(o, src_nets) transform.wire_transform(f, select_types=pyrtl.Output, exclude_types=tuple()) w2 = pyrtl.working_block().get_wirevector_by_name('w2') src_nets, dst_nets = pyrtl.working_block().net_connections() self.assertEqual(dst_nets[w1], [pyrtl.LogicNet('w', None, (w1, ), (w2, ))]) self.assertNotIn(o, src_nets)
def test_all_paths(self): a, b, c = pyrtl.input_list('a/2 b/4 c/1') o, p = pyrtl.output_list('o/4 p/2') o <<= a + (b ^ (b + 1)) p <<= c * 2 - a paths = pyrtl.paths() # We have entries for every input, output pair for start in (a, b, c): self.assertEqual(len(paths[start]), 2) self.assertTrue([w.name for w in paths[start].keys()], [o.name, p.name]) paths_a_to_o = paths[a][o] self.assertEqual(len(paths_a_to_o), 1) path_a_to_o = paths_a_to_o[0] self.assertEqual(path_a_to_o[0].op, 'c') self.assertEqual(path_a_to_o[1].op, '+') self.assertEqual(path_a_to_o[2].op, 's') paths_a_to_p = paths[a][p] self.assertEqual(len(paths_a_to_p), 1) path_a_to_p = paths_a_to_p[0] self.assertEqual(path_a_to_p[0].op, 'c') self.assertEqual(path_a_to_p[1].op, '-') self.assertEqual(path_a_to_p[2].op, 's') paths_b_to_o = paths[b][o] self.assertEqual(len(paths_b_to_o), 2) paths_b_to_p = paths[b][p] self.assertEqual(len(paths_b_to_p), 0) paths_c_to_o = paths[c][o] self.assertEqual(len(paths_c_to_o), 0) paths_c_to_p = paths[c][p] self.assertEqual(len(paths_c_to_p), 1)
def test_several_outputs_simulates_correctly(self): i, j = pyrtl.input_list('i/2 j/2') o, p, q = pyrtl.output_list('o p q') o <<= i * j w = i + 2 p <<= w q <<= ~w inputs = [(0, 1), (1, 0), (2, 3), (3, 0), (1, 3)] trace_pre = pyrtl.SimulationTrace() sim = pyrtl.Simulation(tracer=trace_pre) for x, y in inputs: inp_map = {'i': x, 'j': y} sim.step(inp_map) pyrtl.direct_connect_outputs() trace_post = pyrtl.SimulationTrace() sim = pyrtl.Simulation(tracer=trace_post) for x, y in inputs: inp_map = {'i': x, 'j': y} sim.step(inp_map) self.assertEqual(trace_pre.trace, trace_post.trace)
def setUp(self): pyrtl.reset_working_block() a, b, c = pyrtl.input_list('a/8 b/8 c/1') o = pyrtl.Output() o <<= a + b - c
def setUp(self): pyrtl.reset_working_block() a, b = pyrtl.input_list('a/4 b/4') o = pyrtl.Output(5, 'o') o <<= a + b