DE0-Nano
セットアップ
最初はおおむねこれを参考にして Java から変換された VHDL のやつを動かした。
http://labs.beatcraft.com/ja/index.php?DE0-Nano%2FSynthesijer_QuickStart
Terasic の System Builder は wine で問題なく動く。
Java 使わない
ツールが生成した Verilog をそのまんま編集して
module button(CLOCK_50, LED, KEY); input CLOCK_50; output [7:0] LED; input [1:0] KEY; reg [24:0] counter = 25'h000000; reg [7:0] x = 0; reg [7:0] y = 1; reg state = 0; reg prev = 0; assign LED = x; always @(posedge CLOCK_50) begin if (~KEY[0]) begin x <= 0; y <= 1; state <= 0; end if (KEY[1] && prev) begin state <= !state; end prev = ~KEY[1]; counter <= counter + 1; if (counter == 0) begin if (state) begin x <= {x[6:0], x[7]}; end else begin x <= y; y <= x + y; end end end endmodule
とかやってみた。 key0 がリセット、 key1 が state の変化。フィボナッチと左ローテートで切り替え。
これでハローワールドくらいかな。。
GPIO
外部の LED を光らせる。深く考えず抵抗入れずに直結したら死んだ。考えろよ。かわいそうす。 10kΩだと光が弱かったので、 1kΩのはさんだら OK だった。
`default_nettype none module gpio_led(CLOCK_50, LED, KEY, GPIO, GPIO_IN); reg [23:0] counter = 24'h000000; reg led = 0; reg ex_led = 0; input CLOCK_50; output [7:0] LED; input [1:0] KEY; inout [33:0] GPIO; input [1:0] GPIO_IN; assign LED[7] = led; assign GPIO[33] = ex_led; always @(posedge CLOCK_50) begin counter <= counter + 1; if (counter == 0) begin led = !led; ex_led = !ex_led; end end endmodule
7セグ…
と思ったが抵抗が足りないのでやめる。
シリアル
Hello, world からはじめる本の写経をする。僕が買ったのは AE-UM232R 。本には秋月のやつは論理が逆転してる、て書いてあるけど、してないのが正解ぽい。ていうかこの本の写真 GND 刺してないけど、そのへんでおかしくなったりしてないのかな。。
TX/RX ともに動いた。ていうか最初から動いてたけど、シリアル端末が自分の入力エコーバックしてると思ってたら、 FPGA がしてるやつを表示してるだけだった。適当に小文字大文字変換とかかけるとわかりやすかった。
端末はとりあえず microcom というのを使っている。 minicom というのも試したが UI が気にいらなかった。
$ microcom -s 19200 -p /dev/ttyUSB0
配線忘れがちなので写真をはっておく。 verilog 側で rx てなってる方が tx なのよね
https://goo.gl/photos/XzKck3w65ySqmP6b9
client.rb というやつが送ったりするプログラムという俺メモ
RAM
SDRAM を使おうとしてアレコレしたが、やや難しそうだったので、とりあえず IP core というのを使って 256 byte の RAM をゲットしてみた。内蔵 RAM なんで、 LU 消費することなく確保できるぽい。 SDRAM と比べてこれは簡単…
だと思ってたが、いまひとつよくわかってないことがわかった。今ひとつ読み書きのできてるタイミングがわからん。 50MHz で読み書きしてるとなんかおかしくなる。メモリにレイテンシがあるのは別にいいんだけど、その仕様が今一つわからん…というかどこに書いてあるかわからん。読み書きする時に3クロック待ちを入れてやると動く。なんか資料を読むにぱっと見次クロックで結果来てるべきな気がするんだけどな。。ちょっとちゃんと調べないとこれは厳しそう。
まぁでもとりあえず Brainfuck インタプリタが動いた。結構でかい Brainfuck プログラムであるところの、 cal.bf が軽く動いてる。
RAM にレイテンシある問題は、要は入力をレジスタに書いてるわけで、そのレジスタが読まれるのに 1 clock かかって、読んだ結果がレジスタに書かれるまでにもう 1 clock …という理解で良さそうな気がする。設定で読んだ結果を書く方は wire にできぽいので、無駄な待ちは 1 clock まで削れる…というわけだと思う。
いやそうでもないな…なんか知らんけど、とにかく、 write enable してから次のクロックで disable して…と繰り返すのは大丈夫、 read enable してから3クロック後でアクセスすれば読める…みたいな感じ…そういうもんなのか、なんか遅いのか、はて。
Keyword(s):
References:[CPUTsukuru]