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

Last change on this file since 148 was 148, checked in by alain, 13 years ago

Introducing two new components : vci_vdspin_initiator_wrapper & vci_vdspin_target_wrapper

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