![]() |
1 |
BSV(Bluespec SystemVerilog) (4) |
![]() |
モジュールインタフェースの引出し
Vivadoにより合成をかける場合に、前稿のモジュールmkFibOneのように出力の信号が無いと、何もしないものとみなされ最適化され、全てのロジックが削除されてしまいます。従って、mkFibOneモジュールに、計算した値を出力するインタフェースを設ける修正を行います。合わせて、テストベンチ記述がモジュール内に混入されていたものを、テストベンチに移します。
BSVではモジュールとインタフェースは明確に分離されています。修正したファイル(ファイル名FibOne.bsv)を示します。前述のように\$displayや\$finishはテストベンチへ移しました。
モジュールファイル:FibOne.bsv
interface Fib_ifc;
method int read();
endinterface
(* synthesize, always_ready, always_enabled *)
module mkFibOne(Fib_ifc);
Reg#(int) this_fib <- mkReg(0);
Reg#(int) next_fib <- mkReg(1);
rule fib;
this_fib <= next_fib;
next_fib <= this_fib + next_fib; // note that this uses stale this_fib
endrule: fib
method int read();
return this_fib;
endmethod
endmodule: mkFibOne
ここで、
Reg#(int) this_fib <- mkReg(0);
これは前稿で2行になっていたレジスタのインスタンシエーションの省略記法で、
Interface_type identifier <- module_name;
という文法を持ちます。この意味は、「Interface_typeの型を持つインタフェースを提供するモジュールmodule_nameをインスタンス化し、インタフェースのハンドルidentifierを取得する」ということです。
Verilogの生成
BSVプログラムに対して、bscによりverilog生成を実行すれば、
$ bsc -verilog FibOne.bsv
Verilog file created: mkFibOne.v
合成されたverilog(ファイル名mkFibOne.v)は以下のようになります。
モジュールファイル:mkFibOne.v
//
// Generated by Bluespec Compiler (build 38534dc)
//
// On Wed Mar 25 09:12:14 JST 2020
//
//
// Ports:
// Name I/O size props
// read O 32 reg
// CLK I 1 clock
// RST_N I 1 reset
//
// No combinational paths from inputs to outputs
//
//
`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
`endif
`ifdef BSV_POSITIVE_RESET
`define BSV_RESET_VALUE 1'b1
`define BSV_RESET_EDGE posedge
`else
`define BSV_RESET_VALUE 1'b0
`define BSV_RESET_EDGE negedge
`endif
module mkFibOne(CLK,
RST_N,
read);
input CLK;
input RST_N;
// value method read
output [31 : 0] read;
// signals for module outputs
wire [31 : 0] read;
// register next_fib
reg [31 : 0] next_fib;
wire [31 : 0] next_fib$D_IN;
wire next_fib$EN;
// register this_fib
reg [31 : 0] this_fib;
wire [31 : 0] this_fib$D_IN;
wire this_fib$EN;
// value method read
assign read = this_fib ;
// register next_fib
assign next_fib$D_IN = this_fib + next_fib ;
assign next_fib$EN = 1'd1 ;
// register this_fib
assign this_fib$D_IN = next_fib ;
assign this_fib$EN = 1'd1 ;
// handling of inlined registers
always@(posedge CLK)
begin
if (RST_N == `BSV_RESET_VALUE)
begin
next_fib <= `BSV_ASSIGNMENT_DELAY 32'd1;
this_fib <= `BSV_ASSIGNMENT_DELAY 32'd0;
end
else
begin
if (next_fib$EN) next_fib <= `BSV_ASSIGNMENT_DELAY next_fib$D_IN;
if (this_fib$EN) this_fib <= `BSV_ASSIGNMENT_DELAY this_fib$D_IN;
end
end
// synopsys translate_off
`ifdef BSV_NO_INITIAL_BLOCKS
`else // not BSV_NO_INITIAL_BLOCKS
initial
begin
next_fib = 32'hAAAAAAAA;
this_fib = 32'hAAAAAAAA;
end
`endif // BSV_NO_INITIAL_BLOCKS
// synopsys translate_on
endmodule // mkFibOne
テストベンチ
修正したVerilogテストベンチtbmkFibOne.vを以下に示します。前稿ではクロックとリセットを下位モジュールに供給するだけだったのを、データ表示とシミュレーションの停止機能をモジュールから移動しています。
テストベンチファイル:tbmkFibOne.v
`timescale 1ns/1ps
module tb_mkFibOne;
/*AUTOREGINPUT*/
// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)
reg CLK; // To mkFibOne of mkFibOne.v
reg RST_N; // To mkFibOne of mkFibOne.v
// End of automatics
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [31:0] read; // From mkFibOne of mkFibOne.v
// End of automatics
mkFibOne mkFibOne (/*AUTOINST*/
// Outputs
.read (read[31:0]),
// Inputs
.CLK (CLK),
.RST_N (RST_N));
initial begin
RST_N = 1'b0;
#30;
RST_N = 1'b1;
forever begin
if (CLK) $display("%0d", read);
if (read > 10000) $finish;
#10;
end
end
initial begin
CLK = 1'b0;
forever begin
#5 CLK = ~CLK;
end
end
initial begin
$dumpfile("tbmkFibOne.vcd");
$dumpvars(0,mkFibOne);
end
endmodule
Verilogシミュレーション
準備ができたので、iverilogによるverilogシミュレーションを実行します。
$ iverilog tbmkFibOne.v mkFibOne.v -o mkFibOne.exev
$ ./mkFibOne.exev
VCD info: dumpfile tbmkFibOne.vcd opened for output.
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
前稿と同様の結果になりました。
Vivadoによるシミュレーション
VivadoのIPインテグレータにより、生成されたverilogを取り込み、IPインテグレータ上で最上位のテストベンチを作成します。先に作成したテストベンチ(ファイル名tbmkFibOne.v)はシミュレーション用で合成できないため、IPインテグレータで上位を作成します。図の左からZynqのPS部、クロックリセット生成、対象回路となっています。
![図%%.1](/images/fig231-1.png)
vivado上でbehaviorシミュレーションを実施した結果です。iverilogの結果と同一になっています。
![図%%.2](/images/fig231-2.png)