/* -*- 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, Asim * Cesar Fuguet , 2014 * */ #include "vci_tsar_config.h" #include "tsar_config.h" namespace soclib { namespace caba { #define tmpl(x) template x VciTsarConfig ////////////////////////////////////////////////// tmpl(void)::transition() { p_blackhole_pos = r_blackhole_pos.read(); if (!p_resetn.read()) { r_fsm_state = IDLE; r_blackhole_pos = 0; return; } switch (r_fsm_state.read()) { case IDLE: // waiting a VCI command { if (!p_vci.cmdval.read()) break; vci_addr_t address = p_vci.address.read(); std::list::iterator seg; bool seg_error = true; for (seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++) { if (seg->contains(address) and p_vci.eop.read()) { seg_error = false; break; } } r_srcid = p_vci.srcid.read(); r_trdid = p_vci.trdid.read(); r_pktid = p_vci.pktid.read(); if (seg_error) { if (!p_vci.eop.read()) break; r_fsm_state = RSP_ERROR; break; } int reg = (int)((address >> 2) & 0x1) % CONFIG_SPAN; if ((p_vci.cmd.read() == vci_param::CMD_WRITE) && (reg == CONFIG_BHPOS)) { r_blackhole_pos = (int)p_vci.wdata.read(); r_fsm_state = RSP_WRITE; break; } if ((p_vci.cmd.read() == vci_param::CMD_READ) && (reg == CONFIG_BHPOS)) { r_rdata = (vci_data_t)r_blackhole_pos.read(); r_fsm_state = RSP_READ; break; } if (p_vci.eop.read()) { r_fsm_state = RSP_ERROR; } break; } // end case IDLE case RSP_ERROR: // return an error response case RSP_READ: // return a valid read response case RSP_WRITE: // return a valid write response { if (p_vci.rspack.read()) { r_fsm_state = IDLE; } break; } } // end switch r_fsm_state } // end transition ////////////////////////////////////////////////// tmpl(void)::genMoore() { p_vci.rsrcid = r_srcid.read(); p_vci.rtrdid = r_trdid.read(); p_vci.rpktid = r_pktid.read(); p_vci.reop = true; switch(r_fsm_state.read()) { case IDLE: p_vci.cmdack = true; p_vci.rspval = false; p_vci.rdata = 0; p_vci.rerror = vci_param::ERR_NORMAL; break; case RSP_WRITE: p_vci.cmdack = false; p_vci.rspval = true; p_vci.rdata = 0; p_vci.rerror = vci_param::ERR_NORMAL; break; case RSP_READ: p_vci.cmdack = false; p_vci.rspval = true; p_vci.rdata = r_rdata.read(); p_vci.rerror = vci_param::ERR_NORMAL; break; case RSP_ERROR: p_vci.cmdack = false; p_vci.rspval = true; p_vci.rdata = 0; p_vci.rerror = vci_param::ERR_GENERAL_DATA_ERROR; break; } } // end genMoore() ////////////////////////////////////////////////// tmpl(/**/)::VciTsarConfig(sc_module_name name, const IntTab &index, const MappingTable &mt) : soclib::caba::BaseModule(name), p_clk("clk"), p_resetn("resetn"), p_vci("vci"), m_seglist(mt.getSegmentList(index)) { SC_METHOD(transition); dont_initialize(); sensitive << p_clk.pos(); SC_METHOD(genMoore); dont_initialize(); sensitive << p_clk.neg(); } ////////////////////////////////////////////////// tmpl(/**/)::~VciTsarConfig() { } ////////////////////////////////////////////////// tmpl(void)::print_trace() { const char* state_str[] = {"IDLE", "RSP_WRITE", "RSP_READ", "RSP_ERROR"}; std::cout << "VCI_TSAR_CONFIG " << name() << " : state = " << state_str[r_fsm_state.read()] << std::endl; } }} // 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