1 |
2 |
alfik |
#include <cstdio>
|
2 |
|
|
#include <cstdlib>
|
3 |
|
|
|
4 |
|
|
#include <sys/mman.h>
|
5 |
|
|
#include <sys/types.h>
|
6 |
|
|
#include <sys/stat.h>
|
7 |
|
|
#include <fcntl.h>
|
8 |
|
|
#include <unistd.h>
|
9 |
|
|
|
10 |
|
|
#include "Vmain.h"
|
11 |
|
|
#include "verilated.h"
|
12 |
|
|
#include "verilated_vcd_c.h"
|
13 |
|
|
|
14 |
|
|
#include "shared_mem.h"
|
15 |
|
|
|
16 |
|
|
//------------------------------------------------------------------------------
|
17 |
|
|
|
18 |
|
|
volatile shared_mem_t *shared_ptr = NULL;
|
19 |
|
|
|
20 |
|
|
//------------------------------------------------------------------------------
|
21 |
|
|
|
22 |
|
|
int main(int argc, char **argv) {
|
23 |
|
|
//map shared memory
|
24 |
|
|
int fd = open("./../../../sim/sim_pc/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
|
25 |
|
|
|
26 |
|
|
if(fd == -1) {
|
27 |
|
|
perror("open() failed for shared_mem.dat");
|
28 |
|
|
return -1;
|
29 |
|
|
}
|
30 |
|
|
|
31 |
|
|
shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
32 |
|
|
|
33 |
|
|
if(shared_ptr == MAP_FAILED) {
|
34 |
|
|
perror("mmap() failed");
|
35 |
|
|
close(fd);
|
36 |
|
|
return -2;
|
37 |
|
|
}
|
38 |
|
|
|
39 |
|
|
//wait for ack
|
40 |
|
|
shared_ptr->ao486.starting = STEP_REQ;
|
41 |
|
|
printf("Waiting for startup ack...");
|
42 |
|
|
fflush(stdout);
|
43 |
|
|
while(shared_ptr->ao486.starting != STEP_ACK) {
|
44 |
|
|
usleep(100000);
|
45 |
|
|
}
|
46 |
|
|
printf("done.\n");
|
47 |
|
|
|
48 |
|
|
//--------------------------------------------------------------------------
|
49 |
|
|
|
50 |
|
|
|
51 |
|
|
Verilated::commandArgs(argc, argv);
|
52 |
|
|
|
53 |
|
|
Verilated::traceEverOn(true);
|
54 |
|
|
VerilatedVcdC* tracer = new VerilatedVcdC;
|
55 |
|
|
|
56 |
|
|
Vmain *top = new Vmain();
|
57 |
|
|
top->trace (tracer, 99);
|
58 |
|
|
tracer->rolloverMB(1000000);
|
59 |
|
|
tracer->open("ao486.vcd");
|
60 |
|
|
//tracer->flush();
|
61 |
|
|
//return 0;
|
62 |
|
|
//reset
|
63 |
|
|
top->clk = 0; top->rst_n = 1; top->eval();
|
64 |
|
|
top->clk = 1; top->rst_n = 1; top->eval();
|
65 |
|
|
top->clk = 1; top->rst_n = 0; top->eval();
|
66 |
|
|
top->clk = 0; top->rst_n = 0; top->eval();
|
67 |
|
|
top->clk = 0; top->rst_n = 1; top->eval();
|
68 |
|
|
|
69 |
|
|
//--------------------------------------------------------------------------
|
70 |
|
|
|
71 |
|
|
uint32 sdram_read_count = 0;
|
72 |
|
|
uint32 sdram_read_data[4];
|
73 |
|
|
|
74 |
|
|
uint32 sdram_write_count = 0;
|
75 |
|
|
uint32 sdram_write_address = 0;
|
76 |
|
|
|
77 |
|
|
uint32 vga_read_count = 0;
|
78 |
|
|
uint32 vga_read_address = 0;
|
79 |
|
|
uint32 vga_read_byteenable = 0;
|
80 |
|
|
|
81 |
|
|
uint32 vga_write_count = 0;
|
82 |
|
|
uint32 vga_write_address = 0;
|
83 |
|
|
|
84 |
|
|
uint32 io_read_count = 0;
|
85 |
|
|
uint32 io_read_address = 0;
|
86 |
|
|
uint32 io_read_byteenable = 0;
|
87 |
|
|
|
88 |
|
|
uint32 ignored_intr_counter = 0;
|
89 |
|
|
|
90 |
|
|
//--------------------------------------------------------------------------
|
91 |
|
|
|
92 |
|
|
uint64 cycle = 0;
|
93 |
|
|
while(!Verilated::gotFinish()) {
|
94 |
|
|
|
95 |
|
|
//----------------------------------------------------------------------
|
96 |
|
|
if(top->tb_finish_instr) {
|
97 |
|
|
shared_ptr->ao486.instr_counter++;
|
98 |
|
|
|
99 |
|
|
if(shared_ptr->ao486.stop == STEP_REQ) {
|
100 |
|
|
shared_ptr->ao486.stop = STEP_ACK;
|
101 |
|
|
while(shared_ptr->ao486.stop != STEP_IDLE) {
|
102 |
|
|
usleep(500);
|
103 |
|
|
}
|
104 |
|
|
}
|
105 |
|
|
}
|
106 |
|
|
|
107 |
|
|
//---------------------------------------------------------------------- sdram
|
108 |
|
|
|
109 |
|
|
top->sdram_readdatavalid = 0;
|
110 |
|
|
|
111 |
|
|
if(top->sdram_read) {
|
112 |
|
|
uint32 address = top->sdram_address & 0x07FFFFFC;
|
113 |
|
|
|
114 |
|
|
for(uint32 i=0; i<4; i++) {
|
115 |
|
|
sdram_read_data[i] = shared_ptr->mem.ints[(address + i*4)/4];
|
116 |
|
|
|
117 |
|
|
if(((top->sdram_byteenable >> 0) & 1) == 0) sdram_read_data[i] &= 0xFFFFFF00;
|
118 |
|
|
if(((top->sdram_byteenable >> 1) & 1) == 0) sdram_read_data[i] &= 0xFFFF00FF;
|
119 |
|
|
if(((top->sdram_byteenable >> 2) & 1) == 0) sdram_read_data[i] &= 0xFF00FFFF;
|
120 |
|
|
if(((top->sdram_byteenable >> 3) & 1) == 0) sdram_read_data[i] &= 0x00FFFFFF;
|
121 |
|
|
}
|
122 |
|
|
sdram_read_count = top->sdram_burstcount;
|
123 |
|
|
//printf("sdram read: %08x %x [%08x %08x %08x %08x]\n", address, top->sdram_byteenable, sdram_read_data[0], sdram_read_data[1], sdram_read_data[2], sdram_read_data[3]);
|
124 |
|
|
}
|
125 |
|
|
else if(sdram_read_count > 0) {
|
126 |
|
|
top->sdram_readdatavalid = 1;
|
127 |
|
|
top->sdram_readdata = sdram_read_data[0];
|
128 |
|
|
//printf("r: %08x\n", top->sdram_readdata);
|
129 |
|
|
memmove(sdram_read_data, &sdram_read_data[1], sizeof(sdram_read_data)-sizeof(uint32));
|
130 |
|
|
sdram_read_count--;
|
131 |
|
|
}
|
132 |
|
|
|
133 |
|
|
if(top->sdram_write) {
|
134 |
|
|
uint32 address = (sdram_write_count > 0)? sdram_write_address : top->sdram_address & 0x07FFFFFC;
|
135 |
|
|
uint32 data = top->sdram_writedata;
|
136 |
|
|
|
137 |
|
|
if((top->sdram_byteenable & 0x1) == 0) data &= 0xFFFFFF00;
|
138 |
|
|
if((top->sdram_byteenable & 0x2) == 0) data &= 0xFFFF00FF;
|
139 |
|
|
if((top->sdram_byteenable & 0x4) == 0) data &= 0xFF00FFFF;
|
140 |
|
|
if((top->sdram_byteenable & 0x8) == 0) data &= 0x00FFFFFF;
|
141 |
|
|
|
142 |
|
|
printf("sdram write: %08x %x %08x %d", address, top->sdram_byteenable, data, sdram_write_count);
|
143 |
|
|
shared_ptr->ao486.mem_address = address;
|
144 |
|
|
shared_ptr->ao486.mem_byteenable = top->sdram_byteenable;
|
145 |
|
|
shared_ptr->ao486.mem_is_write = 1;
|
146 |
|
|
shared_ptr->ao486.mem_data = data;
|
147 |
|
|
shared_ptr->ao486.mem_step = STEP_REQ;
|
148 |
|
|
while(shared_ptr->ao486.mem_step != STEP_ACK) {
|
149 |
|
|
fflush(stdout);
|
150 |
|
|
usleep(10);
|
151 |
|
|
}
|
152 |
|
|
shared_ptr->ao486.mem_step = STEP_IDLE;
|
153 |
|
|
|
154 |
|
|
if(sdram_write_count == 0) {
|
155 |
|
|
sdram_write_address = (address + 4) & 0x07FFFFFC;
|
156 |
|
|
sdram_write_count = top->sdram_burstcount;
|
157 |
|
|
}
|
158 |
|
|
|
159 |
|
|
if(sdram_write_count > 0) sdram_write_count--;
|
160 |
|
|
printf("\n");
|
161 |
|
|
}
|
162 |
|
|
|
163 |
|
|
//---------------------------------------------------------------------- vga
|
164 |
|
|
|
165 |
|
|
top->vga_readdatavalid = 0;
|
166 |
|
|
|
167 |
|
|
if(top->vga_read) {
|
168 |
|
|
vga_read_address = top->vga_address & 0x000FFFFC;
|
169 |
|
|
|
170 |
|
|
vga_read_count = top->vga_burstcount;
|
171 |
|
|
vga_read_byteenable = top->vga_byteenable;
|
172 |
|
|
printf("vga read: %08x %x %d\n", vga_read_address, vga_read_byteenable, vga_read_count);
|
173 |
|
|
}
|
174 |
|
|
else if(vga_read_count > 0) {
|
175 |
|
|
shared_ptr->ao486.mem_address = vga_read_address;
|
176 |
|
|
shared_ptr->ao486.mem_byteenable = vga_read_byteenable;
|
177 |
|
|
shared_ptr->ao486.mem_is_write = 0;
|
178 |
|
|
shared_ptr->ao486.mem_step = STEP_REQ;
|
179 |
|
|
while(shared_ptr->ao486.mem_step != STEP_ACK) {
|
180 |
|
|
fflush(stdout);
|
181 |
|
|
usleep(10);
|
182 |
|
|
}
|
183 |
|
|
uint32 value = shared_ptr->ao486.mem_data;
|
184 |
|
|
shared_ptr->ao486.mem_step = STEP_IDLE;
|
185 |
|
|
|
186 |
|
|
top->vga_readdatavalid = 1;
|
187 |
|
|
top->vga_readdata = value;
|
188 |
|
|
|
189 |
|
|
vga_read_address = (vga_read_address + 4) & 0x000FFFFC;
|
190 |
|
|
vga_read_count--;
|
191 |
|
|
printf("\n");
|
192 |
|
|
}
|
193 |
|
|
|
194 |
|
|
if(top->vga_write) {
|
195 |
|
|
uint32 address = (vga_write_count > 0)? vga_write_address : top->vga_address & 0x000FFFFC;
|
196 |
|
|
uint32 data = top->vga_writedata;
|
197 |
|
|
|
198 |
|
|
if((top->vga_byteenable & 0x1) == 0) data &= 0xFFFFFF00;
|
199 |
|
|
if((top->vga_byteenable & 0x2) == 0) data &= 0xFFFF00FF;
|
200 |
|
|
if((top->vga_byteenable & 0x4) == 0) data &= 0xFF00FFFF;
|
201 |
|
|
if((top->vga_byteenable & 0x8) == 0) data &= 0x00FFFFFF;
|
202 |
|
|
|
203 |
|
|
printf("vga write: %08x %x %08x %d", address, top->sdram_byteenable, data, vga_write_count);
|
204 |
|
|
shared_ptr->ao486.mem_address = address;
|
205 |
|
|
shared_ptr->ao486.mem_byteenable = top->vga_byteenable;
|
206 |
|
|
shared_ptr->ao486.mem_is_write = 1;
|
207 |
|
|
shared_ptr->ao486.mem_data = data;
|
208 |
|
|
shared_ptr->ao486.mem_step = STEP_REQ;
|
209 |
|
|
while(shared_ptr->ao486.mem_step != STEP_ACK) {
|
210 |
|
|
fflush(stdout);
|
211 |
|
|
usleep(10);
|
212 |
|
|
}
|
213 |
|
|
shared_ptr->ao486.mem_step = STEP_IDLE;
|
214 |
|
|
|
215 |
|
|
if(vga_write_count == 0) {
|
216 |
|
|
vga_write_address = (address + 4) & 0x07FFFFFC;
|
217 |
|
|
vga_write_count = top->vga_burstcount;
|
218 |
|
|
}
|
219 |
|
|
|
220 |
|
|
if(vga_write_count > 0) vga_write_count--;
|
221 |
|
|
printf("\n", vga_write_count);
|
222 |
|
|
}
|
223 |
|
|
|
224 |
|
|
//---------------------------------------------------------------------- io
|
225 |
|
|
|
226 |
|
|
top->avalon_io_readdatavalid = 0;
|
227 |
|
|
|
228 |
|
|
if(top->avalon_io_read) {
|
229 |
|
|
io_read_address = top->avalon_io_address & 0x0000FFFC;
|
230 |
|
|
|
231 |
|
|
io_read_count = 1;
|
232 |
|
|
io_read_byteenable = top->avalon_io_byteenable;
|
233 |
|
|
printf("io read: %08x %x %d", io_read_address, io_read_byteenable, io_read_count);
|
234 |
|
|
}
|
235 |
|
|
else if(io_read_count > 0) {
|
236 |
|
|
shared_ptr->ao486.io_address = io_read_address;
|
237 |
|
|
shared_ptr->ao486.io_byteenable = io_read_byteenable;
|
238 |
|
|
shared_ptr->ao486.io_is_write = 0;
|
239 |
|
|
shared_ptr->ao486.io_step = STEP_REQ;
|
240 |
|
|
while(shared_ptr->ao486.io_step != STEP_ACK) {
|
241 |
|
|
fflush(stdout);
|
242 |
|
|
usleep(10);
|
243 |
|
|
}
|
244 |
|
|
uint32 value = shared_ptr->ao486.io_data;
|
245 |
|
|
shared_ptr->ao486.io_step = STEP_IDLE;
|
246 |
|
|
|
247 |
|
|
top->avalon_io_readdatavalid = 1;
|
248 |
|
|
top->avalon_io_readdata = value;
|
249 |
|
|
|
250 |
|
|
io_read_count--;
|
251 |
|
|
printf("\n");
|
252 |
|
|
}
|
253 |
|
|
|
254 |
|
|
if(top->avalon_io_write) {
|
255 |
|
|
uint32 data = top->avalon_io_writedata;
|
256 |
|
|
|
257 |
|
|
if((top->avalon_io_byteenable & 0x1) == 0) data &= 0xFFFFFF00;
|
258 |
|
|
if((top->avalon_io_byteenable & 0x2) == 0) data &= 0xFFFF00FF;
|
259 |
|
|
if((top->avalon_io_byteenable & 0x4) == 0) data &= 0xFF00FFFF;
|
260 |
|
|
if((top->avalon_io_byteenable & 0x8) == 0) data &= 0x00FFFFFF;
|
261 |
|
|
|
262 |
|
|
printf("io write: %08x %x %08x", (top->avalon_io_address & 0x0000FFFC), top->avalon_io_byteenable, data);
|
263 |
|
|
shared_ptr->ao486.io_address = top->avalon_io_address & 0x0000FFFC;
|
264 |
|
|
shared_ptr->ao486.io_byteenable = top->avalon_io_byteenable;
|
265 |
|
|
shared_ptr->ao486.io_is_write = 1;
|
266 |
|
|
shared_ptr->ao486.io_data = data;
|
267 |
|
|
shared_ptr->ao486.io_step = STEP_REQ;
|
268 |
|
|
while(shared_ptr->ao486.io_step != STEP_ACK) {
|
269 |
|
|
fflush(stdout);
|
270 |
|
|
usleep(10);
|
271 |
|
|
}
|
272 |
|
|
shared_ptr->ao486.io_step = STEP_IDLE;
|
273 |
|
|
printf("\n");
|
274 |
|
|
}
|
275 |
|
|
|
276 |
|
|
//---------------------------------------------------------------------- interrupt
|
277 |
|
|
|
278 |
|
|
top->interrupt_vector = shared_ptr->interrupt_vector;
|
279 |
|
|
|
280 |
|
|
if(top->interrupt_do && top->interrupt_done) {
|
281 |
|
|
printf("irq done at %d\n", shared_ptr->ao486.instr_counter);
|
282 |
|
|
top->interrupt_do = 0;
|
283 |
|
|
ignored_intr_counter = shared_ptr->ao486.instr_counter;
|
284 |
|
|
}
|
285 |
|
|
else if(ignored_intr_counter != shared_ptr->ao486.instr_counter && shared_ptr->interrupt_at_counter == shared_ptr->ao486.instr_counter) {
|
286 |
|
|
printf("irq do %02x at %d\n", top->interrupt_vector, shared_ptr->ao486.instr_counter);
|
287 |
|
|
top->interrupt_do = 1;
|
288 |
|
|
}
|
289 |
|
|
else if(shared_ptr->interrupt_at_counter == 0) {
|
290 |
|
|
printf("irq lower at %d\n", shared_ptr->ao486.instr_counter);
|
291 |
|
|
top->interrupt_do = 0;
|
292 |
|
|
}
|
293 |
|
|
|
294 |
|
|
//----------------------------------------------------------------------
|
295 |
|
|
|
296 |
|
|
//if(shared_ptr->ao486.instr_counter > 7728000) shared_ptr->dump_enabled = 0;
|
297 |
|
|
//else if(cycle > 142400000 || shared_ptr->ao486.instr_counter > 7720000) shared_ptr->dump_enabled = 1;
|
298 |
|
|
//else if(shared_ptr->ao486.instr_counter > 712000) shared_ptr->dump_enabled = 1;
|
299 |
|
|
// shared_ptr->dump_enabled = 1;
|
300 |
|
|
|
301 |
|
|
top->clk = 0;
|
302 |
|
|
top->eval();
|
303 |
|
|
|
304 |
|
|
cycle++;
|
305 |
|
|
if(shared_ptr->dump_enabled) tracer->dump(cycle);
|
306 |
|
|
|
307 |
|
|
top->clk = 1;
|
308 |
|
|
top->eval();
|
309 |
|
|
|
310 |
|
|
cycle++;
|
311 |
|
|
if(shared_ptr->dump_enabled) tracer->dump(cycle);
|
312 |
|
|
|
313 |
|
|
if((cycle % 10000) == 0) printf("half-cycle: %lld\n", cycle);
|
314 |
|
|
//12320000
|
315 |
|
|
|
316 |
|
|
tracer->flush();
|
317 |
|
|
//usleep(1);
|
318 |
|
|
}
|
319 |
|
|
delete top;
|
320 |
|
|
return 0;
|
321 |
|
|
}
|
322 |
|
|
|
323 |
|
|
/*
|
324 |
|
|
uint32 interrupt_vector;
|
325 |
|
|
uint64 interrupt_timestamp;
|
326 |
|
|
uint32 interrupt_valid;
|
327 |
|
|
|
328 |
|
|
----
|
329 |
|
|
|
330 |
|
|
VL_IN8(clk,0,0);
|
331 |
|
|
VL_IN8(rst_n,0,0);
|
332 |
|
|
|
333 |
|
|
VL_IN8(interrupt_do,0,0);
|
334 |
|
|
VL_IN8(interrupt_vector,7,0);
|
335 |
|
|
VL_OUT8(interrupt_done,0,0);
|
336 |
|
|
|
337 |
|
|
VL_OUT8(avalon_io_byteenable,3,0);
|
338 |
|
|
VL_OUT8(avalon_io_read,0,0);
|
339 |
|
|
VL_IN8(avalon_io_readdatavalid,0,0);
|
340 |
|
|
VL_OUT8(avalon_io_write,0,0);
|
341 |
|
|
VL_IN8(avalon_io_waitrequest,0,0);
|
342 |
|
|
VL_OUT16(avalon_io_address,15,0);
|
343 |
|
|
VL_IN(avalon_io_readdata,31,0);
|
344 |
|
|
VL_OUT(avalon_io_writedata,31,0);
|
345 |
|
|
|
346 |
|
|
VL_OUT8(sdram_byteenable,3,0);
|
347 |
|
|
VL_OUT8(sdram_read,0,0);
|
348 |
|
|
VL_OUT8(sdram_write,0,0);
|
349 |
|
|
VL_OUT8(sdram_burstcount,2,0);
|
350 |
|
|
VL_OUT(sdram_address,31,0);
|
351 |
|
|
VL_OUT(sdram_writedata,31,0);
|
352 |
|
|
VL_IN8(sdram_waitrequest,0,0);
|
353 |
|
|
VL_IN8(sdram_readdatavalid,0,0);
|
354 |
|
|
VL_IN(sdram_readdata,31,0);
|
355 |
|
|
|
356 |
|
|
VL_OUT8(vga_byteenable,3,0);
|
357 |
|
|
VL_OUT8(vga_read,0,0);
|
358 |
|
|
VL_OUT8(vga_write,0,0);
|
359 |
|
|
VL_IN8(vga_waitrequest,0,0);
|
360 |
|
|
VL_IN8(vga_readdatavalid,0,0);
|
361 |
|
|
VL_OUT8(vga_burstcount,2,0);
|
362 |
|
|
VL_OUT(vga_address,31,0);
|
363 |
|
|
VL_IN(vga_readdata,31,0);
|
364 |
|
|
VL_OUT(vga_writedata,31,0);
|
365 |
|
|
*/
|