copyleft: gplv3 added and set repo to public
[calu.git] / 3b_sim / extensions / cuart.hpp
1 /*   `Deep Thought', a softcore CPU implemented on a FPGA
2
3     Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4     Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5     Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6     Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7     Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
8
9     This program is free software: you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation, either version 3 of the License, or
12     (at your option) any later version.
13
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18
19     You should have received a copy of the GNU General Public License
20     along with this program.  If not, see <http://www.gnu.org/licenses/>. */
21
22 #include "../iext.hpp"
23
24 class Cuart : public Iext {
25         public:
26                 Cuart() : m_writeAddress(0), m_fetchCount(0), m_readCount(0), m_recRdy(0), m_txRdy(0), m_recVal(0), m_txVal(0) {};
27                 void applyTick() {};
28                 void loadData(const int address, CDat value);
29                 CDat readData(const int);
30                 void parseInput(const vector<string>& in);
31         private:
32                 int m_writeAddress, m_fetchCount, m_readCount;
33                 bool m_recRdy, m_txRdy;
34                 CDat m_recVal, m_txVal;
35 };
36
37
38 void Cuart::parseInput(const vector<string>& in)
39 {
40         if(in.size() > 1) {
41                 if((in[1].compare("h") == 0)) {
42                         cout << "UART:" << endl;
43                         cout << "\textension uart r 0xXX \t -- to load the module with a value" << endl;
44                         cout << "\textension uart f \t-- to load a value from the module" << endl;
45                 }
46         }
47         if(in.size() < 2) {
48                 return;
49         }
50         if(in[1].compare("uart") == 0) {
51                 if(in[2].compare("r") == 0) {
52                         if(in.size() < 3) {
53                                 return;
54                         }
55                         if(in[3].substr(0,2) == "0x") {
56                                 m_recVal = lexical_cast<uint32_from_hex>(in[3]);
57                         }
58                         else {
59                                 m_recVal = lexical_cast<unsigned int>(in[3]);
60                         }
61                         cout << "UART: loaded 0x" << std::hex << m_recVal << std::dec << endl;
62                         m_recRdy = 1;
63                         m_fetchCount = 0;
64                         m_readCount = 0;
65                 }
66                 else if(in[2].compare("f") == 0) {
67                         cout << "UART: sended 0x" << std::hex << m_txVal << std::dec << endl;
68                         m_txRdy = 0;
69                         m_fetchCount = 0;
70                         m_readCount = 0;
71                 }
72                 else if(in[2].compare("s") == 0) {
73                         cout << "UART:" << endl;
74                         cout << "\ttx busy: " << m_txRdy << endl;
75                         cout << "\trx_newdata: " << m_recRdy << endl;
76                 }
77         }
78 }
79
80 CDat Cuart::readData(const int address)
81 {
82         if(address == 0x2000) {
83                 //status - r only
84 /*              cout << "rx: " << m_recRdy << endl;
85                 cout << "tx: " << m_txRdy << endl;
86                 CDat helpme = m_recRdy;
87                 helpme <<= 1;
88                 helpme |= m_txRdy;
89                 cout << "rx<<1 | tx: " << helpme << endl;
90 */
91                 if(m_txRdy == 1) {
92                         m_fetchCount++;
93                 }
94                 if(m_recRdy == 0) {
95                         m_readCount++;
96                 }
97
98                 if(m_fetchCount >= 5) {
99                         m_fetchCount = 0;
100                         m_readCount = 0;
101                         m_txRdy = 0;
102                         cout << "UART: force fetched 0x" << std::hex << m_txVal << std::dec << endl;
103                 }
104                 if(m_readCount >= 5) {
105                         m_fetchCount = 0;
106                         m_readCount = 0;
107                         m_recRdy = 1;
108                         cout << "UART: force inserted 0x48 ('H')" << endl;
109                         m_recVal = 'H';
110                 }
111                 return (m_recRdy<<1)|(m_txRdy);
112         }
113         else if(address == 0x2008) {
114                 //trans - w only
115                 //data pointer
116         }
117         else if(address == 0x200c) {
118                 //recv - r only
119                 m_recRdy = 0;
120                 m_fetchCount = 0;
121                 m_readCount = 0;
122                 return m_recVal;
123         }
124         return 0;
125 }
126
127 void Cuart::loadData(const int address, CDat value)
128 {
129
130         if(address == 0x2000) {
131                 //status - r only
132         }
133         else if(address == 0x2008) {
134                 //trans - w only
135                 cout << "UART: byte ready to fetch" << endl;
136                 m_txVal = value;
137                 m_txRdy = 1;
138                 m_fetchCount = 0;
139                 m_readCount = 0;
140         }
141         else if(address == 0x200c) {
142                 //recv - r only
143         }
144 }