Пример #1
0
 def write_at(self, control: 'bit', addr: 32, value: 32):
     dest, addr = addr[:3], addr[3:-2] + bit('00000')
     for dest_id, dest_obj, is_memory in self.sources:
         isdest = bit(True)
         for a, b in zip(dest_id, dest):
             isdest = isdest & (b if a == '1' else ~b)
         dest_obj.write_at(control & isdest, addr, value)
Пример #2
0
    def do_division(dividend, divisor, step):
        if step >= len(dividend):
            return (bit(size=0), dividend)
        quotient_up, dividend_up = do_division(dividend, divisor << 1,
                                               step + 1)
        # Don't overflow
        dividend = mux(divisor[1], dividend_up, dividend)
        quotient = mux(divisor[1], quotient_up, bit(0, size=len(quotient_up)))

        sub = hdl.simple_adder(dividend, hdl.negative_of_int(divisor))[0]
        return (mux(sub[0], quotient + '1',
                    quotient + '0'), mux(sub[0], sub, dividend))
Пример #3
0
    def read_at(self, control: 'bit', addr: 32, memory_only=False):
        dest, addr = addr[:3], addr[3:][:-2] + bit('00000')
        self.used = self.used | (control &
                                 (~(dest[0] | dest[1])))  # RAM and ROM -> 00x
        output = bit(0, size=32)

        for dest_id, dest_obj, is_memory in self.sources:
            if not memory_only or is_memory:
                isdest = ~(bit(dest) ^ dest_id)
                isdest = isdest[0] & isdest[1] & isdest[2]
                dest_out = dest_obj.read_at(control & isdest, addr)
                if dest_out is not None:
                    output = mux(isdest, output, dest_out)
        return output
Пример #4
0
    def __init__(self, rom, ram, out_format):
        self.input_signal = bit(-1, size=out_format[0][1])
        # We don't add the first output to the controller because it is reserved
        self.output = OutputController([size for _, size in out_format[1:]])
        self.sources = [
            ('000', ram, True),
            ('001', rom, True),
            ('101', self.output, False),
        ]
        self.used = bit(0)  # If the ROM or RAM has already been used

        # Set default actions
        rom.read_at('0', '0' * rom.rom_size)
        ram.read_at('1', '0' * ram.ram_size)
Пример #5
0
 def add(self, control, left, right, inv=None):
     self.input1.add(control, left)
     self.input2.add(control, right)
     if inv is not None:
         inv = bit(inv)
         self.inv.set((control & inv) | self.inv.get())
     return self.result
Пример #6
0
    def __init__(self, nb_registers, word_size):
        self.nb_registers = nb_registers
        self.reg_addr_size = math.ceil(math.log2(nb_registers))
        self.word_size = word_size

        self.registers = [
            Register(size=word_size, name=f'register_{i}')
            for i in range(nb_registers)
        ]
        self.registers[0] = bit(0, size=word_size)
Пример #7
0
    def __init__(self, inputs):
        self.input_control = MultiControl()
        self.input_addr = virtual(IO_SIGNIFICANT_BITS, self.input_control)

        self.plexer = Multiplexer(control=self.input_addr)
        self.plexer_out = virtual(32, self.plexer)

        self.plexer.plzshutup = True
        self.plexer.add(*inputs)
        # Read at -1 if no address
        self.read_at(1, bit(-1, size=32))
Пример #8
0
    def __init__(self, ram_size, word_size):
        self.ram_size = ram_size  # Size of the address
        self.word_size = word_size

        self.inputs = MultiControl()
        self.write_addrs = hdl.VirtualBit(ram_size)
        self.write_data = hdl.VirtualBit(word_size)
        self.write_enabled = virtual(1, bit('0'))

        self.output = RamOp(ram_size, word_size,
                            virtual(ram_size, self.inputs), self.write_enabled,
                            self.write_addrs, self.write_data)
Пример #9
0
def right_shift(bits, shift, invert=False, lead_bit=bit('0')):
    if invert:
        return left_shift(bits, shift)

    lead = lead_bit
    shift = list(shift)
    k = 1
    while shift:
        bits = mux(shift.pop(), bits, lead + bits[:-k])
        k *= 2
        lead = lead + lead
    return bits
Пример #10
0
    def __init__(self, size, adder_function):
        self.input1 = MultiControl()
        self.input2 = MultiControl()
        self.inv = virtual(1, bit(0))
        self.signed = virtual(1, bit(0))
        self.word_size = size

        operand1 = virtual(size, self.input1)
        operand1 = mux(
            self.signed,
            hdl.extend(size + 1, operand1),
            hdl.sign_extend(size + 1, operand1),
        )

        operand2 = virtual(size, self.input2)
        operand2 = mux(
            self.signed,
            hdl.extend(size + 1, operand2),
            hdl.sign_extend(size + 1, operand2),
        )
        operand2 = mux(self.inv, operand2, hdl.negative_of_int(operand2))
        self.num_result, self.carry = adder_function(operand1, operand2)
        self.result = self.num_result[1:], self.num_result[0]
Пример #11
0
 def op_auipc(self, control, rd, imm):
     result = self.alu.add(control, self.proc.reg_pc,
                           imm + bit(0, size=12))[0]
     self.write_rd(control, result)
Пример #12
0
 def op_lui(self, control, rd, imm):
     result = imm + bit(0, size=12)
     self.write_rd(control, result)
Пример #13
0
 def __init__(self, out_sizes):
     self.outputs = [bit(0, size=s) for s in out_sizes]
     self.out_addresses = [
         bit(k, size=IO_SIGNIFICANT_BITS) for k in range(len(out_sizes))
     ]
Пример #14
0
 def first_less_than(self, control, first, second, unsigned=False):
     r = self.comp(control, first, second, bit(not unsigned))
     return '0' * (self.word_size - 1) + r