全体を組み合わせる。あとはメモリーブロックに直接プログラムが書き込めればいいのだが今のところ方法が分からず、プログラムメモリーの初期化ファイルを書き換えるたびに毎回全体をコンパイルしている。(追記: .mifファイルのデータだけ入れ換える方法がわかった)
TD4は、クロックを受けた時点でROMから命令を受け取り終えていなければならないため、DFFを2個挟み込んでCPU側のクロックを少しだけ遅らせた。
A_REG、B_REGについても、確認できるよう端子を出した。
↓これが、プログラムメモリーの初期化ファイルを作るための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 MOV_A(Im): return ( 3 << 4)|(Im & 0xF) # AレジスタにImを転送 def MOV_B(Im): return ( 7 << 4)|(Im & 0xF) # BレジスタにImを転送 def MOV_AB() : return ( 1 << 4) # AレジスタにBレジスタを転送 def MOV_BA() : return ( 4 << 4) # BレジスタにAレジスタを転送 def ADD_A(Im): return ( 0 << 4)|(Im & 0xF) # AレジスタにImを加算 def ADD_B(Im): return ( 5 << 4)|(Im & 0xF) # BレジスタにImを加算 def IN_A() : return ( 2 << 4) # 入力ポートからAレジスタへ転送 def IN_B() : return ( 6 << 4) # 入力ポートからBレジスタへ転送 def OUT(Im) : return (11 << 4)|(Im & 0xF) # 出力ポートへImを転送 def OUT_B() : return ( 9 << 4) # 出力ポートへBレジスタを転送 def JMP(Im) : return (15 << 4)|(Im & 0xF) # Im番地へジャンプ def JNC(Im) : return (14 << 4)|(Im & 0xF) # Cフラグが1ではないときにIm番地へジャンプ FILE_NAME = "rom_init.mif" WIDTH = 8 DEPTH = 16 _ = [0] * DEPTH pc = -1 jump_where = pc+1 _[(pc:=pc+1)] = MOV_B(0b0001) _[(pc:=pc+1)] = MOV_AB() _[(pc:=pc+1)] = OUT_B() _[(pc:=pc+1)] = MOV_B(0b0010) _[(pc:=pc+1)] = MOV_AB() _[(pc:=pc+1)] = OUT_B() _[(pc:=pc+1)] = MOV_B(0b0100) _[(pc:=pc+1)] = MOV_AB() _[(pc:=pc+1)] = OUT_B() _[(pc:=pc+1)] = MOV_B(0b1000) _[(pc:=pc+1)] = MOV_AB() _[(pc:=pc+1)] = OUT_B() _[(pc:=pc+1)] = JMP(jump_where) generate_mif(FILE_NAME, WIDTH, DEPTH, _)
↓これが、上のPythonスクリプトで生成された初期化ファイル。
WIDTH=8; DEPTH=16; ADDRESS_RADIX=UNS; DATA_RADIX=BIN; CONTENT BEGIN 0 : 01110001; 1 : 00010000; 2 : 10010000; 3 : 01110010; 4 : 00010000; 5 : 10010000; 6 : 01110100; 7 : 00010000; 8 : 10010000; 9 : 01111000; 10 : 00010000; 11 : 10010000; 12 : 11110000; 13 : 00000000; 14 : 00000000; 15 : 00000000; END;
実行結果:
右から4ビットずつ、B、A、OUTの各レジスタの値。