0% found this document useful (0 votes)
24 views5 pages

Porocols

The document describes a testbench for testing a SPI module. It defines classes for transactions, driving and monitoring the interface, and scoring the results. There are classes for a generator, driver, monitor and scoreboard. An environment class integrates these components and runs the test.

Uploaded by

manu tyagi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views5 pages

Porocols

The document describes a testbench for testing a SPI module. It defines classes for transactions, driving and monitoring the interface, and scoring the results. There are classes for a generator, driver, monitor and scoreboard. An environment class integrates these components and runs the test.

Uploaded by

manu tyagi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

module spi(

input clk, newd,rst,


input [11:0] din,
output reg sclk,cs,mosi
);

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

default : state <= idle;

endcase
end
end
endmodule
///////////////////////////
Testbench Code:
////////////////Transaction Class
class transaction;

rand bit newd;


rand bit [11:0] din;
bit cs;
bit mosi;

function void display (input string tag);


$display("[%0s] : DATA_NEW : %0b DIN : %0d CS : %b MOSI : %0b ", tag, newd, din, cs, mosi);
endfunction

function transaction copy();


copy = new();
copy.newd = this.newd;
copy.din = this.din;
copy.cs = this.cs;
copy.mosi = this.mosi;
endfunction
endclass

////////////////Generator Class
class generator;

transaction tr;
mailbox #(transaction) mbx;
event done;
int count = 0;
event drvnext;
event sconext;

function new(mailbox #(transaction) mbx);


this.mbx = mbx;
tr = new();
endfunction

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;

bit [11:0] din;


function new(mailbox #(bit [11:0]) mbxds, mailbox #(transaction) mbx);
this.mbx = mbx;
this.mbxds = mbxds;
endfunction

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);

for(int i= 0; i<= 11; i++) begin


@(posedge vif.sclk);
srx[i] = vif.mosi;
end
wait(vif.cs == 1'b1); ///end of transaction

$display("[MON] : DATA SENT : %0d", srx);


mbx.put(srx);
end

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

spi_if vif(); initial begin


fork
spi drv.reset();
dut(vif.clk,vif.newd,vif.rst,vif.din,vif.scl gen.run();
k,vif.cs,vif.mosi); drv.run();
mon.run();
initial begin join_none
vif.clk <= 0; wait(gen.done.triggered);
end $finish();
always #10 vif.clk <= ~vif.clk; end
initial begin initial begin
mbx = new(); $dumpfile("dump.vcd");
mbxds = new(); $dumpvars;
mbxms = new(); end
gen = new(mbx); endmodule
drv = new(mbxds,mbx); */
mon = new(mbxms);

///////////Scoreboard Class
class scoreboard;
mailbox #(bit [11:0]) mbxds, mbxms;
bit [11:0] ds;
bit [11:0] ms;
event sconext;

function new(mailbox #(bit [11:0]) mbxds, mailbox #(bit [11:0]) mbxms);


this.mbxds = mbxds;
this.mbxms = mbxms;
endfunction

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

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy