インターフェース
SystemVerilogは、インターフェースを使用してブロック間の通信をモデル化します。インターフェースは、インテリジェント接続のバンドルと見なすことができます。インターフェースには、2つ以上のブロック間の通信を接続および同期する機能が含まれ、設計ブロックとテストプラットフォームを接続します。
クロックとリセットは、インターフェイスステートメントの一部にすることも、独立した内部ポートにすることもできます。
インターフェイスを使用する利点:
(1)インターフェイスの設計と再利用が簡単:設計に同じ通信プロトコルを持つバス接続のセットが複数ある場合は、AXI4バスの複数のセットなど、インターフェイスを考慮する必要があります。 AXISバス;
(2)新しい信号を追加する必要がある場合、他のモジュールではなく、インターフェイスで一度だけ宣言する必要があります。
プログラム例
次のプログラムは、インターフェイスとタスクの使用方法を示しています。インターフェイスはtbで定義されており、インターフェイスの定義は実際のプロジェクトの別の.svファイルに配置できます。
adder.v
`timescale 1ns / 1ps
// Company:
// Engineer:
//
// Create Date: 11/27/2020
// Author Name: Sniper
// Module Name: adder
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module adder(
input clk,
input rst_n,
input [7:0] a,
input [7:0] b,
input write_en,
output reg [8:0] p,
output reg out_en
);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
p <= 0;
out_en <= 0;
end
else
begin
if(write_en)
begin
p <= a + b;
out_en <= 1;
end
else
out_en <= 0;
end
end
endmodule
tb_adder.sv
`timescale 1ns / 1ps
// Company:
// Engineer:
//
// Create Date: 11/27/2020
// Author Name: Sniper
// Module Name: tb_adder
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
interface adderInterface(input bit clk, input bit rst_n);
//write in
logic [7:0] a;
logic [7:0] b;
logic write_en;
//output
logic [8:0] p;
logic out_en;
//task
task init;
begin
a = 0;
b = 0;
write_en = 0;
end
endtask
task write(input [7:0] data_a, input [7:0] data_b);
begin
@(posedge clk);
write_en <= 0;
a <= data_a;
b <= data_b;
@(posedge clk);
write_en <= 1;
@(posedge clk);
write_en <= 0;
end
endtask
task catch;
begin
@(posedge clk);
if(out_en)
begin
$display("Catch one output: %0d ", p);
end
end
endtask
endinterface
module tb_adder;
//system signals
reg clk;
reg rst_n;
//interface
adderInterface adder_if(clk, rst_n);
initial
begin
clk = 0;
rst_n = 0;
adder_if.init;
repeat(10) @(posedge clk);
rst_n <= 1;
for(int i=0;i<8;i++)
adder_if.write(2,i);
end
initial
begin
forever adder_if.catch;
end
//clock
always #5 clk = ~clk;
//DUT
adder DUT
(
.clk(clk),
.rst_n(rst_n),
.a(adder_if.a),
.b(adder_if.b),
.write_en(adder_if.write_en),
.p(adder_if.p),
.out_en(adder_if.out_en)
);
initial
begin
$dumpfile("curve.vcd");
$dumpvars(0,DUT);
end
initial #1000 $finish;
endmodule
運転結果
[IC@IC sim]$ vcs -R -sverilog ../rtl/adder.v ../bench/tb_adder.sv -l run.log
...
Catch one output: 2
Catch one output: 3
Catch one output: 4
Catch one output: 5
Catch one output: 6
Catch one output: 7
Catch one output: 8
Catch one output: 9
$finish called from file "../bench/tb_adder.sv", line 123.
$finish at simulation time 1000000
V C S S i m u l a t i o n R e p o r t
Time: 1000000 ps
CPU Time: 0.140 seconds; Data structure size: 0.0Mb
...
[IC@IC sim]$