source: trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/source/src/vci_dma_tsar_v2.cpp @ 259

Last change on this file since 259 was 259, checked in by almaless, 12 years ago

Introduce ALMOS used platforms for TSAR.
See the package's README file for more information.

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.