source: trunk/modules/vci_dma_tsar/caba/source/src/vci_dma_tsar.cpp @ 2

Last change on this file since 2 was 2, checked in by nipo, 14 years ago

Import TSAR modules in TSAR's own svn

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Rev URL Revision"
  • Property svn:mime-type set to text/plain
File size: 6.7 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6, Asim
24 *         Nicolas Pouillon <nipo@ssji.net>, 2007
25 */
26
27#include <stdint.h>
28#include "register.h"
29#include "../include/vci_dma_tsar.h"
30#include "dma_tsar.h"
31
32namespace soclib { namespace caba {
33
34#define tmpl(t) template<typename vci_param> t VciDmaTsar<vci_param>
35
36tmpl(bool)::on_write(int seg, typename vci_param::addr_t addr, typename vci_param::data_t data, int be)
37{
38    int cell = (int)addr / vci_param::B;
39
40        switch ((enum SoclibDmaRegisters)cell) {
41        case DMA_SRC:
42                m_src = data;
43                return true;
44    case DMA_DST:
45                m_dst = data;
46                return true;
47    case DMA_LEN:
48                m_len = data;
49                return true;
50    case DMA_RESET:
51        m_must_finish = true;
52        m_irq_enabled = false;
53                r_irq = false;
54        return true;
55    case DMA_IRQ_DISABLED:
56                m_irq_enabled = !data;
57                return true;
58        };
59        return false;
60}
61
62tmpl(void)::ended()
63{
64        if ( m_irq_enabled )
65                r_irq = true;
66        m_len = 0;
67    m_must_finish = false;
68        m_handling = false;
69}
70
71tmpl(bool)::on_read(int seg, typename vci_param::addr_t addr, typename vci_param::data_t &data)
72{
73    int cell = (int)addr / vci_param::B;
74
75        switch ((enum SoclibDmaRegisters)cell) {
76        case DMA_SRC:
77                data = m_src;
78                return true;
79    case DMA_DST:
80                data = m_dst;
81                return true;
82        case DMA_LEN:
83                data = m_len;
84                return true;
85    default:
86        return false;
87        }
88        return false;
89}
90
91tmpl(void)::read_done( req_t *req )
92{
93        if ( !req->failed() && !m_must_finish ) {
94                ssize_t remaining = (ssize_t)m_len-(size_t)m_offset;
95                ssize_t burst = m_offset_buffer;
96
97        if ( ( ( 0 < ( remaining-(size_t)m_offset_buffer ) )
98            && ( ( remaining-(size_t)m_offset_buffer ) < m_data.size()) ) && m_partial ){
99            VciInitSimpleReadReq<vci_param> *new_req =
100                new VciInitSimpleReadReq<vci_param>(
101                        &m_data[m_offset_buffer], m_src+m_offset+m_offset_buffer, 4 );
102            m_offset_buffer+=4;
103            new_req->setDone( this, ON_T(read_done) );
104            m_vci_init_fsm.doReq( new_req );
105            delete req;
106            return;
107        }
108        if ( (( m_src+m_offset+m_offset_buffer ) & ( m_data.size()-1 )) && m_partial ){
109            VciInitSimpleReadReq<vci_param> *new_req =
110                new VciInitSimpleReadReq<vci_param>(
111                        &m_data[m_offset_buffer], m_src+m_offset+m_offset_buffer, 4 );
112            m_offset_buffer+=4;
113            new_req->setDone( this, ON_T(read_done) );
114            m_vci_init_fsm.doReq( new_req );
115            delete req;
116            return;
117        }
118        m_partial = false;
119        if( (( m_dst+m_offset ) & ~( m_data.size()-1 )) !=
120            (( m_dst+m_offset+m_offset_buffer-4 ) & ~( m_data.size()-1 )) ){
121            burst = (((m_dst+m_offset) & ~( m_data.size()-1))+m_data.size()) - (m_dst+m_offset);
122            m_partial = true;
123        }
124                VciInitSimpleWriteReq<vci_param> *new_req =
125                        new VciInitSimpleWriteReq<vci_param>( m_dst+m_offset, &m_data[0], burst );
126                new_req->setDone( this, ON_T(write_finish) );
127                m_vci_init_fsm.doReq( new_req );
128        } else {
129                ended();
130        }
131        delete req;
132}
133
134tmpl(void)::write_finish( req_t *req )
135{
136    ssize_t burst = 0;
137    uint32_t offset = 0;
138    if( m_partial ){
139        burst = m_dst + m_offset + m_offset_buffer - ((m_dst+m_offset+m_offset_buffer) & ~( m_data.size()-1));
140        offset = m_offset_buffer - burst;
141    } else {
142            m_offset += m_offset_buffer;
143    }
144        if ( !req->failed() && !m_must_finish ){
145        if(m_partial){
146            VciInitSimpleWriteReq<vci_param> *new_req =
147                new VciInitSimpleWriteReq<vci_param>( m_dst+m_offset+offset, &m_data[offset], burst );
148            new_req->setDone( this, ON_T(write_finish) );
149            m_partial = false;
150            m_vci_init_fsm.doReq( new_req );
151            delete req;
152            return;
153        }
154                next_req();
155    }
156        else {
157                ended();
158        }
159        delete req;
160}
161
162tmpl(void)::next_req()
163{
164        ssize_t remaining = (ssize_t)m_len-(size_t)m_offset;
165        if ( remaining <= 0 ) {
166                ended();
167                return;
168        }
169
170        ssize_t burst = m_data.size();
171    m_partial = false;
172        if ( remaining < burst ){
173                burst = 4;
174        m_partial = true;
175    }
176    if ( ( m_src+m_offset ) & ( m_data.size()-1 ) ){
177        burst = 4;
178        m_partial = true;
179    }
180
181    m_offset_buffer = burst;
182        VciInitSimpleReadReq<vci_param> *req =
183                new VciInitSimpleReadReq<vci_param>(
184                        &m_data[0], m_src+m_offset, burst );
185        req->setDone( this, ON_T(read_done) );
186        m_vci_init_fsm.doReq( req );
187}
188
189tmpl(void)::transition()
190{
191        if (!p_resetn) {
192                m_vci_target_fsm.reset();
193                m_vci_init_fsm.reset();
194                r_irq = false;
195                m_irq_enabled = false;
196                m_len = 0;
197        m_offset_buffer = 0;
198                m_handling = false;
199        m_must_finish = false;
200                return;
201        }
202
203
204        if ( m_len && !m_handling ) {
205                m_handling = true;
206                m_offset = 0;
207
208                next_req();
209        }
210   
211    if( !m_handling )
212        m_must_finish = false;
213
214        m_vci_target_fsm.transition();
215        m_vci_init_fsm.transition();
216}
217
218tmpl(void)::genMoore()
219{
220        m_vci_target_fsm.genMoore();
221        m_vci_init_fsm.genMoore();
222
223        p_irq = r_irq && m_irq_enabled;
224}
225
226tmpl(/**/)::VciDmaTsar(
227    sc_module_name name,
228    const MappingTable &mt,
229    const IntTab &srcid,
230    const IntTab &tgtid,
231        const size_t burst_size )
232        : caba::BaseModule(name),
233          m_vci_target_fsm(p_vci_target, mt.getSegmentList(tgtid)),
234          m_vci_init_fsm(p_vci_initiator, mt.indexForId(srcid)),
235          m_len(0),
236          m_data(burst_size, (uint8_t)0),
237      p_clk("clk"),
238      p_resetn("resetn"),
239      p_vci_target("vci_target"),
240      p_vci_initiator("vci_initiator"),
241      p_irq("irq")
242{
243        m_vci_target_fsm.on_read_write(on_read, on_write);
244   
245    assert(burst_size && "Useless DMA with no buffer");
246    assert(burst_size < (1<<vci_param::K) && "I will be unable to create requests that big");
247
248        SC_METHOD(transition);
249        dont_initialize();
250        sensitive << p_clk.pos();
251
252        SC_METHOD(genMoore);
253        dont_initialize();
254        sensitive << p_clk.neg();
255}
256
257}}
258
259// Local Variables:
260// tab-width: 4
261// c-basic-offset: 4
262// c-file-offsets:((innamespace . 0)(inline-open . 0))
263// indent-tabs-mode: nil
264// End:
265
266// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
267
Note: See TracBrowser for help on using the repository browser.