├── model ├── adder.py ├── __pycache__ │ └── adder.cpython-36.pyc └── adder.cpp ├── tb ├── shm.tcl ├── input_if.sv ├── output_if.sv ├── tr_out.sv ├── tr_in.sv ├── sequence_in.sv ├── my_pkg.sv ├── simple_test.sv ├── agent_out.sv ├── top.sv ├── agent_in.sv ├── Makefile ├── env.sv ├── driver_out.sv ├── refmod.sv ├── scoreboard.sv ├── monitor_out.sv ├── monitor_in.sv ├── driver_in.sv └── coverage.sv ├── LICENSE ├── rtl └── adder.sv └── README.md /model/adder.py: -------------------------------------------------------------------------------- 1 | def adder(a, b): 2 | return a+b -------------------------------------------------------------------------------- /tb/shm.tcl: -------------------------------------------------------------------------------- 1 | database -open waves -shm 2 | probe -create top -depth all -all -memories -shm -database waves 3 | run 4 | exit 5 | -------------------------------------------------------------------------------- /model/__pycache__/adder.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoseIuri/UVM_Python/HEAD/model/__pycache__/adder.cpython-36.pyc -------------------------------------------------------------------------------- /tb/input_if.sv: -------------------------------------------------------------------------------- 1 | interface input_if(input clk, rst); 2 | logic [31:0] A, B; 3 | logic valid, ready; 4 | 5 | modport port(input clk, rst, A, B, valid, output ready); 6 | endinterface -------------------------------------------------------------------------------- /tb/output_if.sv: -------------------------------------------------------------------------------- 1 | interface output_if(input clk, rst); 2 | logic [31:0] data; 3 | logic valid, ready; 4 | 5 | modport port(input clk, rst, output valid, data, ready); 6 | endinterface -------------------------------------------------------------------------------- /tb/tr_out.sv: -------------------------------------------------------------------------------- 1 | class tr_out extends uvm_sequence_item; 2 | rand integer data; 3 | 4 | `uvm_object_utils_begin(tr_out) 5 | `uvm_field_int(data, UVM_ALL_ON|UVM_HEX) 6 | `uvm_object_utils_end 7 | 8 | function new(string name="tr_out"); 9 | super.new(name); 10 | endfunction: new 11 | endclass: tr_out -------------------------------------------------------------------------------- /tb/tr_in.sv: -------------------------------------------------------------------------------- 1 | class tr_in extends uvm_sequence_item; 2 | rand integer A; 3 | rand integer B; 4 | 5 | `uvm_object_utils_begin(tr_in) 6 | `uvm_field_int(A, UVM_ALL_ON|UVM_HEX) 7 | `uvm_field_int(B, UVM_ALL_ON|UVM_HEX) 8 | `uvm_object_utils_end 9 | 10 | function new(string name="tr_in"); 11 | super.new(name); 12 | endfunction: new 13 | endclass: tr_in -------------------------------------------------------------------------------- /tb/sequence_in.sv: -------------------------------------------------------------------------------- 1 | class sequence_in extends uvm_sequence #(tr_in); 2 | `uvm_object_utils(sequence_in) 3 | 4 | function new(string name="sequence_in"); 5 | super.new(name); 6 | endfunction: new 7 | 8 | task body; 9 | tr_in tr; 10 | 11 | forever begin 12 | tr = tr_in::type_id::create("tr"); 13 | start_item(tr); 14 | assert(tr.randomize()); 15 | finish_item(tr); 16 | end 17 | endtask: body 18 | endclass: sequence_in -------------------------------------------------------------------------------- /tb/my_pkg.sv: -------------------------------------------------------------------------------- 1 | package my_pkg; 2 | 3 | import uvm_pkg::*; 4 | `include "uvm_macros.svh" 5 | `include "./tr_in.sv" 6 | `include "./tr_out.sv" 7 | `include "./sequence_in.sv" 8 | `include "./driver_in.sv" 9 | `include "./driver_out.sv" 10 | `include "./monitor_in.sv" 11 | `include "./monitor_out.sv" 12 | `include "./agent_in.sv" 13 | `include "./agent_out.sv" 14 | `include "./refmod.sv" 15 | `include "./coverage.sv" 16 | `include "./scoreboard.sv" 17 | `include "./env.sv" 18 | `include "./simple_test.sv" 19 | 20 | endpackage -------------------------------------------------------------------------------- /tb/simple_test.sv: -------------------------------------------------------------------------------- 1 | class simple_test extends uvm_test; 2 | env env_h; 3 | sequence_in seq; 4 | 5 | `uvm_component_utils(simple_test) 6 | 7 | function new(string name, uvm_component parent = null); 8 | super.new(name, parent); 9 | endfunction 10 | 11 | virtual function void build_phase(uvm_phase phase); 12 | super.build_phase(phase); 13 | env_h = env::type_id::create("env_h", this); 14 | seq = sequence_in::type_id::create("seq", this); 15 | endfunction 16 | 17 | task run_phase(uvm_phase phase); 18 | seq.start(env_h.mst.sqr); 19 | endtask: run_phase 20 | 21 | endclass -------------------------------------------------------------------------------- /tb/agent_out.sv: -------------------------------------------------------------------------------- 1 | class agent_out extends uvm_agent; 2 | driver_out drv; 3 | monitor_out mon; 4 | 5 | uvm_analysis_port #(tr_out) item_collected_port; 6 | 7 | `uvm_component_utils(agent_out) 8 | 9 | function new(string name = "agent_out", uvm_component parent = null); 10 | super.new(name, parent); 11 | item_collected_port = new("item_collected_port", this); 12 | endfunction 13 | 14 | virtual function void build_phase(uvm_phase phase); 15 | super.build_phase(phase); 16 | mon = monitor_out::type_id::create("mon_out", this); 17 | drv = driver_out::type_id::create("drv_out", this); 18 | endfunction 19 | 20 | virtual function void connect_phase(uvm_phase phase); 21 | super.connect_phase(phase); 22 | mon.item_collected_port.connect(item_collected_port); 23 | endfunction 24 | endclass: agent_out -------------------------------------------------------------------------------- /tb/top.sv: -------------------------------------------------------------------------------- 1 | //Top 2 | module top; 3 | 4 | import uvm_pkg::*; 5 | import my_pkg::*; 6 | logic clk; 7 | logic rst; 8 | 9 | initial begin 10 | clk = 0; 11 | rst = 1; 12 | #22 rst = 0; 13 | 14 | end 15 | 16 | always #5 clk = !clk; 17 | 18 | logic [1:0] state; 19 | 20 | input_if in(clk, rst); 21 | output_if out(clk, rst); 22 | 23 | adder sum(in, out, state); 24 | 25 | initial begin 26 | `ifdef XCELIUM 27 | $recordvars(); 28 | `endif 29 | `ifdef VCS 30 | $vcdpluson; 31 | `endif 32 | `ifdef QUESTA 33 | $wlfdumpvars(); 34 | set_config_int("*", "recording_detail", 1); 35 | `endif 36 | 37 | uvm_config_db#(input_vif)::set(uvm_root::get(), "*.env_h.mst.*", "vif", in); 38 | uvm_config_db#(output_vif)::set(uvm_root::get(), "*.env_h.slv.*", "vif", out); 39 | 40 | run_test("simple_test"); 41 | end 42 | endmodule -------------------------------------------------------------------------------- /tb/agent_in.sv: -------------------------------------------------------------------------------- 1 | class agent_in extends uvm_agent; 2 | `uvm_component_utils(agent_in) 3 | 4 | uvm_sequencer #(tr_in) sqr; 5 | driver_in drv; 6 | monitor_in mon; 7 | 8 | uvm_analysis_port #(tr_in) item_ref_port; 9 | 10 | 11 | function new(string name = "agent_in", uvm_component parent = null); 12 | super.new(name, parent); 13 | item_ref_port = new("item_ref_port", this); 14 | endfunction 15 | 16 | virtual function void build_phase(uvm_phase phase); 17 | super.build_phase(phase); 18 | mon = monitor_in::type_id::create("mon", this); 19 | sqr = uvm_sequencer #(tr_in)::type_id::create("sqr", this); 20 | drv = driver_in::type_id::create("drv", this); 21 | endfunction 22 | 23 | virtual function void connect_phase(uvm_phase phase); 24 | super.connect_phase(phase); 25 | mon.item_collected_port.connect(item_ref_port); 26 | drv.seq_item_port.connect(sqr.seq_item_export); 27 | endfunction 28 | endclass: agent_in -------------------------------------------------------------------------------- /model/adder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" int adder(int a, int b){ 5 | Py_Initialize(); 6 | PyObject* sysPath = PySys_GetObject((char*) "path"); 7 | PyList_Append(sysPath, PyUnicode_DecodeFSDefault("../model/")); 8 | 9 | PyObject *pModule = NULL, *pFunc = NULL, *pArgs = NULL, *pValue = NULL; 10 | 11 | pModule = PyImport_ImportModule("adder"); 12 | if (pModule == NULL) return -1; 13 | 14 | pFunc = PyObject_GetAttrString(pModule, "adder"); 15 | if (pFunc == NULL) return -2; 16 | 17 | pArgs = Py_BuildValue("ii", a, b); 18 | if (pArgs == NULL) return -3; 19 | 20 | pValue = PyObject_Call(pFunc, pArgs, NULL); 21 | if (pValue == NULL) return -4; 22 | // printf("Result of call: %ld\n", PyLong_AsLong(pValue)); 23 | 24 | Py_XDECREF(pValue); 25 | Py_XDECREF(pArgs); 26 | Py_XDECREF(pFunc); 27 | Py_XDECREF(pModule); 28 | 29 | int result = int(PyLong_AsLong(pValue)); 30 | 31 | printf("%d\n", result); 32 | 33 | Py_Finalize(); 34 | return result; 35 | } -------------------------------------------------------------------------------- /tb/Makefile: -------------------------------------------------------------------------------- 1 | RTL_SRC = ../rtl/ 2 | MODEL_SRC = ../model/ 3 | 4 | IF = input_if.sv \ 5 | output_if.sv 6 | RTL = ../rtl/adder.sv \ 7 | 8 | 9 | REFMOD = ../model/adder.cpp 10 | PKGS = ./my_pkg.sv 11 | 12 | SEED = 100 13 | COVER = 100 14 | TRANSA = 5000 15 | 16 | RUN_ARGS_COMMON = -access +r -input shm.tcl \ 17 | +uvm_set_config_int=*,recording_detail,1 -coverage all -covoverwrite 18 | 19 | sim: 20 | @g++ -g -fPIC -Wall -I/usr/include/python3.6m -lpython3.6m -std=c++0x $(REFMOD) -shared -o test.so 21 | @xrun -64bit -uvm +incdir+$(RTL_SRC) $(IF) $(RTL) $(PKGS) top.sv -sv_lib test.so \ 22 | +UVM_TESTNAME=simple_test -covtest simple_test-$(SEED) -svseed $(SEED) \ 23 | -defparam top.min_cover=$(COVER) -defparam top.min_transa=$(TRANSA) $(RUN_ARGS_COMMON) $(RUN_ARGS) 24 | 25 | clean: 26 | @rm -rf INCA_libs waves.shm rtlsim/* *.history *.log rtlsim/* *.key mdv.log imc.log imc.key ncvlog_*.err *.trn *.dsn .simvision/ xcelium.d simv.daidir *.so *.o *.err 27 | 28 | rebuild: clean sim 29 | 30 | view_waves: 31 | simvision waves.shm & 32 | 33 | view_cover: 34 | imc & -------------------------------------------------------------------------------- /tb/env.sv: -------------------------------------------------------------------------------- 1 | class env extends uvm_env; 2 | agent_in mst; 3 | agent_out slv; 4 | scoreboard scb; 5 | coverage cov; 6 | 7 | `uvm_component_utils(env) 8 | 9 | function new(string name, uvm_component parent = null); 10 | super.new(name, parent); 11 | // to_refmod = new("to_refmod", this); 12 | endfunction 13 | 14 | virtual function void build_phase(uvm_phase phase); 15 | super.build_phase(phase); 16 | mst = agent_in::type_id::create("mst", this); 17 | slv = agent_out::type_id::create("slv", this); 18 | scb = scoreboard::type_id::create("scb", this); 19 | cov = coverage::type_id::create("cov", this); 20 | endfunction 21 | 22 | virtual function void connect_phase(uvm_phase phase); 23 | super.connect_phase(phase); 24 | // Connect MST to FIFO 25 | mst.item_ref_port.connect(scb.ap_rfm); 26 | slv.item_collected_port.connect(scb.ap_comp); 27 | 28 | mst.item_ref_port.connect(cov.req_port); 29 | slv.item_collected_port.connect(cov.resp_port); 30 | 31 | endfunction 32 | endclass -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 José Iuri Barbosa de Brito 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tb/driver_out.sv: -------------------------------------------------------------------------------- 1 | typedef virtual output_if output_vif; 2 | 3 | class driver_out extends uvm_driver #(tr_out); 4 | `uvm_component_utils(driver_out) 5 | output_vif vif; 6 | 7 | function new(string name = "driver_out", uvm_component parent = null); 8 | super.new(name, parent); 9 | endfunction 10 | 11 | virtual function void build_phase(uvm_phase phase); 12 | super.build_phase(phase); 13 | assert(uvm_config_db#(output_vif)::get(this, "", "vif", vif)); 14 | endfunction 15 | 16 | virtual task run_phase(uvm_phase phase); 17 | super.run_phase(phase); 18 | fork 19 | reset_signals(); 20 | drive(phase); 21 | join 22 | endtask 23 | 24 | virtual protected task reset_signals(); 25 | wait (vif.rst === 1); 26 | forever begin 27 | vif.ready <= '0; 28 | @(posedge vif.rst); 29 | end 30 | endtask 31 | 32 | virtual protected task drive(uvm_phase phase); 33 | wait(vif.rst === 1); 34 | @(negedge vif.rst); 35 | @(posedge vif.clk); 36 | 37 | vif.ready <= 1; 38 | endtask 39 | endclass -------------------------------------------------------------------------------- /rtl/adder.sv: -------------------------------------------------------------------------------- 1 | module adder(input_if.port inter, output_if.port out_inter, output state); 2 | enum logic [1:0] {INITIAL,WAIT,SEND} state; 3 | 4 | always_ff @(posedge inter.clk) 5 | if(inter.rst) begin 6 | inter.ready <= 0; 7 | out_inter.data <= 'x; 8 | out_inter.valid <= 0; 9 | state <= INITIAL; 10 | end 11 | else case(state) 12 | INITIAL: begin 13 | inter.ready <= 1; 14 | state <= WAIT; 15 | end 16 | 17 | WAIT: begin 18 | if(inter.valid) begin 19 | inter.ready <= 0; 20 | out_inter.data <= inter.A + inter.B; 21 | out_inter.valid <= 1; 22 | state <= SEND; 23 | end 24 | end 25 | 26 | SEND: begin 27 | if(out_inter.ready) begin 28 | out_inter.valid <= 0; 29 | inter.ready <= 1; 30 | state <= WAIT; 31 | end 32 | end 33 | endcase 34 | endmodule: adder -------------------------------------------------------------------------------- /tb/refmod.sv: -------------------------------------------------------------------------------- 1 | import "DPI-C" context function int adder(int a, int b); 2 | 3 | class refmod extends uvm_component; 4 | `uvm_component_utils(refmod) 5 | 6 | tr_in tr; 7 | tr_out tr_o; 8 | integer a, b; 9 | uvm_analysis_imp #(tr_in, refmod) in; 10 | uvm_analysis_export #(tr_out) out; 11 | event begin_refmodtask; 12 | 13 | function new(string name = "refmod", uvm_component parent); 14 | super.new(name, parent); 15 | in = new("in", this); 16 | out = new("out", this); 17 | endfunction 18 | 19 | virtual function void build_phase(uvm_phase phase); 20 | super.build_phase(phase); 21 | tr_o = tr_out::type_id::create("tr_o", this); 22 | endfunction: build_phase 23 | 24 | virtual task run_phase(uvm_phase phase); 25 | super.run_phase(phase); 26 | 27 | forever begin 28 | @begin_refmodtask; 29 | tr_o.data = adder(tr.A, tr.B); 30 | $display("%d",tr_o.data); 31 | out.write(tr_o); 32 | end 33 | endtask: run_phase 34 | 35 | virtual function write (tr_in t); 36 | tr = tr_in::type_id::create("tr", this); 37 | tr.copy(t); 38 | -> begin_refmodtask; 39 | endfunction 40 | 41 | 42 | endclass: refmod -------------------------------------------------------------------------------- /tb/scoreboard.sv: -------------------------------------------------------------------------------- 1 | class scoreboard extends uvm_scoreboard; 2 | 3 | typedef tr_out T; 4 | typedef uvm_in_order_class_comparator #(T) comp_type; 5 | // uvm_tlm_analysis_fifo #(packet) to_refmod; 6 | 7 | //typedef uvm_in_order_comparator #(T,uvm_class_comp#(comp_policy),uvm_class_converter#(T),uvm_class_pair #(T)) comp_type; 8 | refmod rfm; 9 | comp_type comp; 10 | 11 | uvm_analysis_port #(T) ap_comp; 12 | uvm_analysis_port #(tr_in) ap_rfm; 13 | 14 | `uvm_component_utils(scoreboard) 15 | 16 | function new(string name = "translator", uvm_component parent = null); 17 | super.new(name, parent); 18 | ap_comp = new("ap_comp", this); 19 | ap_rfm = new("ap_rfm", this); 20 | // to_refmod = new("to_refmod", this); 21 | endfunction : new 22 | 23 | virtual function void build_phase(uvm_phase phase); 24 | super.build_phase(phase); 25 | rfm = refmod::type_id::create("rfm", this); 26 | comp = comp_type::type_id::create("comp", this); 27 | endfunction 28 | 29 | virtual function void connect_phase(uvm_phase phase); 30 | super.connect_phase(phase); 31 | //ap_rfm.connect(to_refmod.analysis_export); 32 | //rfm.in.connect(to_refmod.get_export); 33 | ap_comp.connect(comp.before_export); 34 | rfm.out.connect(comp.after_export); 35 | ap_rfm.connect(rfm.in); 36 | endfunction 37 | endclass -------------------------------------------------------------------------------- /tb/monitor_out.sv: -------------------------------------------------------------------------------- 1 | class monitor_out extends uvm_monitor; 2 | `uvm_component_utils(monitor_out) 3 | output_vif vif; 4 | event begin_record, end_record; 5 | tr_out tr; 6 | uvm_analysis_port #(tr_out) item_collected_port; 7 | 8 | function new(string name, uvm_component parent); 9 | super.new(name, parent); 10 | item_collected_port = new ("item_collected_port", this); 11 | endfunction 12 | 13 | virtual function void build_phase(uvm_phase phase); 14 | super.build_phase(phase); 15 | assert(uvm_config_db#(output_vif)::get(this, "", "vif", vif)); 16 | tr = tr_out::type_id::create("tr", this); 17 | endfunction 18 | 19 | virtual task run_phase(uvm_phase phase); 20 | super.run_phase(phase); 21 | fork 22 | collect_transactions(phase); 23 | record_tr(); 24 | join 25 | endtask 26 | 27 | virtual task collect_transactions(uvm_phase phase); 28 | wait(vif.rst === 1); 29 | @(negedge vif.rst); 30 | 31 | forever begin 32 | do begin 33 | @(posedge vif.clk); 34 | end while (vif.valid === 0 || vif.ready === 0); 35 | -> begin_record; 36 | 37 | tr.data = vif.data; 38 | item_collected_port.write(tr); 39 | 40 | @(posedge vif.clk); 41 | -> end_record; 42 | end 43 | endtask 44 | 45 | virtual task record_tr(); 46 | forever begin 47 | @(begin_record); 48 | begin_tr(tr, "monitor_out"); 49 | @(end_record); 50 | end_tr(tr); 51 | end 52 | endtask 53 | endclass -------------------------------------------------------------------------------- /tb/monitor_in.sv: -------------------------------------------------------------------------------- 1 | class monitor_in extends uvm_monitor; 2 | `uvm_component_utils(monitor_in) 3 | 4 | input_vif vif; 5 | event begin_record, end_record; 6 | tr_in tr; 7 | uvm_analysis_port #(tr_in) item_collected_port; 8 | 9 | function new(string name, uvm_component parent); 10 | super.new(name, parent); 11 | item_collected_port = new ("item_collected_port", this); 12 | endfunction 13 | 14 | virtual function void build_phase(uvm_phase phase); 15 | super.build_phase(phase); 16 | assert(uvm_config_db#(input_vif)::get(this, "", "vif", vif)); 17 | tr = tr_in::type_id::create("tr", this); 18 | endfunction 19 | 20 | virtual task run_phase(uvm_phase phase); 21 | super.run_phase(phase); 22 | fork 23 | collect_transactions(phase); 24 | record_tr(); 25 | join 26 | endtask 27 | 28 | virtual task collect_transactions(uvm_phase phase); 29 | wait(vif.rst === 1); 30 | @(negedge vif.rst); 31 | 32 | forever begin 33 | do begin 34 | @(posedge vif.clk); 35 | end while (vif.valid === 0 || vif.ready === 0); 36 | -> begin_record; 37 | 38 | tr.A = vif.A; 39 | tr.B = vif.B; 40 | item_collected_port.write(tr); 41 | 42 | @(posedge vif.clk); 43 | -> end_record; 44 | end 45 | endtask 46 | 47 | virtual task record_tr(); 48 | forever begin 49 | @(begin_record); 50 | begin_tr(tr, "monitor"); 51 | @(end_record); 52 | end_tr(tr); 53 | end 54 | endtask 55 | endclass -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UVM_Python 2 | 3 | ## Table of Contents 4 | 5 | - [Getting Started](#getting-started) 6 | - [Prerequisites](#prerequisites) 7 | - [Running the tests](#running-the-tests) 8 | - [Authors](#authors) 9 | - [License](#license) 10 | - [Contributing](#contributing) 11 | - [Acknowledgments](#acknowledgments) 12 | 13 | ## Getting Started 14 | 15 | Python is a language that provides a high-level programming language for numerical computation and other operations. This repository contains an example of a connection between an UVM testbench and a Python reference model for a simple operation of sum. 16 | 17 |

18 | 19 | XMEN Lab 20 | 21 |

22 | 23 | ### Prerequisites 24 | 25 | ``` 26 | UVM 1.2 27 | 28 | Cadence xrun(64): 18.09-s011 29 | 30 | Python 3.6 31 | ``` 32 | 33 | ## Running the tests 34 | 35 | To run the simulation just do the make command. 36 | 37 | ``` 38 | make 39 | ``` 40 | 41 | ## Authors 42 | 43 | * **José Iuri Barbosa de Brito** - [JoseIuri](https://github.com/JoseIuri) 44 | 45 | See also the list of [contributors](https://github.com/JoseIuri/UVM_Python/contributors) who participated in this project. 46 | 47 | ## License 48 | 49 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 50 | 51 | ## Contributing 52 | 53 | 1. Fork it () 54 | 2. Create your feature branch (`git checkout -b feature/fooBar`) 55 | 3. Commit your changes (`git commit -am 'Add some fooBar'`) 56 | 4. Push to the branch (`git push origin feature/fooBar`) 57 | 5. Create a new Pull Request 58 | 59 | ## Acknowledgments 60 | 61 | * XMEN Lab - Federal University of Campina Grande - Brazil 62 | * Sistenix - () 63 | 64 |

65 | 66 | XMEN Lab 67 | 68 |

69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /tb/driver_in.sv: -------------------------------------------------------------------------------- 1 | typedef virtual input_if input_vif; 2 | 3 | class driver_in extends uvm_driver #(tr_in); 4 | `uvm_component_utils(driver_in) 5 | input_vif vif; 6 | event begin_record, end_record; 7 | 8 | function new(string name = "driver_in", uvm_component parent = null); 9 | super.new(name, parent); 10 | endfunction 11 | 12 | virtual function void build_phase(uvm_phase phase); 13 | super.build_phase(phase); 14 | assert(uvm_config_db#(input_vif)::get(this, "", "vif", vif)); 15 | endfunction 16 | 17 | virtual task run_phase(uvm_phase phase); 18 | super.run_phase(phase); 19 | fork 20 | reset_signals(); 21 | get_and_drive(phase); 22 | record_tr(); 23 | join 24 | endtask 25 | 26 | virtual protected task reset_signals(); 27 | wait (vif.rst === 1); 28 | forever begin 29 | vif.valid <= '0; 30 | vif.A <= 'x; 31 | vif.B <= 'x; 32 | @(posedge vif.rst); 33 | end 34 | endtask 35 | 36 | virtual protected task get_and_drive(uvm_phase phase); 37 | wait(vif.rst === 1); 38 | @(negedge vif.rst); 39 | @(posedge vif.clk); 40 | 41 | forever begin 42 | seq_item_port.try_next_item(req); 43 | -> begin_record; 44 | drive_transfer(req); 45 | seq_item_port.item_done(); 46 | end 47 | endtask 48 | 49 | virtual protected task drive_transfer(tr_in tr); 50 | vif.A = tr.A; 51 | vif.B = tr.B; 52 | vif.valid = 1; 53 | 54 | @(posedge vif.clk) 55 | 56 | while(!vif.ready) 57 | @(posedge vif.clk); 58 | 59 | -> end_record; 60 | @(posedge vif.clk); //hold time 61 | vif.valid = 0; 62 | @(posedge vif.clk); 63 | endtask 64 | 65 | virtual task record_tr(); 66 | forever begin 67 | @(begin_record); 68 | begin_tr(req, "driver_in"); 69 | @(end_record); 70 | end_tr(req); 71 | end 72 | endtask 73 | endclass -------------------------------------------------------------------------------- /tb/coverage.sv: -------------------------------------------------------------------------------- 1 | `uvm_analysis_imp_decl(_req) 2 | `uvm_analysis_imp_decl(_resp) 3 | 4 | class coverage extends uvm_component; 5 | 6 | `uvm_component_utils(coverage) 7 | 8 | tr_in req; 9 | tr_out resp; 10 | 11 | uvm_analysis_imp_req#(tr_in, coverage) req_port; 12 | uvm_analysis_imp_resp#(tr_out, coverage) resp_port; 13 | 14 | int min_cover; 15 | int min_transa = 5000; 16 | int transa = 0; 17 | logic result_available = 0; 18 | 19 | 20 | function new(string name = "cover", uvm_component parent= null); 21 | super.new(name, parent); 22 | req_port = new("req_port", this); 23 | resp_port = new("resp_port", this); 24 | resp=new; 25 | req=new; 26 | endfunction 27 | 28 | function void build_phase(uvm_phase phase); 29 | super.build_phase (phase); 30 | uvm_config_db#(int)::get(this, "", "min_cover", min_cover); 31 | uvm_config_db#(int)::get(this, "", "min_transa", min_transa); 32 | endfunction 33 | 34 | protected uvm_phase running_phase; 35 | task run_phase(uvm_phase phase); 36 | running_phase = phase; 37 | running_phase.raise_objection(this); 38 | running_phase.raise_objection(this); 39 | endtask: run_phase 40 | 41 | //============= Função para copiar transações do agent (Requisições) ====================== 42 | function void write_req(tr_in t); 43 | req.copy (t); 44 | transa = transa + 1; 45 | //$display("cobertura:%d",$get_coverage()); 46 | $display("transa:%d",transa); 47 | $display("min_transa:%d",min_transa); 48 | if(transa >= min_transa)begin 49 | $display("dropou"); 50 | running_phase.drop_objection(this); 51 | end 52 | endfunction: write_req 53 | 54 | 55 | //============= Função para copiar transações do agent (Respostas) ======================== 56 | function void write_resp(tr_out t); 57 | resp.copy(t); 58 | transa = transa + 1; 59 | //$display("cobertura:%d",$get_coverage()); 60 | $display("transa:%d",transa); 61 | $display("min_transa:%d",min_transa); 62 | if(transa >= min_transa)begin 63 | $display("dropou"); 64 | running_phase.drop_objection(this); 65 | end 66 | 67 | endfunction: write_resp 68 | endclass : coverage --------------------------------------------------------------------------------