Sim's blog

電子工作はじめてみました

MAX II マイクロキットでZ80

2008-11-22 14:09:21 | FPGA
トラ技12月号ではPICマイコンをCPLDで作っています。昔なつかしいZ80をMMKに入れてみました。もちろんCPUから全部自分で作るわけではありません。回路規模が小さいので有名なfz80コアを使わせてもらいます。fz80コアは「FPGAでPC-8001を作る計画」で使われたCPUコアです。fz80の最新バージョンはこちらからダウンロードできます。

ブロック図です。

クロックはmmkの50MHzを16分周した3.125MHzにしました。fz80にはwait入力があるので分周しない実装もありです。
RAMはなしでROMだけです。LEDチカチカをする最低限のROMを組み合わせ回路で実装します。

合成結果の回路規模はLE数が1255 / 2210 (57%)でした。まだ余裕がありますね。
時間はどれを見ればいいのかあいまいですが、Timing Analyzerのsummaryを見るとClock Setup: 'clk'のところに7.90MHz ( period = 126.509ns )と書いてあります。metしていないような気もしますが、マルチサイクルパスなので動いているということなんでしょうね。

fz80をmmkに載せるための回路のRTLです。
//`default_nettype none
module main(
    output reg [7:0] led = 8'h0,
    input [3:0] button,
    input clk);

    wire reset = ~button[3];// リセット(active h)
    wire [15:0] adr;        // アドレス

    // クロック生成 (分周 50MHz / 8 / 2 = 3.125MHz)
    reg [2:0] ctr = 3'h0;   // 分周用クロック
    reg zclk = 1'b0;        // 分周されたクロック

    always @(posedge clk)
        ctr <= ctr + 1;

    always @(posedge clk)
        if(ctr == 3'h0) zclk <= ~zclk;

    // rom
    wire [7:0] romout;      // ROMからのデータ出力 8bit

    rom rom1(
        .adr(adr),          // I アドレス入力
        .out(romout));      // O データ出力

    // fz80
    wire mreq, iorq, rd, wr;
    wire [7:0] cpuin, cpuout;

    fz80 cpu(
        .data_in(cpuin),    // I データ入力 8bit
        .reset_in(reset),   // I リセット入力 active H
        .clk(zclk),         // I クロック入力
        .adr(adr),          // O アドレス出力
        .intreq(1'b0),      // I 割り込み入力 active H?
        .nmireq(1'b0),      // I NMI入力      active H?
        .busreq(1'b0),      // I busreq入力   active H?
        .start(),           // O ???
        .mreq(mreq),        // O メモリアクセス
        .iorq(iorq),        // O I/Oアクセス
        .rd(rd),            // O データバス入力リクエスト
        .wr(wr),            // O データバス出力リクエスト
        .data_out(cpuout),  // O 出力用データバス 8bit
        .busack_out(),      // O busack出力
        .intack_out(),      // O intack出力
        .mr(),              // O ???
        .waitreq(1'b0));    // I ???

    // データバス
    assign cpuin = mreq & rd ? romout : 8'h00;
    always @(posedge clk)
        if(iorq & wr) led <= ~cpuout;

endmodule


module rom(
    input [15:0] adr,
    output reg [7:0] out);

    always @(*)
        case(adr)
        16'h0000: out = 8'h3e; // ld a, 80
        16'h0001: out = 8'h80; //
        16'h0002: out = 8'h07; // rlca
        16'h0003: out = 8'hd3; // out 0, a
        16'h0004: out = 8'h00; //
        16'h0005: out = 8'h4f; // ld c, a
        16'h0006: out = 8'h06; // ld b, 2
        16'h0007: out = 8'h02; //
        16'h0008: out = 8'h21; // ld hl, 0
        16'h0009: out = 8'h00; //
        16'h000a: out = 8'h00; //
        16'h000b: out = 8'h23; // inc hl
        16'h000c: out = 8'h7c; // ld a, h
        16'h000d: out = 8'hb5; // or l
        16'h000e: out = 8'h20; // jr nz, 000b
        16'h000f: out = 8'hfb; //
        16'h0010: out = 8'h10; // djnz 0008
        16'h0011: out = 8'hf6; //
        16'h0012: out = 8'h79; // ld a, c
        16'h0013: out = 8'hc3; // jp 0002
        16'h0014: out = 8'h02; //
        16'h0015: out = 8'h00; //
        16'h0016: out = 8'h00; // nop
        16'h0017: out = 8'h00; // nop
        16'h0018: out = 8'h00; // nop
        16'h0019: out = 8'h00; // nop
        16'h001a: out = 8'h00; // nop
        16'h001b: out = 8'h00; // nop
        16'h001c: out = 8'h00; // nop
        16'h001d: out = 8'h00; // nop
        16'h001e: out = 8'h00; // nop
        16'h001f: out = 8'h00; // nop
        default:  out = 8'hxx; // 最適化用
        endcase

endmodule

16分周でなく32分周になっていたのでソースを載せなおしました。

最新の画像もっと見る

12 コメント

コメント日が  古い順  |   新しい順
あこがれ (ぼのぐらし)
2008-11-22 15:11:03
CPLD,FPGAでできたらなあ、と思うことの一つがこれですね。
遠い目標においておきましょう。
re:あこがれ (Sim)
2008-11-22 22:26:34
こんばんは、ぼのぐらしさん
いつかはマイCPUですね。男のロマンです^^。

男のロマン (nekosan)
2008-11-26 00:04:23
いいですねぇ。「男のロマン」

CPUを自分の手でゼロから作っちゃうって言うのは夢ですよねぇ。まさに「アーキテクト」。

でもきっと私には無理だと思いますが…

そう。この間教えていただいたVHDLの本、纏まった時間が取れなくてまだ読み進められてません…(TへT)

12月に入ったら少しは読む時間が取れるかなと思うので、じっくりお勉強したいと思います。

私もいつかZ80とかのIP組み込んで、マイコン+FPGAをワンチップに押し込んだようなモノを作ってみたいなぁとか思ってますが、まだまだ先になりそうです。

re:男のロマン (Sim)
2008-11-26 06:41:59
こんにちは、nekosanさん
男のロマン、松本零士の世界です。たしか宇宙船を自作する人の漫画がありました。タイトルすら忘れています。

CPUだけでなく、OSから言語からアプリから、なんでもかんでも、ってそりゃ無理ですね。あはは。

VHDLで書かれたHDLも読んでみたいので、VHDLの勉強をしようと以前思ったのですが、挫折しまくりです。やっぱり自分で書いてみないと身につかないみたいです。open coresのアンケート集計結果を見るとVHDLを使っている方の方が少し多いみたいでした。両方使っているのは、かなりの少数派みたいです。

nekosanさんなら、そんなに遠い先じゃないような気がします。
入るのか (ぷるぷる)
2008-11-26 08:16:21
ふむう
チップの規模の見方が理解できていないので、トラ技の付録の十倍ってどんなもんだろうと思ってたのですがものすごく大きいものなのですね。びっくりです。
re:入るのか (Sim)
2008-11-26 18:15:05
こんにちは、ぷるぷるさん
ええ、入っちゃいました。xilinxだと700sliceくらいだったはずです。ただ、かなり外側回路を簡略化しているので、最適化で回路がごっそり削られている可能性もあります。
こうなってくると、外にROMとかRAMとか載せたくなってきますね。
Unknown (nekosan)
2008-11-26 23:37:54
>男のロマン、松本零士の世界です。たしか宇宙船を自作する人の漫画がありました。タイトルすら忘れています。

宇宙船を作っちゃうマンガはわからないのですが、松本零士でなんでも作っちゃう人といえばやっぱり宇宙戦艦ヤマトの「真田さん」。

大きくなったらあんな風に、あっという間に何でも作れちゃうエンジニアって言うのが理想像でした…。

verilogHDLのほうが言語的に洗練されていてスマートって聞いたことがあって、あと例のFPGAでPC-8001作っちゃうっていうサイトもverilogだったので、以前はverilogを勉強しようと思っていたはずなのですが、たまたま三省堂で買ってきた「FPGAボードで学ぶ論理回路設計」がVHDLだったので、なんとなくVHDLを手にしてしまいました。

なんとなく今でもverilogに憧れ的なものがあるんですけどねぇ…。
re:Unknown (Sim)
2008-11-27 22:20:08
こんばんは、nekosanさん
宇宙船を作る話はもしかすると、クイーン・エメラルダスかもしれません。
真田技師長というと、「こんなこともあろうかと・・・」の名セリフを残していますね。組織に無断で密かに開発って、あこがれちゃいますね。

verilogはCに似ていてタイプする量が少ないのは魅力です。以前のverilogは宣言しなくても変数が使えるとか、K&Rの頃のCのような雰囲気でした。verilog 2001やsystem verilogになってからは、ANSI Cに近くなった気がします。なんというか手軽さよりも安心して使える方が重視されてきているみたいな感じです。
verilogもいいですよー(悪魔のささやき)。

dwm2007/7でやってみました (ぷるぷる)
2008-11-28 01:59:51
トラ技2006/4からはじめたので私もVHDLなので、verilogのfz80は縁がないのかなあとおもってましたが、simさんに触発されてわたしもやってみました。xilinx ise webpackってVHDLのプロジェクトでも、verilogのモジュールを組み込んで動かすのは普通にできるのですね。とりあえず00 00 00 c3 00 00 とかいうromにつないでadrがぐるぐる回るのが実機で確認できました(dwm2007/7)。混在だとしみゅれーしょんで問題があるのかもしれないけど、simさんのサンプルのおかげでとっかかりができました。さんくす


Unknown (nekosan)
2008-11-29 01:14:06
>xilinx ise webpackってVHDLの
>プロジェクトでも、verilogの
>モジュールを組み込んで動かす
>のは普通にできるのですね。

そうなんですか…。それは便利ですねぇ。
勉強が進んだらやってみようっと。

verilogはCに似てるって言いますよね。
その点に実はとても惹かれてverilogやるはずだったんだけどなぁ…なんで間違えちゃったんだろう?

verilogかVHDLかどっちかが自由に書けて、もう片方はザーーと読める程度でもひとまず十分かなぁっていう気がしてますが、でもやっぱ両方書けると嬉しいな。

まぁ、まずは地に足つけて…かな。

コメントを投稿