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

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