szty's diary

電子工作、プログラミングなど

FPGAでTD4(4bit CPU)を作る

Verilog HDLでTD4を作成し、シミュレータで動作確認をしてからFPGA(Artix-7)に実装した。

TD4上でラーメンタイマプログラムを実行することができた。

TD4について

TD4とは『CPUの創りかた』で製作していく4bitのCPUである。

仕様は以下のとおり。

  • 汎用レジスタ...A、B (4bit×2)
  • I/Oポート...Input、Output (4bit×2)
  • ステータスレジスタ...Carry Flag (1bit)
  • プログラムカウンタ...4bit
  • 命令フォーマット...Opcode+Immediate (4bit+4bit)

命令セット

ニモニック オペランド オペコード 動作
ADD A,Im 0000_Im A←A+Im
ADD B,Im 0101_Im B←B+Im
JMP Im 1111_Im Imへジャンプ
JNC Im 1110_Im C=0ならImへジャンプ
MOV A,Im 0011_Im A←Im
MOV B,Im 0111_Im B←Im
MOV A,B 0001_0000 A←B
MOV B,A 0100_0000 B←A
IN A 0010_0000 A←Input
IN B 0110_0000 B←Input
OUT Im 1011_Im Im→Output
OUT B 1001_0000 B→Output

プログラムについて

ラーメンタイマプログラムは(1Hzで動作する前提で)

  1. 0秒から約1分(65クロック)まで、7
  2. 約1分(66クロック)から約2分(130クロック)まで、6
  3. 約2分(131クロック)から約3分(194クロック)まで交互に、0、4
  4. 約3分(195クロック)以降、8

を出力する。

開発環境

  • CPU...Corei7 2700k
  • RAM...16GB (DDR3)
  • OS...Windows10 Pro 64bit
  • 開発ツール...Vivado (WebPACK Edition)
  • HDL...Verilog
  • FPGAボード...Basys 3

ソースコード

GitHubに公開した。

Basys 3は100MHzのクロック周波数で動作するので、周波数を1/100Mにして1Hzを作る分周回路(Divider.v)を追加した。

TD4と分周回路をまとめたものがTop.v。

module Top(input clk,input reset,input [3:0] in,output [3:0] out);

    wire divclk;

    Divider Divider(clk,reset,divclk);
    TD4 TD4(divclk,reset,in,out);

endmodule
  • Divider.v
module Divider(input clk,input reset,output out);

    reg [26:0] cnt27;

    initial begin
        cnt27 <= 27'b0;
    end

    always @(negedge clk) begin
        if(reset)
            cnt27 <= 27'b0;
        else if(cnt27 == 27'h5F5E100)
            cnt27 <= 27'b0;
        else
            cnt27 <= cnt27 + 1'b1;
    end

    function div;
    input [26:0] cnt27;
    begin
    if(cnt27 == 27'h5F5E100)
        div= 1'b1;
    else
        div = 1'b0;
    end
    endfunction

    assign out = div(cnt27);
    
endmodule

シミュレータの動作

f:id:szty1012:20171021203353p:plain
図1 シミュレータの動作(全体)

f:id:szty1012:20171023012353p:plain
図1 シミュレータの動作(130秒~145秒付近拡大)

  1. 0クロックから65クロックまで、7
  2. 66クロックから130クロックまで、6
  3. 131クロックから194クロックまで交互に、0、4
  4. 195クロック(3分15秒)以降、8

を出力しているので、正常に動作している。

FPGAの動作

図2 FPGAの動作(0秒~約1分)

図2 FPGAの動作(約1分~約2分)

図2 FPGAの動作(約2分~約3分)(消灯)

図2 FPGAの動作(約2分~約3分)(点灯)

図2 FPGAの動作(約3分~)

  1. 約1分間、7(0b0111)
  2. 約1分間、6(0b0110)
  3. 約1分間交互に、0、4(0b0100)
  4. 約3分以降、8(0b1000)

を出力しているので、実機でも正常に動作した。

メモ

次にできそうなこと

  • TD4のアセンブラ
  • 命令セットやbit数を増やすなどの改善
  • オリジナルのCPU
  • FPGAでなくICで作る