Clocking Block
Gün 5: Arayüzler, Assertion ve Coverage | Zamanlama blokları, setup/hold yönetimi, APB protokolü
Kaynak Kod
// =============================================================================
// GUN 5 - Konu 2: Clocking Blocks (Zamanlama Bloklari)
// =============================================================================
interface apb_if(input logic clk);
logic psel;
logic penable;
logic pwrite;
logic [7:0] paddr;
logic [31:0] pwdata;
logic [31:0] prdata;
logic pready;
// Clocking Block: Testbench zamanlama yonetimi
// Sinyallerin ornekleme ve surme zamanlarini tanimlar
clocking cb @(posedge clk);
default input #1step output #1; // Setup/hold zamanlari
output psel;
output penable;
output pwrite;
output paddr;
output pwdata;
input prdata;
input pready;
endclocking
// Modport'lar clocking block referansi ile
modport tb (clocking cb, input clk);
modport dut (
input clk, psel, penable, pwrite, paddr, pwdata,
output prdata, pready
);
endinterface
// Basit APB Slave (DUT rolunde)
module apb_slave(apb_if.dut apb);
logic [31:0] reg_file [256];
always @(posedge apb.clk) begin
apb.pready <= 0;
if (apb.psel && apb.penable) begin
if (apb.pwrite)
reg_file[apb.paddr] <= apb.pwdata;
else
apb.prdata <= reg_file[apb.paddr];
apb.pready <= 1;
end
end
endmodule
module clocking_block;
logic clk = 0;
always #5 clk = ~clk;
apb_if aif(clk);
apb_slave dut(aif);
// Clocking block ile surme
task apb_write(input logic [7:0] addr, input logic [31:0] data);
// Setup phase
aif.cb.psel <= 1;
aif.cb.pwrite <= 1;
aif.cb.paddr <= addr;
aif.cb.pwdata <= data;
aif.cb.penable <= 0;
@(aif.cb);
// Access phase
aif.cb.penable <= 1;
@(aif.cb);
wait(aif.cb.pready);
// Idle
aif.cb.psel <= 0;
aif.cb.penable <= 0;
$display(" [%0t] APB Write: Addr=0x%02h, Data=0x%08h", $time, addr, data);
endtask
task apb_read(input logic [7:0] addr, output logic [31:0] data);
aif.cb.psel <= 1;
aif.cb.pwrite <= 0;
aif.cb.paddr <= addr;
aif.cb.penable <= 0;
@(aif.cb);
aif.cb.penable <= 1;
@(aif.cb);
wait(aif.cb.pready);
data = aif.cb.prdata;
aif.cb.psel <= 0;
aif.cb.penable <= 0;
$display(" [%0t] APB Read: Addr=0x%02h, Data=0x%08h", $time, addr, data);
endtask
initial begin
logic [31:0] rdata;
$display("=== Clocking Block ===\n");
// Baslangic degerleri
aif.cb.psel <= 0;
aif.cb.penable <= 0;
#20;
// Yazma
apb_write(8'h00, 32'hAAAA_BBBB);
apb_write(8'h04, 32'hCCCC_DDDD);
// Okuma
apb_read(8'h00, rdata);
apb_read(8'h04, rdata);
#50;
$display("\n=== Clocking Block Sonu ===");
$finish;
end
endmodule