2016-07-11 6 views
0

Ich habe ein System Verilog-SchnittstelleWie binden Sie eine Schnittstelle mit dem System-Verilog-Modul?

interface add_sub_if(
input bit clk, 
input [7:0] a, 
input [7:0] b, 
input  doAdd, 
input [8:0] result 
); 

    clocking dut_cb @(posedge clk); 
    output a; 
    output b; 
    output doAdd; 
    input  result; 
    endclocking // cb 

    modport dut(clocking dut_cb); 

endinterface: add_sub_if 

Und ich habe ein SV-Modul, das diese Schnittstelle

module dummy(add_sub_if.dut _if); 
    .... 
endmodule: dummy 

verwendet Was der ideale Weg ist, dies in meinem TB anschließen?

Wenn ich die Schnittstelle instanziiere, muss ich Drähte erstellen.

Wenn ich bind verwende, dann muss ich auch ein Port-Mapping der einzelnen Signale machen, das ist besser als eine Schnittstelle.

Eine weitere Frage ist, wie man eine solche Schnittstelle einer anderen Schnittstelle zuweist?

Vielen Dank im Voraus,

Rajdeep

Antwort

2

Sie können ein einfaches Beispiel einer Schnittstelle Definition und Verwendung in der IEEE Std 1800-2012 Abschnitt 3.5 (Interfaces) finden. Es zeigt, wie man die Schnittstelle definiert und an das Design anschließt (so wie du es bereits gemacht hast). Es zeigt auch, wie die Schnittstelle (und verbunden) instanziiert werden kann in einem Top-Level-Modul/Wrapper (I den Code direkt aus der Spezifikation für Ihre Bequemlichkeit kopiert):

interface simple_bus(input logic clk); // Define the interface 
    logic req, gnt; 
    logic [7:0] addr, data; 
    logic [1:0] mode; 
    logic start, rdy; 
endinterface: simple_bus 

module memMod(simple_bus a); // simple_bus interface port 
    logic avail; 
    // When memMod is instantiated in module top, a.req is the req 
    // signal in the sb_intf instance of the 'simple_bus' interface 
    always @(posedge clk) a.gnt <= a.req & avail; 
endmodule 

module cpuMod(simple_bus b); // simple_bus interface port 
    ... 
endmodule 

module top; 
    logic clk = 0; 

    simple_bus sb_intf(.clk(clk)); // Instantiate the interface 

    memMod mem(.a(sb_intf)); // Connect interface to module instance 
    cpuMod cpu(.b(sb_intf)); // Connect interface to module instance 

endmodule 

Sobald Sie die Schnittstelle angeschlossen haben, dann können Sie alle Signale von einem Testfall-Programm ansteuern/abfragen (denken Sie daran, dass Sie die Schnittstelle dorthin übergeben müssen). In diesem Fall wäre es so etwas wie sein:

program testcase(simple_bus tb_if); 

    initial begin 
    tb_if.mode <= 0; 
    repeat(3) #20 tb_if.req <= 1'b1; 
    [...] 
    $finish; 
    end 

endprogram 

Für ein reales Beispiel, können Sie die source code of a UVM testbench überprüfen, die auf meiner GitHub Seite verfügbar ist. Der Schnittstellenanschluss erfolgt in der Datei xge_test_top.sv.

+0

Hallo AndresM, Dies ist, wo meine Verwirrung ist, anstelle der Schnittstelle, die Sie haben, wenn die Schnittstelle wie folgt definiert ist: Schnittstelle simple_bus (Eingangslogik clk // Definieren Sie die Schnittstelle Eingangslogik req, Eingangslogik GNT , Eingangslogik [7: 0] Adr, Eingangslogikdaten, Eingangslogik [1: 0] -Modus, Ausgangslogikstart, Ausgang rdy); endinterface: simple_bus Dann wie sollte ich diese Schnittstelle anschließen? Ich konnte kein gutes Beispiel dafür finden. – justrajdeep

+0

Ich habe einen Code in meine Antwort eingefügt, damit Sie sehen können, wie Sie Signale von einem Testfallprogramm steuern. Bitte schau es dir an - das sollte hoffentlich deine Fragen klären. – AndresM

1

Sie können die Schnittstelle im System Verilog-Modul binden.

Hier bietet ich Beispielcode mit der Hilfe, die Sie verstehen können, wie Schnittstelle in System Verilog-Modul und mit dut zu binden.

Hier bietet ich Verilog-Modul und System Verilog-Modul. Der Hauptteil des Codes ist eine Schnittstelle, von der Verilog- und System-Verilog-Modul verbunden sind.

Verilog Modulcode (dut):

module dff(qn,d,clk,reset); 

output qn; 
input d,clk,reset; 
reg qn; 

[email protected](posedge clk,negedge reset) 

begin 

if (!reset) 

begin 
qn=1'bx; 
end 

else if (d==0) 
begin 
qn=0; 
end 
else if (d==1) 
begin 
qn=1; 
end 

end 

endmodule 

Systemverilog Modulcode (Testbank):

interface melay_intf(input bit clk); 

    logic o,clk,rst,i; 

    clocking [email protected](posedge clk); 
    input o; 
    output i,rst; 
    endclocking 

endinterface 

module top; 
    bit clk; 

    always 
    #1 clk = ~clk; 

    melay_intf i1(clk); 

    dff d1(.o(i1.o),.clk(i1.clk),.rst(i1.rst),.i(i1.i)); 

    melay_tes(i1.tes); 

endmodule 

program melay_tes(melay_intf i1); 

    initial 
    #100 $finish; 

    initial 
    begin 
     i1.rst <= 0; 
     #4 i1.rst <= 1; 
     #4 i1.rst <= 0; 

     i1.i = 1; 
      #2 i1.i = 0; 
      #2 i1.i = 1; 
      #2 i1.i = 0; 
      #2 i1.i = 1; 
      #2 i1.i = 0; 


     repeat(10) 
     begin 
      i1.i = 1; 
      #2 i1.i = $urandom_range(0,1); 
     end 
    end 

    initial 
    $monitor("output = %d clk = %d rst = %d i = %d",i1.o,i1.clk,i1.rst,i1.i); 
    initial 
    begin 
     $dumpfile("mem.vcd"); 
     $dumpvars(); 

    end 
endprogram 

Hier wichtiger Teil Schnittstelle ist und in ihm I verwendet Taktungsblock für Synchronisationszweck. Hier takten c1 @ (posedge clk); also alle Signale, die innerhalb des Taktblocks erwähnt werden, die i, o, rst sind. Alle dieses Signal ändern seinen Wert an jeder Stelle des clk-Signals.

Hier dff d1 (.o (i1.o), clk (i1.clk), zuerst (i1.rst), i (i1.i)); Wichtig ist, dass Sie im obersten Modul eine Verbindung zwischen Verilog-Signalen und System-Verilog-Signalen hergestellt haben.

Sie können den Namen des Verilog-Moduls "dff" finden. Ich nahm die Instanz von dff Verilog-Modul und stellte die Verbindung her. Hier sind i1.o, i1.clk, i1.rst, i1.i System-Verilog-Signale, die mit o, clk, i, Signalen von Verilog-Modul mit Punktkonvention verbunden sind.

+0

Hallo Ashutosh, die Schnittstelle sollte nicht eine "Uhr" als "Logik" haben. Ich konnte 'melay_tes (i1.tes);' was ist 'tes' nicht finden – justrajdeep

+0

Tatsächlich gibt es einen Fehler Code zu aktualisieren Entschuldigung dafür. Ich werde Ihnen einen genauen Code zur Korrelation geben. Sowohl Prüfstand als auch Dut ist anders. –

2

Hier ist fsm dut mit Testbench.

Dieser fsm dut führt den Zustandsübergang 1 - 0 - 1 - 0 der Reihe nach durch.

Der Prüfstand überprüft, ob dut ordnungsgemäß funktioniert oder nicht.

Verilog-Modul-Code (dut):

module melay_fsm(o,clk,rst,i); 
output o; 
input i,clk,rst; 
reg o; 
reg [1:0]state; 
// [1:0]state; 
[email protected](posedge clk,posedge rst) 
begin 
if(rst) 
begin 
state <=2'b00; 
end 
else 
begin 
case(state) 
2'b00: 
begin 
if(i) 
state<=2'b01; 
else 
state<=2'b00; 
end 

2'b01: 
begin 
if(!i) 
state<=2'b10; 
else 
state<=2'b01; 
end 

2'b10: 
begin 
if(i) 
state<=2'b11; 
else 
state<=2'b00; 
end 

2'b11: 
begin 
if(!i) 
state<=2'b00; 
else 
state<=2'b01; 
end 
endcase 
end 
end 

[email protected](posedge clk,negedge rst) 
begin 
if(rst) 
o<=1'b0; 
else if(state==2'b11 && i==0) 
o<=1'b1; 
else 
o<=1'b0; 
end 
endmodule 

Systemverilog Modulcode (Testbench):

interface melay_intf(input bit clk); 

    logic o,rst,i; 
    wire clk; 

    clocking [email protected](posedge clk); 
    input o; 
    output i,rst; 
    endclocking 

    modport tes(clocking c1); 

endinterface 

    module top; 
     bit clk; 

     always 
     #1 clk = ~clk; 

     melay_intf i1(clk); 

     melay_fsm a1(.o(i1.o),.clk(i1.clk),.rst(i1.rst),.i(i1.i)); 

     melay_tes(i1); 

    endmodule 

    program melay_tes(melay_intf i1); 

     initial 
     #100 $finish; 

     initial 
     begin 
      i1.rst <= 0; 
      #4 i1.rst <= 1; 
      #4 i1.rst <= 0; 

      i1.i = 1; 
       #2 i1.i = 0; 
       #2 i1.i = 1; 
       #2 i1.i = 0; 
       #2 i1.i = 1; 
       #2 i1.i = 0; 


      repeat(10) 
      begin 
       i1.i = 1; 
       #2 i1.i = $urandom_range(0,1); 
      end 
     end 

     initial 
     $monitor("output = %d clk = %d rst = %d i = %d",i1.o,i1.clk,i1.rst,i1.i); 
     initial 
     begin 
      $dumpfile("mem.vcd"); 
      $dumpvars(); 

     end 
    endprogram 

Wichtig ist hier zu notieren ist Verbindung von Signalen in Top-Modul .

melay_fsm a1 (.o (i1.o), clk (i1.clk), zuerst (i1.rst), i (i1.i));

Bitte beachten Sie richtig, wie ich Schnittstelle mit Testbench und dut verbinde. Bitte beachten Sie folgende Punkte.

Ich definiere Schnittstelle mit allen duts Signalen.

Ich nahm Instanz (i1) der Schnittstelle (melay_intf) im obersten Modul.

Ich nahm Instanz (a1) von dut (melay_fsm) im obersten Modul.

beobachtet Jetzt melay_fsm a1 (.o (i1.o) ,. clk (i1.clk) ,. rst (i1.rst) ,. i (i1.i))

All DUTs Signale sind mit der Schnittstelle verbunden.

Ich übergeben Instanz der Schnittstelle (i1) in Testbench. melay_tes (i1)

So kann Testbench auf Schnittstellensignale zugreifen und Schnittstellensignale werden mit duts Signalen verbunden.

Jetzt können Sie mit Hilfe der Schnittstelle auf duts Signale in Ihrem Prüfstand zugreifen.

Ich denke jetzt können Sie richtigen Fluss verstehen.

Bitte stellen Sie die Frage, wenn Sie irgendwelche Zweifel haben.

+0

Danke Asutosh, das erklärt. – justrajdeep

+0

Tatsächlich gibt es zwei Methoden, um die Signale zu verbinden. (1) Verbunden durch Port-Reihenfolge (implizit) (2) Module, die durch Namen verbunden sind, was hier erläutert wird melay_fsm a1 (.o (i1.o), clk (i1.clk), rst (i1.rst), i (i1.i)). Dies ist eine bevorzugte Methode. Für (1) verbunden durch Port-Reihenfolge (implizit) sollten Sie jedes Signal korrekt zuordnen. So ist es keine bevorzugte Methode. –

Verwandte Themen