├── LICENSE ├── README.md ├── agent.sv ├── coverage.sv ├── design.sv ├── driver.sv ├── fifo_pkg.sv ├── monitor.sv ├── scoreboard.sv ├── sequencer.sv ├── tests_top.sv ├── top_testbench.sv └── transaction.sv /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ishfaq Ahmed 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SYNCHRONOUS FIFO TESTBENCH 2 | 3 | ![FIFO](https://user-images.githubusercontent.com/34355989/131266987-d41cd93f-4aff-4437-a54e-0e49d5e2a28b.jpg) 4 | 5 | - Getting familiar with SystemVerilog and UVM Testbenches 6 | - Device Under Test (DUT) is a single-clock Register-based FIFO 7 | - The circular buffer has a maximum capacity of 16, with an active LOW Reset 8 | - Has Enable signals for READ and WRITE operations, and flags to determine EMPTY and FULL status 9 | - Made reusable testbench components like sequences, drivers, monitors, agents 10 | -------------------------------------------------------------------------------- /agent.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----AGENT---- 5 | 6 | class fifo_agent extends uvm_agent; 7 | `uvm_component_utils(fifo_agent) 8 | protected uvm_active_passive_enum is_active = UVM_ACTIVE; 9 | 10 | fifo_sequencer sequencer; 11 | fifo_driver driver; 12 | fifo_monitor monitor; 13 | 14 | function new(string name, uvm_component parent); 15 | super.new(name,parent); 16 | endfunction: new 17 | 18 | 19 | function void build_phase(uvm_phase phase); 20 | super.build_phase(phase); 21 | if (is_active == UVM_ACTIVE) begin 22 | sequencer = fifo_sequencer::type_id::create("sequencer", this); 23 | driver = fifo_driver::type_id::create("driver", this); 24 | end 25 | monitor = fifo_monitor::type_id::create("monitor", this); 26 | endfunction: build_phase 27 | 28 | 29 | function void connect_phase(uvm_phase phase); 30 | if (is_active == UVM_ACTIVE) 31 | driver.seq_item_port.connect(sequencer.seq_item_export); 32 | `uvm_info(get_full_name(), "Driver connected to sequencer! ", UVM_LOW) 33 | endfunction: connect_phase 34 | 35 | endclass: fifo_agent 36 | 37 | // ----ENVIRONMENTS---- 38 | 39 | class agent_env extends uvm_env; 40 | fifo_agent agent; 41 | 42 | `uvm_component_utils(fifo_agent) 43 | 44 | function new(string name, uvm_component parent); 45 | super.new(name, parent); 46 | endfunction 47 | 48 | function void build_phase(uvm_phase phase); 49 | super.build_phase(phase); 50 | agent = fifo_agent::type_id::create("agent", this); 51 | endfunction: build_phase 52 | endclass: agent_env 53 | 54 | 55 | class fifo_env extends uvm_env; 56 | `uvm_component_utils(fifo_env) 57 | 58 | agent_env fifo_in_env; 59 | agent_env fifo_out_env; 60 | fifo_scoreboard fifo_sb; 61 | 62 | function new(string name, uvm_component parent); 63 | super.new(name, parent); 64 | endfunction 65 | 66 | function void build_phase(uvm_phase phase); 67 | super.build_phase(phase); 68 | 69 | `uvm_config_db#(int)::set(this, "fifo_in_env.agent", "is_active", UVM_ACTIVE); 70 | `uvm_config_db#(int)::set(this, "fifo_out_env.agent", "is_active", UVM_PASSIVE); 71 | 72 | `uvm_config_db#(string)::set(this, "fifo_in_env.agent.monitor", "monitor_intf", "input_intf"); 73 | `uvm_config_db#(string)::set(this, "fifo_out_env.agent.monitor", "monitor_intf", "output_intf"); 74 | 75 | fifo_in_env = agent_env::type_id::create("fifo_in_env", this); 76 | fifo_out_env = agent_env::type_id::create("fifo_out_env", this); 77 | sb = fifo_scoreboard::type_id::create("fifo_sb", this); 78 | 79 | `uvm_info(get_full_name(), "Build stage done! ", UVM_LOW) 80 | endfunction: build_phase 81 | 82 | function void connect_phase(uvm_phase phase); 83 | super.connect_phase(phase); 84 | fifo_agent.custom_ap.connect(fifo_coverage.analysis_export); 85 | fifo_in_env.agent.monitor.item_collected_port.connect(); 86 | fifo_out_env.agent.monitor.item_collected_port.connect(); 87 | `uvm_info(get_full_name(), "Connect stage done! ", UVM_LOW) 88 | endfunction: connect_phase 89 | 90 | endclass: fifo_env -------------------------------------------------------------------------------- /coverage.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----COVERAGE---- 5 | 6 | class fifo_coverage extends uvm_subscriber #(data_item); 7 | `uvm_component_utils(fifo_coverage) 8 | data_item pkt; 9 | int i; 10 | 11 | covergroup cg; 12 | covg_write_en : coverpoint pkt.write_en; 13 | covg_read_en : coverpoint pkt.read_en; 14 | covg_data_in : coverpoint pkt.data_in; 15 | covg_data_out : coverpoint pkt.data_out; 16 | endgroup: cg 17 | 18 | function new(string name, uvm_component parent); 19 | super.new(name, parent); 20 | cg = new(); 21 | endfunction: new 22 | 23 | function void write(data_item t); 24 | pkt = t; 25 | i++; 26 | cg.sample(); 27 | endfunction: write 28 | 29 | virtual function void extract_phase(uvm_phase phase); 30 | `uvm_info(get_type_name(), $sformatf("Coverage : %f", cg.get_coverage()), UVM_LOW) 31 | endtask: extract_phase 32 | 33 | endclass: fifo_coverage -------------------------------------------------------------------------------- /design.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | // ------DUT------- 4 | 5 | module fifo( 6 | input clk, 7 | input rst_n, 8 | input read_en, 9 | input write_en, 10 | input [WIDTH-1:0] data_in, 11 | output empty_fifo, // Active LOW signal 12 | output full_fifo, // Active LOW signal 13 | output [WIDTH-1:0] data_out 14 | ); 15 | 16 | parameter WIDTH = 32; 17 | parameter DEPTH = 16; 18 | parameter CTR_SIZE = 5; 19 | 20 | reg [CTR_SIZE:0] write_addr_reg; 21 | reg [CTR_SIZE:0] read_addr_reg; 22 | reg empty_fifo; 23 | reg full_fifo; 24 | reg [WIDTH-1:0] data_out; 25 | 26 | reg [WIDTH-1:0] fifo_buffer [DEPTH-1:0]; 27 | 28 | 29 | wire [CTR_SIZE-1:0] write_pointer; // Pointer to write data to FIFO 30 | wire [CTR_SIZE-1:0] read_pointer; // Pointer to read data from FIFO 31 | wire empty; // Condition for EMPTY_FIFO 32 | wire full; // Condition for FULL_FIFO 33 | wire read_ready; // Prevents read from empty FIFO 34 | wire write_ready; // Prevents write to full FIFO 35 | wire [DEPTH:0] counter; 36 | 37 | 38 | assign counter = write_addr_reg - read_addr_reg; 39 | assign empty = (counter == 5'b00000 || read_addr_reg + 1 == write_addr_reg); 40 | assign full = (counter == 5'b10000 || write_addr_reg + 1 == read_addr_reg); 41 | assign write_pointer = write_addr_reg[CTR_SIZE-1:0]; 42 | assign read_pointer = read_addr_reg[CTR_SIZE-1:0]; 43 | assign read_ready = (read_en && empty == 1'b0); 44 | assign write_ready = (write_en && full == 1'b0); 45 | 46 | 47 | // FIFO read/write logic, increment pointer to update location 48 | 49 | always @ (posedge clk) begin 50 | if (!rst_n)begin 51 | write_addr_reg <= 0; 52 | read_addr_reg <= 0; 53 | counter <= 0; 54 | end 55 | else begin 56 | if (read_ready) begin 57 | data_out <= fifo_buffer[read_pointer]; 58 | if (read_addr_reg == DEPTH - 1) begin 59 | read_addr_reg <= 0; 60 | end 61 | else begin 62 | read_addr_reg++; 63 | end 64 | end 65 | else if (write_ready) begin 66 | fifo_buffer[write_pointer] <= data_in; 67 | if (write_addr_reg == DEPTH - 1) begin 68 | write_addr_reg <= 0; 69 | end 70 | else begin 71 | write_addr_reg++; 72 | end 73 | end 74 | end 75 | end 76 | 77 | // Assign Latch to set synchronous EMPTY/FULL flags 78 | 79 | always @ (empty or full) begin 80 | empty_fifo <= ~empty; 81 | full_fifo <= ~full; 82 | end 83 | 84 | endmodule: fifo 85 | 86 | // -----INTERFACE------ 87 | 88 | interface fifo_if; 89 | bit clk, 90 | bit rst_n, 91 | logic read_en, 92 | logic write_en, 93 | logic [WIDTH-1:0] data_in, 94 | logic empty_fifo, 95 | logic full_fifo, 96 | logic [WIDTH-1:0] data_out 97 | endinterface: fifo_if 98 | -------------------------------------------------------------------------------- /driver.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----DRIVER---- 5 | 6 | class fifo_driver extends uvm_driver #(data_item) 7 | `uvm_component_utils(fifo_driver) 8 | 9 | virtual fifo_if fifo_driver_vif; 10 | 11 | function new(string name, uvm_component parent); 12 | super.new(name, parent); 13 | endfunction: new 14 | 15 | function void build_phase(uvm_phase phase); 16 | super.build(phase); 17 | if (!uvm_config_db#(virtual fifo_if)::get(this, "", "fifo_if", fifo_driver_vif)) 18 | `uvm_fatal("NO_VIF", {"Must set virtual interface for: ", get_full_name(), ".fifo_driver_vif"}) 19 | `uvm_info(get_full_name(), "Build stage done ", UVM_LOW) 20 | endfunction 21 | 22 | virtual task run_phase(uvm_phase phase); 23 | fork 24 | check_reset(); 25 | driver_to_dut(); 26 | join 27 | endtask: run_phase 28 | 29 | virtual task check_reset(); 30 | forever begin 31 | @(negedge fifo_driver_vif.rst_n); 32 | `uvm_info(get_type_name(), "Resetting signals ", UVM_LOW) 33 | fifo_driver_vif.read_en <= 1'b0; 34 | fifo_driver_vif.write_en <= 1'b0; 35 | fifo_driver_vif.data_in <= 32'b0; 36 | fifo_driver_vif.data_out <= 32'b0; 37 | end 38 | endtask: check_reset 39 | 40 | virtual task driver_to_dut(data_item pkt); 41 | forever begin 42 | while (!fifo_driver_vif.rst) begin 43 | seq_item_port.get_next_item(req); 44 | fifo_driver_vif.write_en <= 1'b0; 45 | fifo_driver_vif.read_en <= 1'b0; 46 | repeat(pkt.delay) @(posedge fifo_driver_vif.clk) 47 | fifo_driver_vif.read_en <= pkt.read_en; 48 | fifo_driver_vif.write_en <= pkt.write_en; 49 | fifo_driver_vif.data_in <= pkt.data_in; 50 | fifo_driver_vif.data_out <= pkt.data_out; 51 | @(posedge fifo_driver_vif.clk) 52 | fifo_driver_vif.write_en <= 1'b0; 53 | fifo_driver_vif.read_en <= 1'b0; 54 | seq_item_port.item_done(); 55 | end 56 | end 57 | endtask: driver_to_dut 58 | 59 | endclass: fifo_driver 60 | -------------------------------------------------------------------------------- /fifo_pkg.sv: -------------------------------------------------------------------------------- 1 | package fifo_pkg; 2 | 3 | import uvm_pkg::*; 4 | `include "uvm_macros.svh" 5 | `include "transaction.sv" 6 | `include "driver.sv" 7 | `include "monitor.sv" 8 | `include "sequencer.sv" 9 | `include "agent.sv" 10 | `include "environments.sv" 11 | `include "scoreboard.sv" 12 | `include "coverage.sv" 13 | `include "tests_top.sv" 14 | 15 | endpackage: fifo_pkg -------------------------------------------------------------------------------- /monitor.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----MONITOR---- 5 | 6 | class fifo_monitor extends uvm_monitor; 7 | `uvm_component_utils (fifo_monitor) 8 | 9 | virtual fifo_if vif; 10 | string monitor_intf; 11 | int num_pkts; 12 | 13 | uvm_analysis_port #(data_item) item_collected_port; 14 | data_item data_collected; 15 | 16 | function new(string name, uvm_component parent); 17 | super.new(name, parent); 18 | endfunction: new 19 | 20 | function void build_phase(uvm_phase phase); 21 | super.build_phase(phase); 22 | if (!uvm_config_db#(virtual fifo_if)::get(this, "", monitor_intf, vif)) 23 | `uvm_fatal("NO_VIF", {"Set virtual interface for: ", get_full_name(), ".vif"}) 24 | 25 | `uvm_info(get_type_name(), $sformatf("MONITOR INTERFACE USED = %0s", monitor_intf), UVM_LOW) 26 | 27 | item_collected_port = new("item_collected_port", this); 28 | 29 | data_collected = data_item::type_id::create("data_collected"); 30 | 31 | `uvm_info(get_full_name(), "Build stage complete ", UVM_LOW) 32 | endfunction: build_phase 33 | 34 | virtual task run_phase(uvm_phase phase); 35 | collect_data(); 36 | endtask: run_phase 37 | 38 | virtual task collect_data(); 39 | forever begin 40 | @ (posedge vif.clk) 41 | if(vif.write_en & vif.full_fifo & !vif.rst_n)begin 42 | data_collected.data_in = vif.data_in; 43 | end 44 | if(vif.read_en & vif.empty_fifo & !vif.rst_n)begin 45 | data_collected.data_out = vif.data_out; 46 | end 47 | item_collected_port.write(data_collected); 48 | num_pkts++; 49 | end 50 | endtask: collect_data 51 | 52 | virtual function void report_phase(uvm_phase phase); 53 | `uvm_info(get_type_name(), $sformatf("TOTAL PACKETS = %0d", num_pkts), UVM_LOW) 54 | endfunction: report_phase 55 | 56 | endclass: fifo_monitor 57 | -------------------------------------------------------------------------------- /scoreboard.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----SCOREBOARD---- 5 | 6 | class fifo_scoreboard extends uvm_scoreboard; 7 | 8 | uvm_tlm_analysis_fifo #(data_item) input_pkts_collected; 9 | uvm_tlm_analysis_fifo #(data_item) output_pkts_collected; 10 | 11 | data_item input_data; 12 | data_item output_data; 13 | bit result; 14 | 15 | `uvm_component_utils(fifo_scoreboard) 16 | 17 | function new (string name, uvm_component parent); 18 | super.new(name, parent); 19 | endfunction 20 | 21 | function void build_phase(uvm_phase phase); 22 | super.build_phase(phase); 23 | 24 | input_pkts_collected = new("Input data port ", this); 25 | output_pkts_collected = new("Output data port ", this); 26 | 27 | input_data = data_item::type_id::create("input_data"); 28 | output_data = data_item::type_id::create("output_data"); 29 | endfunction: build_phase 30 | 31 | virtual task run_phase(uvm_phase phase); 32 | forever begin 33 | input_pkts_collected.get(input_data); 34 | output_pkts_collected.get(output_data); 35 | result = input_data.compare(output_data); 36 | if(result) 37 | $display("RESULTS COMPARED SUCCESSFULLY! "); 38 | else begin 39 | `uvm_error("COMPARE", "RESULTS DID NOT MATCH! ") 40 | $display("Expected data: "); 41 | input_data.print(); 42 | $display("Actual data: "); 43 | output_data.print(); 44 | end 45 | end 46 | endtask: run_phase 47 | 48 | endclass: fifo_scoreboard -------------------------------------------------------------------------------- /sequencer.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----SEQUENCER---- 5 | 6 | class fifo_sequencer extends uvm_sequencer #(data_item); 7 | `uvm_component_utils(fifo_sequencer) 8 | 9 | function new(string name, uvm_component parent); 10 | super.new(name, parent); 11 | endfunction: new 12 | 13 | endclass: fifo_sequencer 14 | 15 | /* ----SEQUENCE INSTANCES---- 16 | Non-Reset test-1 : i) write FIFO from empty -> full -> wrap 17 | ii) read FIFO from full -> empty -> wrap 18 | 19 | Non-Reset test-2 : i) write FIFO from empty -> half-full 20 | ii) read/write concurrently 21 | 22 | Reset test : Toggles "rst_n" 23 | */ 24 | 25 | class fifo_seq_test1 extends uvm_sequence #(data_item); 26 | `uvm_object_utils(fifo_seq_test1) 27 | 28 | data_item seq; 29 | int loop1 = 48; 30 | int loop2 = 22; 31 | 32 | function new(string name = "fifo_seq_test1", uvm_component parent); 33 | super.new(name); 34 | endfunction: new 35 | 36 | task body(); 37 | for (int i = 0; i < loop1; i++) begin 38 | seq = data_item::type_id::create("write_seq"); 39 | start_item(seq); 40 | if (i < loop2) begin 41 | if (!seq.randomize() with {seq.read_en == 1'b0; seq.write_en == 1'b1;}) begin 42 | `uvm_error("Sequence", "Randomization failed for Write sequence ") 43 | end 44 | end 45 | else begin 46 | if (!seq.randomize() with {seq.read_en == 1'b1; seq.write_en == 1'b0}) begin 47 | `uvm_error("Sequence", "Randomization failed for Read sequence ") 48 | end 49 | end 50 | finish_item(seq); 51 | end 52 | endtask: body 53 | 54 | endclass: fifo_seq_test1 55 | 56 | class fifo_seq_test2 extends uvm_sequence #(data_item); 57 | `uvm_object_utils(fifo_seq_test2) 58 | 59 | data_item seq; 60 | int loop1 = 68; 61 | int loop2 = 8; 62 | 63 | function new(string name = "fifo_seq_test2", uvm_component parent); 64 | super.new(name); 65 | endfunction: new 66 | 67 | task body(); 68 | for (int i = 0; i < loop1; i++) begin 69 | seq = data_item::type_id::create("read_seq"); 70 | start_item(seq); 71 | if (i < loop2) begin 72 | if (!seq.randomize() with {seq.read_en == 1'b0; seq.write_en == 1'b1;}) begin 73 | `uvm_error("Sequence", "Randomization failed for Write sequence ") 74 | end 75 | end 76 | else begin 77 | if (!seq.randomize() with {seq.read_en == 1'b1; seq.write_en == 1'b1;}) begin 78 | `uvm_error("Sequence", "Randomization failed for Read sequence ") 79 | end 80 | end 81 | finish_item(seq); 82 | end 83 | endtask: body 84 | 85 | endclass: fifo_seq_test2 86 | 87 | class fifo_seq_reset extends uvm_sequence #(data_item); 88 | `uvm_object_utils(fifo_seq_reset) 89 | 90 | data_item seq; 91 | 92 | function new(string name = "fifo_seq_reset", uvm_component parent); 93 | super.new(name); 94 | endfunction: new 95 | 96 | task body(); 97 | seq = data_item::type_id::create("reset_seq"); 98 | start_item(seq); 99 | seq.rst_n = 1'b1; 100 | @(posedge vif.clk); 101 | seq.rst_n = 1'b0; 102 | finish_item(seq); 103 | endtask 104 | 105 | endclass: fifo_seq_reset -------------------------------------------------------------------------------- /tests_top.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----TEST TOPOLOGY---- 5 | 6 | class fifo_base_test extends uvm_test; 7 | `uvm_component_utils(fifo_base_test) 8 | 9 | fifo_env env; 10 | uvm_table_printer printer; 11 | 12 | function new(string name, uvm_component parent); 13 | super.new(name, parent); 14 | endfunction: new 15 | 16 | function void build_phase(uvm_phase phase); 17 | super.build_phase(phase); 18 | env = fifo_env::type_id::create("env", this); 19 | printer = new(); 20 | printer.knobs.depth = 4; 21 | endfunction: build_phase 22 | 23 | function void end_of_elaboration_phase(uvm_phase phase); 24 | `uvm_info(get_type_name(), $sformatf("Printing the test topology :\n%s", this.sprint(printer)), UVM_DEBUG) 25 | endfunction: end_of_elaboration_phase 26 | 27 | virtual task run_phase(uvm_phase phase); 28 | phase.phase_done.set_drain_time(this, 50); 29 | endtask: run_phase 30 | 31 | endclass: fifo_base_test 32 | 33 | 34 | class sample_test extends fifo_base_test; 35 | `uvm_component_utils(sample_test) 36 | 37 | function new(string name, uvm_component parent); 38 | super.new(name, parent); 39 | endfunction: new 40 | 41 | function void build_phase(uvm_phase phase); 42 | super.build_phase(phase); 43 | endfunction: build_phase 44 | 45 | virtual task run_phase(uvm_phase phase); 46 | fifo_seq_test1 seq; 47 | 48 | super.run_phase(phase); 49 | phase.raise_objection(this); 50 | seq = fifo_seq_test1::type_id::create("seq"); 51 | seq.start(env.fifo_in_env.agent.sequencer); 52 | phase.drop_objection(this); 53 | endtask: run_phase 54 | 55 | endclass: sample_test 56 | 57 | 58 | class fifo_reset_test extends fifo_base_test; 59 | `uvm_component_utils(fifo_reset_test) 60 | 61 | function new(string name, uvm_component parent); 62 | super.new(name, parent); 63 | endfunction: new 64 | 65 | function void build_phase(uvm_phase phase); 66 | super.build_phase(phase); 67 | endfunction: build_phase 68 | 69 | virtual task run_phase(uvm_phase phase); 70 | fifo_seq_reset seq; 71 | 72 | super.run_phase(phase); 73 | phase.raise_objection(this); 74 | seq = fifo_seq_reset::type_id::create("seq"); 75 | seq.start(env.fifo_out_env.agent.sequencer); 76 | phase.drop_objection(this); 77 | endtask: run_phase 78 | 79 | endclass: fifo_reset_test 80 | -------------------------------------------------------------------------------- /top_testbench.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | // -----TOP MODULE (TESTBENCH)----- 4 | 5 | module top_tb; 6 | import uvm_pkg::*; 7 | import fifo_pkg::*; 8 | 9 | bit clk; 10 | bit rst_n; 11 | 12 | fifo_if fifo_vif_input(.clk(clk), .rst_n(rst_n)); 13 | fifo_if fifo_vif_output(.clk(clk), .rst_n(rst_n)); 14 | 15 | fifo fifo_dut( 16 | .clk(clk), 17 | .rst_n(rst_n), 18 | .read_en(fifo_vif_input.read_en), 19 | .write_en(fifo_vif_input.write_en), 20 | .data_in(fifo_vif_input.data_in), 21 | .empty_fifo(fifo_vif_output.empty_fifo), 22 | .full_fifo(fifo_vif_output.full_fifo), 23 | .data_out(fifo_vif_output.data_out) 24 | ); 25 | 26 | initial begin 27 | rst_n = 1'b0; 28 | clk = 1'b1; 29 | #35 rst_n = 1'b1; 30 | end 31 | 32 | always #5 clk = ~clk; 33 | 34 | initial begin 35 | uvm_config_db#(virtual fifo_if)::set(null, "uvm_test_top.agent.input_intf", "fifo_if", fifo_vif_input); 36 | uvm_config_db#(virtual fifo_if)::set(null, "uvm_test_top.monitor.output_intf", "fifo_if", fifo_vif_output); 37 | 38 | run_test(); 39 | end 40 | 41 | endmodule: top_tb -------------------------------------------------------------------------------- /transaction.sv: -------------------------------------------------------------------------------- 1 | import uvm_pkg::*; 2 | `include "uvm_macros.svh" 3 | 4 | // ----DATA TRANSACTION---- 5 | 6 | class data_item extends uvm_sequence_item; 7 | rand logic read_en; 8 | rand logic write_en; 9 | rand logic [31:0] data_in; 10 | rand logic [31:0] data_out; 11 | 12 | function new(string name = "data_item", uvm_component parent); 13 | super.new(name); 14 | endfunction: new 15 | 16 | `uvm_object_utils_begin(data_item) 17 | `uvm_field_int(read_en, UVM_DEFAULT) 18 | `uvm_field_int(write_en, UVM_DEFAULT) 19 | `uvm_field_int(data_in, UVM_DEFAULT) 20 | `uvm_field_int(data_out, UVM_DEFAULT) 21 | `uvm_object_utils_end 22 | 23 | endclass: data_item 24 | --------------------------------------------------------------------------------