Free Online Training Events
Free Technical Resources
Interfaces are a major new construct in SystemVerilog, created specifically to encapsulate the communication between blocks, allowing a smooth refinement from abstract system-level through successive steps down to lower RTL and structural levels of the design. Interfaces also facilitate design re-use. Interfaces are hierarchical structures that can contain other interfaces.
// Interface definition
interface Bus;
logic [7:0] Addr, Data;
logic RWn;
endinterface
// Using the interface
module TestRAM;
Bus TheBus(); // Instance the interface
logic[7:0] mem[0:7];
RAM TheRAM (.MemBus(TheBus)); // Connect it
initial
begin
TheBus.RWn = 0; // Drive and monitor the bus
TheBus.Addr = 0;
for (int I=0; I<7; I++)
TheBus.Addr = TheBus.Addr + 1;
TheBus.RWn = 1;
TheBus.Data = mem[0];
end
endmodule
module RAM (Bus MemBus);
logic [7:0] mem[0:255];
always @*
if (MemBus.RWn)
MemBus.Data = mem[MemBus.Addr];
else
mem[MemBus.Addr] = MemBus.Data;
endmodule
interface ClockedBus (input Clk);
logic[7:0] Addr, Data;
logic RWn;
endinterface
module RAM (ClockedBus Bus);
always @(posedge Bus.Clk)
if (Bus.RWn)
Bus.Data = mem[Bus.Addr];
else
mem[Bus.Addr] = Bus.Data;
endmodule
// Using the interface
module Top;
reg Clock;
// Instance the interface with an input, using named connection
ClockedBus TheBus (.Clk(Clock));
RAM TheRAM (.Bus(TheBus));
...
endmodule
interface Channel #(parameter N = 0)
(input bit Clock, bit Ack, bit Sig);
bit Buff[N-1:0];
initial
for (int i = 0; i < N; i++)
Buff[i] = 0;
always @ (posedge Clock)
if(Ack = 1)
Sig = Buff[N-1];
else
Sig = 0;
endinterface
// Using the interface
module Top;
bit Clock, Ack, Sig;
// Instance the interface. The parameter N is set to 7using named
// connection while the ports are connected using implicit connection
Channel #(.N(7)) TheCh (.*);
TX TheTx (.Ch(TheCh));
...
endmodule
interface MSBus (input Clk);
logic [7:0] Addr, Data;
logic RWn;
modport Slave (input Addr, inout Data);
endinterface
module TestRAM;
logic Clk;
MSBus TheBus(.Clk(Clk));
RAM TheRAM (.MemBus(TheBus.Slave));
...
endmodule
module RAM (MSBus.Slave MemBus);
// MemBus.Addr is an input of RAM
endmodule
interface MSBus (input Clk);
logic [7:0] Addr, Data;
logic RWn;
task MasterWrite (input logic [7:0] waddr,
input logic [7:0] wdata);
Addr = waddr;
Data = wdata;
RWn = 0;
#10ns RWn = 1;
Data = 'z;
endtask
task MasterRead (input logic [7:0] raddr,
output logic [7:0] rdata);
Addr = raddr;
RWn = 1;
#10ns rdata = Data;
endtask
endinterface
module TestRAM;
logic Clk;
logic [7:0] data;
MSBus TheBus(.Clk(Clk));
RAM TheRAM (.MemBus(TheBus));
initial
begin
// Write to the RAM
for (int i = 0; i<256; i++)
TheBus.MasterWrite(i[7:0],i[7:0]);
// Read from the RAM
for (int i = 0; i<256; i++)
begin
TheBus.MasterRead(i[7:0],data);
ReadCheck : assert (data === i[7:0])
else $error("memory read error");
end
end
endmodule