Porocols
Porocols
typedef enum bit [1:0] {idle = 2'b00, enable = 2'b01, send = 2'b10, comp = 2'b11 }
state_type;
state_type state = idle;
int countc = 0;
int count = 0;
always@(posedge clk)
begin
if(rst == 1'b1) begin
countc <= 0;
sclk <= 1'b0;
end
else begin
if(countc < 50 )
countc <= countc + 1;
else
begin
countc <= 0;
sclk <= ~sclk;
end
end
end
interface spi_if;
logic clk;
logic newd;
logic rst;
logic [11:0] din;
logic sclk;
logic cs;
logic mosi;
endinterface
//////////////////state machine
reg [11:0] temp;
always@(posedge sclk)
begin
if(rst == 1'b1) begin
cs <= 1'b1;
mosi <= 1'b0;
end
else begin
case(state)
idle:
begin
if(newd == 1'b1) begin
state <= send;
temp <= din;
cs <= 1'b0;
end
else begin
state <= idle;
temp <= 8'h00;
end
end
send : begin
if(count <= 11) begin
mosi <= temp[count]; /////sending lsb first
count <= count + 1;
end
else
begin
count <= 0;
state <= idle;
cs <= 1'b1;
mosi <= 1'b0;
end end
endcase
end
end
endmodule
///////////////////////////
Testbench Code:
////////////////Transaction Class
class transaction;
////////////////Generator Class
class generator;
transaction tr;
mailbox #(transaction) mbx;
event done;
int count = 0;
event drvnext;
event sconext;
task run();
repeat(count) begin
assert(tr.randomize) else $error("[GEN] :Randomization Failed");
mbx.put(tr.copy);
tr.display("GEN");
@(drvnext);
@(sconext);
end
-> done;
endtask
endclass
//DRIVER
class driver;
virtual spi_if vif;
transaction tr;
mailbox #(transaction) mbx;
mailbox #(bit [11:0]) mbxds;
event drvnext;
task reset();
vif.rst <= 1'b1;
vif.cs <= 1'b1;
vif.newd <= 1'b0;
vif.din <= 1'b0;
vif.mosi <= 1'b0;
repeat(10) @(posedge vif.clk);
vif.rst <= 1'b0;
repeat(5) @(posedge vif.clk);
$display("[DRV] : RESET DONE");
endtask
task run();
forever begin
mbx.get(tr);
@(posedge vif.sclk);
vif.newd <= 1'b1;
vif.din <= tr.din;
mbxds.put(tr.din);
@(posedge vif.sclk);
vif.newd <= 1'b0;
wait(vif.cs == 1'b1);
$display("[DRV] : DATA SENT TO DAC : %0d",tr.din);
->drvnext;
end
endtask
endclass
////MONITOR
class monitor;
transaction tr;
mailbox #(bit [11:0]) mbx;
bit [11:0] srx; //////send
virtual spi_if vif;
function new(mailbox #(bit [11:0]) mbx);
this.mbx = mbx;
endfunction
task run();
forever begin
@(posedge vif.sclk);
wait(vif.cs == 1'b0); ///start of transaction
@(posedge vif.sclk);
endtask
endclass
/*
module tb; gen.count = 20;
generator gen; drv.vif = vif;
driver drv; mon.vif = vif;
monitor mon;
gen.drvnext = next;
event next;
event done; drv.drvnext = next;
event sconext;
gen.sconext = sconext;
mailbox #(transaction) mbx; mon.sconext = sconext;
mailbox #(bit [11:0]) mbxds, mbxms; end
///////////Scoreboard Class
class scoreboard;
mailbox #(bit [11:0]) mbxds, mbxms;
bit [11:0] ds;
bit [11:0] ms;
event sconext;
task run();
forever begin
mbxds.get(ds);
mbxms.get(ms);
$display("[SCO] : DRV : %0d MON : %0d", ds, ms);
if(ds == ms)
$display("[SCO] : DATA MATCHED");
else
$display("[SCO] : DATA MISMATCHED");
->sconext;
end
endtask
endclass
////////////////Environment Class
class environment; gen.drvnext = nextgd;
generator gen; drv.drvnext = nextgd;
driver drv;
monitor mon; endfunction
scoreboard sco;
event nextgd; ///gen -> drv task pre_test();
event nextgs; /// gen -> sco drv.reset();
mailbox #(transaction) mbxgd; ///gen – endtask
drv
mailbox #(bit [11:0]) mbxds; /// drv - task test();
mon fork
mailbox #(bit [11:0]) mbxms; /// mon - gen.run();
sco drv.run();
virtual spi_if vif; mon.run();
sco.run();
function new(virtual spi_if vif); join_any
mbxgd = new(); endtask
mbxms = new();
mbxds = new(); task post_test();
gen = new(mbxgd); wait(gen.done.triggered);
drv = new(mbxds,mbxgd); $finish();
mon = new(mbxms); endtask
sco = new(mbxds, mbxms);
task run();
this.vif = vif; pre_test();
drv.vif = this.vif; test();
mon.vif = this.vif; post_test();
endtask
gen.sconext = nextgs; endclass
sco.sconext = nextgs;
////////////////Testbench Top
module tb;
spi_if vif();
spi dut(vif.clk,vif.newd,vif.rst,vif.din,vif.sclk,vif.cs,vif.mosi);
initial begin
vif.clk <= 0;
end
always #10 vif.clk <= ~vif.clk;
environment env;
initial begin
env = new(vif);
env.gen.count = 20;
env.run();
end
initial begin
$dumpfile("dump.vcd");
$dumpvars;
End
endmodule