EDIT:私は以下の方法を試してみました:ロジックの代わりにワイヤにインターフェイスを設定し、ドライバのZを制御から放棄したい他の運転者が引き継ぐことができるように信号を送る。 u_slave_dutが私のインターフェースから駆動されていないのが分かるので、まだ動作しません。何が間違っているかの手がかりは?私の動作例:https://www.edaplayground.com/x/4SSP私のインターフェイスタスクから私のモジュールの内部ワイヤを動かす
いくつかのサブモジュールを持つトップレベルモジュール用のテストベンチを作成しています。インターフェイスをインスタンス化し、サブモジュールの1つに接続したいとします。my_submodule簡単に、私はmy_submoduleピンがトグルされたときに私のインターフェイスピンがトグルするのを見ることができます。これは大きな見通しです。
次に、タスクを使用して自分のインターフェイスからピンを自分自身に切り替えることができると決めました。私はこれが同じバス上の2人のドライバーにつながることを理解しています。だから私にこれをさせる方法はありますか?
edaplaygroundの小さなサンプルを実験用に作成しました。ここで私のタスクからの私の書き込みから実際にu_slave_dutのピンを切り替えることはありません。また、コンパイラからも私には気になる警告は出ません。
私の作業例はここにある:https://www.edaplayground.com/x/5fcP
testbench.sv
`include "my_interface.sv"
module tb;
bit clk = 1'b1;
bit control = 1'b0;
initial begin
forever begin
#5 clk = ~clk;
end
end
my_interface my_vif(clk);
assign my_vif.addr = (control)? tb.u_top.u_slave_dut.i_addr : 'hz;
assign my_vif.wdata = (control)? tb.u_top.u_slave_dut.i_wdata : 'hz;
assign my_vif.write = (control)? tb.u_top.u_slave_dut.i_write : 'hz;
top u_top(.clk(clk));
initial begin
#80 my_vif.master_write_something;
#160 $finish;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule
interface.sv
interface my_interface(input clk);
logic [3:0] addr;
logic write;
logic [3:0] wdata;
logic [3:0] rdata;
logic resp;
clocking master_cb @(posedge clk);
input resp, rdata;
output addr, write, wdata;
endclocking
clocking slave_cb @(posedge clk);
input addr, write, wdata;
output resp, rdata;
endclocking
task master_write_something;
@(master_cb);
master_cb.write <= 1'b1;
@(master_cb);
master_cb.wdata <= 3'b101;
master_cb.addr <= 3'b111;
@(master_cb);
master_cb.write <= 1'b0;
endtask
task slave_write_something;
@(slave_cb);
slave_cb.resp <= 1'b1;
@(slave_cb);
slave_cb.rdata <= 3'b101;
@(slave_cb);
slave_cb.resp <= 1'b0;
slave_cb.rdata <= 3'b000;
endtask
endinterface
design.sv
module slave_dut (
input clk,
input [3:0] i_addr,
input [3:0] i_wdata,
input i_write,
output o_resp,
output [3:0] o_rdata
);
reg o_resp_reg;
reg [3:0] o_rdata_reg;
initial begin
o_resp_reg <= 1'b0;
o_rdata_reg <= 'h0;
end
always @(posedge clk) begin
if (i_write == 1'b1) begin
o_resp_reg <= 1'b1;
o_rdata_reg <= i_wdata;
end
else begin
o_resp_reg <= 1'b0;
o_rdata_reg <= 'h0;
end
end
assign o_resp = o_resp_reg;
assign o_rdata = o_rdata_reg;
endmodule : slave_dut
module master_dut (
input clk,
output [3:0] o_addr,
output [3:0] o_wdata,
output o_write,
input i_resp,
input [3:0] i_rdata
);
reg [3:0] o_addr_reg;
reg [3:0] o_wdata_reg;
reg o_write_reg;
initial begin
o_addr_reg <= 'h0;
o_wdata_reg <= 'h0;
o_write_reg <= 'h0;
repeat (2) @(posedge clk);
o_addr_reg <= 'hF;
o_wdata_reg <= 'hB;
o_write_reg <= 1'b1;
@(posedge clk);
o_addr_reg <= 'h0;
o_wdata_reg <= 'h0;
o_write_reg <= 'h0;
repeat (2) @(posedge clk);
o_addr_reg <= 'h4;
o_wdata_reg <= 'hD;
o_write_reg <= 1'b1;
@(posedge clk);
o_addr_reg <= 'h0;
o_wdata_reg <= 'h0;
o_write_reg <= 'h0;
end
assign o_addr = o_addr_reg;
assign o_wdata = o_wdata_reg;
assign o_write = o_write_reg;
endmodule : master_dut
module top(input clk);
wire [3:0] addr;
wire [3:0] wdata;
wire write;
wire resp;
wire [3:0] rdata;
master_dut u_master_dut (
.clk(clk),
.o_addr(addr),
.o_wdata(wdata),
.o_write(write),
.i_resp(resp),
.i_rdata(rdata)
);
slave_dut u_slave_dut (
.clk(clk),
.i_addr(addr),
.i_wdata(wdata),
.i_write(write),
.o_resp(resp),
.o_rdata(rdata)
);
endmodule
どこが間違っているのですか?
ご回答ありがとうございます。私はその論文を読み、私が理解したことを実装しようとしました:(1)私は論理の代わりにワイヤーにインターフェイスを変更しました。 (2)私はu_master_dutで 'hZ'に信号を送りました。私はまだ、my_interfaceからu_slave_dutの入力を駆動することができないようです。私はここで何が欠けていますか?私はまた、2つの他の質問があります:(3)私は私のインターフェイスでワイヤを駆動する手続き割り当てを使用しています。これはどのように許可されますか? (4)私はu_master_dutの私の例で行ったように、内部ドライバから内部ドライバをアクセスして 'hZ'に設定することはできません。 https://www.edaplayground.com/x/2Y6x – noobuntu
(2)あなたが逃したものを知るために、更新されたコードを見る必要があります。 (3)手順の割り当てではなく、クロッキングがワイヤをブロックすることになります。私の論文とLRMをチェックしてください(4)あなたは 'force/release'を使う必要があります –
https://www.edaplayground.com/x/2Y6x – noobuntu