Пример #1
0
class ProgramCounter(Component):
    def __init__(self, n):
        super().__init__("pc " + n)
        self.v = 0
        self.addr = Signal(self, "addr", 8)
        self.data = Signal(self, "data", 8)
        self.rst = NotifySignal(self, "rst", 1)
        self.inc = NotifySignal(self, "inc", 1)
        self.we = NotifySignal(self, "we", 1)
        self.co = Signal(self, "co", 1)

    def update(self, signal):
        if self.rst.value() == 1:
            self.v = 0
        elif self.we.value():
            self.v = self.data.value()
            # print('Jump')
        elif self.inc.had_edge(0, 1):
            if self.v == 0xFF:
                self.v = 0
                self.co <<= 1
            else:
                self.v += 1
                self.co <<= 0
        self.addr <<= self.v
Пример #2
0
class ALU(Component):
    def __init__(self):
        super().__init__("alu")
        self.a = Signal(self, "a", 9)
        self.b = Signal(self, "b", 8)
        self.out = Signal(self, "out", 9)
        self.fn = Signal(self, "fn", 1)
        self.oe = NotifySignal(self, "oe", 1)
        self.we = NotifySignal(self, "we", 1)
        self.v = 0

    def update(self, signal):
        if self.we.had_edge(0, 1):
            if self.fn.value() == 0:
                # nor
                trace("alu nor {} {}".format(self.a.value(), self.b.value()),
                      end="")
                carry = self.a.value() & 0b100000000
                value = self.a.value() & 0xFF
                self.v = carry | ((~(value | self.b.value())) & 0xFF)
            else:
                # add
                trace("alu add {} {}".format(self.a.value(), self.b.value()),
                      end="")
                self.v = ((self.a.value() & 0xFF) + self.b.value()) & 0x1FF

            trace(" --> {}".format(self.v))

        if self.oe.value() == 1:
            self.out <<= self.v
        else:
            self.out <<= None
Пример #3
0
class Decoder(Component):
    def __init__(self):
        super().__init__("decoder")
        self.clk = NotifySignal(self, "clk", 1)
        self.addr = Signal(self, "addr", 6)
        self.data = Signal(self, "data", 8)
        self.we = Signal(self, "we", 1)
        self.oe = Signal(self, "oe", 1)
        self.acc = 0
        self.adreg = 0
        self.pc = 0
        self.states = 0

    def reset(self):
        self.addr <<= 0
        self.data <<= None
        self.oe <<= 1
        self.we <<= 0

    def update(self, signal):
        if self.clk.had_edge(0, 1):
            if self.states == 0b000:
                self.pc = self.adreg + 1
                self.adreg = self.data.value()
            else:
                self.adreg = self.pc

            # ALU / Data Path
            if self.states == 0b010:
                # print('  add a {} + {}'.format(self.acc, self.data.value()))
                self.acc = ((self.acc & 0xFF) + self.data.value()) & 0x1FF
                # print('    = {}'.format(self.acc))
            elif self.states == 0b011:
                # print('  nor a {} + {}'.format(self.acc, self.data.value()))
                carry = self.acc & 0b100000000
                value = self.acc & 0xFF
                nor = (~(value | self.data.value())) & 0xFF
                self.acc = carry | nor
                # print('    = {}'.format(self.acc))
            elif self.states == 0b101:
                # Clear carry
                self.acc = self.acc & 0xFF

            # State machine
            if self.states != 0b000:
                self.states = 0b000
            elif (self.data.value()
                  & 0b11000000) == 0b11000000 and self.acc & 0b100000000:
                self.states = 0b101
            else:
                self.states = ~((self.data.value() >> 6) & 0b11) & 0b11

        clk = self.clk.value()
        self.addr <<= self.adreg & 0x3F
        self.data <<= None if self.states != 0b001 else self.acc & 0xFF
        self.oe <<= (0 if (clk == 1 or self.states == 0b001
                           or self.states == 0b101) else 1)
        self.we <<= 0 if (clk == 1 or self.states != 0b001) else 1
Пример #4
0
class AccumulatorRegister(IORegister):
    def __init__(self):
        super().__init__("accumulator", width=9)
        self.z = Signal(self, "z", 1)
        self.cc = NotifySignal(self, "cc", 1)

    def update(self, signal):
        super().update(signal)
        self.z <<= 1 if self.v == 0 else 0
        if self.cc.had_edge(0, 1):
            self.v = self.v & 0xFF
Пример #5
0
class InstructionRegister(Component):
    def __init__(self):
        super().__init__("ir")
        self.v = 0
        self.data = Signal(self, "data", 8)
        self.instr = Signal(self, "instr", 8)
        self.imm = Signal(self, "imm", 8)
        self.we = NotifySignal(self, "we", 1)
        self.oe = NotifySignal(self, "oe", 1)

    def update(self, signal):
        if self.we.had_edge(0, 1):
            self.v = self.data.value()
            self.instr <<= self.v
        if self.oe.value():
            imm = self.v & 0xF
            self.imm <<= imm | (imm << 4)
        else:
            self.imm <<= None
Пример #6
0
class Decoder(Component):
    def __init__(self):
        super().__init__("decoder")

        self.clk = NotifySignal(self, "clk", 1)

        self.ram_oe = Signal(self, "ram_oe", 1)
        self.ram_we = Signal(self, "ram_oe", 1)
        self.ar_oe = Signal(self, "ar_oe", 1)
        self.ar_we = Signal(self, "ar_we", 1)
        self.ir_oe = Signal(self, "ir_oe", 1)
        self.ir_we = Signal(self, "ir_we", 1)
        self.pc_we = Signal(self, "pc_we", 1)
        self.pc_oe = Signal(self, "pc_oe", 1)
        self.pc_inc = Signal(self, "pc_inc", 1)
        self.a_oe = Signal(self, "a_oe", 1)
        self.a_we = Signal(self, "a_we", 1)
        self.a_cc = Signal(self, "a_cc", 1)
        self.alu_oe = Signal(self, "alu_oe", 1)
        self.alu_we = Signal(self, "alu_we", 1)

        self.carry = Signal(self, "carry", 1)
        self.z = Signal(self, "z", 1)
        self.fn = Signal(self, "fn", 1)

        self.instr = Signal(self, "instr", 2)

        self.state = 0

    def reset(self):
        self.ram_oe <<= 0
        self.ram_we <<= 0
        self.ar_oe <<= 0
        self.ar_we <<= 0
        self.ir_oe <<= 0
        self.ir_we <<= 0
        self.pc_we <<= 0
        self.pc_oe <<= 0
        self.pc_inc <<= 0
        self.a_oe <<= 0
        self.a_we <<= 0
        self.a_cc <<= 0
        self.alu_oe <<= 0
        self.alu_we <<= 0

        self.fn <<= 0

    def update(self, signal):
        if self.clk.had_edge(0, 1):
            self.state = (self.state + 1) % 8
            # print('state: {}: instr: {:02b}'.format(self.state, self.instr.value()))

        self.ram_oe <<= self.state <= 3 or (
            self.instr.value()
            in (
                0b00,
                0b01,
            )
            and self.state <= 5
        )
        # not (self.instr.value() == 0b10 and self.state in (5, 6,))

        # self.pc_oe <<= 0
        # self.ir_oe <<= 0
        # self.ar_oe <<= 0
        # self.a_oe <<= 0

        self.ar_oe <<= self.state > 3
        self.ir_oe <<= self.state > 3
        self.pc_oe <<= self.state <= 3
        self.ir_we <<= self.state == 1
        self.pc_inc <<= self.state in (
            2,
            4,
        )
        self.ar_we <<= self.state == 3

        # alu
        self.alu_we <<= (
            self.instr.value()
            in (
                0b00,
                0b01,
            )
            and self.state == 5
        )
        self.alu_oe <<= self.instr.value() in (0b00, 0b01,) and self.state in (
            5,
            6,
        )
        self.a_we <<= (
            self.instr.value()
            in (
                0b00,
                0b01,
            )
            and self.state == 6
        )
        self.fn <<= self.instr.value() & 1

        # sta
        self.a_oe <<= self.instr.value() == 0b10 and self.state in (
            5,
            6,
        )
        self.ram_we <<= self.instr.value() == 0b10 and self.state == 6

        # jcc c=0
        self.pc_we <<= (
            self.instr.value() == 0b11 and self.carry.value() == 0 and self.state == 5
        )
        # jcc c=1
        self.a_cc <<= (
            self.instr.value() == 0b11 and self.carry.value() != 0 and self.state == 5
        )
Пример #7
0
class Decoder(Component):
    def __init__(self):
        super().__init__("decoder")
        self.clk = NotifySignal(self, "clk", 1)
        self.addr = Signal(self, "addr", 5)
        self.data = Signal(self, "data", 8)
        self.we = Signal(self, "we", 1)
        self.oe = Signal(self, "oe", 1)
        self.acc = 0
        self.x = 0
        self.adreg = 0
        self.pc = 0
        self.states = 0

    def reset(self):
        self.addr <<= 0
        self.data <<= None
        self.oe <<= 1
        self.we <<= 0

    def update(self, signal):
        if self.clk.had_edge(0, 1):
            if self.states == 0b0000:
                self.pc = self.adreg + 1
                self.adreg = self.data.value()
            else:
                self.adreg = self.pc

                # ALU / Data Path
                if self.states == 0b0110:
                    # print('  add a {} + {}'.format(self.acc, self.data.value()))
                    self.acc = ((self.acc & 0xFF) + self.data.value()) & 0x1FF
                    # print('    = {}'.format(self.acc))
                elif self.states == 0b0111:
                    # print('  nor a {} + {}'.format(self.acc, self.data.value()))
                    carry = self.acc & 0b100000000
                    value = self.acc & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.acc = carry | nor
                    # print('    = {}'.format(self.acc))
                elif self.states == 0b0010:
                    # print('  add x {} + {}'.format(self.x, self.data.value()))
                    self.x = ((self.x & 0xFF) + self.data.value()) & 0x1FF
                elif self.states == 0b0011:
                    # print('  nor x {} + {}'.format(self.x, self.data.value()))
                    carry = self.x & 0b100000000
                    value = self.x & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.x = carry | nor
                elif self.states == 0b1101:
                    # Clear carry
                    # print('  j not taken')
                    self.acc = self.acc & 0xFF
                elif self.states == 0b0101:
                    # print('  sta')
                    pass
                elif self.states == 0b0001:
                    # print('  stx')
                    pass
                else:
                    print("  unknown state")

            # State machine
            if self.states != 0b0000:
                self.states = 0b0000
            elif (self.data.value() & 0b01100000) == 0b01100000:
                # print('  maybe jump {} {}'.format(self.acc >> 8, self.acc))
                if not (self.data.value() & 0b10000000) and (self.acc
                                                             & 0b100000000):
                    # print('  jcc not taken')
                    self.states = 0b1101
                elif (self.data.value() & 0b10000000) and (self.acc
                                                           & 0xFF) == 0:
                    # print('  jnz not taken')
                    self.states = 0b1101
                else:
                    # print('  branch taken')
                    self.states = 0b0000
            else:
                # print('  going to state for {:03b}'.format(self.data.value() >> 5))
                self.states = ~((self.data.value() >> 5) & 0b111) & 0b111
                if (not (self.data.value() >> 7)
                        and (self.data.value() & 0b01100000) != 0b01100000):
                    # print('offset by x', self.x)
                    self.adreg += self.x

        clk = self.clk.value()
        self.addr <<= self.adreg & 0x1F
        if self.states == 0b0101:
            self.data <<= self.acc & 0xFF
        elif self.states == 0b0001:
            self.data <<= self.x & 0xFF
        else:
            self.data <<= None
        self.oe <<= (0 if (clk == 1 or self.states in (
            0b0001,
            0b0101,
            0b1101,
        )) else 1)
        self.we <<= (0 if (clk == 1 or self.states not in (
            0b0001,
            0b0101,
        )) else 1)
Пример #8
0
class Decoder(Component):
    MASK_OP = 0b011
    MASK_REG = 0b100
    OP_NOR = 0b000
    OP_ADD = 0b001
    OP_ST = 0b010
    OP_J = 0b011
    REG_A = 0b000
    REG_X = 0b100

    def __init__(self):
        super().__init__("decoder")
        self.clk = NotifySignal(self, "clk", 1)
        self.addr = Signal(self, "addr", 13)
        self.data = Signal(self, "data", 8)
        self.we = Signal(self, "we", 1)
        self.oe = Signal(self, "oe", 1)
        self.acc = 0
        self.x = 0
        self.adreg = 0
        self.hi5 = 0
        self.pc = 0
        self.state = 0
        self.op = 0

    def reset(self):
        self.addr <<= 0
        self.data <<= None
        self.oe <<= 1
        self.we <<= 0

    def update(self, signal):
        if self.clk.had_edge(0, 1):
            # print('clock {}'.format(self.state))
            if self.state == 0:
                self.pc = self.adreg + 2
                self.adreg = self.adreg + 1
                self.op = (self.data.value() >> 5) & 0b111
                self.hi5 = self.data.value() & 0x1F
            elif self.state == 1:
                self.adreg = (self.hi5 << 8) | self.data.value()
            elif self.state == 2:
                self.adreg = self.pc

                # ALU / Data Path
                if self.op == Decoder.REG_A | Decoder.OP_ADD:
                    # print('  add a {} + {}'.format(self.acc, self.data.value()))
                    self.acc = ((self.acc & 0xFF) + self.data.value()) & 0x1FF
                    # print('    = {}'.format(self.acc))
                elif self.op == Decoder.REG_A | Decoder.OP_NOR:
                    # print('  nor a {} + {}'.format(self.acc, self.data.value()))
                    carry = self.acc & 0b100000000
                    value = self.acc & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.acc = carry | nor
                    # print('    = {}'.format(self.acc))
                elif self.op == Decoder.REG_X | Decoder.OP_ADD:
                    # print('  add x {} + {}'.format(self.x, self.data.value()))
                    self.x = ((self.x & 0xFF) + self.data.value()) & 0x1FF
                elif self.op == Decoder.REG_X | Decoder.OP_NOR:
                    # print('  nor x {} + {}'.format(self.x, self.data.value()))
                    carry = self.x & 0b100000000
                    value = self.x & 0xFF
                    nor = (~(value | self.data.value())) & 0xFF
                    self.x = carry | nor
                elif (self.op & Decoder.MASK_OP) == Decoder.OP_J:
                    # Clear carry on all non-taken jumps.
                    # print('  j not taken')
                    self.acc = self.acc & 0xFF
                elif (self.op & Decoder.MASK_OP) == Decoder.OP_ST:
                    # print('  sta / stx')
                    pass
                else:
                    print("  unknown op")
            else:
                print("unknown state")

            # State machine
            if self.state == 0:
                # print('get next byte')
                self.state = 1
            elif self.state == 2:
                self.state = 0
            elif self.state == 1:
                if (self.op & Decoder.MASK_OP) == Decoder.OP_J:
                    # print('  maybe jump {} {}'.format(self.acc >> 8, self.acc))
                    if self.op & Decoder.MASK_REG == Decoder.REG_A and (
                            self.acc & 0b100000000):
                        # print('  jcc not taken')
                        self.state = 2
                    elif (self.op & Decoder.MASK_REG == Decoder.REG_X
                          and (self.acc & 0xFF) == 0):
                        # print('  jnz not taken')
                        self.state = 2
                    else:
                        # print('  branch taken')
                        self.state = 0
                else:
                    self.state = 2
                    # print('  going to state={} op={:03b}'.format(self.state, self.op))
                    if self.op & Decoder.MASK_REG == 0:
                        # print('offset by x', self.x)
                        self.adreg += self.x
            else:
                print("unknown state")

        clk = self.clk.value()
        # print('addr: {:04x}'.format(self.adreg & 0x1fff))
        self.addr <<= self.adreg & 0x1FFF

        if self.state == 2 and self.op == Decoder.REG_A | Decoder.OP_ST:
            self.data <<= self.acc & 0xFF
        elif self.state == 2 and self.op == Decoder.REG_X | Decoder.OP_ST:
            self.data <<= self.x & 0xFF
        else:
            self.data <<= None

        if clk == 1:
            self.oe <<= 0
            self.we <<= 0
        else:
            if self.state == 2 and (self.op
                                    & Decoder.MASK_OP) == Decoder.OP_ST:
                self.oe <<= 0
            else:
                self.oe <<= 1

            if self.state == 2 and (self.op
                                    & Decoder.MASK_OP) == Decoder.OP_ST:
                self.we <<= 1
            else:
                self.we <<= 0