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
class RamIndex(Component): def __init__(self): super().__init__("ram_index") self.addr = NotifySignal(self, "addr", 12) self.x = NotifySignal(self, "x", 8) self.out = Signal(self, "out", 12) self.en = NotifySignal(self, "en", 1) def update(self, signal): if self.en.value(): # print('offset by {}'.format(self.x.value())) self.out <<= self.addr.value() + self.x.value() else: self.out <<= self.addr.value()
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
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
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
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.x_oe = Signal(self, "a_oe", 1) self.x_we = Signal(self, "a_we", 1) self.alu_oe = Signal(self, "alu_oe", 1) self.alu_we = Signal(self, "alu_we", 1) self.idx_en = Signal(self, "idx_en", 1) self.carry = Signal(self, "carry", 1) self.z = Signal(self, "z", 1) self.instr = Signal(self, "instr", 3) self.state = 0 self.last_clk = None 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.x_oe <<= 0 self.x_we <<= 0 self.alu_oe <<= 1 self.alu_we <<= 0 self.idx_en <<= 0 def update(self, signal): if self.clk.value() != self.last_clk: self.state = (self.state + 1) % 8 self.last_clk = self.clk.value() else: return # print('state: {}: instr: {:02b}'.format(self.state, self.instr.value())) self.ram_oe <<= self.state <= 3 or (self.instr.value() in (0b000, 0b001, 0b100, 0b101) and self.state <= 5) 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 (0b000, 0b001, 0b100, 0b101) and self.state == 5) # self.alu_oe <<= self.instr.value() in (0b000, 0b001, 0b100, 0b101) and self.state in (5, 6,) self.a_we <<= (self.instr.value() in ( 0b000, 0b001, ) and self.state == 6) self.x_we <<= self.instr.value() in (0b100, 0b101) and self.state == 6 # sta/stx self.a_oe <<= self.instr.value() == 0b010 and self.state in ( 5, 6, ) self.x_oe <<= self.instr.value() == 0b110 and self.state in ( 5, 6, ) self.ram_we <<= (self.instr.value() in ( 0b010, 0b110, ) and self.state == 6) # Indexing for alu(a), sta self.idx_en <<= self.instr.value() in (0b000, 0b001, 0b010) and self.state > 3 # jcc c=0 / jnz z=0 self.pc_we <<= ( (self.instr.value() == 0b011 and self.carry.value() == 0) or (self.instr.value() == 0b111 and self.z.value() == 0)) and self.state == 5 # jcc c=1 / jnz z=1 self.a_cc <<= ( (self.instr.value() == 0b011 and self.carry.value() != 0) or (self.instr.value() == 0b111 and self.z.value() != 0)) and self.state == 5
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)
class Logic(Component): def __init__(self): super().__init__("logic") self.a = NotifySignal(self, "a", 8) self.b = NotifySignal(self, "b", 8) self.fn = NotifySignal(self, "fn", 4) self.out = Signal(self, "out", 8) self.fi = NotifySignal(self, "fi", 4) self.fo = Signal(self, "fo", 4) self.oe = NotifySignal(self, "oe", 1) # c = carry # z = zero # n = negative # v = overflow def update(self, signal): if self.oe.value(): a = self.a.value() b = self.b.value() flags = self.fi.value() c = (flags >> 3) & 1 v = (flags >> 2) & 1 n = (flags >> 1) & 1 z = (flags >> 0) & 1 o = 0 of = None calc_flags = True fn = self.fn.value() if fn == 0: # not, cznv o = ~a elif fn == 1: # xor, znv o = a ^ b elif fn == 2: # or, znv o = a | b elif fn == 3: # and, znv o = a & b elif fn == 4: # add, cznv o = a + b # + c elif fn == 5: # sub, cznv o = a - b # - c elif fn == 6: # cmp, cznv # a - b - c? o = a of = a - b elif fn == 7: # shl, cznv o = a << 1 elif fn == 8: # shr, cznv o = a >> 1 elif fn == 9: # inc, znv o = a + 1 elif fn == 10: # dec, znv o = a - 1 elif fn == 11: # neg, cznv o = -a elif fn == 12: # clf, cznv o = a c = 0 z = 0 n = 0 v = 0 calc_flags = False elif fn == 13: # inv, cvnz o = a c = 1 - c z = 1 - z n = 1 - n v = 1 - v calc_flags = False elif fn == 14: # rol, c=a[7], znv o = (a << 1) | c elif fn == 15: # ror, c=a[0], znv o = (a >> 1) | (c << 7) if calc_flags: if of is None: of = o c = of > 0xFF z = of == 0 v = 0 # TODO: signed n = of < 0 # TODO: signed self.out <<= o & 0xFF self.fo <<= (c << 3) | (v << 2) | (n << 1) | (z << 0) else: self.out <<= None self.fo <<= None
class Decoder(Component): def __init__(self): super().__init__("decoder") self.instr = Signal(self, "instr", 8) self.flags = Signal(self, "flags", 4) self.clk = NotifySignal(self, "clk", 2) self.al_ie = Signal(self, "al_ie", 1) self.ah_ie = Signal(self, "ah_ie", 1) self.bl_ie = Signal(self, "bl_ie", 1) self.bh_ie = Signal(self, "bh_ie", 1) self.cl_ie = Signal(self, "cl_ie", 1) self.ch_ie = Signal(self, "ch_ie", 1) self.dl_ie = Signal(self, "dl_ie", 1) self.dh_ie = Signal(self, "dh_ie", 1) self.e_ie = Signal(self, "e_ie", 1) self.f_ie = Signal(self, "f_ie", 1) self.g_ie = Signal(self, "g_ie", 1) self.h_ie = Signal(self, "h_ie", 1) self.t_ie = Signal(self, "t_ie", 1) self.a_oe = Signal(self, "a_oe", 1) self.b_oe = Signal(self, "b_oe", 1) self.c_oe = Signal(self, "c_oe", 1) self.d_oe = Signal(self, "d_oe", 1) self.e_oe = Signal(self, "e_oe", 1) self.f_oe = Signal(self, "f_oe", 1) self.g_oe = Signal(self, "g_oe", 1) self.h_oe = Signal(self, "h_oe", 1) self.t_oe = Signal(self, "t_oe", 1) self.pc_inc = Signal(self, "pc_inc", 1) self.pc_ie = Signal(self, "pc_ie", 1) self.ir_ie = Signal(self, "ir_ie", 1) self.ir_oe = Signal(self, "ir_oe", 1) self.alu_fn = Signal(self, "alu_fn", 4) self.alu_oe = Signal(self, "alu_oe", 1) self.sel_cd = Signal(self, "sel_cd", 1) self.sel_gh = Signal(self, "sel_gh", 1) self.mem_ie = Signal(self, "mem_ie", 1) self.mem_oe = Signal(self, "mem_oe", 1) self.flags_ie = Signal(self, "flags_ie", 1) self.flags_tmp_ie = Signal(self, "flags_tmp_ie", 1) def reset(self): self.pc_inc <<= 0 def update(self, signal): clk = self.clk.value() m1 = clk <= 1 m2 = clk == 1 m3 = clk >= 2 m4 = clk == 3 # print('m1' if m1 else '', 'm2' if m2 else '', 'm3' if m3 else '', 'm4' if m4 else '') self.ir_ie <<= m1 self.flags_ie <<= m1 instr = self.instr.value() flags = self.flags.value() c = (flags >> 3) & 1 v = (flags >> 2) & 1 n = (flags >> 1) & 1 z = (flags >> 0) & 1 b7 = (instr >> 7) & 1 b6 = (instr >> 6) & 1 b5 = (instr >> 5) & 1 b4 = (instr >> 4) & 1 a_ie = 0 b_ie = 0 c_ie = 0 d_ie = 0 e_ie = 0 f_ie = 0 g_ie = 0 h_ie = 0 a_oe = 0 b_oe = 0 c_oe = 0 d_oe = 0 e_oe = 0 f_oe = 0 g_oe = 0 h_oe = 0 t_ie = 0 t_oe = 0 flags_tmp_ie = 0 sel_cd = 0 sel_gh = 0 # IMM is_imm = not b7 is_imm_high = (instr >> 4) & 1 imm_dest = (instr >> 5) & 3 self.ir_oe <<= m3 & is_imm # MOV is_mov = b7 and not b6 mov_src = (instr >> 3) & 7 mov_dst = instr & 7 mov_oe = m1 & is_mov mov_ie = m4 & is_mov a_oe |= mov_oe & (mov_src == 0) b_oe |= mov_oe & (mov_src == 1) c_oe |= mov_oe & (mov_src == 2) d_oe |= mov_oe & (mov_src == 3) e_oe |= mov_oe & (mov_src == 4) f_oe |= mov_oe & (mov_src == 5) g_oe |= mov_oe & (mov_src == 6) h_oe |= mov_oe & (mov_src == 7) a_ie |= mov_ie & (mov_dst == 0) b_ie |= mov_ie & (mov_dst == 1) c_ie |= mov_ie & (mov_dst == 2) d_ie |= mov_ie & (mov_dst == 3) e_ie |= mov_ie & (mov_dst == 4) f_ie |= mov_ie & (mov_dst == 5) g_ie |= mov_ie & (mov_dst == 6) h_ie |= mov_ie & (mov_dst == 7) t_ie |= m2 & is_mov t_oe |= m3 & is_mov # ALU is_alu = b7 and b6 and not b5 self.alu_fn <<= (instr >> 1) & 0xF self.alu_oe <<= m1 & is_alu t_ie |= m2 & is_alu t_oe |= m3 & is_alu a_ie |= m4 & is_alu & ~(instr & 1) c_ie |= m4 & is_alu & (instr & 1) flags_tmp_ie |= m2 & is_alu # MEM is_mem = b7 and b6 and b5 and not b4 is_mem_read = is_mem & ~((instr >> 1) & 1) is_mem_write = is_mem & ((instr >> 1) & 1) sel_cd |= is_mem & ~(instr & 1) sel_gh |= is_mem & (instr & 1) mem_reg = (instr >> 2) & 3 mem_reg_oe = m1 & is_mem_write mem_reg_ie = m4 & is_mem_read a_oe |= mem_reg_oe & (mem_reg == 0) b_oe |= mem_reg_oe & (mem_reg == 1) e_oe |= mem_reg_oe & (mem_reg == 2) f_oe |= mem_reg_oe & (mem_reg == 3) a_ie |= mem_reg_ie & (mem_reg == 0) b_ie |= mem_reg_ie & (mem_reg == 1) e_ie |= mem_reg_ie & (mem_reg == 2) f_ie |= mem_reg_ie & (mem_reg == 3) t_ie |= m2 & is_mem t_oe |= m3 & is_mem self.mem_ie <<= m4 & is_mem_write self.mem_oe <<= m1 & is_mem_read # JMP is_jmp = b7 and b6 and b5 and b4 # jmp, jz, jn, jls, jc, jo jmp_type = instr & 7 do_jmp = is_jmp & ( (jmp_type == 0) | (jmp_type == 1 and z == 1) | (jmp_type == 2 and n == 1) | (jmp_type == 3 and (n ^ v) == 1) | (jmp_type == 4 and c == 1) | (jmp_type == 5 and v == 1) ) self.pc_inc <<= m4 & ~do_jmp # Increment if not jump self.pc_ie <<= m4 & do_jmp # Load PC if jump sel_cd |= m3 & do_jmp & ~((instr >> 3) & 1) sel_gh |= m3 & do_jmp & ((instr >> 3) & 1) # Set ie/oe lines. imm_ie_l = m4 & is_imm & ~is_imm_high imm_ie_h = m4 & is_imm & is_imm_high self.al_ie <<= a_ie | (imm_ie_l & (imm_dest == 0)) self.ah_ie <<= a_ie | (imm_ie_h & (imm_dest == 0)) self.bl_ie <<= b_ie | (imm_ie_l & (imm_dest == 1)) self.bh_ie <<= b_ie | (imm_ie_h & (imm_dest == 1)) self.cl_ie <<= c_ie | (imm_ie_l & (imm_dest == 2)) self.ch_ie <<= c_ie | (imm_ie_h & (imm_dest == 2)) self.dl_ie <<= d_ie | (imm_ie_l & (imm_dest == 3)) self.dh_ie <<= d_ie | (imm_ie_h & (imm_dest == 3)) self.e_ie <<= e_ie self.f_ie <<= f_ie self.g_ie <<= g_ie self.h_ie <<= h_ie self.a_oe <<= a_oe self.b_oe <<= b_oe self.c_oe <<= c_oe self.d_oe <<= d_oe self.e_oe <<= e_oe self.f_oe <<= f_oe self.g_oe <<= g_oe self.h_oe <<= h_oe self.t_ie <<= t_ie self.t_oe <<= t_oe self.flags_tmp_ie <<= flags_tmp_ie self.sel_cd <<= sel_cd self.sel_gh <<= sel_gh
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