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

Subversion Repositories openhmc

[/] [openhmc/] [trunk/] [openHMC/] [sim/] [tb/] [common/] [src/] [hmc_2_axi4_sequence.sv] - Blame information for rev 15

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 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
// hmc_2_axi4_sequence
43
//
44
//
45
 
46
`ifndef HMC_2_AXI4_SEQUENCE_SV
47
`define HMC_2_AXI4_SEQUENCE_SV
48
 
49
class hmc_2_axi4_sequence #(parameter DATA_BYTES = 16, parameter TUSER_WIDTH = 16) extends uvm_sequence #(axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES), .TUSER_WIDTH(TUSER_WIDTH)));
50
 
51
        int unsigned num_packets = 1;                           //-- packets to generate
52
        int unsigned max_pkts_per_cycle = 4;            //-- maximum packets in single AXI4 cycle
53
 
54
 
55
        rand hmc_req_packet hmc_items[];
56
        hmc_packet hmc_packets_ready[$];
57
 
58
        int working_pos = 0;
59
 
60
 
61
        typedef bit [1+1+1+127:0] tail_header_flit_t;
62
        tail_header_flit_t flit_queue[$];
63
        rand int tag = 0;
64
 
65
        constraint tag_value_c {
66
                tag >= 0;
67
                tag <  512;
68
        }
69
 
70
        axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)) axi4_queue[$];
71
 
72
        `uvm_object_param_utils_begin(hmc_2_axi4_sequence #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)))
73
                `uvm_field_int(num_packets, UVM_DEFAULT | UVM_DEC)
74
                `uvm_field_int(max_pkts_per_cycle, UVM_DEFAULT | UVM_DEC)
75
        `uvm_object_utils_end
76
 
77
        `uvm_declare_p_sequencer(hmc_2_axi4_sequencer #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)))
78
 
79
 
80
        function new(string name="hmc_2_axi4_sequence");
81
                super.new(name);
82
 
83
        endfunction : new
84
 
85
        function void pre_randomize ();
86
                super.pre_randomize();
87
 
88
                hmc_items = new[num_packets];
89
 
90
                foreach (hmc_items[i]) begin
91
                        hmc_items[i] = hmc_req_packet::type_id::create($psprintf("hmc_item[%0d]", i) );
92
                end
93
 
94
                `uvm_info(get_type_name(),$psprintf("%0d HMC packets generated", num_packets), UVM_HIGH)
95
        endfunction : pre_randomize
96
 
97
        function void pack_hmc_packet(hmc_packet pkt);
98
                bit bitstream[];
99
                tail_header_flit_t tmp_flit;
100
 
101
                int unsigned bitcount;
102
                int unsigned packet_count=1;
103
 
104
                bitcount = pkt.pack(bitstream);
105
 
106
                pkt_successfully_packed : assert (bitcount > 0);
107
 
108
                //-- For each FLIT in the packet, add the flit entry
109
                for (int f=0; f
110
                        for (int i=0; i< 128; i++)
111
                                tmp_flit[i] = bitstream[f*128+i];
112
 
113
                        tmp_flit[128] = (f==0);                                 //-- Header
114
 
115
                        tmp_flit[129] = (f==bitcount/128-1);    //-- Tail
116
 
117
                        tmp_flit[130] = 1'b1;                                   //-- Flit is valid
118
 
119
                        flit_queue.push_back(tmp_flit);
120
                end
121
        endfunction : pack_hmc_packet
122
 
123
        function void hmc_packet_2_axi_cycles();
124
 
125
                axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)) axi4_item;
126
 
127
                int unsigned FPW     = DATA_BYTES/16; //--FPW: desired Data width in Flits (HMC packet length) valid: 4.6.8  databytes= tdata_width /8 fpw = tdata_width /128
128
                int unsigned HEADERS = 1*FPW;
129
                int unsigned TAILS   = 2*FPW;
130
                int unsigned VALIDS  = 0;
131
 
132
                int unsigned pkts_in_cycle = 0;         //-- HMC tails inserted in current AXI4 cycle
133
                int unsigned header_in_cycle = 0;               //-- HMC headers inserted in current AXI4 cycle
134
                int unsigned valids_in_cycle = 0;
135
                hmc_packet hmc_pkt;
136
 
137
 
138
                int flit_offset=0;              //-- flit offset First flit-> create new axi_item
139
                tail_header_flit_t current_flit;
140
                tail_header_flit_t next_flit;
141
 
142
 
143
                //-- create empty vc
144
                `uvm_create_on(axi4_item, p_sequencer)
145
                        axi4_item.tdata = 0;
146
                        axi4_item.tuser = 0;
147
                        axi4_item.delay = hmc_packets_ready[0].flit_delay / FPW; //-- measured in flits
148
 
149
                while (hmc_packets_ready.size() >0 )  begin
150
                        hmc_pkt = hmc_packets_ready.pop_front();
151
                        pack_hmc_packet(hmc_pkt);
152
 
153
 
154
                        //-- write flits 2 axi4_queue
155
                        while( flit_queue.size > 0 ) begin      //-- flit queue contains flits
156
 
157
 
158
                                current_flit = flit_queue.pop_front();
159
 
160
                                        if (current_flit[128]) begin    //-- If current flit is header
161
                                                flit_offset += hmc_pkt.flit_delay;
162
                                        end
163
 
164
                                //-- check if axi4_item is full
165
                                if ((flit_offset >= FPW) || pkts_in_cycle == max_pkts_per_cycle  ) begin
166
                                        //-- push full axi item to axi4_queue
167
                                        `uvm_info(get_type_name(),$psprintf("axi4_item is full (offset = %0d), writing element %0d to queue ", flit_offset, axi4_queue.size()), UVM_MEDIUM)
168
 
169
                                        if (valids_in_cycle != 0)
170
                                        axi4_queue.push_back(axi4_item);
171
 
172
                                        //-- create new AXI4 cycle
173
                                        `uvm_create_on(axi4_item, p_sequencer)
174
                                        axi4_item.tdata = 0;
175
                                        axi4_item.tuser = 0;
176
 
177
                                        //-- set AXI4 cycle delay
178
                                        axi4_item.delay = (flit_offset / FPW) -1;       //-- flit offset contains also empty flits
179
                                        if (flit_offset % FPW >0)
180
                                                axi4_item.delay += 1;
181
 
182
                                        //-- reset counter
183
                                        `uvm_info(get_type_name(),$psprintf("HMC Packets in last cycle: %0d, %0d", pkts_in_cycle, header_in_cycle), UVM_HIGH)
184
                                        pkts_in_cycle   = 0;    //-- reset HMC packet counter in AXI4 Cycle
185
                                        header_in_cycle = 0;
186
                                        valids_in_cycle = 0;
187
                                        `uvm_info(get_type_name(),$psprintf("axi_delay is %0d", axi4_item.delay), UVM_MEDIUM)
188
 
189
                                        //-- reset flit_offset
190
                                        flit_offset = 0;
191
                                end
192
 
193
                                //-- write flit to axi4_item
194
                                for (int i =0;i<128;i++) begin
195
                                        axi4_item.tdata[(flit_offset*128)+i] = current_flit[i];
196
                                end
197
 
198
                                //-- Write tuser flags
199
                                //-- write valid
200
                                axi4_item.tuser[VALIDS  +flit_offset] = current_flit[130];      //-- valid [fpw-1:0]
201
                                //-- write header
202
                                axi4_item.tuser[HEADERS +flit_offset] = current_flit[128];      //-- only 1 if header
203
                                //-- write tail
204
                                axi4_item.tuser[TAILS   +flit_offset] = current_flit[129];      //-- only 1 if tail
205
 
206
                                valids_in_cycle ++;
207
 
208
 
209
                                if(current_flit[129]) begin             //-- count tails in current cycle
210
                                        pkts_in_cycle ++;
211
                                end
212
 
213
                                if(current_flit[128]) begin             //-- count headers in current cycle
214
                                        header_in_cycle ++;
215
                                end
216
 
217
                                //-- debugging output
218
                                if(current_flit[128]) begin
219
                                        `uvm_info(get_type_name(),$psprintf("FLIT is header at pos %d", flit_offset), UVM_MEDIUM)
220
                                end
221
                                if(current_flit[129]) begin
222
                                        `uvm_info(get_type_name(),$psprintf("FLIT is tail at pos %d", flit_offset), UVM_MEDIUM)
223
                                end
224
 
225
                                flit_offset++;
226
                        end
227
                end
228
                //-- push last axi4_item to axi4_queue
229
                axi4_queue.push_back(axi4_item);
230
 
231
        endfunction : hmc_packet_2_axi_cycles
232
 
233
 
234
        task aquire_tags();
235
                for (int i = working_pos; i < hmc_items.size(); i++) begin //-- get a tag for each packet
236
                                //-- only register a tag if response required!
237
                                if      (hmc_items[i].get_command_type() == HMC_WRITE_TYPE              ||
238
                                         hmc_items[i].get_command_type() == HMC_MISC_WRITE_TYPE ||
239
                                         hmc_items[i].get_command_type() == HMC_READ_TYPE               ||
240
                                         hmc_items[i].get_command_type() == HMC_MODE_READ_TYPE)
241
                                begin
242
                                        p_sequencer.handler.get_tag(tag);
243
                                end else begin
244
                                        tag = 0;
245
                                end
246
 
247
                                hmc_items[i].tag = tag;
248
 
249
                                //-- move packet to ready queue if tag valid
250
                                if (tag >= 0) begin
251
 
252
                                        `uvm_info(get_type_name(),$psprintf("Tag for HMC Packet Type %0d is: %0d", hmc_items[i].get_command_type(), hmc_items[i]), UVM_HIGH)
253
                                        hmc_packets_ready.push_back(hmc_items[i]);
254
                                        working_pos = i+1;
255
                                end else begin
256
                                        break;  //-- send all already processed AXI4 Cycles if tag_handler can not provide an additional tag
257
                                end
258
                        end
259
 
260
        endtask : aquire_tags
261
 
262
        task send_axi4_cycles();
263
                axi4_stream_valid_cycle #(.DATA_BYTES(DATA_BYTES),.TUSER_WIDTH(TUSER_WIDTH)) axi4_item;
264
                while( axi4_queue.size() > 0 ) begin
265
                                        `uvm_info(get_type_name(),$psprintf("axi4_queue contains %0d items", axi4_queue.size()), UVM_MEDIUM)
266
 
267
                                        axi4_item = axi4_queue.pop_front();
268
 
269
                                        if ((axi4_item.tuser == {{(TUSER_WIDTH){1'b0}}})) begin
270
                                                axi4_item.print();
271
                                                `uvm_fatal("AXI4_Master_Driver", "sent an empty cycle")
272
                                        end
273
                                        `uvm_send(axi4_item);
274
 
275
                                        `uvm_info(get_type_name(),$psprintf("\n%s", axi4_item.sprint()), UVM_HIGH)
276
                                end
277
 
278
 
279
        endtask : send_axi4_cycles
280
 
281
        task body();
282
 
283
                `uvm_info(get_type_name(),$psprintf("HMC Packets to send: %0d", hmc_items.size()), UVM_MEDIUM)
284
 
285
                while (hmc_items.size-1 >= working_pos)begin //-- cycle until all hmc_packets have been sent
286
                        //-- try to aquire a tag for each non posted packet
287
                        aquire_tags();
288
 
289
                        //-- send all packets with tags
290
                        if (hmc_packets_ready.size()>0) begin
291
 
292
                                //-- generate axi4_queue
293
                                hmc_packet_2_axi_cycles();
294
 
295
                                //-- send axi4_queue
296
                                send_axi4_cycles();
297
                        end
298
                end
299
        endtask : body
300
 
301
endclass : hmc_2_axi4_sequence
302
 
303
`endif // HMC_2_AXI4_SEQUENCE_SV
304
 

powered by: WebSVN 2.1.0

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