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

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

bug fixing

File size: 13.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        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 | 0x100000000;
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 | 0x100000000;
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() & 0x8000000000) )   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() & 0x8000000000) )   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() & 0x7FFFF80000;
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() & 0x00FFFFFFFF);
263                p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read() & 0x0F00000000) >> 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() & 0x7FFE000000) >> 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()  & 0x00FFFFFFFF);
306                p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read()   & 0x0F00000000) >> 32);
307                p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf1.read()   & 0x7FFE000000) >> 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() & 0x8000000000) == 0x8000000000); 
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.