def test_two_way_concat(self): i = pyrtl.Const(0b1100) j = pyrtl.Const(0b011, bitwidth=3) k = pyrtl.Const(0b100110) o = pyrtl.Output(13, 'o') o <<= pyrtl.concat(i, j, k) block = pyrtl.working_block() concat_nets = list(block.logic_subset(op='c')) self.assertEqual(len(concat_nets), 1) self.assertEqual(concat_nets[0].args, (i, j, k)) pyrtl.two_way_concat() concat_nets = list(block.logic_subset(op='c')) self.assertEqual(len(concat_nets), 2) upper_concat = next(n for n in concat_nets if i is n.args[0]) lower_concat = next(n for n in concat_nets if k is n.args[1]) self.assertNotEqual(upper_concat, lower_concat) self.assertEqual(upper_concat.args, (i, j)) self.assertEqual(lower_concat.args, (upper_concat.dests[0], k)) sim = pyrtl.Simulation() sim.step({}) self.assertEqual(sim.inspect('o'), 0b1100011100110)
def test_area_est_unchanged(self): a = pyrtl.Const(2, 8) b = pyrtl.Const(85, 8) zero = pyrtl.Const(0, 1) reg = pyrtl.Register(8) mem = pyrtl.MemBlock(8, 8) out = pyrtl.Output(8) nota, aLSB, athenb, aORb, aANDb, aNANDb, \ aXORb, aequalsb, altb, agtb, aselectb, \ aplusb, bminusa, atimesb, memread = [pyrtl.Output() for i in range(15)] out <<= zero nota <<= ~a aLSB <<= a[0] athenb <<= pyrtl.concat(a, b) aORb <<= a | b aANDb <<= a & b aNANDb <<= a.nand(b) aXORb <<= a ^ b aequalsb <<= a==b altb <<= a < b agtb <<= a > b aselectb <<= pyrtl.select(zero, a, b) reg.next <<= a aplusb <<= a + b bminusa <<= a - b atimesb <<= a*b memread <<= mem[0] mem[1] <<= a self.assertEquals(estimate.area_estimation(), (0.00734386752, 0.01879779717361501))
def test_over_max_write_ports(self): lim_memory = pyrtl.MemBlock(bitwidth=self.bitwidth, addrwidth=self.addrwidth, name='lim_memory', max_write_ports=4) for i in range(lim_memory.max_write_ports): lim_memory[self.mem_write_address] <<= pyrtl.Const(6) with self.assertRaises(pyrtl.PyrtlError): lim_memory[self.mem_write_address] <<= pyrtl.Const(6)
def test_time_est_unchanged(self): a = pyrtl.Const(2, 8) b = pyrtl.Const(85, 8) zero = pyrtl.Const(0, 1) reg = pyrtl.Register(8) mem = pyrtl.MemBlock(8, 8) out = pyrtl.Output(8) nota, aLSB, athenb, aORb, aANDb, aNANDb, \ aXORb, aequalsb, altb, agtb, aselectb, \ aplusb, bminusa, atimesb, memread = [pyrtl.Output() for i in range(15)] out <<= zero nota <<= ~a aLSB <<= a[0] athenb <<= pyrtl.concat(a, b) aORb <<= a | b aANDb <<= a & b aNANDb <<= a.nand(b) aXORb <<= a ^ b aequalsb <<= a == b altb <<= a < b agtb <<= a > b aselectb <<= pyrtl.select(zero, a, b) reg.next <<= a aplusb <<= a + b bminusa <<= a - b atimesb <<= a * b memread <<= mem[0] mem[1] <<= a timing = estimate.TimingAnalysis() self.assertEqual(timing.max_freq(), 610.2770657878676) self.assertEquals(timing.max_length(), 1255.6000000000001)
def test_dup_consts2(self): sel = pyrtl.WireVector(3) c1 = pyrtl.Const(4) c2 = pyrtl.Const(4) res = muxes.sparse_mux(sel, {6: c1, 2: c2}) self.assertIsInstance(res, pyrtl.Const) self.assertEqual(res.val, 4)
def nrml(din, offset=24): zero = pyrtl.Const(0, 1) one = pyrtl.Const(1, 1) temp = pyrtl.Register(32, name='temp') temp.next <<= barrel_shifter(din, zero, zero, offset) dout = pyrtl.Register(8, name='dout') dout.next <<= temp[:8] return dout
def test_equivalent_const(self): a = pyrtl.Const(1) b = pyrtl.Const(1) c = pyrtl.Const(1, 2) d = pyrtl.Const(3) self.assertTrue(muxes._is_equivelent(a, a)) self.assertTrue(muxes._is_equivelent(a, b)) self.assertFalse(muxes._is_equivelent(a, c)) self.assertFalse(muxes._is_equivelent(a, d))
def test_const_values_2(self): in_w = pyrtl.Input(5) const = pyrtl.Const(23, 5) const_2 = pyrtl.Const(23, 5) wire_1 = in_w + const wire_2 = in_w + const_2 pyrtl.common_subexp_elimination() self.num_net_of_type('+', 1) pyrtl.working_block().sanity_check()
def test_const_different_bitwidth_1(self): in_w = pyrtl.Input(5) const = pyrtl.Const(23, 5) const_2 = pyrtl.Const(23, 6) wire_1 = in_w + const wire_2 = in_w + const_2 pyrtl.common_subexp_elimination() self.num_net_of_type('+', 2) pyrtl.working_block().sanity_check()
class Array: # Returning a function which returns a WireVector thread1 = (8, t1) # Returning a function with returns a Const with explicit size thread2 = (8, lambda: pyrtl.Const(0b01100110, 8)) # Returning a WireVector thread3 = (8, t3()) # Returning a Const without an explicit size thread4 = (8, pyrtl.Const(0b00000011)) # Returning a literal thread5 = (8, 0b01000011)
def test_const_integers(self): c = pyrtl.Const(1) self.assertTrue(c.val == 1) self.assertTrue(c.bitwidth == 1) c = pyrtl.Const(5) self.assertTrue(c.val == 5) self.assertTrue(c.bitwidth == 3) c = pyrtl.Const(1, bitwidth=5) self.assertTrue(c.val == 1) self.assertTrue(c.bitwidth == 5)
def test_const_neg_integers(self): c = pyrtl.Const(-1, bitwidth=5) self.assertTrue(c.val == 0b11111) self.assertTrue(c.bitwidth == 5) c = pyrtl.Const(-2, bitwidth=3) self.assertTrue(c.val == 0b110) self.assertTrue(c.bitwidth == 3) c = pyrtl.Const(-5, bitwidth=4) self.assertTrue(c.val == 0b1011) self.assertTrue(c.bitwidth == 4)
def __init__(self, depth_width=2, data_width=32): aw = depth_width dw = data_width self.wr_data_i = pyrtl.Input(dw, 'wr_data_i') self.wr_en_i = pyrtl.Input(1, 'wr_en_i') self.rd_data_o = pyrtl.Output(dw, 'rd_data_o') self.rd_en_i = pyrtl.Input(1, 'rd_en_i') self.full_o = pyrtl.Output(1, 'full_o') self.empty_o = pyrtl.Output(1, 'empty_o') self.one_left = pyrtl.Output(1, 'one_left') self.reset = pyrtl.Input(1, 'reset') self.write_pointer = pyrtl.Register(aw + 1, 'write_pointer') self.read_pointer = pyrtl.Register(aw + 1, 'read_pointer') self.read_plus_1 = pyrtl.Const(1, 1) + self.read_pointer self.read_pointer.next <<= pyrtl.select(self.rd_en_i, truecase=self.read_plus_1, falsecase=self.read_pointer) self.write_pointer.next <<= pyrtl.select( self.reset, truecase=pyrtl.Const(0, aw + 1), falsecase=pyrtl.select(self.wr_en_i, truecase=self.write_pointer + 1, falsecase=self.write_pointer)) self.empty_int = pyrtl.WireVector(1, 'empty_int') self.full_or_empty = pyrtl.WireVector(1, 'full_or_empty') self.empty_int <<= self.write_pointer[aw] == self.read_pointer[aw] self.full_or_empty <<= self.write_pointer[0:aw] == self.read_pointer[ 0:aw] self.full_o <<= self.full_or_empty & ~self.empty_int self.empty_o <<= self.full_or_empty & self.empty_int self.one_left <<= (self.read_pointer + 1) == self.write_pointer self.mem = m = _RAM(num_entries=1 << aw, data_nbits=dw, name='FIFOStorage') m.wen <<= self.wr_en_i m.ren <<= self.rd_en_i m.raddr <<= self.read_pointer[0:aw] m.waddr <<= self.write_pointer[0:aw] m.wdata <<= self.wr_data_i self.rd_data_o <<= pyrtl.select(self.rd_en_i, truecase=m.rdata, falsecase=pyrtl.Const(0, dw))
def setUp(self): pyrtl.reset_working_block() bitwidth = 3 self.r = pyrtl.Register(bitwidth=bitwidth, name='r') self.result = _basic_add(self.r, pyrtl.Const(1).zero_extended(bitwidth)) self.r.next <<= self.result
def test_memblock_with_write_enable_with_equalsign(self): memory = pyrtl.MemBlock(bitwidth=self.bitwidth, addrwidth=self.addrwidth, name='memory') we = pyrtl.Const(1, bitwidth=1) self.output1 <<= memory[self.mem_read_address1] self.output2 <<= memory[self.mem_read_address2] memory[self.mem_write_address] <<= \ pyrtl.MemBlock.EnabledWrite(self.mem_write_data, enable=we)
def test_fastsim_wire_names(self): """ Testing ability to use wire names instead of wires in input""" in1 = pyrtl.Input(8, "in1") in2 = pyrtl.Input(8, "in2") in3 = pyrtl.Input(8, "in3") truth = pyrtl.Const(1, 1) out1 = pyrtl.Output(16, "out2") out2 = pyrtl.Output(16, "out3") out1 <<= in1 + in2 out2 <<= in3 | truth sim_trace = pyrtl.SimulationTrace() sim = self.sim(tracer=sim_trace) for i in range(10): sim.step({ 'in1': 2 * i, 'in2': 3 * i, 'in3': 40 - 2 * i }) correct_outp = (" --- Values in base 10 ---\n" "in1 0 2 4 6 8 10 12 14 16 18\n" "in2 0 3 6 9 12 15 18 21 24 27\n" "in3 40 38 36 34 32 30 28 26 24 22\n" "out2 0 5 10 15 20 25 30 35 40 45\n" "out3 41 39 37 35 33 31 29 27 25 23\n") output = six.StringIO() sim_trace.print_trace(output) self.assertEqual(output.getvalue(), correct_outp)
def test_memblock_with_write_enable_with_equalsign(self): we = pyrtl.Const(1, bitwidth=1) self.output1 <<= self.memory[self.mem_read_address1] self.output2 <<= self.memory[self.mem_read_address2] self.memory[self.mem_write_address] <<= \ pyrtl.MemBlock.EnabledWrite(self.mem_write_data, enable=we) pyrtl.working_block().sanity_check()
def test_error_condition_connect_const(self): i = pyrtl.Const(3, 2) o = pyrtl.WireVector(bitwidth=2, name='o') with pyrtl.conditional_assignment: with i <= 2: with self.assertRaises(pyrtl.PyrtlError): i |= o
def test_reg_to_reg_simulation(self): self.r2 = pyrtl.Register(bitwidth=self.bitwidth, name='r2') self.r.next <<= self.r2 self.r2.next <<= self.r + pyrtl.Const(2, bitwidth=self.bitwidth) self.o2 = pyrtl.Output(bitwidth=self.bitwidth, name='o2') self.o2 <<= self.r2 self.check_trace(' o 00224466\no2 02244660\n')
def test_error_on_non_boolean(self): c = pyrtl.Const(2) r = pyrtl.Register(bitwidth=2, name='r') with self.assertRaises(pyrtl.PyrtlError): with pyrtl.conditional_assignment: with c: r.next |= r + 1
def test_old_conditionupdate_provides_notice(self): c = pyrtl.Const(1) r = pyrtl.Register(bitwidth=2, name='r') with self.assertRaises(pyrtl.PyrtlError): with pyrtl.ConditionalUpdate() as condition: with condition(c): r.next |= r + 1
def test_short_true_condition(self): c = pyrtl.Const(1) r = pyrtl.Register(bitwidth=2, name='r') with pyrtl.conditional_assignment: with c: r.next |= r + 1 self.check_trace('r 01230123\n')
def test_no_elimination_of_different_const_bitwidths(self): # trying to merge const wires with different bitwidths # together will cause mismatches in bitwidths of certain wires const_1 = pyrtl.Const(3, 3) const_2 = pyrtl.Const(3, 5) out_1 = pyrtl.Output(5) out_2 = pyrtl.Output(5) out_1 <<= const_1 | const_1 out_2 <<= const_2 | const_2 pyrtl.common_subexp_elimination() self.num_net_of_type('|', 2) self.num_net_of_type('w', 2) self.assert_num_net(6) self.assert_num_wires(9) pyrtl.working_block().sanity_check()
def test_basic_false_condition(self): c = pyrtl.Const(0) r = pyrtl.Register(bitwidth=2, name='r') with pyrtl.conditional_assignment: with c: r.next |= r + 1 self.check_trace('r 00000000\n')
def test_error_on_unconditioned_update_in_under_conditional(self): with self.assertRaises(pyrtl.PyrtlError): c = pyrtl.Const(1) i = pyrtl.Register(bitwidth=2, name='i') with pyrtl.conditional_assignment: i.next |= i + 1 with c: i.next |= 2
def test_no_named_wires_erro(self): a = pyrtl.Const(-1, bitwidth=8) b = pyrtl.Input(8) c = pyrtl.Output() c <<= a + b with self.assertRaises(pyrtl.PyrtlError): sim_trace = pyrtl.SimulationTrace()
def setUp(self): pyrtl.reset_working_block() bitwidth = 3 self.r = pyrtl.Register(bitwidth=bitwidth, name='r') self.sum, self.cout = generate_full_adder( self.r, pyrtl.Const(1).zero_extended(bitwidth)) self.r.next <<= self.sum
def _g(word, key_expand_round): # One-byte left circular rotation, substitution of each byte a = libutils.partition_wire(word, 8) sub = pyrtl.concat(sbox[a[1]], sbox[a[2]], sbox[a[3]], sbox[a[0]]) # xor substituted bytes with round constant. round_const = pyrtl.concat(rcon[key_expand_round + 1], pyrtl.Const(0, bitwidth=24)) return round_const ^ sub
def test_netgraph_unused_wires(self): genwire = pyrtl.WireVector(8, "genwire") inwire = pyrtl.Input(8, "inwire") outwire = pyrtl.Output(8, "outwire") constwire = pyrtl.Const(8, 8) reg = pyrtl.Register(8, "reg") g = inputoutput.net_graph() self.assertEquals(len(g), 0)
def test_inconsistent_wirevector_by_name(self): c = pyrtl.Const(42) inp = pyrtl.Input(8, 'inp') out = pyrtl.Output(8, 'out') out <<= inp & c pyrtl.working_block().wirevector_by_name['inp'] = c self.sanity_error("inconsistent entry in wirevector_by_name", pyrtl.PyrtlInternalError)