別シリーズでGoogleの生成AI、Gemini様にVerilogコードなど書いていただいております。Verilog素人の年寄が捻りだすよりお楽に感じます。そこで今回からしばらく、まずGemini様にお願いして、それを年寄がCMOD-S7ボード用に実装する、という段取りで練習したいと思います。今回はシリパラ変換ね。
※かえらざるMOS回路 投稿順 INDEX
※Digilent CMOD S7ボードのマニュアルは以下のページにあります。
なお、CMOD S7に搭載されているFPGAは「多分、お求めやすい」XC7S25-1CSGA225Cです(Spartan-7シリーズ。)
※実習には AMD社(Xilinx) Vivado 2023.2 を使用させていただいております。
ターゲットのシリパラ変換回路をGeminiにお願い
8ビットのシリアル入力、パラレル出力のclk同期式の変換回路を作製したいと思います。8発のクロックのクロックエッジでシリアル入力し、入力完了後8ビットのパラレル出力を行うもの。例によってGeminiのプロンプトに以下のような茫漠とした問いかけをしてみました。
Verilogを使って、8ビットのシリアル入力パラレル出力の変換器を設計して
Geminiからもらった回答の3案を老人の勝手な思惑で解釈すると以下のごとし。
案1、シリアル入力はMSBファースト、リセット信号はポジティブエッジ。3ビットのカウンタでシフト・インを制御しているのだが、「カウント値小なり8」でシフトか完了かを判定している。3ビットのカウンタじゃいつでも小なり8でないのかい。いいの?なお、テスト・ベンチとして使えるトップモジュールのコードまで生成してくれている。便利。あざーす。
案2、シリアル入力はMSBファースト、リセット信号はポジティブエッジ。4ビットのカウンタでシフト・インを制御しているので「カウント値小なり8」での判定は意味あり。ただし、トップモジュールはモジュールの結線のみ、テストベンチとしては使えず。
案3、シリアル入力はLSBファースト、リセット信号はネガティブエッジ。カウンタは3ビットなのに「カウント値小なり8」での判定。トップモジュールはモジュールの結線のみ。
帯に短し襷に長しっと。とりあえずトップモジュールまで作ってくれた案1に以下のような追加の投げかけをしてみました。
入力をLSBファーストにして
これへの回答をベースとして、Verilog素人の老人が「動きそうな感じ」に勝手に書き変えたコードが以下に。
Verilogソース
まずは本体、シリパラ変換部分。
module serpar0( input clk, input rst, input sin, output [7:0] sout, output rdy ); reg [7:0] shift_reg; reg [3:0] count; reg rdy; reg [7:0] sout; always @(posedge clk or posedge rst) begin if (rst) begin shift_reg <= 8'b0; count <= 3'b0; rdy <= 1'b0; end else begin if (~rdy && (count[3] == 1'b0)) begin shift_reg <= {sin, shift_reg[7:1]}; count <= count + 1; end else begin sout <= shift_reg; rdy <= 1'b1; count <= 4'b0; end end end endmoduleつ
つづいて過激に手抜きのテストベンチ(ほぼGemini様の案1そのままっす。)
module serpar0_tb( ); reg clk; reg rst; reg serial_in; wire [7:0] parallel_out; wire data_ready; serpar0 dut ( .clk(clk), .rst(rst), .sin(serial_in), .sout(parallel_out), .rdy(data_ready) ); always #5 clk = ~clk; initial begin clk = 0; rst = 1; serial_in = 0; #10; rst = 0; #100; serial_in = 1; #10; rst = 1; #10; rst = 0; #100; serial_in = 0; #100; $finish; end endmodule
シミュレーション結果
以下タイムスケールでの「ビヘイビア」シミュレーション結果がその下に。
`timescale 1ns / 1ps
オール0とオール1の時だけテストしてお茶を濁すとは不埒な。まあ意図どおりに動いておるみたい。
シンセシスとインプリメンテーション
シンセシスをかけたところ、Vivadoから以下のエラーを受領。
Methodology Violationsとな。これは以前にも遭遇したのでお馴染みさんね。そういえば制約ファイルを「コピー」しただけで何もしてなかった。そのためね。GeminiからコピペしただけでFPGA上にインプリできると思うなよ、ってか。
すると以下のような恐ろし気なエラーに遭遇。Poor placement for routing between an IO pin and BUFGとな。
説明を読むと、どうもCLKバッファのルーティングに問題があるような。オリジナルのDigilent社の制約ファイルはその辺いいところにとってある筈なのだが。。。手で書き変えた制約ファイルの中身をみてみていて発見。clk端子だけでなく、rst端子のつもりの端子にも「clk」というお名前つけてました。こいをclkとみて、恐ろし気なエラーが出てたのね。ダメじゃん。お名前を変更したら上記のエラーは消えました。
インプリ後、ビットストリームの生成まで行きつけたので、これにてOKといたしとうございます。実ボードに書き込まないのか?手抜きだな、自分。