福野泰介の一日一創 - create every day

Macで開発、FPGAで作る4bit学習用CPU「GMC-4」 - Parallels x Ubuntu x Quartus x Verilog

2018/09/26
#FPGA #maker #Verilog 

Intel/ALTERAのFPGA開発環境「Quartus」は、Windows/Linux対応、Mac非対応。
でも、仮想環境 Parallels Desktop を使えば、Mac上でLinuxが動かし、開発できます。
以前はIchigoJamで作った学習用4bitCPU「GMC-4」を、今度はハードウェアで実現!

50MHzで動作する4bitマイコン「GMC-4 - Vol.24 4ビットマイコン | 大人の科学マガジン | 大人の科学.net
音やウェイトは未実装。次は、回路シミュレーターで遊んでみる予定。

MacでFPGA開発する手順 (GMC-4)
1. Parallels Desktop を Mac にインストール(Windowsを使わなければ無料版のLiteでOK)
2. Parallelsのインストールアシスタントで、Ubuntu Linuxを選ぶだけで簡単インストール
3. MacのファイルシステムをUbuntuと共有設定する
4. 仮想環境で使うメモリを1GBから4GBに変更する(Quratusのインストールで落ちた)
5. Quartus Prime Lite をUbuntuでセットアップする(要、ユーザー登録)
6. 書き込み器「USB Blaster」が使えるように設定して、Ubuntuを再起動(末尾に設定方法)
7. VerilogでGMC-4を作り、ピン設定する
8. コンパイル(MacBook Pro 2.3GHz Intel Core i5で、論理合成40秒、Windows環境でもほぼ同じ時間)
9. QuartusのProgrammerで書き込み、動く!


Mac上で動くUbuntu Linux、マウスもキーボードもシームレスに動いてくれるので、普通にアプリケーションを使う感覚で使えて便利! 速度差も思ったほどなく、いつでもどこでもFPGAプログラミングができるようになって嬉しい!


Intel® Programmable Acceleration Card with Stratix® 10 SX FPGAより)
IntelだけどArmも入ってる!(Overview)

FPGAニュース「インテル、「多機能アクセラレータ」のFPGA新モデルを追加 - ZDNet Japan
本気で使うFPGA、サーバーマシンに接続し、ソフトウェアでは到達不可能な処理速度を実現!
なんと、回路規模はトランジスタ換算で6600万コ!(2755k LE x 12ゲート/LE x 2トランジスタ/ゲート)
25Gbpsの通信路に、2.4GbpsでアクセスできるRAM、ArmのプロセッサCortex-A53も入っている豪華仕様。
お値段、約100万円。
解説書付きで5,000円書き込み器内蔵のものも3,000円などの手頃なFPGAと比較し、回路規模だけで340倍違うので、なかなかいい値段。

サーバー処理のボトルネックをハードウェア化する時代、到来!

(おまけ)
4bitCPU「GMC-4」をVerilogで書いたプログラム。
gmc4_top.v

module gmc4_top( input clk, output [3:0] outport); reg n_reset; poweronreset por(clk, n_reset); wire cpuclk; clockdivider clkdiv(clk, n_reset, 4, cpuclk); reg [3:0] key; wire [7:0] ledbin; wire [3:0] lednum; gmc4 cpu(cpuclk, n_reset, key, ledbin, lednum); assign outport = ~lednum; endmodule

gmc4.v

module gmc4( input clk, input n_reset, input [3:0] key, output reg [7:0] ledbin, output reg [3:0] lednum); reg [3:0] mem[0:8'h5f]; reg [7:0] pc; reg [3:0] rega, regb, regy, regz, rega2, regb2, regy2, regz2; reg flg; wire [3:0] op1, op2, op3; assign op1 = mem[pc]; assign op2 = mem[pc + 1]; assign op3 = mem[pc + 2]; always @(posedge clk, negedge n_reset) begin if (!n_reset) begin // rom_blink; rom_count; pc <= 0; flg <= 0; lednum <= 0; ledbin <= 0; end else begin case (op1) 4'h0: begin rega <= key; flg <= key != 0; end 4'h1: begin lednum <= rega; flg <= 1; end 4'h2: begin rega <= regb; regb <= rega; regy <= regz; regz <= regy; flg <= 1; end 4'h3: begin rega <= regy; regy <= rega; flg <= 1; end 4'h4: begin mem[regy] <= rega; flg <= 1; end 4'h5: begin rega <= mem[regy]; flg <= 1; end 4'h6: { flg, mem[regy] } <= mem[regy] + rega; 4'h7: begin mem[regy] <= mem[regy] < rega ? 0 : mem[regy] - rega; flg <= mem[regy] < rega; end 4'h8: begin rega <= op2; flg <= 1; end 4'h9: { flg, rega } <= rega + op2; 4'hA: begin regy <= op2; flg <= 1; end 4'hB: { flg, regy } <= regy + op2; 4'hC: flg <= rega != op2; 4'hD: flg <= regy != op2; 4'hE: begin case (op2) 4'h0: lednum <= 0; 4'h1: ledbin[regy] <= 1; 4'h2: ledbin[regy] <= 0; 4'h3: ; // none 4'h4: rega <= ~rega; 4'h5: begin rega <= rega2; rega2 <= rega; regb <= regb2; regb2 <= regb; regy <= regy2; regy2 <= regy; regz <= regz2; regz2 <= regz; end 4'h6: begin rega <= rega >> 1; flg <= ~rega[1]; end 4'h7: ; // sound end 4'h8: ; // sound err 4'h9: ; // sound pi 4'hA: ; // sound piii 4'hB: ; // sound rega 4'hC: ; // wait (rega + 1) * 0.1sec 4'hD: begin ledbin[3:0] <= mem[8'h5e]; ledbin[7:4] <= mem[8'h5f]; end 4'hE: mem[regy] <= mem[regy] - rega; 4'hF: { mem[regy - 1], mem[regy] } <= { mem[regy - 1], mem[regy] } + rega; endcase if (op2 != 4'h6) flg <= 1; end 4'hF: begin pc <= flg ? { op2, op3 } : pc + 3; flg <= 1; end endcase if (op1 < 4'h8) pc <= pc + 1; else if (op1 < 4'hF) pc <= pc + 2; end end task rom_blink; mem[0] <= 4'h8; mem[1] <= 4'h1; mem[2] <= 4'h1; mem[3] <= 4'h8; mem[4] <= 4'h0; mem[5] <= 4'h1; mem[6] <= 4'hF; mem[7] <= 4'h0; mem[8] <= 4'h0; endtask task rom_count; mem[0] <= 4'h8; mem[1] <= 4'h0; mem[2] <= 4'h9; mem[3] <= 4'h1; mem[4] <= 4'h1; mem[5] <= 4'hF; mem[6] <= 4'h0; mem[7] <= 4'h2; endtask endmodule

poweronreset.v

module poweronreset( input clk, output n_reset); reg [7:0] counter; always @(posedge clk) begin if (counter != 8'b11111111) counter <= counter + 8'b1; end assign n_reset = counter == 8'b11111111; endmodule

clockdivider.v

`define LEN_CLOCK 50_000_000 module clockdivider( input clk, input n_reset, input [3:0] div, output reg outclk); reg [31:0] counter; always @(posedge clk, negedge n_reset) begin if (!n_reset) begin outclk <= 0; counter <= 0; end else if (counter == (`LEN_CLOCK >> div) - 1) begin counter <= 0; outclk <= ~outclk; end else counter <= counter + 1'b1; end endmodule

USB Blaster設定 for Ubuntu Linux

su cat > /etc/udev/rules.d/51-usbblaster.rules # Intel/Altera USB-Blaster SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6001", MODE="0666", SYMLINK+="usbblaster/%k" SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6002", MODE="0666", SYMLINK+="usbblaster/%k" SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6003", MODE="0666", SYMLINK+="usbblaster/%k" # Intel/Altera USB-Blaster II SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6010", MODE="0666", SYMLINK+="usbblaster2/%k" SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6810", MODE="0666", SYMLINK+="usbblaster2/%k"

links
- プログラムたった64行、FPGAで創るオレオレ32bitCPU「TF32CPU r1」90Mhz x 2コア動作 on MAX10
- 最大動作周波数468MHz!? 書籍の付録とUSB BlasterではじめるFPGA「MAX10-FB」の組み立て方

プログラムたった64行、FPGAで創るオレオレ32bitCPU「TF32CPU r1」90Mhz x 2コア動作 on MAX10

2018/09/23
#FPGA #Verilog #maker #kosen 

半導体チップを作り放題な夢のデバイス「FPGA」で動かしてみた4bitCPU TD4
せっかくなので手で配線するのは大変な32bitCPUのツインコアに挑戦!
シンプル設計なオレオレCPUを創って、MAX10評価ボード上で、2コア動作させてみました。


90MHzで動作している32bit CPU 2コアの様子。
単にエルチカしているだけですが、毎秒1.8億回計算しています。

オレオレCPUづくりの手順
1. 32bit CPUをつくろう(汎用レジスタが32bit)
2. マシン語は32bit固定長にしよう
3. 命令は、ロード、ストア、代入、加算、減算、or、and、xor、左シフト、右シフト、掛け算の11種類
4. 命令に4bit、レジスタ指定に4bit x 2、16bitを値に使おう
5. レジスタは4bitなので16コ、最後レジスタをArmっぽくプログラムカウンタにしよう
6. 条件判定用のフラグはゼロフラグだけ
7. 残り4bit、Arm32っぽいフラグによるスキップ、フラグ更新するか否か、16bitの値の符号としよう
8. 出力はメモリにマッピングしておこう(RAMは32bit x 32word、最後の31番目を出力に接続)

9. Verilogを勉強する

初めて使うハードウェア記述言語、なんとなくサンプルいじっていてもよくわからないので書籍を購入。
わかるVerilog HDL入門―文法の基礎から論理回路設計、論理合成、実装まで (トランジスタ技術SPECIAL)
購入の決め手は、著書の木村真也さんが群馬高専の先生なこと。
しかも、函館高専の出身でした!

Verilogのコツは、組み合わせ回路と順序回路、シミュレーション用と論理合成用をきちんと区別すること。

組み合わせ回路:wireでassignしたりfunctionでつなぐ(フリップフロップなど、フィードバックなしの回路)
順序回路:alwaysでclk立ち上がりとn_reset立ち下がりでのregの変化をtaskなどで記述

シミュレーション用記述:#10などの遅延、initialはシミュレーション用(initialでも合成されてたけど??)

10. Verilogで実装する(名付けて、TF32CPU r1 - Taisuke Fukuno's 32 bit CPU release 1)

module tf32cpu_r1( input clk, input n_reset, output [3:0] outport); reg [31:0] r[0:15]; // register reg [31:0] mem[0:31]; // 32 word reg zeroflg; wire [31:0] code; wire skipflgnz; wire skipflgz; wire flgchg; wire minusim; wire [3:0] op; // operation code wire [3:0] rega; wire [3:0] regb; wire [31:0] opland; wire [15:0] im; // immediate data assign code = mem[r[15]]; assign skipflgnz = code[31]; assign skipflgz = code[30]; assign flgchg = code[29]; assign minusim = code[28]; assign op = code[27:24]; assign rega = code[23:20]; assign regb = code[19:16]; assign im = code[15:0]; assign opland = r[regb] + (minusim ? -im : im); always @(posedge clk, negedge n_reset) begin if (!n_reset) begin // program init_blink; init_reg; end else begin if (skipflgnz && !zeroflg || skipflgz && zeroflg) r[15] <= r[15] + 1; else begin case (op) 4'h0: r[rega] <= mem[opland]; 4'h1: mem[opland] <= r[rega]; 4'h2: r[rega] <= opland; 4'h3: r[rega] <= r[rega] + opland; 4'h4: r[rega] <= r[rega] - opland; 4'h5: r[rega] <= r[rega] | opland; 4'h6: r[rega] <= r[rega] & opland; 4'h7: r[rega] <= r[rega] ^ opland; 4'h8: r[rega] <= r[rega] << opland; 4'h9: r[rega] <= r[rega] >> opland; 4'hA: r[rega] <= r[rega] * opland; endcase if (flgchg) zeroflg <= r[rega] == 0; if (rega != 15) r[15] <= r[15] + 1; end end end assign outport = mem[31][3:0]; endmodule

- Verilogの特徴
短く書ける!(32bit CPUが、64行)
moduleが回路のかたまりを表す。(inputやoutputでインターフェイスを定義)
ブロックの表記方法は、begin / end({ }はbitの括りを表すのに使っちゃっている)
a[3:0]で、aのbit3からbit0までの4bitを表す。(何もつけないと1bit)
bitの長さを意識することは大事だけど、割といい感じにキャストされる
posedgeが立ち上がった時、negedgeが立ち下がった時
<= が、順序回路で次のタイミングへの切り替えを表す(同じタイミングで同じregに入れるとエラー)

11. レジスタの初期化とプログラムを task でメモリにセットするコードを追記

task init_blink; // for slowclock begin mem[ 0] <= 32'h0_2_3_0_0001; // R3=1 mem[ 1] <= 32'h0_1_3_0_001F; // [31]=R3 mem[ 2] <= 32'h0_2_3_0_0002; // R3=2 mem[ 3] <= 32'h0_1_3_0_001F; // [31]=R3 mem[ 4] <= 32'h0_2_F_0_0000; // PC=0 mem[31] <= 32'h00000000; // outport end endtask task init_reg; begin r[ 0] <= 32'h0; r[ 1] <= 32'h0; r[ 2] <= 32'h0; r[ 3] <= 32'h0; r[ 4] <= 32'h0; r[ 5] <= 32'h0; r[ 6] <= 32'h0; r[ 6] <= 32'h0; r[ 7] <= 32'h0; r[ 8] <= 32'h0; r[ 9] <= 32'h0; r[10] <= 32'h0; r[11] <= 32'h0; r[12] <= 32'h0; r[13] <= 32'h0; r[14] <= 32'h0; r[15] <= 32'h0; zeroflg <= 1'b0; end endtask

12. クロックやリセットとつないでオレオレCPUが動いた!
(MAX10評価ボードの場合、クロック clk=27、LED outport=132,134,135,140,141)

module tf32cpu( input clk, output [4:0] outport); wire cpuclk; assign cpuclk = clk; wire n_reset; poweronreset por(cpuclk, n_reset); reg [3:0] exout; tf32cpu_r1 cpu1(cpuclk, n_reset, exout); assign outport = { cpuclk, ~exout }; endmodule

poweonreset.v (起動後に少し待って n_reset を0にする回路)

module poweronreset( input clk, output n_reset); reg [7:0] counter; always @(posedge clk) begin if (counter != 8'b11111111) counter <= counter + 8'b1; end assign n_reset = counter == 8'b11111111; endmodule

13. ALTPLL(50MHzを9逓倍5分周)でクロックアップ!(90MHzが限界でした、それ以上だと沈黙)

module tf32cpu( input clk, output [4:0] outport); wire cpuclk; pll pll1(clk, cpuclk); // 略 endmodule

14. CPUのインスタンスを足して、ゆっくりCPUとの2コア(ツインCPU!)構成にしてみる

module tf32cpu( input clk, output [4:0] outport); wire cpuclk; pll pll1(clk, cpuclk); wire n_reset; poweronreset por(cpuclk, n_reset); reg [3:0] exout; tf32cpu_r1 cpu1(cpuclk, n_reset, exout); reg [3:0] exout2; wire slowclk; clockdivider cdiv2(cpuclk, n_reset, 2, slowclk); tf32cpu_r1 cpu2(slowclk, n_reset, exout2); assign outport = { slowclk, ~(exout | (exout2[1:0] << 2)) }; endmodule

クロックを遅くする clockdivider.v

`define LEN_CLOCK 50_000_000 module clockdivider( input clk, input n_reset, input [3:0] div, output reg outclk); reg [31:0] counter; always @(posedge clk, negedge n_reset) begin if (!n_reset) begin outclk <= 0; counter <= 0; end else if (counter == (`LEN_CLOCK >> div) - 1) begin counter <= 0; outclk <= ~outclk; end else counter <= counter + 1'b1; end endmodule

15. ツインCPUで動いた!
論理合成に2分半かかり、MAX10-08のLE使用率87%なのでトリプルにするにはきっとROM/RAMの切り離しが必要。(1コアだと合成1分14秒、46%)
* ツインCPUという懐かしい変な言葉。CPUという部品はなく、あるコンピューターの中心的役割を果たすコンピューターをCPU(中央処理装置 / Central Processing Unit)と呼ぶ。なので、正しくはツインコアのCPU。

16. マシン語プログラムを書き換える

mem[ 0] <= 32'h0_2_1_0_2FAF; // R1=#2FAF (50M=2FAF080) mem[ 1] <= 32'h0_8_1_0_0009; // R1=R1<<9 // mem[ 0] <= 32'h0_2_1_0_0003; // R1=3 for slowclock // mem[ 1] <= 32'h0_2_1_0_0003; // R1=3 mem[ 2] <= 32'h0_3_3_0_0001; // R3=R3+1 mem[ 3] <= 32'h0_1_3_0_001F; // [31]=R3 // LED1 mem[ 4] <= 32'h0_2_2_1_0000; // R2=R1 mem[ 5] <= 32'h2_4_2_0_0001; // R2=R2-1 flg mem[ 6] <= 32'h4_4_F_0_0001; // if !Z PC=PC-1 mem[ 7] <= 32'h0_1_4_0_001F; // [31]=R0 // LED0 mem[ 8] <= 32'h0_2_2_1_0000; // R2=R1 mem[ 9] <= 32'h2_4_2_0_0001; // R2=R2-1 flg mem[10] <= 32'h4_4_F_0_0001; // if !Z PC=PC-1 mem[11] <= 32'h0_2_F_0_0002; // PC=2

4つのLEDを2進数でカウントアップするデモプログラム(マシン語 for TF32CPU r1)

links
- 憧れのCPUづくりが超簡単!あの4bitコンピューターTD4マシン語プログラム on FPGA MAX10
- FPGAはじめのいっぽ、MAX10 FPGA 評価キットでエルチカ成功!
- 最大動作周波数468MHz!? 書籍の付録とUSB BlasterではじめるFPGA「MAX10-FB」の組み立て方

最大動作周波数468MHz!? 書籍の付録とUSB BlasterではじめるFPGA「MAX10-FB」の組み立て方

2018/09/19
#FPGA #Verilog #maker 

FPGAの評価ボードに替えて、雑誌付録のMAX10基板でフルカラーエルチカできました!

書き込み器「USB Blaster」は、なんと687円!?


FPGA MAX10搭載基板が付録の「FPGA電子工作スーパーキット」+1,000円ちょっとで揃います!
著書は、LPC1114との出会いの書「2枚入り!組み合わせ自在!超小型ARMマイコン基板」と同じ、圓山宗智さん。


付録のFPGAチップ搭載の基板!
クリスタルオシレーター(48MHz)とピンヘッダーで、USB Blaster仕様の最小仕上げをします。
※写真は家にあった12MHzのクリスタルオシレーター


USB BlasterのJTAGケーブルを接続するCN7端子を、ピンヘッダー5ピンx2にして、はんだづけ。
(JTAGケーブルを挿してはんだづけするとゆがみにくい!)


裏面、はんだジャンパーを12箇所、はんだづけします。


CN3のVCC33とGNDで電源を供給できるようにピンソケットをはんだづけ。


Flashに書き込めば、電源つないだら数msecで即動作!
MeganeJamは5Vから3.3Vを生成するためにのみ使用、単3を2本の電池ボックスなどでもOK)

無償で使える開発環境 Quartus Prime Light edition、IPカタログからALTPLLを選択して、クリスタルオシレーターと入力周波数を合わせ(12MHzや、48MHzなど)、倍率を設定することで任意の周波数で動かせます。

クリスタルオシレーター12MHzを39倍にした468MHzまでは動作しました!(40倍の480MHzでは沈黙)
* スペックとしては450MHzでした (2018.9.23 追記)

自由自在に超高速エルチカできる環境が手に入ったわけです!

下記、動作確認で使ったエルチカプログラム Verilog for MAX10-FB書籍付属基板
ピン配置(外部クロック 27、LED_R/G/B 120/121/122、タクトスイッチ 123)

`define PER_CLOCK 48_000_000 / 10 module max10cq(input clk, output [2:0] leds, input sw1); wire clk2; wire locked; wire clk48; wire red; wire green; assign leds[0] = sw1 == 0 ? 1 : red; assign leds[1] = sw1 == 0 ? 1 : green; clkdivider clkdiv(clk48, clk2); ledsign led1(clk2, red, green, leds[2]); pll pll1(1'b0, clk, clk48, locked); endmodule module clkdivider (input inclk, output reg outclk); reg [31:0] cnt; initial begin cnt <= 32'b0; outclk = 1'b0; end always @(posedge inclk) begin if (cnt == `PER_CLOCK / 2 - 1) begin cnt <= 0; outclk <= ~outclk; end else cnt <= cnt + 32'b1; end endmodule module ledsign (input clk, output reg a, output reg b, output reg c); reg [2:0] memcnt; reg [2:0] mem [3:0]; initial begin { a, b, c } <= 3'b111; memcnt <= 0; mem[0] <= 3'b110; mem[1] <= 3'b101; mem[2] <= 3'b011; mem[3] <= 3'b101; end always @(posedge clk) begin { a, b, c } <= mem[memcnt]; memcnt <= memcnt + 3'b1; end endmodule

links
- (1)MAX10(2)ライタ(3)DVD付き! FPGA電子工作スーパーキット (トライアルシリーズ) | 圓山 宗智 |本 | 通販 | Amazon
- 憧れのCPUづくりが超簡単!あの4bitコンピューターTD4マシン語プログラム on FPGA MAX10
- FPGAはじめのいっぽ、MAX10 FPGA 評価キットでエルチカ成功!

憧れのCPUづくりが超簡単!あの4bitコンピューターTD4マシン語プログラム on FPGA MAX10

2018/09/17
#FPGA #Verilog 

新たに手に入れた武器、FPGAのMAX10でフラッシュへの書き込み方法がわかったので、半導体レベルからのものづくりができるようになりました。

こちら有名な4bitコンピューターTD4をちょっといじって、マシン語プログラムをROMとして書き込み、ナイトライダー風に動かしたデモ。
CPUの創りかた TD4 を Spartan-3A で - 言語ゲーム


フラッシュへの書き込み方法は、Programmerで、一旦 Delete として、output_filesからpofファイルを選択し、CFM0かUFMのProgram/Configureをチェックして、Startするだけ! ちょっと長い書き込み時間を待てば、あとはパソコンから切り離し、電源投入だけでオリジナルの半導体として使えます!起動時間も十分高速。


TD4は、2006/4/3に購入した2003年発刊の名著「CPUの創りかた」で創られた4bit CPU。

こちらの「CPUの創りかた TD4 を Spartan-3A で - 言語ゲーム」のVerilogでかかれた、td4.v のROMとして書かれたマシン語プログラム部分を変更したものでした。

ROM[0] = 8'b1011_0001; // OUT 0001 ROM[1] = 8'b1011_0010; // OUT 0010 ROM[2] = 8'b1011_0100; // OUT 0100 ROM[3] = 8'b1011_1000; // OUT 1000 ROM[4] = 8'b1011_0100; // OUT 0100 ROM[5] = 8'b1011_0010; // OUT 0010 ROM[6] = 8'b1011_0001; // OUT 0001 ROM[7] = 8'b1111_0000; // JMP 0000

INとRESETは、タクトスイッチが接続されている 120, 124, 127, 130, 131番ピンへ、
OUTは、LEDが接続されている 132, 134, 135, 140, 141番ピンへそれぞれ Pin Designer で設定。

MAX10の内蔵クロック50MHzを100万倍ほど遅くして、I/Oに接続(assign)すれば、できあがり!

`define LEN_CLOCK 50000000 / 10 module top_td4( input CLOCK, input RESET, input [3:0] IN, output [4:0] OUT ); reg [26:0] counter; reg td4_CLOCK; reg [4:0] td4_OUT; initial begin td4_CLOCK <= 0; td4_OUT <= 5'b00000; end always @(posedge CLOCK) begin if (RESET | counter == `LEN_CLOCK - 1) begin counter <= 0; td4_CLOCK <= ~td4_CLOCK; end else counter <= counter + 1'b1; end assign OUT = { td4_CLOCK, ~td4_OUT[3:0] }; td4 td4_0(td4_CLOCK, RESET, IN, td4_OUT[3:0]); endmodule

夢のオレオレCPUづくり、超簡単ですね!


これを手作りでやるとこのような配線か、多量の配線を回路CADでレイアウトするかが必要だったわけです。FPGA、エライ!

links
- FPGAはじめのいっぽ、MAX10 FPGA 評価キットでエルチカ成功!

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / アイコン画像 / プロフィール画像