コード例 #1
0
ファイル: test_conditional.py プロジェクト: UCSBarchlab/PyRTL
 def test_default_value_for_wires(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r1 = pyrtl.Register(bitwidth=3, name='r1')
     r2 = pyrtl.Register(bitwidth=3, name='r2')
     r3 = pyrtl.Register(bitwidth=3, name='r3')
     o = pyrtl.Output(bitwidth=3, name='o')
     with pyrtl.conditional_assignment(defaults={r1: r1 + 2, r2: 6, o: 3}):
         with i < 2:
             r1.next |= r1 + 1
             # r2 will be updated to 6
             # r3 remains the same as previous cycle
             o |= i
         with i < 3:
             # r1 will be updated to r1 + 2
             r2.next |= r2 + 1
             # r3 remains the same as previous cycle
             # o will be updated to 3
         with pyrtl.otherwise:
             # r1 will be updated to r1 + 2
             # r2 will be updated to 6
             r3.next |= 2
             o |= 7
     self.check_trace(' i 01230123\n'
                      ' o 01370137\n'
                      'r1 01246702\n'
                      'r2 06676667\n'
                      'r3 00002222\n')
コード例 #2
0
def simple_mult(A, B, start):
    """ Generate simple shift-and-add multiplier.

    Builds a slow, small multiplier using the simple shift-and-add algorithm.
    Requires very small area (it uses only a single adder), but has long delay
    (worst case is len(a) cycles). a and b are arbitrary-length inputs; start
    is a one-bit input to indicate inputs are ready.done is a one-bit signal
    output raised when the multiplication is finished, at which point the
    product will be on the result line (returned by the function).
    """
    alen = len(A)
    blen = len(B)
    areg = pyrtl.Register(alen)
    breg = pyrtl.Register(blen + alen)
    accum = pyrtl.Register(blen + alen)
    done = areg == 0  # Multiplication is finished when a becomes 0

    # During multiplication, shift a right every cycle, b left every cycle
    with pyrtl.conditional_assignment:
        with start:  # initialization
            areg.next |= A
            breg.next |= B
            accum.next |= 0
        with ~done:  # don't run when there's no work to do
            areg.next |= areg[1:]  # right shift
            breg.next |= pyrtl.concat(breg, "1'b0")  # left shift

            # "Multply" shifted breg by LSB of areg by conditionally adding
            with areg[0]:
                accum.next |= accum + breg  # adds to accum only when LSB of areg is 1

    return accum, done
コード例 #3
0
def attempt2_hardware_fibonacci(n, bitwidth):
    a = pyrtl.Register(bitwidth, 'a')
    b = pyrtl.Register(bitwidth, 'b')

    a.next <<= b
    b.next <<= a + b

    return a
コード例 #4
0
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
コード例 #5
0
    def decryption_statem(self, ciphertext_in, key_in, reset):
        """
        Builds a multiple cycle AES Decryption state machine circuit

        :param reset: a one bit signal telling the state machine
          to reset and accept the current plaintext and key
        :return ready, plain_text: ready is a one bit signal showing
          that the decryption result (plain_text) has been calculated.

        """
        if len(key_in) != len(ciphertext_in):
            raise pyrtl.PyrtlError(
                "AES key and ciphertext should be the same length")

        cipher_text, key = (pyrtl.Register(len(ciphertext_in))
                            for i in range(2))
        key_exp_in, add_round_in = (pyrtl.WireVector(len(ciphertext_in))
                                    for i in range(2))

        # this is not part of the state machine as we need the keys in
        # reverse order...
        reversed_key_list = reversed(self._key_gen(key_exp_in))

        counter = pyrtl.Register(4, 'counter')
        round = pyrtl.WireVector(4)
        counter.next <<= round

        inv_shift = self._inv_shift_rows(cipher_text)
        inv_sub = self._sub_bytes(inv_shift, True)
        key_out = pyrtl.mux(round, *reversed_key_list, default=0)
        add_round_out = self._add_round_key(add_round_in, key_out)
        inv_mix_out = self._mix_columns(add_round_out, True)

        with pyrtl.conditional_assignment:
            with reset == 1:
                round |= 0
                key.next |= key_in
                key_exp_in |= key_in  # to lower the number of cycles needed
                cipher_text.next |= add_round_out
                add_round_in |= ciphertext_in

            with counter == 10:  # keep everything the same
                round |= counter
                cipher_text.next |= cipher_text

            with pyrtl.otherwise:  # running through AES
                round |= counter + 1

                key.next |= key
                key_exp_in |= key
                add_round_in |= inv_sub
                with counter == 9:
                    cipher_text.next |= add_round_out
                with pyrtl.otherwise:
                    cipher_text.next |= inv_mix_out

        ready = (counter == 10)
        return ready, cipher_text
コード例 #6
0
ファイル: test_simulation.py プロジェクト: UCSBarchlab/PyRTL
 def setUp(self):
     pyrtl.reset_working_block()
     self.i = pyrtl.Input(bitwidth=3)
     self.r1 = pyrtl.Register(name='r1', bitwidth=3)
     self.r2 = pyrtl.Register(name='r2', bitwidth=3)
     self.o = pyrtl.Output(name='o', bitwidth=3)
     self.r1.next <<= self.i
     self.r2.next <<= self.r1
     self.o <<= self.r2
コード例 #7
0
 def test_basic_two_conditions(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r = pyrtl.Register(bitwidth=2, name='r')
     with pyrtl.conditional_assignment:
         with i == 2:
             r.next |= r + 1
         with i == 3:
             r.next |= r - 1
     self.check_trace('i 01230123\nr 00010001\n')
コード例 #8
0
def attempt3_hardware_fibonacci(n, bitwidth):
    a = pyrtl.Register(bitwidth, 'a')
    b = pyrtl.Register(bitwidth, 'b')
    i = pyrtl.Register(bitwidth, 'i')

    i.next <<= i + 1
    a.next <<= b
    b.next <<= a + b

    return a, i == n
コード例 #9
0
def rcoinc(a, b):
    last_a = pyrtl.Register(bitwidth=1)
    last_b = pyrtl.Register(bitwidth=1)
    holdit = pyrtl.Register(bitwidth=1)
    last_a.next <<= a
    last_b.next <<= b
    coinc_instant = a & b & (~last_a) & (~last_b)
    coinc = holdit | coinc_instant
    holdit.next <<= coinc
    return coinc
コード例 #10
0
 def test_two_seperate_conditions(self):
     c = pyrtl.Const(1)
     i = pyrtl.Register(bitwidth=2, name='i')
     r = pyrtl.Register(bitwidth=2, name='r')
     with pyrtl.conditional_assignment:
         with c:
             i.next |= i + 1
     with pyrtl.conditional_assignment:
         with i == 2:
             r.next |= r + 1
     self.check_trace('i 01230123\nr 00011112\n')
コード例 #11
0
 def test_nested_under_default_condition(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r = pyrtl.Register(bitwidth=3, name='r')
     with pyrtl.conditional_assignment:
         with i < 2:
             r.next |= r + 2
         with pyrtl.otherwise:
             with r < 6:
                 r.next |= r - 1
     self.check_trace('i 01230123\nr 02432466\n')
コード例 #12
0
 def test_basic_nested_condition(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r = pyrtl.Register(bitwidth=3, name='r')
     with pyrtl.conditional_assignment:
         with (i == 2) | (i == 3):
             with r < 3:
                 r.next |= r + 2
             with pyrtl.otherwise:
                 r.next |= r + 1
     self.check_trace('i 01230123\nr 00024445\n')
コード例 #13
0
 def test_basic_default_condition(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r = pyrtl.Register(bitwidth=2, name='r')
     with pyrtl.conditional_assignment:
         with i == 2:
             r.next |= r
         with i == 3:
             r.next |= r - 1
         with pyrtl.otherwise:
             r.next |= r + 1
     self.check_trace('i 01230123\nr 01221233\n')
コード例 #14
0
 def test_basic_nested_non_exclusive_condition(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r1 = pyrtl.Register(bitwidth=3, name='r1')
     r2 = pyrtl.Register(bitwidth=3, name='r2')
     with pyrtl.conditional_assignment:
         with r1 < 3:
             r1.next |= r1 + 1
         with pyrtl.otherwise:
             pass
         with r2 < 3:
             r2.next |= r2 + 1
     self.check_trace(' i 01230123\nr1 01233333\nr2 01233333\n')
コード例 #15
0
 def test_two_signals_under_default_condition(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r1 = pyrtl.Register(bitwidth=3, name='r1')
     r2 = pyrtl.Register(bitwidth=3, name='r2')
     with pyrtl.conditional_assignment:
         with i < 2:
             r1.next |= r1 + 1
         with i < 3:
             r2.next |= r2 + 1
         with pyrtl.otherwise:
             r2.next |= 3
     self.check_trace(' i 01230123\nr1 01222344\nr2 00013334\n')
コード例 #16
0
 def test_overlaping_assignments_in_non_exclusive_assignments(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r1 = pyrtl.Register(bitwidth=3, name='r1')
     r2 = pyrtl.Register(bitwidth=3, name='r2')
     with self.assertRaises(pyrtl.PyrtlError):
         with pyrtl.conditional_assignment:
             with r1 < 3:
                 r1.next |= r1 + 1
             with pyrtl.otherwise:
                 pass
             with r2 < 3:
                 r1.next |= r2 + 1
コード例 #17
0
 def test_one_deep_nested_non_exclusive_condition(self):
     i = pyrtl.Register(bitwidth=2, name='i')
     i.next <<= i + 1
     r1 = pyrtl.Register(bitwidth=3, name='r1')
     r2 = pyrtl.Register(bitwidth=3, name='r2')
     with pyrtl.conditional_assignment:
         with (i == 2) | (i == 3):
             with r1 < 3:
                 r1.next |= r1 + 2
             with pyrtl.otherwise:
                 pass
             with r2 < 3:
                 r2.next |= r2 + 2
     self.check_trace(' i 01230123\nr1 00024444\nr2 00024444\n')
コード例 #18
0
    def encrypt_state_m(self, plaintext_in, key_in, reset):
        """
        Builds a multiple cycle AES Encryption state machine circuit

        :param reset: a one bit signal telling the state machine
          to reset and accept the current plaintext and key
        :return ready, cipher_text: ready is a one bit signal showing
          that the encryption result (cipher_text) has been calculated.

        """
        if len(key_in) != len(plaintext_in):
            raise pyrtl.PyrtlError(
                "AES key and plaintext should be the same length")

        plain_text, key = (pyrtl.Register(len(plaintext_in)) for i in range(2))
        key_exp_in, add_round_in = (pyrtl.WireVector(len(plaintext_in))
                                    for i in range(2))

        counter = pyrtl.Register(4, 'counter')
        round = pyrtl.WireVector(4, 'round')
        counter.next <<= round
        sub_out = self._sub_bytes(plain_text)
        shift_out = self._shift_rows(sub_out)
        mix_out = self._mix_columns(shift_out)
        key_out = self._key_expansion(key, counter)
        add_round_out = self._add_round_key(add_round_in, key_exp_in)
        with pyrtl.conditional_assignment:
            with reset == 1:
                round |= 0
                key_exp_in |= key_in  # to lower the number of cycles
                plain_text.next |= add_round_out
                key.next |= key_in
                add_round_in |= plaintext_in

            with counter == 10:  # keep everything the same
                round |= counter
                plain_text.next |= plain_text

            with pyrtl.otherwise:  # running through AES
                round |= counter + 1
                key_exp_in |= key_out
                plain_text.next |= add_round_out
                key.next |= key_out
                with counter == 9:
                    add_round_in |= shift_out
                with pyrtl.otherwise:
                    add_round_in |= mix_out

        ready = (counter == 10)
        return ready, plain_text
コード例 #19
0
    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))
コード例 #20
0
ファイル: test_simulation.py プロジェクト: UCSBarchlab/PyRTL
 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
コード例 #21
0
ファイル: test_simulation.py プロジェクト: UCSBarchlab/PyRTL
    def test_default_value_for_registers_without_reset_value(self):
        r = pyrtl.Register(2, name='r', reset_value=3)
        s = pyrtl.Register(2, name='s')
        r.next <<= r + 1
        s.next <<= s - 1
        o = pyrtl.Output(4, 'o')
        o <<= r + s

        sim_trace = pyrtl.SimulationTrace()
        # Should set default value for s only (since r has specified 'reset_value')
        sim = self.sim(tracer=sim_trace, default_value=3)
        sim.step_multiple(nsteps=7)
        output = six.StringIO()
        sim_trace.print_trace(output, compact=True)
        self.assertEqual(output.getvalue(),
                         'o 6222622\nr 3012301\ns 3210321\n')
コード例 #22
0
ファイル: test_simulation.py プロジェクト: UCSBarchlab/PyRTL
    def test_weird_wire_names(self):
        """
        Some simulations need to be careful when handling special names
        (eg Fastsim June 2016)
        """
        i = pyrtl.Input(8, '"182&!!!\n')
        o = pyrtl.Output(8, '*^*)#*$\'*')
        o2 = pyrtl.Output(8, 'test@+')
        w = pyrtl.WireVector(8, '[][[-=--09888')
        r = pyrtl.Register(8, '&@#)^#@^&(asdfkhafkjh')

        w <<= i
        r.next <<= i
        o <<= w
        o2 <<= r

        trace = pyrtl.SimulationTrace()
        sim = self.sim(tracer=trace)

        sim.step({i: 28})
        self.assertEqual(sim.inspect(o), 28)
        self.assertEqual(sim.inspect(o.name), 28)
        self.assertEqual(trace.trace[o.name], [28])

        sim.step({i: 233})
        self.assertEqual(sim.inspect(o), 233)
        self.assertEqual(sim.inspect(o2), 28)
        self.assertEqual(sim.inspect(o2.name), 28)
        self.assertEqual(trace.trace[o2.name], [0, 28])
コード例 #23
0
 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)
コード例 #24
0
 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))
コード例 #25
0
    def test_trace_to_html_repr_per_name_enum_is_bool(self):
        from enum import IntEnum

        class Foo(IntEnum):
            A = 0
            B = 1

        i = pyrtl.Input(2, 'i')
        state = pyrtl.Register(max(Foo).bit_length(), name='state')
        o = pyrtl.Output(name='o')
        o <<= state

        with pyrtl.conditional_assignment:
            with i == 0b01:
                state.next |= Foo.A
            with i == 0b10:
                state.next |= Foo.B

        sim = pyrtl.Simulation()
        sim.step_multiple({'i': [1, 2, 1, 2, 2]})

        htmlstring = pyrtl.trace_to_html(sim.tracer,
                                         repr_per_name={'state': Foo})
        expected = (
            '<script type="WaveDrom">\n'
            '{\n'
            '  signal : [\n'
            '    { name: "i",  wave: "====.", data: ["0x1", "0x2", "0x1", "0x2"] },\n'
            '    { name: "o",  wave: "0.101" },\n'
            '    { name: "state",  wave: "=.===", data: ["Foo.A", "Foo.B", "Foo.A", "Foo.B"] },\n'
            '  ],\n'
            '  config: { hscale: 2 }\n'
            '}\n'
            '</script>\n')
        self.assertEqual(htmlstring, expected)
コード例 #26
0
 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')
コード例 #27
0
ファイル: test_wire.py プロジェクト: AaronHuanger/PyRTL
    def create_and_check_bundle(self, bundler):
        w = pyrtl.Bundle(bundler)
        assert isinstance(w, pyrtl.WireVector)
        assert hasattr(w, 'funct7')
        assert hasattr(w, 'rs2')
        assert hasattr(w, 'rs1')
        assert hasattr(w, 'funct3')
        assert hasattr(w, 'rd')
        assert hasattr(w, 'opcode')
        assert len(w) == 32
        assert len(w.funct7) == 7
        assert len(w.rs2) == 5
        assert len(w.rs1) == 5
        assert len(w.funct3) == 3
        assert len(w.rd) == 5
        assert len(w.opcode) == 7

        r = pyrtl.Register(len(w))
        r.next <<= w
        y = r.as_bundle(bundler)
        assert hasattr(y, 'funct7')
        assert hasattr(y, 'rs2')
        assert hasattr(y, 'rs1')
        assert hasattr(y, 'funct3')
        assert hasattr(y, 'rd')
        assert hasattr(y, 'opcode')
        assert len(y) == 32
        assert len(y.funct7) == 7
        assert len(y.rs2) == 5
        assert len(y.rs1) == 5
        assert len(y.funct3) == 3
        assert len(y.rd) == 5
        assert len(y.opcode) == 7
コード例 #28
0
def fib(first, second):
    a = pyrtl.Register(bitwidth=32, name='a')
    b = pyrtl.Register(bitwidth=32, name='b')
    return_val = pyrtl.WireVector(bitwidth=32, name='return_val')
    with pyrtl.conditional_assignment:
        with a == 0:
            with b == 0:
                a.next |= first
                b.next |= second
                return_val |= first
        with pyrtl.otherwise:
            a.next |= b
            b.next |= a + b
            return_val |= b

    return return_val
コード例 #29
0
 def test_all_does_simulation_correct(self):
     r = pyrtl.Register(3, 'r')
     r.next <<= r + 1
     a, b, c = r[0], r[1], r[2]
     o = pyrtl.Output(name='o')
     o <<= pyrtl.corecircuits.rtl_all(a, b, c)
     self.check_trace('o 00000001\nr 01234567\n')
コード例 #30
0
 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')