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