0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Shrike-LiteでAtCoder問題を解く(32):Detour:ABC470A - 公式ジャッジにVerilogで参加してみる

0
Last updated at Posted at 2026-08-14

はじめに

前回は、ABC470BをShrike-Liteへ実装しました。

今回はABC470Aを見ていたのですが、問題そのものとは別のところで気になるものを見つけました。

AtCoderの提出言語にVerilogがある。

昔AtCoderを触っていたころ、こんな選択肢は見た記憶がありません。

しかも現在の実行環境を見ると、

  • Verilog 2012
  • Icarus Verilog 12.0
  • コンパイル:iverilog
  • 実行:vvp

となっています。

つまり、普通にVerilogのコードを提出して公式ジャッジへ参加できるようです。

これはやってみるしかありません。

まず標準入出力をどうするんだ

競技プログラミングで新しい言語を使うと、最初に立ちはだかるのはだいたいアルゴリズムではありません。

標準入力をどうやって読むんだ?

今回もそこから始まりました。

Cならscanf、Pythonならinput()でいいのですが、Verilogで標準入力と言われても困ります。

普段のVerilogなら、入力はこんな感じです。

input wire [7:0] data;

いや、そうじゃない。

AtCoderは標準入力から数字を送ってきます。

少し調べると、Icarus Verilogでは標準入力をファイルディスクリプタとして扱えます。

integer n;
integer rc;

rc = $fscanf(32'h80000000, "%d", n);

Icarus Verilogの実装でも、0x80000000はSTDINとして扱われています。

出力はもっと簡単で、

$display("%0d", n);

で標準出力へ出せます。

これで競プロができそうです。

ところでIcarusってことは……

ここで別の疑問が出てきました。

これはFPGAへ合成するわけではありません。

Icarus Verilogでシミュレーションするだけです。

ということは、

回路面積の制限がないのでは?

さらに、

initial begin
    // いろいろ処理
end

の中で#10のような遅延も、posedge clkのようなイベント待ちも書かなければ、シミュレーション上は全部同じ時刻に処理されます。

つまり……

実質無限面積、処理時間ゼロの理想FPGAが爆誕したのでは?

かなり怪しい話になってきました。

もちろん現実にはIcarus Verilogを動かしているCPUが処理しているので、本当に時間がゼロになるわけではありません。

AtCoder側でも、生成されたプログラムはvvpで実行されます。

したがって競うことになるのは、回路のクロック周波数ではなく、

Icarus Verilogがそのシミュレーションを何秒で処理できるか

ということになりそうです。

これはもう、いつものFPGAとはかなり違います。

ABC470Aをやってみる

今回のお題はABC470A - Fizzです。

正の整数Nが与えられ、1からNまで順番に、

  • 3の倍数ならFizz
  • それ以外なら数字

を出力します。

Nは最大100です。

普通のプログラミング言語なら、ほとんど説明することもない問題です。

ではVerilogで書いてみます。

module Main;

    integer n;
    integer i;
    integer rc;

    initial begin
        rc = $fscanf(32'h80000000, "%d", n);

        for (i = 1; i <= n; i = i + 1) begin
            if (i % 3 == 0)
                $display("Fizz");
            else
                $display("%0d", i);
        end
    end

endmodule

……書けました。

何でしょう、この感じ。

integerがあって、

forがあって、

ifがあって、

剰余演算して、

$displayする。

妙なC言語を書いている気分です。

FPGAを作っている感じがほとんどありません。

コードテストで動かしてみる

まずはAtCoderのコードテストで試してみます。

入力はサンプルの、

10

です。

期待する出力は、

1
2
Fizz
4
5
Fizz
7
8
Fizz
10

です。

実行。

……

出ました。

普通に動きます。

VerilogがAtCoderの標準入力を読み、答えを標準出力へ出しています。

ワクワクします。

しかし何かがおかしい

動いたのですが、かなり違和感があります。

いつものFPGAなら、

  • 何bitで値を持つか
  • どのクロックで動かすか
  • 1クロックでどこまで計算するか
  • FSMをどう構成するか
  • LUTやFFをどれだけ使うか

といったことを考えます。

今回は何も考えていません。

integerを用意してforで回しただけです。

しかもクロックすらありません。

これは「FPGAでABC470Aを解いた」と言ってよいのでしょうか。

少なくとも、これまでShrike-Liteでやってきたこととはかなり違います。

Icarus VerilogはHDLのシミュレータです。

回路を作って実行しているというより、

Verilogで書いたシミュレーション記述をCPUで実行している

と考えたほうが実態に近そうです。

理想FPGAが誕生したと思ったら、どうもそうではありませんでした。

ただし、これはこれで面白い。

次回

今回は、とりあえずAtCoderのコードテストでVerilogが動くところまで確認しました。

しかし、せっかくVerilogを使うなら、

always @(posedge clk)

ぐらいは書きたいところです。

次回はABC470Dを題材に、クロックという概念をAtCoderへ持ち込んでみます

果たして、競技プログラミングの2秒という制限時間と、Verilogシミュレーション上のクロックはどういう関係になるのでしょうか。

Shrike-Liteとは何の関係もない話ですが、もう一回寄り道をしますね。


前回:
Shrike-LiteでAtCoder問題を解く(31):ABC470B - DistRAMで色を数える

次回:
Shrike-LiteでAtCoder問題を解く(33):Detour:ABC470D - 仮想理想FPGAなら何クロックで解ける?

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?