Interface ve Modport
Gün 5: Arayüzler, Assertion ve Coverage | Sinyal gruplama, erişim yönü tanımlama, master/slave/monitor
Kaynak Kod
// =============================================================================
// GUN 5 - Konu 1: Interface Kavrami ve Modports
// =============================================================================
// Interface tanimi: Sinyalleri gruplar
interface bus_if(input logic clk);
logic rst_n;
logic valid;
logic ready;
logic rw; // 0=read, 1=write
logic [7:0] addr;
logic [31:0] wdata;
logic [31:0] rdata;
logic resp; // 0=OK, 1=ERROR
// Modport: Her bilesenin sinyallere erisim yonunu tanimlar
modport master (
input clk, rst_n, ready, rdata, resp,
output valid, rw, addr, wdata
);
modport slave (
input clk, rst_n, valid, rw, addr, wdata,
output ready, rdata, resp
);
modport monitor (
input clk, rst_n, valid, ready, rw, addr, wdata, rdata, resp
);
endinterface
// Master modulu
module bus_master(bus_if.master bus);
int txn_count = 0;
task write(input logic [7:0] address, input logic [31:0] data);
@(posedge bus.clk);
bus.valid <= 1;
bus.rw <= 1;
bus.addr <= address;
bus.wdata <= data;
@(posedge bus.clk);
wait(bus.ready);
bus.valid <= 0;
txn_count++;
$display(" [%0t][Master] WRITE: Addr=0x%02h, Data=0x%08h", $time, address, data);
endtask
task read(input logic [7:0] address, output logic [31:0] data);
@(posedge bus.clk);
bus.valid <= 1;
bus.rw <= 0;
bus.addr <= address;
@(posedge bus.clk);
wait(bus.ready);
data = bus.rdata;
bus.valid <= 0;
txn_count++;
$display(" [%0t][Master] READ: Addr=0x%02h, Data=0x%08h", $time, address, data);
endtask
endmodule
// Slave modulu
module bus_slave(bus_if.slave bus);
logic [31:0] memory [256];
always @(posedge bus.clk or negedge bus.rst_n) begin
if (!bus.rst_n) begin
bus.ready <= 0;
bus.rdata <= 0;
bus.resp <= 0;
end else if (bus.valid) begin
#2;
if (bus.rw) begin // Write
memory[bus.addr] <= bus.wdata;
bus.resp <= 0;
end else begin // Read
bus.rdata <= memory[bus.addr];
bus.resp <= 0;
end
bus.ready <= 1;
@(posedge bus.clk);
bus.ready <= 0;
end
end
endmodule
// Monitor modulu
module bus_monitor(bus_if.monitor bus);
int total_reads = 0, total_writes = 0;
always @(posedge bus.clk) begin
if (bus.valid && bus.ready) begin
if (bus.rw) begin
total_writes++;
$display(" [%0t][Monitor] WRITE gozlemlendi: Addr=0x%02h", $time, bus.addr);
end else begin
total_reads++;
$display(" [%0t][Monitor] READ gozlemlendi: Addr=0x%02h", $time, bus.addr);
end
end
end
endmodule
// Top-level
module interface_modport;
logic clk = 0;
always #5 clk = ~clk;
// Interface ornekleme
bus_if bif(clk);
// Modul baglantilari
bus_master mst(bif);
bus_slave slv(bif);
bus_monitor mon(bif);
logic [31:0] read_data;
initial begin
$display("=== Interface ve Modport ===\n");
// Reset
bif.rst_n = 0;
#20;
bif.rst_n = 1;
#10;
// Yazma islemleri
mst.write(8'h10, 32'hDEAD_BEEF);
mst.write(8'h20, 32'hCAFE_BABE);
mst.write(8'h30, 32'h1234_5678);
#20;
// Okuma islemleri
mst.read(8'h10, read_data);
mst.read(8'h20, read_data);
#50;
$display("\n --- Istatistikler ---");
$display(" Master islem sayisi: %0d", mst.txn_count);
$display(" Monitor - Read: %0d, Write: %0d", mon.total_reads, mon.total_writes);
$display("\n=== Interface ve Modport Sonu ===");
$finish;
end
endmodule