/* -*- c++ -*- * * SOCLIB_LGPL_HEADER_BEGIN * * This file is part of SoCLib, GNU LGPLv2.1. * * SoCLib is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; version 2.1 of the License. * * SoCLib is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with SoCLib; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * SOCLIB_LGPL_HEADER_END * * Copyright (c) UPMC, Lip6 * Nicolas Pouillon , 2009 */ #include #include "xicu.h" #include "register.h" #include "arithmetics.h" #include "alloc_elems.h" #include "../include/vci_xicu.h" namespace soclib { namespace caba { using namespace soclib; #define tmpl(t) template t VciXicu #ifdef SOCLIB_MODULE_DEBUG #define CHECK_BOUNDS(x) \ do { \ if ( idx >= (m_##x##_count) ) { \ std::cout << name() << " error: " #x " index " << idx \ << " out of bounds (" \ << m_##x##_count << ")" \ << std::endl; \ return false; \ } \ } while(0) #else #define CHECK_BOUNDS(x) do { if ( idx >= (m_##x##_count) ) return false; } while(0) #endif ////////////////////////////////////////////////////// tmpl(bool)::on_write( int seg, typename vci_param::addr_t addr, typename vci_param::data_t data, int be) { size_t cell = (size_t)addr / vci_param::B; size_t idx = cell & 0x1f; size_t func = (cell >> 5) & 0x1f; if ( be != 0xf ) return false; switch (func) { case XICU_WTI_REG: CHECK_BOUNDS(wti); r_wti_reg[idx] = data; r_wti_pending |= 1< >("irq", irq_count)), p_hwi(soclib::common::alloc_elems >("hwi", hwi_count)) { std::cout << " - Building VciXicu : " << name << std::endl; std::list::iterator seg; for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) { std::cout << " => segment " << seg->name() << " / base = " << std::hex << seg->baseAddress() << " / size = " << seg->size() << std::endl; } if ( cfg_count > 0 ) { r_cfg_reg = new uint32_t[cfg_count]; p_cfg = soclib::common::alloc_elems >("cfg", cfg_count); } m_vci_fsm.on_read_write( on_read, on_write ); SC_METHOD(transition); dont_initialize(); sensitive << p_clk.pos(); SC_METHOD(genMoore); dont_initialize(); sensitive << p_clk.neg(); } ////////////////////// tmpl(/**/)::~VciXicu() { delete [] r_msk_pti; delete [] r_msk_wti; delete [] r_msk_hwi; delete [] r_pti_per; delete [] r_pti_val; delete [] r_wti_reg; soclib::common::dealloc_elems(p_irq, m_irq_count); soclib::common::dealloc_elems(p_hwi, m_hwi_count); if ( m_cfg_count > 0 ) { delete [] r_cfg_reg; soclib::common::dealloc_elems(p_cfg, m_cfg_count); } } }} // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4