/* `Deep Thought', a softcore CPU implemented on a FPGA Copyright (C) 2010 Markus Hofstaetter Copyright (C) 2010 Martin Perner Copyright (C) 2010 Stefan Rebernig Copyright (C) 2010 Manfred Schwarz Copyright (C) 2010 Bernhard Urban This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "../iext.hpp" class Cuart : public Iext { public: Cuart() : m_writeAddress(0), m_fetchCount(0), m_readCount(0), m_recRdy(0), m_txRdy(0), m_recVal(0), m_txVal(0) {}; void applyTick() {}; void loadData(const int address, CDat value); CDat readData(const int); void parseInput(const vector& in); private: int m_writeAddress, m_fetchCount, m_readCount; bool m_recRdy, m_txRdy; CDat m_recVal, m_txVal; }; void Cuart::parseInput(const vector& in) { if(in.size() > 1) { if((in[1].compare("h") == 0)) { cout << "UART:" << endl; cout << "\textension uart r 0xXX \t -- to load the module with a value" << endl; cout << "\textension uart f \t-- to load a value from the module" << endl; } } if(in.size() < 2) { return; } if(in[1].compare("uart") == 0) { if(in[2].compare("r") == 0) { if(in.size() < 3) { return; } if(in[3].substr(0,2) == "0x") { m_recVal = lexical_cast(in[3]); } else { m_recVal = lexical_cast(in[3]); } cout << "UART: loaded 0x" << std::hex << m_recVal << std::dec << endl; m_recRdy = 1; m_fetchCount = 0; m_readCount = 0; } else if(in[2].compare("f") == 0) { cout << "UART: sended 0x" << std::hex << m_txVal << std::dec << endl; m_txRdy = 0; m_fetchCount = 0; m_readCount = 0; } else if(in[2].compare("s") == 0) { cout << "UART:" << endl; cout << "\ttx busy: " << m_txRdy << endl; cout << "\trx_newdata: " << m_recRdy << endl; } } } CDat Cuart::readData(const int address) { if(address == 0x2000) { //status - r only /* cout << "rx: " << m_recRdy << endl; cout << "tx: " << m_txRdy << endl; CDat helpme = m_recRdy; helpme <<= 1; helpme |= m_txRdy; cout << "rx<<1 | tx: " << helpme << endl; */ if(m_txRdy == 1) { m_fetchCount++; } if(m_recRdy == 0) { m_readCount++; } if(m_fetchCount >= 5) { m_fetchCount = 0; m_readCount = 0; m_txRdy = 0; cout << "UART: force fetched 0x" << std::hex << m_txVal << std::dec << endl; } if(m_readCount >= 5) { m_fetchCount = 0; m_readCount = 0; m_recRdy = 1; cout << "UART: force inserted 0x48 ('H')" << endl; m_recVal = 'H'; } return (m_recRdy<<1)|(m_txRdy); } else if(address == 0x2008) { //trans - w only //data pointer } else if(address == 0x200c) { //recv - r only m_recRdy = 0; m_fetchCount = 0; m_readCount = 0; return m_recVal; } return 0; } void Cuart::loadData(const int address, CDat value) { if(address == 0x2000) { //status - r only } else if(address == 0x2008) { //trans - w only cout << "UART: byte ready to fetch" << endl; m_txVal = value; m_txRdy = 1; m_fetchCount = 0; m_readCount = 0; } else if(address == 0x200c) { //recv - r only } }