見出し画像

ChatGPTに回路設計をやらせてみた 2

前回、ChatGPTにRTLを書いてもらったのですが、その正しさが分からずに終わってしまいました。今回は検証環境を整え、動作確認まで行いました。

検証環境導入

以下を参考にしました。
オープンソースのIcarus Veriog、GTKWaveを使用します。
https://miyanetdev.com/archives/240

rev. 0

前回ChatGPTに出力させたRTLをそのまま使います。
テストベンチは以下を使用しました。100円を入れて50円の商品を購入した時、お釣りが50円と出ればpassです。ChatGPTに出してもらったものをベースに、pin名の変更やIcarus Verilog対応(assertが使えない)などを行っています。すべての機能をテストできていない気もしますが、今回はこれがpassすればOKとします。

`timescale 1ns/1ns
module testbench();

 // Inputs
 reg [7:0] product_price;
 reg [7:0] deposit;
 reg clk;
 reg reset;
 reg btn;

 // Outputs
 wire [7:0] change;
 wire dispense;

 // Instantiate the DUT
 vending_machine dut(
   .clk(clk),
   .reset(reset),
   .product_price(product_price),
   .deposit(deposit),
   .change(change),
   .dispense(dispense),
   .btn(btn)
 );

 initial begin
   $dumpvars;
   // Initialize inputs
   product_price = 8'h32;  // 50 in decimal
   deposit = 8'h64; // 100 in decimal
   clk = 0;
   btn = 0;
   reset = 1;

   //reset
   #5; clk = 1; #5; clk = 0;

   // Toggle clock and test
   reset = 0;
   btn = 1;
   #5; clk = 1; #5; clk = 0;
   if(change == 8'h32) ;else $display("Test failed: Incorrect change amount");
   if(dispense) ;       else $display("Test failed: Item not purchased");

   // End simulation
   $finish;
 end

endmodule

実行結果

Test failed: Incorrect change amount

ChatGPTの解析によると以下が原因らしいです。

テストベンチとvending_machineモジュールのコードには明らかなエラーは見当たりませんが、change_amountの初期値が0に設定されているため、以下のシナリオが発生すると期待した値と異なる結果になります。product_price=50、deposit=100の場合
ボタンを押す前にtotal_depositが100になりますが、purchase_priceが0のままでchange_amountが-100に設定されてしまいます。この場合、テストベンチで期待するchange_amountは50なので、テストが失敗します。


この問題を修正するには、change_amountを最初に-1に設定し、ディスペンスする前にchange_amountの値が負である場合は0に設定する必要があります。vending_machineモジュールの変更例を以下に示します。

ChatGPTによる回答(2023/4/23)

rev. 1

修正してもらいました。

always @(posedge clk) begin
if (reset) begin
total_deposit <= 0;
purchase_price <= 0;
change_amount <= -1; // change_amountを-1に設定
dispense <= 0;
end
else begin
total_deposit <= total_deposit + deposit;
if (btn) begin
purchase_price <= product_price;
change_amount <= total_deposit - purchase_price;
if (change_amount < 0) begin // change_amountが負の場合は0に設定
change_amount <= 0;
end
total_deposit <= 0;
dispense <= 1;
end
else begin
dispense <= 0;
end
end
end

ChatGPTによる回答(2023/4/23)

実行結果。また同じエラーが出ました。

Test failed: Incorrect change amount

rev. 5

何度か修正してもらった結果、ようやくテストをpassできました。

module vending_machine (
input clk,
input reset,
input [7:0] product_price,
input [7:0] deposit,
input btn,
output [7:0] change,
output reg dispense
);

reg [7:0] total_deposit;
reg [7:0] purchase_price;
reg [7:0] change_amount;

always @(posedge clk) begin
if (reset) begin
total_deposit <= 0;
purchase_price <= 0;
change_amount <= product_price;
dispense <= 0;
end
else begin
total_deposit <= total_deposit + deposit;
if (btn && !dispense) begin
purchase_price <= product_price;
total_deposit <= total_deposit - purchase_price;
dispense <= 1;
end
if (dispense && !change_amount) begin
change_amount <= total_deposit;
total_deposit <= 0;
end
if (!btn) begin
dispense <= 0;
end
end
end

assign change = change_amount;

endmodule

ChatGPTによる回答(2023/4/23)

ただ、passはしたものの、お釣りの金額がボタンを押す前から表示されてしまいます。しかも、お釣りの金額に商品価格が代入されているため、このテストではたまたま一致しただけのようです。とはいえ、この問題はChatGPTの設計が悪いわけではなく、テストベンチの問題です。続く。

rev.5 sim波形

この記事が気に入ったらサポートをしてみませんか?