OpenCores
URL https://opencores.org/ocsvn/openhmc/openhmc/trunk

Subversion Repositories openhmc

[/] [openhmc/] [trunk/] [openHMC/] [sim/] [UVC/] [axi4_stream/] [sv/] [axi4_stream_hmc_monitor.sv] - Diff between revs 12 and 15

Only display areas with differences | Details | Blame | View Log

Rev 12 Rev 15
/*
/*
 *                              .--------------. .----------------. .------------.
 *                              .--------------. .----------------. .------------.
 *                             | .------------. | .--------------. | .----------. |
 *                             | .------------. | .--------------. | .----------. |
 *                             | | ____  ____ | | | ____    ____ | | |   ______ | |
 *                             | | ____  ____ | | | ____    ____ | | |   ______ | |
 *                             | ||_   ||   _|| | ||_   \  /   _|| | | .' ___  || |
 *                             | ||_   ||   _|| | ||_   \  /   _|| | | .' ___  || |
 *       ___  _ __   ___ _ __  | |  | |__| |  | | |  |   \/   |  | | |/ .'   \_|| |
 *       ___  _ __   ___ _ __  | |  | |__| |  | | |  |   \/   |  | | |/ .'   \_|| |
 *      / _ \| '_ \ / _ \ '_ \ | |  |  __  |  | | |  | |\  /| |  | | || |       | |
 *      / _ \| '_ \ / _ \ '_ \ | |  |  __  |  | | |  | |\  /| |  | | || |       | |
 *       (_) | |_) |  __/ | | || | _| |  | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
 *       (_) | |_) |  __/ | | || | _| |  | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
 *      \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
 *      \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
 *           | |               | |            | | |              | | |          | |
 *           | |               | |            | | |              | | |          | |
 *           |_|               | '------------' | '--------------' | '----------' |
 *           |_|               | '------------' | '--------------' | '----------' |
 *                              '--------------' '----------------' '------------'
 *                              '--------------' '----------------' '------------'
 *
 *
 *  openHMC - An Open Source Hybrid Memory Cube Controller
 *  openHMC - An Open Source Hybrid Memory Cube Controller
 *  (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
 *  (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
 *  www.ziti.uni-heidelberg.de
 *  www.ziti.uni-heidelberg.de
 *  B6, 26
 *  B6, 26
 *  68159 Mannheim
 *  68159 Mannheim
 *  Germany
 *  Germany
 *
 *
 *  Contact: openhmc@ziti.uni-heidelberg.de
 *  Contact: openhmc@ziti.uni-heidelberg.de
 *  http://ra.ziti.uni-heidelberg.de/openhmc
 *  http://ra.ziti.uni-heidelberg.de/openhmc
 *
 *
 *   This source file is free software: you can redistribute it and/or modify
 *   This source file is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *   (at your option) any later version.
 *
 *
 *   This source file is distributed in the hope that it will be useful,
 *   This source file is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *   GNU Lesser General Public License for more details.
 *
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this source file.  If not, see .
 *   along with this source file.  If not, see .
 *
 *
 *
 *
 */
 */
//
//
//
//
// axi4_stream_packet hmc_monitor
// axi4_stream_packet hmc_monitor
//
//
//
//
`ifndef AXI4_STREAM_HMC_MONITOR_SV
`ifndef AXI4_STREAM_HMC_MONITOR_SV
`define AXI4_STREAM_HMC_MONITOR_SV
`define AXI4_STREAM_HMC_MONITOR_SV
class axi4_stream_hmc_monitor #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends  hmc_module_mon ;
class axi4_stream_hmc_monitor #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends  hmc_module_mon ;
        int FPW ;
        int FPW ;
        int HEADERS ;
        int HEADERS ;
        int TAILS ;
        int TAILS ;
        int VALIDS ;
        int VALIDS ;
        int valids_per_cycle            = 0;
        int valids_per_cycle            = 0;
        int current_packet_length       = 0;
        int current_packet_length       = 0;
        bit request = 1;
        bit request = 1;
        int flit_delay [$];
        int flit_delay [$];
        //-- uvm_analysis_port #(hmc_packet) item_collected_port;
        //-- uvm_analysis_port #(hmc_packet) item_collected_port;
        uvm_analysis_imp #(
        uvm_analysis_imp #(
          axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)),
          axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)),
          axi4_stream_hmc_monitor  #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))
          axi4_stream_hmc_monitor  #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))
          ) axi4_port;
          ) axi4_port;
        int n_valids                            = 0;
        int n_valids                            = 0;
        int headers_seen        = 0;
        int headers_seen        = 0;
        int tails_seen          = 0;
        int tails_seen          = 0;
        typedef bit [127:0] flit_t;
        typedef bit [127:0] flit_t;
        flit_t flit_queue[$];
        flit_t flit_queue[$];
        int packets_per_cycle = 0;
        int packets_per_cycle = 0;
        hmc_packet packet_queue[$];
        hmc_packet packet_queue[$];
        //-- covergroup definition
        //-- covergroup definition
        `uvm_component_param_utils(axi4_stream_hmc_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
        `uvm_component_param_utils(axi4_stream_hmc_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
        function new ( string name="axi4_stream_hmc_monitor", uvm_component parent );
        function new ( string name="axi4_stream_hmc_monitor", uvm_component parent );
                super.new(name, parent);
                super.new(name, parent);
                axi4_port = new("axi4_port",this);
                axi4_port = new("axi4_port",this);
                hmc_pkt_cg              = new();
                hmc_pkt_cg              = new();
        endfunction : new
        endfunction : new
        function void build_phase(uvm_phase phase);
        function void build_phase(uvm_phase phase);
                super.build_phase(phase);
                super.build_phase(phase);
                FPW     = DATA_BYTES/16;//-- convert to variables!
                FPW     = DATA_BYTES/16;//-- convert to variables!
                HEADERS = FPW;
                HEADERS = FPW;
                TAILS   = 2*FPW;
                TAILS   = 2*FPW;
                VALIDS  = 0;
                VALIDS  = 0;
        endfunction : build_phase
        endfunction : build_phase
        //-- Stuff FLITs into a FIFO, separate control signals
        //-- Stuff FLITs into a FIFO, separate control signals
        function void collect_flits(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
        function void collect_flits(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
                //-- read tuser flags for valid flags
                //-- read tuser flags for valid flags
                flit_t tmp_flit;
                flit_t tmp_flit;
                flit_t current_flit;
                flit_t current_flit;
                packets_per_cycle = 0;
                packets_per_cycle = 0;
                valids_per_cycle =0;
                valids_per_cycle =0;
                for (int i = 0; i
                for (int i = 0; i
                //-- Check if valid
                //-- Check if valid
                        if (vc.tuser[VALIDS+i] == 1) begin
                        if (vc.tuser[VALIDS+i] == 1) begin
                                valids_per_cycle ++;
                                valids_per_cycle ++;
                                //-- Write 2 flit queue
                                //-- Write 2 flit queue
                                for (int b=0; b<128; b++)
                                for (int b=0; b<128; b++)
                                        tmp_flit[b] = vc.tdata[128*i+b];
                                        tmp_flit[b] = vc.tdata[128*i+b];
                                flit_queue.push_back(tmp_flit);
                                flit_queue.push_back(tmp_flit);
                                if (vc.tuser[HEADERS+i] == 1'b1) begin
                                if (vc.tuser[HEADERS+i] == 1'b1) begin
                                        headers_seen++; //-- Complete hmc_packets to assemble
                                        headers_seen++; //-- Complete hmc_packets to assemble
                                        packets_per_cycle++;
                                        packets_per_cycle++;
                                        flit_delay.push_back(n_valids);
                                        flit_delay.push_back(n_valids);
                                        n_valids = 0;
                                        n_valids = 0;
                                end
                                end
                                //-- Check if tail for complete hmc packet
                                //-- Check if tail for complete hmc packet
                                if (vc.tuser[TAILS+i] == 1'b1) begin
                                if (vc.tuser[TAILS+i] == 1'b1) begin
                                        tails_seen++; //-- Complete hmc_packets to assemble
                                        tails_seen++; //-- Complete hmc_packets to assemble
                                        assert (n_valids == 0)
                                        assert (n_valids == 0)
                                        else `uvm_fatal(get_type_name(), $psprintf("Non valid flits in pkt detected!"))
                                        else `uvm_fatal(get_type_name(), $psprintf("Non valid flits in pkt detected!"))
                                end
                                end
                                //-- Check complete hmc packets
                                //-- Check complete hmc packets
                                assert (tails_seen<= headers_seen)
                                assert (tails_seen<= headers_seen)
                                else  `uvm_fatal(get_type_name(), $psprintf("packet is null"))
                                else  `uvm_fatal(get_type_name(), $psprintf("packet is null"))
                                assert (headers_seen <= tails_seen+1)
                                assert (headers_seen <= tails_seen+1)
                                else  `uvm_fatal(get_type_name(), $psprintf("Packet without Tail detected"))
                                else  `uvm_fatal(get_type_name(), $psprintf("Packet without Tail detected"))
                        end
                        end
                        else begin
                        else begin
                                n_valids ++;
                                n_valids ++;
                        end
                        end
                end
                end
 
                if(|vc.tuser)
                `uvm_info(get_type_name(),$psprintf("%d header and %d tails available", headers_seen, tails_seen)  ,UVM_HIGH)
                `uvm_info(get_type_name(),$psprintf("%d header and %d tails available", headers_seen, tails_seen)  ,UVM_HIGH)
        endfunction : collect_flits
        endfunction : collect_flits
        //-- Use FLITs to form packets
        //-- Use FLITs to form packets
        function void collect_packet();
        function void collect_packet();
                flit_t current_flit;
                flit_t current_flit;
                bit bitstream[];
                bit bitstream[];
                //-- Assemble 1 hmc packet
                //-- Assemble 1 hmc packet
                flit_queue_underflow : assert (flit_queue.size() > 0);
                flit_queue_underflow : assert (flit_queue.size() > 0);
                //-- First flit is always header
                //-- First flit is always header
                current_flit = flit_queue.pop_front();
                current_flit = flit_queue.pop_front();
                no_length_mismatches_allowed : assert (current_flit[14:11] == current_flit[10:7]);      //--check internal hmc_packet length
                no_length_mismatches_allowed : assert (current_flit[14:11] == current_flit[10:7]);      //--check internal hmc_packet length
                current_packet_length = current_flit[10:7];
                current_packet_length = current_flit[10:7];
 
                `uvm_info(get_type_name(),$psprintf("packet length %0d ", current_packet_length), UVM_HIGH)
 
                `uvm_info(get_type_name(),$psprintf("queue size %0d ", flit_queue.size()), UVM_HIGH)
                flit_queue_underflow2 : assert (flit_queue.size() >= current_packet_length - 1);                //--check check hmc_packet complete received
                flit_queue_underflow2 : assert (flit_queue.size() >= current_packet_length - 1);                //--check check hmc_packet complete received
                //-- pack flits 2 bitstream
                //-- pack flits 2 bitstream
                bitstream = new[current_packet_length*128];
                bitstream = new[current_packet_length*128];
                //-- Pack first flit
                //-- Pack first flit
                for (int i=0; i<128; i=i+1)
                for (int i=0; i<128; i=i+1)
                        bitstream[i] = current_flit[i];
                        bitstream[i] = current_flit[i];
                //-- Get and pack the remaining flits
                //-- Get and pack the remaining flits
                for (int flit=1; flit < current_packet_length; flit ++) begin
                for (int flit=1; flit < current_packet_length; flit ++) begin
                        current_flit = flit_queue.pop_front();
                        current_flit = flit_queue.pop_front();
                        `uvm_info(get_type_name(),$psprintf("pop flit %0d (%0x)", flit, current_flit), UVM_HIGH)
                        `uvm_info(get_type_name(),$psprintf("pop flit %0d (%0x)", flit, current_flit), UVM_HIGH)
                        for (int i=0; i<128; i=i+1) begin
                        for (int i=0; i<128; i=i+1) begin
                                bitstream[flit*128+i] = current_flit[i];
                                bitstream[flit*128+i] = current_flit[i];
                        end
                        end
                end
                end
                packet = hmc_packet::type_id::create("packet", this);
                packet = hmc_packet::type_id::create("packet", this);
                void'(packet.unpack(bitstream));
                void'(packet.unpack(bitstream));
                packet.flit_delay = flit_delay.pop_front();
                packet.flit_delay = flit_delay.pop_front();
                hmc_pkt_cg.sample();
                hmc_pkt_cg.sample();
                //-- assembled a packet
                //-- assembled a packet
                headers_seen--;
                headers_seen--;
                tails_seen--;
                tails_seen--;
                if (packet == null) begin
                if (packet == null) begin
                  `uvm_fatal(get_type_name(), $psprintf("packet is null"))
                  `uvm_fatal(get_type_name(), $psprintf("packet is null"))
                end
                end
                packet_queue.push_back(packet);
                packet_queue.push_back(packet);
                if(packet.get_command_type() == HMC_RESPONSE_TYPE)begin
                if(packet.get_command_type() == HMC_RESPONSE_TYPE)begin
                `uvm_info("RESPONSE collected",$psprintf("Rsp %0d : %s",rsp_rcvd, packet.command.name()), UVM_LOW)
                `uvm_info("RESPONSE collected",$psprintf("Rsp %0d : %s",rsp_rcvd, packet.command.name()), UVM_LOW)
                rsp_rcvd++;
                rsp_rcvd++;
                end else begin
                end else begin
                `uvm_info("REQUEST collected",$psprintf("Req %0d : %s",req_rcvd, packet.command.name()), UVM_LOW)
                `uvm_info("REQUEST collected",$psprintf("Req %0d : %s",req_rcvd, packet.command.name()), UVM_LOW)
                req_rcvd++;
                req_rcvd++;
                end
                end
                `uvm_info("AXI4 to HMC Monitor",$psprintf("\n%s", packet.sprint()), UVM_HIGH)
                `uvm_info("AXI4 to HMC Monitor",$psprintf("\n%s", packet.sprint()), UVM_HIGH)
        endfunction : collect_packet
        endfunction : collect_packet
        function void write(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
        function void write(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
                hmc_packet packet;
                hmc_packet packet;
 
 
 
 
                `uvm_info(get_type_name(),$psprintf("got valid cycle"), UVM_HIGH)
 
 
 
                collect_flits(vc);
                collect_flits(vc);
 
 
 
                //`uvm_info(get_type_name(),$psprintf("got %0d tails and %0d flits",tails_seen, flit_queue.size() ), UVM_HIGH)
                `uvm_info(get_type_name(),$psprintf("got %0d tails and %0d flits",tails_seen, flit_queue.size() ), UVM_HIGH)
 
 
 
 
 
                //-- Convert flit_queue to hmc_packets
                //-- Convert flit_queue to hmc_packets
                while (tails_seen >0) begin
                while (tails_seen >0) begin
                        collect_packet();
                        collect_packet();
                end
                end
                //-- If flit queue is not empty -> hmc packet striped over 2 axi cycles
                //-- If flit queue is not empty -> hmc packet striped over 2 axi cycles
                while (packet_queue.size()>0) begin
                while (packet_queue.size()>0) begin
                        packet = packet_queue.pop_front();
                        packet = packet_queue.pop_front();
                        //if (packet.command != HMC_ERROR_RESPONSE)
                        //if (packet.command != HMC_ERROR_RESPONSE)
                                item_collected_port.write(packet);
                                item_collected_port.write(packet);
                end
                end
        endfunction
        endfunction
        function void check_phase(uvm_phase phase);
        function void check_phase(uvm_phase phase);
                if (flit_queue.size() >0)
                if (flit_queue.size() >0)
                        `uvm_fatal(get_type_name(),$psprintf("flit_queue is not empty: %0d", flit_queue.size()))
                        `uvm_fatal(get_type_name(),$psprintf("flit_queue is not empty: %0d", flit_queue.size()))
        endfunction : check_phase
        endfunction : check_phase
endclass : axi4_stream_hmc_monitor
endclass : axi4_stream_hmc_monitor
`endif // AXI4_STREAM_HMC_MONITOR_SV
`endif // AXI4_STREAM_HMC_MONITOR_SV
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.