|
- `timescale 1ns / 1ps
-
- /*
- module tb();
-
- reg presetn = 0;
- reg pclk = 0;
- reg psel = 0;
- reg penable = 0 ;
- reg pwrite = 0;
- reg [31:0] paddr = 0, pwdata = 0;
- wire [31:0] prdata;
- wire pready, pslverr;
-
- apb_ram dut (presetn, pclk, psel, penable, pwrite, paddr, pwdata, prdata, pready, pslverr);
-
- always #10 pclk = ~pclk;
-
- initial begin
- presetn = 0;
- repeat(5) @(posedge pclk);
- presetn = 1;
- psel = 1;
- pwrite = 1;
- paddr = 12;
- pwdata = 35;
- @(posedge pclk);
- penable = 1;
- @(posedge pready);
- psel = 0;
- penable = 0;
- @(posedge pclk);
- psel = 1;
- pwrite = 1'b0;
- paddr = 12;
- pwdata = 35;
- @(posedge pclk);
- penable = 1'b1;
- @(posedge pready);
- psel = 0;
- penable = 0;
- @(posedge pclk);
- psel = 1;
- pwrite = 1;
- paddr = 45;
- pwdata = 35;
- @(posedge pclk);
- penable = 1;
- @(posedge pready);
- psel = 0;
- penable = 0;
- @(posedge pclk);
- psel = 1;
- pwrite = 0;
- paddr = 45;
- pwdata = 35;
- @(posedge pclk);
- penable = 1;
- @(posedge pready);
- @(posedge pclk);
- $stop();
- end
-
-
- endmodule
-
- */
-
- `include "uvm_macros.svh"
- import uvm_pkg::*;
-
-
- ////////////////////////////////////////////////////////////////////////////////////
- class abp_config extends uvm_object; /////configuration of env
- `uvm_object_utils(abp_config)
-
- function new(string name = "abp_config");
- super.new(name);
- endfunction
-
-
-
- uvm_active_passive_enum is_active = UVM_ACTIVE;
-
-
- endclass
-
- ///////////////////////////////////////////////////////
-
-
- typedef enum bit [1:0] {readd = 0, writed = 1, rst = 2} oper_mode;
- //////////////////////////////////////////////////////////////////////////////////
-
- class transaction extends uvm_sequence_item;
-
-
-
-
- rand oper_mode op;
- rand logic PWRITE;
- rand logic [31 : 0] PWDATA;
- rand logic [31 : 0] PADDR;
-
- // Output Signals of DUT for APB UART's transaction
- logic PREADY;
- logic PSLVERR;
- logic [31: 0] PRDATA;
-
- `uvm_object_utils_begin(transaction)
- `uvm_field_int (PWRITE,UVM_ALL_ON)
- `uvm_field_int (PWDATA,UVM_ALL_ON)
- `uvm_field_int (PADDR,UVM_ALL_ON)
- `uvm_field_int (PREADY,UVM_ALL_ON)
- `uvm_field_int (PSLVERR,UVM_ALL_ON)
- `uvm_field_int (PRDATA,UVM_ALL_ON)
- `uvm_field_enum(oper_mode, op, UVM_DEFAULT)
- `uvm_object_utils_end
-
- constraint addr_c { PADDR <= 31; }
- constraint addr_c_err { PADDR > 31; }
-
- function new(string name = "transaction");
- super.new(name);
- endfunction
-
- endclass : transaction
-
- ///////////////////////////////////////////////////////////////
- /*
- module tb;
-
-
- transaction tr;
-
- initial begin
- tr = transaction::type_id::create("tr");
- tr.randomize();
- tr.print();
- end
-
- endmodule
- */
- //////////////////////////////////////////////////////////////////
- ///////////////////write seq
- class write_data extends uvm_sequence#(transaction);
- `uvm_object_utils(write_data)
-
- transaction tr;
-
- function new(string name = "write_data");
- super.new(name);
- endfunction
-
- virtual task body();
- repeat(15)
- begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(1);//enable
- tr.addr_c_err.constraint_mode(0);//disable
- start_item(tr);
- assert(tr.randomize);
- tr.op = writed;
- finish_item(tr);
- end
- endtask
-
-
- endclass
- //////////////////////////////////////////////////////////
- ////////////////////////read seq
- class read_data extends uvm_sequence#(transaction);
- `uvm_object_utils(read_data)
-
- transaction tr;
-
- function new(string name = "read_data");
- super.new(name);
- endfunction
-
- virtual task body();
- repeat(15)
- begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(1);
- tr.addr_c_err.constraint_mode(0);//disable
- start_item(tr);
- assert(tr.randomize);
- tr.op = readd;
- finish_item(tr);
- end
- endtask
-
-
- endclass
-
-
-
- /////////////////////////////////////////////
-
- class write_read extends uvm_sequence#(transaction); //////read after write
- `uvm_object_utils(write_read)
-
- transaction tr;
-
- function new(string name = "write_read");
- super.new(name);
- endfunction
-
- virtual task body();
- repeat(15)
- begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(1);
- tr.addr_c_err.constraint_mode(0);
-
- start_item(tr);
- assert(tr.randomize);
- tr.op = writed;
- finish_item(tr);
-
- start_item(tr);
- assert(tr.randomize);
- tr.op = readd;
- finish_item(tr);
-
- end
- endtask
-
-
- endclass
- ///////////////////////////////////////////////////////
- ///////////////write bulk read bulk
- class writeb_readb extends uvm_sequence#(transaction);
- `uvm_object_utils(writeb_readb)
-
- transaction tr;
-
- function new(string name = "writeb_readb");
- super.new(name);
- endfunction
-
- virtual task body();
-
- repeat(15) begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(1);
- tr.addr_c_err.constraint_mode(0);
-
- start_item(tr);
- assert(tr.randomize);
- tr.op = writed;
- finish_item(tr);
-
-
- end
-
-
- repeat(15) begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(1);
- tr.addr_c_err.constraint_mode(0);
-
- start_item(tr);
- assert(tr.randomize);
- tr.op = readd;
- finish_item(tr);
-
- end
- endtask
-
-
- endclass
-
- /////////////////////////////////////////////////////////////////
- //////////////////////slv_error_write
- class write_err extends uvm_sequence#(transaction);
- `uvm_object_utils(write_err)
-
- transaction tr;
-
- function new(string name = "write_err");
- super.new(name);
- endfunction
-
- virtual task body();
- repeat(15)
- begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(0);
- tr.addr_c_err.constraint_mode(1);
-
- start_item(tr);
- assert(tr.randomize);
- tr.op = writed;
- finish_item(tr);
- end
- endtask
-
-
- endclass
- ///////////////////////////////////////////////////////////////
- /////////////////////////read err
-
-
- class read_err extends uvm_sequence#(transaction);
- `uvm_object_utils(read_err)
-
- transaction tr;
-
- function new(string name = "read_err");
- super.new(name);
- endfunction
-
- virtual task body();
- repeat(15)
- begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(0);
- tr.addr_c_err.constraint_mode(1);
-
- start_item(tr);
- assert(tr.randomize);
- tr.op = readd;
- finish_item(tr);
- end
- endtask
-
-
- endclass
-
- ///////////////////////////////////////////////////////////////
-
- class reset_dut extends uvm_sequence#(transaction);
- `uvm_object_utils(reset_dut)
-
- transaction tr;
-
- function new(string name = "reset_dut");
- super.new(name);
- endfunction
-
- virtual task body();
- repeat(15)
- begin
- tr = transaction::type_id::create("tr");
- tr.addr_c.constraint_mode(1);
- tr.addr_c_err.constraint_mode(0);
-
- start_item(tr);
- assert(tr.randomize);
- tr.op = rst;
- finish_item(tr);
- end
- endtask
-
-
- endclass
-
-
-
- ////////////////////////////////////////////////////////////
- class driver extends uvm_driver #(transaction);
- `uvm_component_utils(driver)
-
- virtual apb_if vif;
- transaction tr;
-
-
- function new(input string path = "drv", uvm_component parent = null);
- super.new(path,parent);
- endfunction
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- tr = transaction::type_id::create("tr");
-
- if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
- `uvm_error("drv","Unable to access Interface");
- endfunction
-
-
-
- task reset_dut();
-
- repeat(5)
- begin
- vif.presetn <= 1'b0;
- vif.paddr <= 'h0;
- vif.pwdata <= 'h0;
- vif.pwrite <= 'b0;
- vif.psel <= 'b0;
- vif.penable <= 'b0;
- `uvm_info("DRV", "System Reset : Start of Simulation", UVM_MEDIUM);
- @(posedge vif.pclk);
- end
- endtask
-
- task drive();
- reset_dut();
- forever begin
-
- seq_item_port.get_next_item(tr);
-
-
- if(tr.op == rst)
- begin
- vif.presetn <= 1'b0;
- vif.paddr <= 'h0;
- vif.pwdata <= 'h0;
- vif.pwrite <= 'b0;
- vif.psel <= 'b0;
- vif.penable <= 'b0;
- @(posedge vif.pclk);
- end
-
- else if(tr.op == writed)
- begin
- vif.psel <= 1'b1;
- vif.paddr <= tr.PADDR;
- vif.pwdata <= tr.PWDATA;
- vif.presetn <= 1'b1;
- vif.pwrite <= 1'b1;
- @(posedge vif.pclk);
- vif.penable <= 1'b1;
- `uvm_info("DRV", $sformatf("mode:%0s, addr:%0d, wdata:%0d, rdata:%0d, slverr:%0d",tr.op.name(),tr.PADDR,tr.PWDATA,tr.PRDATA,tr.PSLVERR), UVM_NONE);
- @(negedge vif.pready);
- vif.penable <= 1'b0;
- tr.PSLVERR = vif.pslverr;
-
- end
- else if(tr.op == readd)
- begin
- vif.psel <= 1'b1;
- vif.paddr <= tr.PADDR;
- vif.presetn <= 1'b1;
- vif.pwrite <= 1'b0;
- @(posedge vif.pclk);
- vif.penable <= 1'b1;
- `uvm_info("DRV", $sformatf("mode:%0s, addr:%0d, wdata:%0d, rdata:%0d, slverr:%0d",tr.op.name(),tr.PADDR,tr.PWDATA,tr.PRDATA,tr.PSLVERR), UVM_NONE);
- @(negedge vif.pready);
- vif.penable <= 1'b0;
- tr.PRDATA = vif.prdata;
- tr.PSLVERR = vif.pslverr;
- end
- seq_item_port.item_done();
-
- end
- endtask
-
-
- virtual task run_phase(uvm_phase phase);
- drive();
- endtask
-
- endclass
-
- //////////////////////////////////////////////////////////////////
-
- class mon extends uvm_monitor;
- `uvm_component_utils(mon)
-
- uvm_analysis_port#(transaction) send;
- transaction tr;
- virtual apb_if vif;
-
- function new(input string inst = "mon", uvm_component parent = null);
- super.new(inst,parent);
- endfunction
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- tr = transaction::type_id::create("tr");
- send = new("send", this);
- if(!uvm_config_db#(virtual apb_if)::get(this,"","vif",vif))//uvm_test_top.env.agent.drv.aif
- `uvm_error("MON","Unable to access Interface");
- endfunction
-
-
- virtual task run_phase(uvm_phase phase);
- forever begin
- @(posedge vif.pclk);
- if(!vif.presetn)
- begin
- tr.op = rst;
- `uvm_info("MON", "SYSTEM RESET DETECTED", UVM_NONE);
- send.write(tr);
- end
- else if (vif.presetn && vif.pwrite)
- begin
- @(negedge vif.pready);
- tr.op = writed;
- tr.PWDATA = vif.pwdata;
- tr.PADDR = vif.paddr;
- tr.PSLVERR = vif.pslverr;
- `uvm_info("MON", $sformatf("DATA WRITE addr:%0d data:%0d slverr:%0d",tr.PADDR,tr.PWDATA,tr.PSLVERR), UVM_NONE);
- send.write(tr);
- end
- else if (vif.presetn && !vif.pwrite)
- begin
- @(negedge vif.pready);
- tr.op = readd;
- tr.PADDR = vif.paddr;
- tr.PRDATA = vif.prdata;
- tr.PSLVERR = vif.pslverr;
- `uvm_info("MON", $sformatf("DATA READ addr:%0d data:%0d slverr:%0d",tr.PADDR, tr.PRDATA,tr.PSLVERR), UVM_NONE);
- send.write(tr);
- end
-
- end
- endtask
-
- endclass
-
- /////////////////////////////////////////////////////////////////////
-
-
- class sco extends uvm_scoreboard;
- `uvm_component_utils(sco)
-
- uvm_analysis_imp#(transaction,sco) recv;
- bit [31:0] arr[32] = '{default:0};
- bit [31:0] addr = 0;
- bit [31:0] data_rd = 0;
-
-
-
- function new(input string inst = "sco", uvm_component parent = null);
- super.new(inst,parent);
- endfunction
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- recv = new("recv", this);
- endfunction
-
-
- virtual function void write(transaction tr);
- if(tr.op == rst)
- begin
- `uvm_info("SCO", "SYSTEM RESET DETECTED", UVM_NONE);
- end
- else if (tr.op == writed)
- begin
- if(tr.PSLVERR == 1'b1)
- begin
- `uvm_info("SCO", "SLV ERROR during WRITE OP", UVM_NONE);
- end
- else
- begin
- arr[tr.PADDR] = tr.PWDATA;
- `uvm_info("SCO", $sformatf("DATA WRITE OP addr:%0d, wdata:%0d arr_wr:%0d",tr.PADDR,tr.PWDATA, arr[tr.PADDR]), UVM_NONE);
- end
- end
- else if (tr.op == readd)
- begin
- if(tr.PSLVERR == 1'b1)
- begin
- `uvm_info("SCO", "SLV ERROR during READ OP", UVM_NONE);
- end
- else
- begin
- data_rd = arr[tr.PADDR];
- if (data_rd == tr.PRDATA)
- `uvm_info("SCO", $sformatf("DATA MATCHED : addr:%0d, rdata:%0d",tr.PADDR,tr.PRDATA), UVM_NONE)
- else
- `uvm_info("SCO",$sformatf("TEST FAILED : addr:%0d, rdata:%0d data_rd_arr:%0d",tr.PADDR,tr.PRDATA,data_rd), UVM_NONE)
- end
-
- end
-
-
- $display("----------------------------------------------------------------");
- endfunction
-
- endclass
-
- /////////////////////////////////////////////////////////////////////
-
- class agent extends uvm_agent;
- `uvm_component_utils(agent)
-
- abp_config cfg;
-
- function new(input string inst = "agent", uvm_component parent = null);
- super.new(inst,parent);
- endfunction
-
- driver d;
- uvm_sequencer#(transaction) seqr;
- mon m;
-
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- cfg = abp_config::type_id::create("cfg");
- m = mon::type_id::create("m",this);
-
- if(cfg.is_active == UVM_ACTIVE)
- begin
- d = driver::type_id::create("d",this);
- seqr = uvm_sequencer#(transaction)::type_id::create("seqr", this);
- end
-
-
- endfunction
-
- virtual function void connect_phase(uvm_phase phase);
- super.connect_phase(phase);
- if(cfg.is_active == UVM_ACTIVE) begin
- d.seq_item_port.connect(seqr.seq_item_export);
- end
- endfunction
-
- endclass
-
- //////////////////////////////////////////////////////////////////////////////////
-
- class env extends uvm_env;
- `uvm_component_utils(env)
-
- function new(input string inst = "env", uvm_component c);
- super.new(inst,c);
- endfunction
-
- agent a;
- sco s;
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- a = agent::type_id::create("a",this);
- s = sco::type_id::create("s", this);
- endfunction
-
- virtual function void connect_phase(uvm_phase phase);
- super.connect_phase(phase);
- a.m.send.connect(s.recv);
- endfunction
-
- endclass
-
- //////////////////////////////////////////////////////////////////////////
-
- class test extends uvm_test;
- `uvm_component_utils(test)
-
- function new(input string inst = "test", uvm_component c);
- super.new(inst,c);
- endfunction
-
- env e;
- write_read wrrd;
- writeb_readb wrrdb;
- write_data wdata;
- read_data rdata;
- write_err werr;
- read_err rerr;
- reset_dut rstdut;
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- e = env::type_id::create("env",this);
- wrrd = write_read::type_id::create("wrrd");
- wdata = write_data::type_id::create("wdata");
- rdata = read_data::type_id::create("rdata");
- wrrdb = writeb_readb::type_id::create("wrrdb");
- werr = write_err::type_id::create("werr");
- rerr = read_err::type_id::create("rerr");
- rstdut = reset_dut::type_id::create("rstdut");
- endfunction
-
- virtual task run_phase(uvm_phase phase);
- phase.raise_objection(this);
- wrrdb.start(e.a.seqr);
- #20;
- phase.drop_objection(this);
- endtask
- endclass
-
- //////////////////////////////////////////////////////////////////////
- module tb;
-
-
- apb_if vif();
-
- apb_ram dut (.presetn(vif.presetn), .pclk(vif.pclk), .psel(vif.psel), .penable(vif.penable), .pwrite(vif.pwrite), .paddr(vif.paddr), .pwdata(vif.pwdata), .prdata(vif.prdata), .pready(vif.pready), .pslverr(vif.pslverr));
-
- initial begin
- vif.pclk <= 0;
- end
-
- always #10 vif.pclk <= ~vif.pclk;
-
-
-
- initial begin
- uvm_config_db#(virtual apb_if)::set(null, "*", "vif", vif);
- run_test("test");
- end
-
-
- initial begin
- $dumpfile("dump.vcd");
- $dumpvars;
- end
-
-
- endmodule
|