sim: added uart extension
authorMartin Perner <martin@perner.cc>
Thu, 13 Jan 2011 14:05:44 +0000 (15:05 +0100)
committerMartin Perner <martin@perner.cc>
Thu, 13 Jan 2011 15:31:28 +0000 (16:31 +0100)
3b_sim/ccpu.cpp
3b_sim/ccpu.hpp
3b_sim/extensions/cprog.hpp
3b_sim/extensions/cuart.hpp [new file with mode: 0644]
3b_sim/iext.hpp
3b_sim/sim.cpp

index d2e64e030e3024ecb3f495b2055ce88de12d5949..3c0049bc9ca1a4684816f7d85be5cd0b221abf8b 100644 (file)
@@ -33,6 +33,13 @@ void CCpu::registerExtension(Iext* ext)
        m_exts.push_back(ext);
 }
 
+void CCpu::applyToExtensions(const vector<string>& in)
+{
+       for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) {
+               (*iter)->parseInput(in);
+       }
+}
+
 void CCpu::tick()
 {
        // signal extensions
index a9747c9092d8f61fa0d26161f56ebddbbe70a54f..fb9447db2c6fb1aee57abcc70f2d4785b95c6b0a 100644 (file)
@@ -32,6 +32,7 @@ class CCpu {
 
        public:
                void registerExtension() {};
+               void applyToExtensions(const vector<string>& in);
                void tick();
 
                CDat getRegister(const int) const;
index 82d83cfd6ccbebe71b05b6c8d67af4cb0ebc74aa..aa695a592f445d33cc6c9662bd94b39e92bca1c7 100644 (file)
@@ -6,6 +6,7 @@ class Cprog : public Iext {
                void applyTick() {};
                void loadData(const int address, CDat value);
                CDat readData(const int) { return 0; }
+               void parseInput(const vector<string>&)  {};
        private:
                int m_writeAddress;
 };
@@ -13,7 +14,7 @@ class Cprog : public Iext {
 void Cprog::loadData(const int address, CDat value)
 {
        if(address == 0x2034) {
-               m_writeAddress = value;
+               m_writeAddress = (value*4);
                //adress pointer
        }
        else if(address == 0x2038) {
diff --git a/3b_sim/extensions/cuart.hpp b/3b_sim/extensions/cuart.hpp
new file mode 100644 (file)
index 0000000..d1889fc
--- /dev/null
@@ -0,0 +1,123 @@
+#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<string>& in);
+       private:
+               int m_writeAddress, m_fetchCount, m_readCount;
+               bool m_recRdy, m_txRdy;
+               CDat m_recVal, m_txVal;
+};
+
+
+void Cuart::parseInput(const vector<string>& 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<uint32_from_hex>(in[3]);
+                       }
+                       else {
+                               m_recVal = lexical_cast<unsigned int>(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
+       }
+}
index 99b08423b9f2fbb6b1d9a9f7dc21a07bac6cae4f..c78ad382d4ba2ae9d7508ba54f23c7008e6c80b7 100644 (file)
@@ -18,6 +18,7 @@ class Iext {
                virtual ~Iext() {}
                //called by cpu before every tick
                virtual void applyTick() = 0;
+               virtual void parseInput(const vector<string>& in) = 0;
                virtual void loadData(const int address, CDat value) = 0;
                virtual CDat readData(const int address) = 0;
                static CCpu* m_cpu;
index 0e1a0aef071cfb6bc7b2304dcb938c2b5d29eb56..09808a0d25ba085233574376b3971ee181c4854f 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "iext.hpp"
 #include "extensions/cprog.hpp"
+#include "extensions/cuart.hpp"
 
 #include "SReadline/SReadline.h"
 using namespace swift;
@@ -455,6 +456,12 @@ void resetPerf(const vector<string>&)
        global_cpu->setPerf(0);
 }
 
+void applyToExtensions(const vector<string>& in)
+{
+       global_cpu->applyToExtensions(in);
+}
+
+
 void printStatus(const vector<string>&)
 {
        CDat stackp = global_cpu->getStack();
@@ -549,6 +556,7 @@ int main(int argc, char* argv[])
        Iext::setDisasm(&disasm);
 
        global_cpu->registerExtension(new Cprog());
+       global_cpu->registerExtension(new Cuart());
 
        vector<string> commentDefer;
        vector<string> labelDefer;
@@ -720,7 +728,7 @@ int main(int argc, char* argv[])
        Completers.push_back(CompleterElement("status",&printStatus, "Prints status of CPU."));
        Completers.push_back(CompleterElement("getperf",&getPerf, "Prints performance counter."));
        Completers.push_back(CompleterElement("resetperf",&resetPerf, "Resets performance counter to 0."));
-
+       Completers.push_back(CompleterElement("extension",&applyToExtensions, "Write to extensions."));
        Reader.RegisterCompletions(Completers);
 
        string UserInput;