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] - Blame information for rev 12

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 juko
/*
2
 *                              .--------------. .----------------. .------------.
3
 *                             | .------------. | .--------------. | .----------. |
4
 *                             | | ____  ____ | | | ____    ____ | | |   ______ | |
5
 *                             | ||_   ||   _|| | ||_   \  /   _|| | | .' ___  || |
6
 *       ___  _ __   ___ _ __  | |  | |__| |  | | |  |   \/   |  | | |/ .'   \_|| |
7
 *      / _ \| '_ \ / _ \ '_ \ | |  |  __  |  | | |  | |\  /| |  | | || |       | |
8
 *       (_) | |_) |  __/ | | || | _| |  | |_ | | | _| |_\/_| |_ | | |\ `.___.'\| |
9
 *      \___/| .__/ \___|_| |_|| ||____||____|| | ||_____||_____|| | | `._____.'| |
10
 *           | |               | |            | | |              | | |          | |
11
 *           |_|               | '------------' | '--------------' | '----------' |
12
 *                              '--------------' '----------------' '------------'
13
 *
14
 *  openHMC - An Open Source Hybrid Memory Cube Controller
15
 *  (C) Copyright 2014 Computer Architecture Group - University of Heidelberg
16
 *  www.ziti.uni-heidelberg.de
17
 *  B6, 26
18
 *  68159 Mannheim
19
 *  Germany
20
 *
21
 *  Contact: openhmc@ziti.uni-heidelberg.de
22
 *  http://ra.ziti.uni-heidelberg.de/openhmc
23
 *
24
 *   This source file is free software: you can redistribute it and/or modify
25
 *   it under the terms of the GNU Lesser General Public License as published by
26
 *   the Free Software Foundation, either version 3 of the License, or
27
 *   (at your option) any later version.
28
 *
29
 *   This source file is distributed in the hope that it will be useful,
30
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
 *   GNU Lesser General Public License for more details.
33
 *
34
 *   You should have received a copy of the GNU Lesser General Public License
35
 *   along with this source file.  If not, see .
36
 *
37
 *
38
 */
39
 
40
//
41
//
42
// axi4_stream_packet hmc_monitor
43
//
44
//
45
 
46
`ifndef AXI4_STREAM_HMC_MONITOR_SV
47
`define AXI4_STREAM_HMC_MONITOR_SV
48
 
49
class axi4_stream_hmc_monitor #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends  hmc_module_mon ;
50
 
51
 
52
        int FPW ;
53
        int HEADERS ;
54
        int TAILS ;
55
        int VALIDS ;
56
        int valids_per_cycle            = 0;
57
        int current_packet_length       = 0;
58
 
59
        bit request = 1;
60
 
61
        int flit_delay [$];
62
 
63
 
64
        //-- uvm_analysis_port #(hmc_packet) item_collected_port;
65
        uvm_analysis_imp #(
66
          axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)),
67
          axi4_stream_hmc_monitor  #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH))
68
          ) axi4_port;
69
 
70
        int n_valids                            = 0;
71
 
72
        int headers_seen        = 0;
73
        int tails_seen          = 0;
74
 
75
 
76
        typedef bit [127:0] flit_t;
77
        flit_t flit_queue[$];
78
 
79
        int packets_per_cycle = 0;
80
 
81
 
82
        hmc_packet packet_queue[$];
83
 
84
        //-- covergroup definition
85
 
86
 
87
 
88
 
89
        `uvm_component_param_utils(axi4_stream_hmc_monitor #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)))
90
 
91
 
92
        function new ( string name="axi4_stream_hmc_monitor", uvm_component parent );
93
                super.new(name, parent);
94
 
95
                axi4_port = new("axi4_port",this);
96
 
97
                hmc_pkt_cg              = new();
98
 
99
 
100
        endfunction : new
101
 
102
        function void build_phase(uvm_phase phase);
103
                super.build_phase(phase);
104
                FPW     = DATA_BYTES/16;//-- convert to variables!
105
                HEADERS = FPW;
106
                TAILS   = 2*FPW;
107
                VALIDS  = 0;
108
        endfunction : build_phase
109
 
110
        //-- Stuff FLITs into a FIFO, separate control signals
111
        function void collect_flits(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
112
                //-- read tuser flags for valid flags
113
                flit_t tmp_flit;
114
                flit_t current_flit;
115
                packets_per_cycle = 0;
116
                valids_per_cycle =0;
117
                for (int i = 0; i
118
                //-- Check if valid
119
                        if (vc.tuser[VALIDS+i] == 1) begin
120
                                valids_per_cycle ++;
121
 
122
 
123
 
124
                                //-- Write 2 flit queue
125
                                for (int b=0; b<128; b++)
126
                                        tmp_flit[b] = vc.tdata[128*i+b];
127
                                flit_queue.push_back(tmp_flit);
128
 
129
                                if (vc.tuser[HEADERS+i] == 1'b1) begin
130
                                        headers_seen++; //-- Complete hmc_packets to assemble
131
                                        packets_per_cycle++;
132
                                        flit_delay.push_back(n_valids);
133
                                        n_valids = 0;
134
                                end
135
                                //-- Check if tail for complete hmc packet
136
                                if (vc.tuser[TAILS+i] == 1'b1) begin
137
                                        tails_seen++; //-- Complete hmc_packets to assemble
138
 
139
                                        assert (n_valids == 0)
140
                                        else `uvm_fatal(get_type_name(), $psprintf("Non valid flits in pkt detected!"))
141
                                end
142
 
143
                                //-- Check complete hmc packets
144
 
145
                                assert (tails_seen<= headers_seen)
146
                                else  `uvm_fatal(get_type_name(), $psprintf("packet is null"))
147
 
148
                                assert (headers_seen <= tails_seen+1)
149
                                else  `uvm_fatal(get_type_name(), $psprintf("Packet without Tail detected"))
150
 
151
                        end
152
                        else begin
153
                                n_valids ++;
154
                        end
155
 
156
                end
157
 
158
                `uvm_info(get_type_name(),$psprintf("%d header and %d tails available", headers_seen, tails_seen)  ,UVM_HIGH)
159
 
160
 
161
 
162
        endfunction : collect_flits
163
 
164
        //-- Use FLITs to form packets
165
        function void collect_packet();
166
 
167
                flit_t current_flit;
168
                bit bitstream[];
169
 
170
                //-- Assemble 1 hmc packet
171
                flit_queue_underflow : assert (flit_queue.size() > 0);
172
 
173
                //-- First flit is always header
174
                current_flit = flit_queue.pop_front();
175
                no_length_mismatches_allowed : assert (current_flit[14:11] == current_flit[10:7]);      //--check internal hmc_packet length
176
                current_packet_length = current_flit[10:7];
177
                flit_queue_underflow2 : assert (flit_queue.size() >= current_packet_length - 1);                //--check check hmc_packet complete received
178
 
179
 
180
                //-- pack flits 2 bitstream
181
                bitstream = new[current_packet_length*128];
182
 
183
                //-- Pack first flit
184
                for (int i=0; i<128; i=i+1)
185
                        bitstream[i] = current_flit[i];
186
 
187
                //-- Get and pack the remaining flits
188
                for (int flit=1; flit < current_packet_length; flit ++) begin
189
                        current_flit = flit_queue.pop_front();
190
                        `uvm_info(get_type_name(),$psprintf("pop flit %0d (%0x)", flit, current_flit), UVM_HIGH)
191
                        for (int i=0; i<128; i=i+1) begin
192
                                bitstream[flit*128+i] = current_flit[i];
193
                        end
194
                end
195
 
196
 
197
 
198
 
199
                packet = hmc_packet::type_id::create("packet", this);
200
                void'(packet.unpack(bitstream));
201
                packet.flit_delay = flit_delay.pop_front();
202
 
203
                hmc_pkt_cg.sample();
204
 
205
                //-- assembled a packet
206
                headers_seen--;
207
                tails_seen--;
208
 
209
                if (packet == null) begin
210
                  `uvm_fatal(get_type_name(), $psprintf("packet is null"))
211
                end
212
 
213
                packet_queue.push_back(packet);
214
 
215
                if(packet.get_command_type() == HMC_RESPONSE_TYPE)begin
216
                `uvm_info("RESPONSE collected",$psprintf("Rsp %0d : %s",rsp_rcvd, packet.command.name()), UVM_LOW)
217
                rsp_rcvd++;
218
                end else begin
219
                `uvm_info("REQUEST collected",$psprintf("Req %0d : %s",req_rcvd, packet.command.name()), UVM_LOW)
220
                req_rcvd++;
221
                end
222
                `uvm_info("AXI4 to HMC Monitor",$psprintf("\n%s", packet.sprint()), UVM_HIGH)
223
        endfunction : collect_packet
224
 
225
        function void write(input axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)) vc);
226
 
227
 
228
                hmc_packet packet;
229
 
230
 
231
                `uvm_info(get_type_name(),$psprintf("got valid cycle"), UVM_HIGH)
232
 
233
                collect_flits(vc);
234
 
235
 
236
                `uvm_info(get_type_name(),$psprintf("got %0d tails and %0d flits",tails_seen, flit_queue.size() ), UVM_HIGH)
237
 
238
 
239
                //-- Convert flit_queue to hmc_packets
240
                while (tails_seen >0) begin
241
                        collect_packet();
242
                end
243
                //-- If flit queue is not empty -> hmc packet striped over 2 axi cycles
244
 
245
 
246
                while (packet_queue.size()>0) begin
247
                        packet = packet_queue.pop_front();
248
                        //if (packet.command != HMC_ERROR_RESPONSE)
249
                                item_collected_port.write(packet);
250
                end
251
        endfunction
252
 
253
        function void check_phase(uvm_phase phase);
254
                if (flit_queue.size() >0)
255
                        `uvm_fatal(get_type_name(),$psprintf("flit_queue is not empty: %0d", flit_queue.size()))
256
        endfunction : check_phase
257
endclass : axi4_stream_hmc_monitor
258
 
259
`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.