VHDL版CPU1738の動作確認 / 9 ÷ 2 = 4余り1を計算する

アセンブラのようなものも『CPUの創りかた』のときと同じくPythonで作った。

def generate_mif(file_name, width, depth, rom):
    f = open(file_name, "w")
    f.write("WIDTH=%d;\n" % width)
    f.write("DEPTH=%d;\n" % depth)
    f.write("ADDRESS_RADIX=UNS;\n")
    f.write("DATA_RADIX=BIN;\n")
    f.write("CONTENT BEGIN\n")
    format_of_code = "0" + str(width) + "b"
    for i in range(depth):
        machine_code = format(rom[i], format_of_code)
        f.write("%10d   :   %s;\n" % (i, machine_code))
    f.write("END;\n")
    f.close()

def LD_A(Data)   : return ( 0 << 4)|(Data & 0xF)    # A ← [Data]
def LD_B(Data)   : return ( 1 << 4)|(Data & 0xF)    # B ← [Data]
def LD_AB()      : return ( 2 << 4)                 # A ← B
def LD_BA()      : return ( 3 << 4)                 # B ← A
def ADD_AB()     : return ( 4 << 4)                 # A ← A + B
def SUB_AB()     : return ( 5 << 4)                 # A ← A - B
def ADD_A(Data)  : return ( 6 << 4)|(Data & 0xF)    # A ← A + [Data]
def SUB_A(Data)  : return ( 7 << 4)|(Data & 0xF)    # A ← A - [Data]
def OUT_A()      : return ( 8 << 4)                 # OUT ← A
def OUT_B()      : return ( 9 << 4)                 # OUT ← B
def OUT(Data)    : return (10 << 4)|(Data & 0xF)    # OUT ← [Data]
def IN_A()       : return (11 << 4)                 # A ← IN
def JUMP(Address): return (12 << 4)|(Address & 0xF) # PC ← [Address]
def JNC(Address) : return (13 << 4)|(Address & 0xF) # PC ← [Address] if NOT Carry
def JNZ(Address) : return (14 << 4)|(Address & 0xF) # PC ← [Address] if NOT Zero
def HALT()       : return (15 << 4)                 # HALT

FILE_NAME = "rom_init.mif"
WIDTH =  8
DEPTH = 16
_ = [0] * DEPTH


# テキストのプログラム例(4)
# インポートとアウトポートとを直結しておく。
# 9/2=4(0100)余り1を計算する。
# 0111(9-2=7)、0101(9-2-2=5)、0011(9-2-2-2=3)、0001(9-2-2-2-2=1)の順に表示されたあと、
# 0100(9/2=4)と表示される。
_[0] = LD_A(9)  # 割られる数
_[1] = LD_B(0)  # 何回引き算ができたかの初期値
_[2] = SUB_A(2) # 割る数(引く数)
_[3] = JNC(10)  # 引いた結果が負なら、ループを抜けて10番地へ
_[4] = OUT_A()  # 今の引き算結果(すなわち余り)を出力して、
_[5] = LD_AB()  # 引き算できた回数をこの3行でインクリメントして、
_[6] = ADD_A(1)
_[7] = LD_BA()
_[8] = IN_A()   # 今の引き算結果(すなわち余り)(今OUTレジスタにある)を読み込んで、
_[9] = JUMP(2)  # 引き算を繰り返す。
_[10] = IN_A()  # (引いた結果が負なら3番地から)余り(今OUTレジスタにある)をAに格納し、
_[11] = OUT_B() # 商(何回引き算ができたか)を出力する。
_[12] = HALT()

generate_mif(FILE_NAME, WIDTH, DEPTH, _)

右から4ビットずつ、Bレジスタ、Aレジスタ、一番左がOUTレジスタ