Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/c/cSh7751.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 149 - (show annotations) (download) (as text)
Sat Feb 13 10:57:58 2010 UTC (14 years ago) by molelord
File MIME type: text/x-c++src
File size: 8580 byte(s)
assert()に書いた条件が間違っていたのを直した。
1 // This software is a part of NOODLYBOX.
2 // This software is distributed under the terms of the new BSD License.
3 // Copyright (c) 2009, 2010, molelord
4 // All rights reserved.
5
6 #include <cassert> // assert()
7 #include <cstring> // strcmp()
8
9 #include "cSh7751.h" // Sh7751
10 #include "cMpuFactoryEnlarger.h" // MpuFactoryEnlarger
11 #if defined(MPU_PIPE)
12 # include "MPU_pipe.h" // v_waitClock()
13 #else
14 # include "MPU_dpi.h" // v_waitClock()
15 #endif
16
17 // fsm.tclおよびsh4config.tclでやっていたことのほとんどが、このクラスで
18 // 実装されている
19
20 namespace nbox {
21 const uint32_t Sh7751::CS_X = 1<<0;
22 const uint32_t Sh7751::OE_X = 1<<1;
23 const uint32_t Sh7751::WE_X = 1<<2;
24 const uint32_t Sh7751::HIZ = 1<<3;
25 const uint32_t Sh7751::BS_X = 1<<4;
26 const uint32_t Sh7751::RDWR = 1<<5;
27
28 static const uint32_t ReadBodyWidth = 0;
29 static const uint32_t WriteBodyWidth = 0;
30
31 Sh7751::Sh7751(int mpu_id) : Mpu(mpu_id),
32 state(&Sh7751::stFetch), subState(FIRST),
33 execAtFall(&Sh7751::exEmpty), execAtRise(&Sh7751::exEmpty)
34 {
35 }
36
37 Sh7751::~Sh7751()
38 {
39 }
40
41 Mpu *Sh7751::create(int mpu_id, const char *mpu_name)
42 {
43 assert(mpu_name != 0);
44 Mpu *p = 0;
45 if (std::strcmp("SH7751", mpu_name) == 0) {
46 p = new Sh7751(mpu_id);
47 }
48 return p;
49 }
50
51 bool Sh7751::reflect(
52 svLogicVecVal *a,
53 svLogicVecVal *dout,
54 const svLogicVecVal *ctrli,
55 svLogicVecVal *ctrlo,
56 int clk)
57 {
58 // 入力信号をクラスのメンバ変数に取り込む
59 this->ctrli = *ctrli;
60
61 if (!reset()) {
62 if (clk) {
63 need_next_rising = false;
64 (this->*execAtRise)();
65 this->execAtRise = &Sh7751::exEmpty;
66 (this->*state)();
67 }
68 else {
69 (this->*execAtFall)();
70 this->execAtFall = &Sh7751::exEmpty;
71 }
72 }
73
74 // 出力信号に対して、クラスの内部状態を反映させる
75 *a = this->a;
76 *dout = this->dout;
77 *ctrlo = this->ctrlo;
78
79 return need_next_rising;
80 }
81
82 void Sh7751::reflect_din(
83 const svLogicVecVal *din)
84 {
85 // 入力信号をクラスのメンバ変数に取り込む
86 this->din = *din;
87 }
88
89 void Sh7751::nop(uint32_t clocks)
90 {
91 pack.count = clocks;
92 this->state = &Sh7751::stNop;
93 this->subState = FIRST;
94
95 // 終わるまでループ
96 do {
97 v_waitClock();
98 } while (this->state != &Sh7751::stFetch);
99 }
100
101 uint32_t Sh7751::readGeneric(uint32_t addr, int bits)
102 {
103 assert(bits == 32 || bits == 16 || bits == 8);
104
105 uint32_t result = 0xdeadbeefU;
106 uint32_t mask = 0xffffffffU;
107 if (bits == 16) {
108 result = 0xdead;
109 mask = 0xffff;
110 }
111 else if (bits == 8) {
112 result = 0xde;
113 mask = 0xff;
114 }
115
116 // これからリードを始めるので、まずは失敗ということにしておく
117 this->read_success = false;
118
119 pack.addr = addr;
120 this->state = &Sh7751::stRead;
121 this->subState = FIRST;
122
123 // 読み出しが終わるまでループ
124 do {
125 v_waitClock();
126 } while (this->state != &Sh7751::stFetch);
127
128 // 'x'または'z'ならば、bvalは0でない値になっているので、もし
129 // 0であれば正常に読み出せたことになる
130 uint32_t bval = this->din.bval & mask;
131 if (bval == 0) {
132 this->read_success = true;
133 result = din.aval & mask;
134 }
135
136 return result;
137 }
138
139 uint8_t Sh7751::readB(uint32_t addr)
140 {
141 return readGeneric(addr, 8);
142 }
143 uint16_t Sh7751::readH(uint32_t addr)
144 {
145 return readGeneric(addr, 16);
146 }
147 uint32_t Sh7751::readW(uint32_t addr)
148 {
149 return readGeneric(addr, 32);
150 }
151
152 void Sh7751::writeB(uint32_t addr, uint8_t data)
153 {
154 writeW(addr, data);
155 }
156 void Sh7751::writeH(uint32_t addr, uint16_t data)
157 {
158 writeW(addr, data);
159 }
160 void Sh7751::writeW(uint32_t addr, uint32_t data)
161 {
162 pack.addr = addr;
163 pack.data = data;
164 this->state = &Sh7751::stWrite;
165 this->subState = FIRST;
166
167 // 書き込み動作が終わるまでループ
168 do {
169 v_waitClock();
170 } while (this->state != &Sh7751::stFetch);
171 }
172
173 void Sh7751::activate(uint32_t x, bool act)
174 {
175 uint32_t set = 0;
176 uint32_t clr = 0;
177
178 if (x & CS_X) { clr |= CS_X; }
179 if (x & OE_X) { clr |= OE_X; }
180 if (x & WE_X) { clr |= WE_X; }
181 if (x & HIZ) { set |= HIZ; }
182 if (x & BS_X) { clr |= BS_X; }
183 if (x & RDWR) { set |= RDWR; }
184
185 // 逆に使えばdeactivateになる
186 if (act)
187 this->ctrlo.aval = (this->ctrlo.aval | set) & ~clr;
188 else
189 this->ctrlo.aval = (this->ctrlo.aval | clr) & ~set;
190 }
191
192 void Sh7751::deactivate(uint32_t x)
193 {
194 activate(x, false);
195 }
196
197 void Sh7751::exEmpty() {}
198
199 // Tcl実装と違って、C++実装では特に何もする必要が無い
200 void Sh7751::stFetch() {}
201
202 void Sh7751::stNop()
203 {
204 switch (this->subState) {
205 case FIRST :
206 deactivate(CS_X);
207 this->subState = NOPTAIL;
208 break;
209 case NOPTAIL :
210 default :
211 break;
212 }
213
214 pack.count--;
215 if (pack.count == 0) {
216 this->state = &Sh7751::stFetch;
217 }
218 }
219
220 void Sh7751::exEndOfReadT1()
221 {
222 activate(OE_X);
223 deactivate(BS_X);
224 }
225
226 void Sh7751::exEndOfReadT2()
227 {
228 deactivate(OE_X);
229 }
230
231 void Sh7751::stRead()
232 {
233 switch (this->subState) {
234 case FIRST :
235 // Read T1
236 activate(CS_X | BS_X | RDWR);
237 this->a.aval = pack.addr;
238 this->execAtRise = &Sh7751::exEndOfReadT1;
239 pack.count = ReadBodyWidth;
240
241 this->subState = READBODY;
242 if (pack.count == 0) {
243 this->subState = READTAIL;
244 }
245 break;
246 case READBODY :
247 // Read Tw
248 pack.count--;
249 if (pack.count == 0) {
250 this->subState = READTAIL;
251 }
252 break;
253 case READTAIL :
254 default :
255 // Read T2
256 this->execAtRise = &Sh7751::exEndOfReadT2;
257 this->state = &Sh7751::stFetch;
258 need_next_rising = true;
259 break;
260 }
261 }
262
263 void Sh7751::exActivateWE()
264 {
265 activate(WE_X);
266 }
267 void Sh7751::exEndOfWriteT1()
268 {
269 this->dout.aval = pack.data;
270 deactivate(BS_X | HIZ);
271 }
272
273 void Sh7751::exDeactivateWE()
274 {
275 deactivate(WE_X);
276 }
277 void Sh7751::exEndOfWriteT2()
278 {
279 activate(HIZ);
280 }
281
282 void Sh7751::stWrite()
283 {
284 switch (this->subState) {
285 case FIRST :
286 // Write T1
287 activate(CS_X | BS_X);
288 deactivate(RDWR);
289 this->a.aval = pack.addr;
290
291 this->execAtFall = &Sh7751::exActivateWE;
292 this->execAtRise = &Sh7751::exEndOfWriteT1;
293 pack.count = WriteBodyWidth;
294 this->subState = WRITEBODY;
295 if (pack.count == 0) {
296 this->subState = WRITETAIL;
297 }
298 break;
299 case WRITEBODY :
300 // Write Tw
301 pack.count--;
302 if (pack.count == 0) {
303 this->subState = WRITETAIL;
304 }
305 break;
306 case WRITETAIL :
307 default :
308 // Write T2
309 this->execAtFall = &Sh7751::exDeactivateWE;
310 this->execAtRise = &Sh7751::exEndOfWriteT2;
311 this->state = &Sh7751::stFetch;
312 break;
313 }
314 }
315
316 // この記述によって、ライブラリ(DLL)のロード時点でcreate()が
317 // MpuFactoryに対して登録される
318 static MpuFactoryEnlarger x(Sh7751::create);
319
320 } // namespace nbox

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26