source: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/source/src/vci_vdspin_initiator_wrapper.cpp @ 259

Last change on this file since 259 was 259, checked in by almaless, 12 years ago

Introduce ALMOS used platforms for TSAR.
See the package's README file for more information.

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