source: trunk/modules/vci_dma_tsar_v2/caba/source/src/vci_dma_tsar_v2.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: 5.8 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_v2.h"
30#include "dma_tsar_v2.h"
31
32namespace soclib { namespace caba {
33
34#define tmpl(t) template<typename vci_param> t VciDmaTsarV2<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 burst = m_offset_buffer;
95
96        m_partial = false;
97        if( (( m_dst+m_offset ) & ~( m_data.size()-1 )) !=
98            (( m_dst+m_offset+m_offset_buffer-1 ) & ~( m_data.size()-1 )) ){
99            burst = (((m_dst+m_offset) & ~( m_data.size()-1))+m_data.size()) - (m_dst+m_offset);
100            m_partial = true;
101        }
102                VciInitSimpleWriteReq<vci_param> *new_req =
103                        new VciInitSimpleWriteReq<vci_param>( m_dst+m_offset, &m_data[0], burst );
104                new_req->setDone( this, ON_T(write_finish) );
105                m_vci_init_fsm.doReq( new_req );
106        } else {
107                ended();
108        }
109        delete req;
110}
111
112tmpl(void)::write_finish( req_t *req )
113{
114    ssize_t burst = 0;
115    uint32_t offset = 0;
116    if( m_partial ){
117        burst = m_dst + m_offset + m_offset_buffer - ((m_dst+m_offset+m_offset_buffer) & ~( m_data.size()-1));
118        offset = m_offset_buffer - burst ;
119    } else {
120            m_offset += m_offset_buffer;
121    }
122        if ( !req->failed() && !m_must_finish ){
123        if(m_partial){
124            VciInitSimpleWriteReq<vci_param> *new_req =
125                new VciInitSimpleWriteReq<vci_param>( m_dst+m_offset+offset, &m_data[offset], burst );
126            new_req->setDone( this, ON_T(write_finish) );
127            m_partial = false;
128            m_vci_init_fsm.doReq( new_req );
129            delete req;
130            return;
131        }
132                next_req();
133    }
134        else {
135                ended();
136        }
137        delete req;
138}
139
140tmpl(void)::next_req()
141{
142        ssize_t remaining = (ssize_t)m_len-(size_t)m_offset;
143        if ( remaining <= 0 ) {
144                ended();
145                return;
146        }
147
148        ssize_t burst = m_data.size();
149    m_partial = false;
150    if ( ( m_src+m_offset ) & ( m_data.size()-1 ) ){
151        burst = m_data.size() - ( (m_src+m_offset) & (m_data.size()-1) );
152        m_partial = true;
153    }
154        if ( remaining < burst ){
155                burst = remaining;
156        m_partial = true;
157    }
158
159    m_offset_buffer = burst;
160
161        VciInitSimpleReadReq<vci_param> *req =
162                new VciInitSimpleReadReq<vci_param>(
163                        &m_data[0], (m_src+m_offset), burst );
164        req->setDone( this, ON_T(read_done) );
165        m_vci_init_fsm.doReq( req );
166}
167
168tmpl(void)::transition()
169{
170        if (!p_resetn) {
171                m_vci_target_fsm.reset();
172                m_vci_init_fsm.reset();
173                r_irq = false;
174                m_irq_enabled = false;
175                m_len = 0;
176        m_offset_buffer = 0;
177                m_handling = false;
178        m_must_finish = false;
179                return;
180        }
181
182
183        if ( m_len && !m_handling ) {
184                m_handling = true;
185                m_offset = 0;
186
187                next_req();
188        }
189   
190    if( !m_handling )
191        m_must_finish = false;
192
193        m_vci_target_fsm.transition();
194        m_vci_init_fsm.transition();
195}
196
197tmpl(void)::genMoore()
198{
199        m_vci_target_fsm.genMoore();
200        m_vci_init_fsm.genMoore();
201
202        p_irq = r_irq && m_irq_enabled;
203}
204
205tmpl(/**/)::VciDmaTsarV2(
206    sc_module_name name,
207    const MappingTable &mt,
208    const IntTab &srcid,
209    const IntTab &tgtid,
210        const size_t burst_size )
211        : caba::BaseModule(name),
212          m_vci_target_fsm(p_vci_target, mt.getSegmentList(tgtid)),
213          m_vci_init_fsm(p_vci_initiator, mt.indexForId(srcid)),
214          m_len(0),
215          m_data(burst_size, (uint8_t)0),
216      p_clk("clk"),
217      p_resetn("resetn"),
218      p_vci_target("vci_target"),
219      p_vci_initiator("vci_initiator"),
220      p_irq("irq")
221{
222        m_vci_target_fsm.on_read_write(on_read, on_write);
223   
224    assert(burst_size && "Useless DMA with no buffer");
225    assert(burst_size < (1<<vci_param::K) && "I will be unable to create requests that big");
226
227        SC_METHOD(transition);
228        dont_initialize();
229        sensitive << p_clk.pos();
230
231        SC_METHOD(genMoore);
232        dont_initialize();
233        sensitive << p_clk.neg();
234}
235
236}}
237
238// Local Variables:
239// tab-width: 4
240// c-basic-offset: 4
241// c-file-offsets:((innamespace . 0)(inline-open . 0))
242// indent-tabs-mode: nil
243// End:
244
245// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
246
Note: See TracBrowser for help on using the repository browser.