source: trunk/modules/vci_vdspin_target_wrapper/caba/source/src/vci_vdspin_target_wrapper.cpp @ 287

Last change on this file since 287 was 287, checked in by joannou, 11 years ago

Updated vci_vdspin_initiator_wrapper and vci_vdspin_target_wrapper to fit new spec :
A single flit VCI response packet with a rdata=0 is translated to a single flit DSPIN response packet.
(All other responses need multi flit DSPIN response packets)

File size: 14.6 KB
Line 
1/* -*- c++ -*-
2  * File : vci_vdspin_target_wrapper.cpp
3  * Copyright (c) UPMC, Lip6
4  * Author : Alain Greiner
5  *
6  * SOCLIB_LGPL_HEADER_BEGIN
7  *
8  * This file is part of SoCLib, GNU LGPLv2.1.
9  *
10  * SoCLib is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published
12  * by the Free Software Foundation; version 2.1 of the License.
13  *
14  * SoCLib is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with SoCLib; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  *
24  * SOCLIB_LGPL_HEADER_END
25  *
26  * Maintainers: alexandre.joannou@lip6.fr
27  *
28  */
29
30#include "../include/vci_vdspin_target_wrapper.h"
31
32using namespace soclib::common;
33
34namespace soclib { namespace caba {
35
36#define tmpl(x) template<typename vci_param, int dspin_cmd_width, int dspin_rsp_width> x VciVdspinTargetWrapper<vci_param, dspin_cmd_width, dspin_rsp_width>
37
38//////////////////////////////////////////////////////////////////////////////////////////
39tmpl(/**/)::VciVdspinTargetWrapper( sc_module_name  name,
40                                    size_t          cmd_fifo_depth,
41                                    size_t          rsp_fifo_depth  )
42        :   soclib::caba::BaseModule(name),
43            p_clk("p_clk"),
44            p_resetn("p_resetn"),
45            p_dspin_out("p_dspin_out"),
46            p_dspin_in("p_dspin_in"),
47            p_vci("p_vci"),
48            r_cmd_fsm("r_cmd_fsm"),
49            r_rsp_fsm("r_rsp_fsm"),
50            r_fifo_cmd("r_fifo_cmd", cmd_fifo_depth),
51            r_fifo_rsp("r_fifo_rsp", rsp_fifo_depth)
52{
53    SC_METHOD (transition);
54    dont_initialize();
55    sensitive << p_clk.pos();
56
57    SC_METHOD (genMoore);
58    dont_initialize();
59    sensitive  << p_clk.neg();
60
61    assert( (dspin_cmd_width == 40) && "The DSPIN CMD flit width must have 40 bits");
62    assert( (dspin_rsp_width == 33) && "The DSPIN RSP flit width must have 33 bits");
63    assert( (vci_param::N    <= 40) && "The VCI ADDRESS field cannot have more than 40 bits");
64    assert( (vci_param::B    == 4 ) && "The VCI DATA filds must have 32 bits");
65    assert( (vci_param::K    == 8 ) && "The VCI PLEN field cannot have more than 8 bits");
66    assert( (vci_param::S    <= 14) && "The VCI SRCID field cannot have more than 14 bits");
67    assert( (vci_param::T    <= 4 ) && "The VCI TRDID field cannot have more than 4 bits");
68    assert( (vci_param::P    <= 4 ) && "The VCI PKTID field cannot have more than 4 bits");
69    assert( (vci_param::E    <= 2 ) && "The VCI RERROR field cannot have more than 2 bits");
70
71} //  end constructor
72
73/////////////////////////
74tmpl(void)::transition()
75{
76    sc_uint<dspin_cmd_width>    cmd_fifo_data;
77    bool                        cmd_fifo_write;
78    bool                        cmd_fifo_read;
79
80    sc_uint<dspin_rsp_width>    rsp_fifo_data;
81    bool                        rsp_fifo_write;
82    bool                        rsp_fifo_read;
83
84    if (p_resetn == false)
85    {
86        r_fifo_cmd.init();
87        r_fifo_rsp.init();
88        r_cmd_fsm = CMD_IDLE;
89        r_rsp_fsm = RSP_IDLE;
90        return;
91    } // end reset
92
93    /////////////////////////////////////////////////////////////
94    // VCI response packet to DSPIN response packet.
95    // The VCI packet is analysed, translated,
96    // and the DSPIN packet is stored in the fifo_rsp
97    /////////////////////////////////////////////////////////////
98    // - A single flit VCI response packet with a 0 RDATA value
99    //   is translated to a single flit DSPIN response.
100    // - All other VCI responses are translated to a multi-flit
101    //   DSPIN response.
102    // In the RSP_IDLE state, the first DSPIN flit is written
103    // in fifo_rsp , but no VCI flit is consumed. The VCI flits
104    // are consumed in the RSP_DSPIN_SINGLE_FLIT, or the
105    // SP_DSPIN_MULTI_FLIT states.
106    //////////////////////////////////////////////////////////////
107
108    // rsp_fifo_read
109    rsp_fifo_read = p_dspin_out.read.read();
110
111    // r_rsp_fsm, rsp_fifo_write and rsp_fifo_data
112    rsp_fifo_write = false;        // default value
113
114    switch(r_rsp_fsm)
115    {
116        case RSP_IDLE:        // write first DSPIN flit into rsp_fifo
117        {
118            if( p_vci.rspval.read() && r_fifo_rsp.wok() )
119            {
120                bool is_single_flit = ( p_vci.reop.read() && ( p_vci.rdata.read() == 0) );
121
122                rsp_fifo_write = true;
123                rsp_fifo_data  = (((sc_uint<dspin_rsp_width>)p_vci.rsrcid.read()) << 18) |
124                                 (((sc_uint<dspin_rsp_width>)p_vci.rerror.read()) << 16) |
125                                 (((sc_uint<dspin_rsp_width>)p_vci.rtrdid.read()) << 12) |
126                                 (((sc_uint<dspin_rsp_width>)p_vci.rpktid.read()) << 8);
127                if ( is_single_flit )
128                {
129                    rsp_fifo_data = rsp_fifo_data | 0x100000000LL; // EOP = 1
130                    rsp_fifo_data = rsp_fifo_data & 0x1FFFFFFFELL; // BC  = 0
131                    r_rsp_fsm = RSP_DSPIN_SINGLE_FLIT;
132                }
133                else
134                {
135                    rsp_fifo_data = rsp_fifo_data & 0x0FFFFFFFFLL; // EOP = 0
136                    rsp_fifo_data = rsp_fifo_data & 0x1FFFFFFFELL; // BC  = 0
137                    r_rsp_fsm = RSP_DSPIN_MULTI_FLIT;
138                }
139            }
140            break;
141        }
142        case RSP_DSPIN_SINGLE_FLIT:
143        {
144            rsp_fifo_write = false;
145            if ( r_fifo_rsp.wok() )
146                r_rsp_fsm = RSP_IDLE;
147            break;
148        }
149        case RSP_DSPIN_MULTI_FLIT:        // write DSPIN data flit
150        {
151            if( p_vci.rspval && r_fifo_rsp.wok() )
152            {
153                rsp_fifo_write   = true;
154                rsp_fifo_data = ((sc_uint<dspin_rsp_width>)p_vci.rdata.read());
155                if ( p_vci.reop )
156                {
157                    rsp_fifo_data = rsp_fifo_data | 0x100000000LL; // EOP = 1
158                    r_rsp_fsm = RSP_IDLE;
159                }
160            }
161            break;
162        }
163    } // end switch r_cmd_fsm
164
165    // fifo_rsp
166    if((rsp_fifo_write == true)  && (rsp_fifo_read == false)) { r_fifo_rsp.simple_put(rsp_fifo_data); }
167    if((rsp_fifo_write == true)  && (rsp_fifo_read == true))  { r_fifo_rsp.put_and_get(rsp_fifo_data); }
168    if((rsp_fifo_write == false) && (rsp_fifo_read == true))  { r_fifo_rsp.simple_get(); }
169
170    //////////////////////////////////////////////////////////////
171    // DSPIN command packet to VCI command packet
172    // The DSPIN packet is stored in the fifo_cmd
173    // The FIFO output is analysed and translated to a VCI packet
174    //////////////////////////////////////////////////////////////
175    // - A 2 flits DSPIN broadcast command is translated
176    //   to a 1 flit VCI broadcast command.
177    // - A 2 flits DSPIN read command is translated
178    //   to a 1 flit VCI read command.
179    // - A N+2 flits DSPIN write command is translated
180    //   to a N flits VCI write command.
181    // The VCI flits are sent in the CMD_READ, CMD_WDATA
182    // & CMD_BROADCAST states.
183    // The r_cmd_buf0 et r_cmd_buf1 buffers are used to store
184    // the two first DSPIN flits (in case of write).
185    //////////////////////////////////////////////////////////////
186
187    // cmd_fifo_write, cmd_fifo_data
188    cmd_fifo_write = p_dspin_in.write.read();
189    cmd_fifo_data  = p_dspin_in.data.read();
190
191    // r_cmd_fsm, cmd_fifo_read
192    cmd_fifo_read = false;         // default value
193
194    switch(r_cmd_fsm)
195    {
196        case CMD_IDLE:
197        {
198            if( r_fifo_cmd.rok() )
199            {
200                bool is_broadcast = ( (r_fifo_cmd.read() & 0x1) == 0x1);
201
202                cmd_fifo_read = true;
203                r_cmd_buf0    = r_fifo_cmd.read();         // save address
204
205                if ( is_broadcast )
206                    r_cmd_fsm = CMD_BROADCAST;
207                else
208                    r_cmd_fsm = CMD_RW;
209            }
210            break;
211        }
212        case CMD_BROADCAST:
213        {
214            if( r_fifo_cmd.rok() && p_vci.cmdack )
215            {
216                cmd_fifo_read = true;
217                r_cmd_fsm = CMD_IDLE;
218            }
219            break;
220        }
221        case CMD_RW:
222        {
223            if( r_fifo_cmd.rok() )
224            {
225                cmd_fifo_read = true;
226                r_cmd_buf1 = r_fifo_cmd.read();        // save command parameters
227                // read command if EOP
228                if ( (r_fifo_cmd.read() & 0x8000000000LL) )
229                    r_cmd_fsm = CMD_READ;
230                else
231                    r_cmd_fsm = CMD_WDATA;
232                r_flit_count = 0;
233            }
234            break;
235        }
236        case CMD_READ:
237        {
238            if ( p_vci.cmdack.read() )
239                r_cmd_fsm = CMD_IDLE;
240            break;
241        }
242        case CMD_WDATA:
243        {
244            if( r_fifo_cmd.rok() && p_vci.cmdack.read() )
245            {
246                if ( (r_cmd_buf1.read() & 0x0000200000LL) == 0 )
247                    r_flit_count = r_flit_count + 1;
248                cmd_fifo_read = true;
249                if ( (r_fifo_cmd.read() & 0x8000000000LL) )
250                    r_cmd_fsm = CMD_IDLE;
251            }
252            break;
253        }
254    } // end switch r_cmd_fsm
255
256    // fifo_cmd
257    if((cmd_fifo_write == true)  && (cmd_fifo_read == false)) { r_fifo_cmd.simple_put(cmd_fifo_data); }
258    if((cmd_fifo_write == true)  && (cmd_fifo_read == true))  { r_fifo_cmd.put_and_get(cmd_fifo_data); }
259    if((cmd_fifo_write == false) && (cmd_fifo_read == true))  { r_fifo_cmd.simple_get(); }
260
261}; // end transition
262
263//////////////////////
264tmpl(void)::genMoore()
265{
266    // VCI RSP interface
267    if ( r_rsp_fsm.read() == RSP_IDLE ) p_vci.rspack = false;
268    else                                p_vci.rspack = r_fifo_rsp.wok();
269
270    // VCI CMD interface
271    if ( (r_cmd_fsm.read() == CMD_IDLE) || (r_cmd_fsm.read() == CMD_RW) )
272    {
273        p_vci.cmdval = false;
274    }
275    else if ( r_cmd_fsm.read() == CMD_BROADCAST )    // VCI CMD broadcast
276    {
277        if ( r_fifo_cmd.rok() )
278        {
279            sc_uint<dspin_cmd_width>  minmax = r_cmd_buf0.read() & 0x7FFFF80000LL;
280            if ( vci_param::N == 40 ) minmax = (minmax << 1);
281            else              minmax = (minmax >> (39 - vci_param::N) );
282            p_vci.cmdval  = true;
283            p_vci.address = (sc_uint<vci_param::N>)minmax | 0x3;
284            p_vci.cmd     = vci_param::CMD_WRITE;
285            p_vci.wdata   = (sc_uint<8*vci_param::B>)(r_fifo_cmd.read() & 0x00FFFFFFFFLL);
286            p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read()  & 0x0F00000000LL) >> 32);
287            p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf0.read()  & 0x000007FFE0LL) >> 5);
288            p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf0.read()  & 0x000000001ELL) >> 1);
289            p_vci.pktid   = 0;
290            p_vci.plen    = vci_param::B;
291            p_vci.contig  = true;
292            p_vci.cons    = false;
293            p_vci.eop     = true;
294        }
295        else
296        {
297            p_vci.cmdval = false;
298        }
299    }
300    else if ( r_cmd_fsm.read() == CMD_READ )    // VCI CMD read
301    {
302        sc_uint<vci_param::N> address;
303        if ( vci_param::N == 40 ) address = (r_cmd_buf0.read() << 1);
304        else                      address = (r_cmd_buf0.read() >> (39 - vci_param::N) );
305        p_vci.cmdval  = true;
306        p_vci.address = address;
307        p_vci.cmd     = (sc_uint<2>)((r_cmd_buf1.read()            & 0x0001800000LL) >> 23);
308        p_vci.wdata   = 0;
309        p_vci.be      = (sc_uint<vci_param::B>)((r_cmd_buf1.read() & 0x000000001ELL) >> 1);
310        p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf1.read() & 0x7FFE000000LL) >> 25);
311        p_vci.pktid   = (sc_uint<vci_param::P>)((r_cmd_buf1.read() & 0x00000001E0LL) >> 5);
312        p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf1.read() & 0x0000001E00LL) >> 9);
313        p_vci.plen    = (sc_uint<vci_param::K>)((r_cmd_buf1.read() & 0x00001FE000LL) >> 13);
314        p_vci.contig  = ((r_cmd_buf1.read() & 0x0000400000LL) != 0);
315        p_vci.cons    = ((r_cmd_buf1.read() & 0x0000200000LL) != 0);
316        p_vci.eop     = true;
317    }
318    else if ( r_cmd_fsm.read() == CMD_WDATA )    // VCI write command
319    {
320        if ( r_fifo_cmd.rok() )
321        {
322            sc_uint<vci_param::N> address;
323            if ( vci_param::N == 40 ) address = (r_cmd_buf0.read() << 1);
324            else                      address = (r_cmd_buf0.read() >> (39 - vci_param::N) );
325            p_vci.cmdval  = true;
326            p_vci.address = address + (r_flit_count.read()*vci_param::B);
327            p_vci.cmd     = (sc_uint<2>)((r_cmd_buf1.read()             & 0x0001800000LL) >> 23);
328            p_vci.wdata   = (sc_uint<8*vci_param::B>)(r_fifo_cmd.read() & 0x00FFFFFFFFLL);
329            p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read()  & 0x0F00000000LL) >> 32);
330            p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf1.read()  & 0x7FFE000000LL) >> 25);
331            p_vci.pktid   = (sc_uint<vci_param::P>)((r_cmd_buf1.read()  & 0x00000001E0LL) >> 5);
332            p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf1.read()  & 0x0000001E00LL) >> 9);
333            p_vci.plen    = (sc_uint<vci_param::K>)((r_cmd_buf1.read()  & 0x00001FE000LL) >> 13);
334            p_vci.contig  = ((r_cmd_buf1.read() & 0x0000400000LL) != 0);
335            p_vci.cons    = ((r_cmd_buf1.read() & 0x0000200000LL) != 0);
336            p_vci.eop     = ((r_fifo_cmd.read() & 0x8000000000LL) == 0x8000000000LL);
337        }
338        else
339        {
340            p_vci.cmdval = false;
341        }
342    }
343
344    // DSPIN_OUT interface
345    p_dspin_out.write = r_fifo_rsp.rok();
346    p_dspin_out.data  = r_fifo_rsp.read();
347
348    // DSPIN_IN interface
349    p_dspin_in.read = r_fifo_cmd.wok();
350
351}; // end genMoore
352
353/////////////////////////
354tmpl(void)::print_trace()
355{
356    const char* cmd_str[] = {
357    "CMD_IDLE     ",
358    "CMD_BROADCAST",
359    "CMD_RW       ",
360    "CMD_READ     ",
361    "CMD_WDATA    ",
362    };
363    const char* rsp_str[] = {
364    "RSP_IDLE             ",
365    "RSP_DSPIN_SINGLE_FLIT",
366    "RSP_DSPIN_MULTI_FLIT ",
367    };
368    std::cout << name() << " : " << cmd_str[r_cmd_fsm.read()]
369                        << " | " << rsp_str[r_rsp_fsm.read()]
370                        << " | fifo_cmd = " << r_fifo_cmd.filled_status()
371                        << " | fifo_rsp = " << r_fifo_rsp.filled_status()
372                        << std::endl;
373}
374
375}} // end namespace
376
377// Local Variables:
378// tab-width: 4
379// c-basic-offset: 4
380// c-file-offsets:((innamespace . 0)(inline-open . 0))
381// indent-tabs-mode: nil
382// End:
383
384// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.