source: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/source/src/vci_vdspin_target_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.8 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
27#include "../include/vci_vdspin_target_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 VciVdspinTargetWrapper<vci_param, dspin_cmd_width, dspin_rsp_width>
32
33//////////////////////////////////////////////////////////:////////////////////////////////
34tmpl(/**/)::VciVdspinTargetWrapper(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 response packet to DSPIN response packet.
88        // The VCI packet is analysed, translated,
89        // and the DSPIN packet is stored in the fifo_rsp
90        /////////////////////////////////////////////////////////////
91        // - A single flit VCI write response packet is translated
92        //   to a single flit DSPIN response.
93        // - A N flits VCI read response packet is translated
94        //   to a N+1 flits DSPIN response
95        // In the RSP_IDLE state, the first DSPIN flit is written
96        // in fifo_rsp , but no VCI flit is consumed. The VCI flits
97        // are consumed in the RSP_READ or RSP_WRITE states.
98        //////////////////////////////////////////////////////////////
99
100        // rsp_fifo_read
101        rsp_fifo_read = p_dspin_out.read.read();
102
103        // r_rsp_fsm, rsp_fifo_write and rsp_fifo_data
104        rsp_fifo_write = false;         // default value
105
106        switch(r_rsp_fsm) {
107            case RSP_IDLE:              // write first DSPIN flit into rsp_fifo
108            {
109                if( p_vci.rspval && r_fifo_rsp.wok() ) 
110                {
111                    bool is_read = ( (p_vci.rerror.read() & 0x2) == 0);
112
113                    rsp_fifo_write = true;
114                    rsp_fifo_data = (((sc_uint<dspin_rsp_width>)p_vci.rsrcid.read()) << 18) |
115                                    (((sc_uint<dspin_rsp_width>)p_vci.rerror.read()) << 16) |
116                                    (((sc_uint<dspin_rsp_width>)p_vci.rtrdid.read()) << 8);
117                    if ( is_read ) 
118                    {
119                        r_rsp_fsm = RSP_READ;
120                    }
121                    else
122                    {
123                        rsp_fifo_data = rsp_fifo_data | 0x100000000ULL;
124                        r_rsp_fsm = RSP_WRITE;
125                    }
126                }
127                break;
128            }
129            case RSP_READ:              // write DSPIN data flit in case of read
130            {   
131                if( p_vci.rspval && r_fifo_rsp.wok() )
132                {
133                    rsp_fifo_write   = true;
134                    rsp_fifo_data = ((sc_uint<dspin_rsp_width>)p_vci.rdata.read());
135                    if ( p_vci.reop ) 
136                    {
137                        rsp_fifo_data = rsp_fifo_data | 0x100000000ULL;
138                        r_rsp_fsm = RSP_IDLE;
139                    }
140                }
141                break;
142            }
143            case RSP_WRITE:
144            {
145                rsp_fifo_write = false;
146                if ( r_fifo_rsp.wok() ) r_rsp_fsm = RSP_IDLE;
147                break;
148            }
149        } // end switch r_cmd_fsm
150       
151        // fifo_rsp
152        if((rsp_fifo_write == true)  && (rsp_fifo_read == false)) { r_fifo_rsp.simple_put(rsp_fifo_data); } 
153        if((rsp_fifo_write == true)  && (rsp_fifo_read == true))  { r_fifo_rsp.put_and_get(rsp_fifo_data); } 
154        if((rsp_fifo_write == false) && (rsp_fifo_read == true))  { r_fifo_rsp.simple_get(); }
155
156        //////////////////////////////////////////////////////////////
157        // DSPIN command packet to VCI command packet
158        // The DSPIN packet is stored in the fifo_rsp
159        // The FIFO output is analysed and translated to a VCI packet
160        //////////////////////////////////////////////////////////////
161        // - A 2 flits DSPIN broadcast command is translated
162        //   to a 1 flit VCI broadcast command.
163        // - A 2 flits DSPIN read command is translated
164        //   to a 1 flit VCI read command.
165        // - A N+2 flits DSPIN write command is translated
166        //   to a N flits VCI write command.
167        // The VCI flits are sent in the CMD_READ, CMD_WDATA
168        // & CMD_BROADCAST states.
169        // The r_cmd_buf0 et r_cmd_buf1 buffers are used to store
170        // the two first DSPIN flits (in case of write).
171        //////////////////////////////////////////////////////////////
172
173        // cmd_fifo_write, cmd_fifo_data
174        cmd_fifo_write = p_dspin_in.write.read();
175        cmd_fifo_data  = p_dspin_in.data.read();
176
177        // r_cmd_fsm, cmd_fifo_read
178        cmd_fifo_read = false;          // default value
179
180        switch(r_cmd_fsm) {
181            case CMD_IDLE:
182            {
183                if( r_fifo_cmd.rok() )
184                {
185                    bool is_broadcast = ( (r_fifo_cmd.read() & 0x1) == 0x1);
186
187                    cmd_fifo_read = true;
188                    r_cmd_buf0    = r_fifo_cmd.read();          // save address
189                    if ( is_broadcast ) r_cmd_fsm = CMD_BROADCAST;
190                    else                r_cmd_fsm = CMD_RW;
191                }
192                break;
193            }
194            case CMD_BROADCAST:
195            {
196                if( r_fifo_cmd.rok() && p_vci.cmdack )
197                {
198                    cmd_fifo_read = true;
199                    r_cmd_fsm = CMD_IDLE;
200                }
201                break;
202            }
203            case CMD_RW:
204            {
205                if( r_fifo_cmd.rok() )
206                {
207                    cmd_fifo_read = true;
208                    r_cmd_buf1 = r_fifo_cmd.read();             // save command parameters
209                    // read command if EOP
210                    if ( (r_fifo_cmd.read() & 0x8000000000ULL) )   r_cmd_fsm = CMD_READ;
211                    else                                        r_cmd_fsm = CMD_WDATA;
212                    r_flit_count = 0;
213                }
214                break;
215            }
216            case CMD_READ:
217            {
218                if ( p_vci.cmdack.read() ) r_cmd_fsm = CMD_IDLE;
219                break;
220            }
221            case CMD_WDATA:
222            {
223                if( r_fifo_cmd.rok() && p_vci.cmdack.read() )
224                {
225                    if ( (r_cmd_buf1.read() & 0x0000200000) == 0 ) r_flit_count = r_flit_count + 1;
226                               cmd_fifo_read = true;
227                    if ( (r_fifo_cmd.read() & 0x8000000000ULL) )        r_cmd_fsm = CMD_IDLE;
228                }
229                break;
230            }
231        } // end switch r_cmd_fsm
232
233        // fifo_cmd
234        if((cmd_fifo_write == true)  && (cmd_fifo_read == false)) { r_fifo_cmd.simple_put(cmd_fifo_data); } 
235        if((cmd_fifo_write == true)  && (cmd_fifo_read == true))  { r_fifo_cmd.put_and_get(cmd_fifo_data); } 
236        if((cmd_fifo_write == false) && (cmd_fifo_read == true))  { r_fifo_cmd.simple_get(); }
237
238}; // end transition
239
240//////////////////////
241tmpl(void)::genMoore()
242{
243        // VCI RSP interface
244        if ( r_rsp_fsm.read() == RSP_IDLE )     p_vci.rspack = false;
245        else                                    p_vci.rspack = r_fifo_rsp.wok();
246
247        // VCI CMD interface
248        if ( (r_cmd_fsm.read() == CMD_IDLE) || (r_cmd_fsm.read() == CMD_RW) )
249        {
250            p_vci.cmdval = false;
251        }
252        else if ( r_cmd_fsm.read() == CMD_BROADCAST )   // VCI CMD broadcast
253        {
254            if ( r_fifo_cmd.rok() )
255            {
256                sc_uint<dspin_cmd_width>  minmax = r_cmd_buf0.read() & 0x7FFFF80000ULL;
257                if ( vci_param::N == 40 ) minmax = (minmax << 1);
258                else                      minmax = (minmax >> (39 - vci_param::N) ); 
259                p_vci.cmdval  = true;
260                p_vci.address = (sc_uint<vci_param::N>)minmax | 0x3;
261                p_vci.cmd     = vci_param::CMD_WRITE;
262                p_vci.wdata   = (sc_uint<8*vci_param::B>)(r_fifo_cmd.read() & 0x00FFFFFFFFUL);
263                p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read() & 0x0F00000000ULL) >> 32);
264                p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf0.read() & 0x000007FFE0) >> 5);
265                p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf0.read() & 0x000000001E) >> 1);
266                p_vci.pktid   = 0;
267                p_vci.plen    = vci_param::B;
268                p_vci.contig  = true;
269                p_vci.cons    = false;
270                p_vci.eop     = true;
271            }
272            else
273            {
274                p_vci.cmdval = false;
275            }
276        }
277        else if ( r_cmd_fsm.read() == CMD_READ )        // VCI CMD read
278        {           
279            sc_uint<vci_param::N> address;
280            if ( vci_param::N == 40 ) address = (r_cmd_buf0.read() << 1);
281            else                      address = (r_cmd_buf0.read() >> (39 - vci_param::N) ); 
282            p_vci.cmdval  = true;
283            p_vci.address = address;
284            p_vci.cmd     = (sc_uint<2>)((r_cmd_buf1.read()            & 0x0001800000) >> 23);
285            p_vci.wdata   = 0;
286            p_vci.be      = (sc_uint<vci_param::B>)((r_cmd_buf1.read() & 0x000000001E) >> 1);
287            p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf1.read() & 0x7FFE000000ULL) >> 25);
288            p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf1.read() & 0x0000001FE0) >> 5);
289            p_vci.pktid   = 0;
290            p_vci.plen    = (sc_uint<vci_param::K>)((r_cmd_buf1.read() & 0x00001FE000) >> 13);
291            p_vci.contig  = ((r_cmd_buf1.read() & 0x0000400000) != 0);
292            p_vci.cons    = ((r_cmd_buf1.read() & 0x0000200000) != 0);
293            p_vci.eop     = true;
294        }
295        else if ( r_cmd_fsm.read() == CMD_WDATA )       // VCI write command
296        {
297            if ( r_fifo_cmd.rok() ) 
298            {
299                sc_uint<vci_param::N> address;
300                if ( vci_param::N == 40 ) address = (r_cmd_buf0.read() << 1);
301                else                      address = (r_cmd_buf0.read() >> (39 - vci_param::N) ); 
302                p_vci.cmdval  = true;
303                p_vci.address = address + (r_flit_count.read()*vci_param::B);
304                p_vci.cmd     = (sc_uint<2>)((r_cmd_buf1.read()              & 0x0001800000) >> 23);
305                p_vci.wdata   = (sc_uint<8*vci_param::B>)(r_fifo_cmd.read()  & 0x00FFFFFFFFUL);
306                p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read()   & 0x0F00000000ULL) >> 32);
307                p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf1.read()   & 0x7FFE000000ULL) >> 25);
308                p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf1.read()   & 0x0000001FE0) >> 5);
309                p_vci.pktid   = 0;
310                p_vci.plen    = (sc_uint<vci_param::K>)((r_cmd_buf1.read() & 0x00001FE000) >> 13);
311                p_vci.contig  = ((r_cmd_buf1.read() & 0x0000400000) != 0);
312                p_vci.cons    = ((r_cmd_buf1.read() & 0x0000200000) != 0);
313                p_vci.eop     = ((r_fifo_cmd.read() & 0x8000000000ULL) == 0x8000000000ULL); 
314            }
315            else
316            {
317                p_vci.cmdval = false;
318            }
319        }
320
321        // DSPIN_OUT interface
322        p_dspin_out.write = r_fifo_rsp.rok();
323        p_dspin_out.data  = r_fifo_rsp.read();
324
325        // DSPIN_IN interface
326        p_dspin_in.read = r_fifo_cmd.wok();
327
328}; // end genMoore
329
330/////////////////////////
331tmpl(void)::print_trace()
332{
333    const char* cmd_str[] = {
334    "CMD_IDLE     ",
335    "CMD_BROADCAST",
336    "CMD_RW       ",
337    "CMD_READ     ",
338    "CMD_WDATA    ",
339    };
340    const char* rsp_str[] = {
341    "RSP_IDLE     ",
342    "RSP_READ     ",
343    "RSP_WRITE    ",
344    };
345    std::cout << name() << " : " << cmd_str[r_cmd_fsm.read()]
346                        << " | " << rsp_str[r_rsp_fsm.read()] 
347                        << " | fifo_cmd = " << r_fifo_cmd.filled_status()
348                        << " | fifo_rsp = " << r_fifo_rsp.filled_status()
349                        << std::endl;
350}
351
352}} // end namespace
353
354// Local Variables:
355// tab-width: 4
356// c-basic-offset: 4
357// c-file-offsets:((innamespace . 0)(inline-open . 0))
358// indent-tabs-mode: nil
359// End:
360
361// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.