1 |
2 |
alfik |
#include <cstdio>
|
2 |
|
|
#include <cstdlib>
|
3 |
|
|
|
4 |
|
|
#include <dlfcn.h>
|
5 |
|
|
|
6 |
|
|
#include <sys/mman.h>
|
7 |
|
|
#include <sys/types.h>
|
8 |
|
|
#include <sys/stat.h>
|
9 |
|
|
#include <fcntl.h>
|
10 |
|
|
#include <unistd.h>
|
11 |
|
|
|
12 |
|
|
#include "Vpic.h"
|
13 |
|
|
#include "verilated.h"
|
14 |
|
|
#include "verilated_vcd_c.h"
|
15 |
|
|
|
16 |
|
|
#include "shared_mem.h"
|
17 |
|
|
|
18 |
|
|
//------------------------------------------------------------------------------
|
19 |
|
|
//------------------------------------------------------------------------------
|
20 |
|
|
//------------------------------------------------------------------------------
|
21 |
|
|
|
22 |
|
|
volatile shared_mem_t *shared_ptr = NULL;
|
23 |
|
|
|
24 |
|
|
//------------------------------------------------------------------------------
|
25 |
|
|
//------------------------------------------------------------------------------
|
26 |
|
|
//------------------------------------------------------------------------------
|
27 |
|
|
|
28 |
|
|
//------------------------------------------------------------------------------
|
29 |
|
|
|
30 |
|
|
int main(int argc, char **argv) {
|
31 |
|
|
//map shared memory
|
32 |
|
|
int fd = open("./../../../sim_pc/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
|
33 |
|
|
|
34 |
|
|
if(fd == -1) {
|
35 |
|
|
perror("open() failed for shared_mem.dat");
|
36 |
|
|
return -1;
|
37 |
|
|
}
|
38 |
|
|
|
39 |
|
|
shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
40 |
|
|
|
41 |
|
|
if(shared_ptr == MAP_FAILED) {
|
42 |
|
|
perror("mmap() failed");
|
43 |
|
|
close(fd);
|
44 |
|
|
return -2;
|
45 |
|
|
}
|
46 |
|
|
|
47 |
|
|
Verilated::commandArgs(argc, argv);
|
48 |
|
|
|
49 |
|
|
Verilated::traceEverOn(true);
|
50 |
|
|
VerilatedVcdC* tracer = new VerilatedVcdC;
|
51 |
|
|
|
52 |
|
|
Vpic *top = new Vpic();
|
53 |
|
|
top->trace (tracer, 99);
|
54 |
|
|
//tracer->rolloverMB(1000000);
|
55 |
|
|
tracer->open("pic.vcd");
|
56 |
|
|
|
57 |
|
|
//reset
|
58 |
|
|
top->clk = 0; top->rst_n = 1; top->eval();
|
59 |
|
|
top->clk = 1; top->rst_n = 1; top->eval();
|
60 |
|
|
top->clk = 1; top->rst_n = 0; top->eval();
|
61 |
|
|
top->clk = 0; top->rst_n = 0; top->eval();
|
62 |
|
|
top->clk = 0; top->rst_n = 1; top->eval();
|
63 |
|
|
|
64 |
|
|
bool dump = false;
|
65 |
|
|
uint64 cycle = 0;
|
66 |
|
|
bool read_cycle = false;
|
67 |
|
|
|
68 |
|
|
int irq_counter = 0;
|
69 |
|
|
|
70 |
|
|
printf("pic main_plugin.cpp\n");
|
71 |
|
|
while(!Verilated::gotFinish()) {
|
72 |
|
|
|
73 |
|
|
//----------------------------------------------------------------------
|
74 |
|
|
|
75 |
|
|
/*
|
76 |
|
|
uint32 combined.io_address;
|
77 |
|
|
uint32 combined.io_data;
|
78 |
|
|
uint32 combined.io_byteenable;
|
79 |
|
|
uint32 combined.io_is_write;
|
80 |
|
|
step_t combined.io_step;
|
81 |
|
|
|
82 |
|
|
//master pic 0020-0021
|
83 |
|
|
input master_address,
|
84 |
|
|
input master_read,
|
85 |
|
|
output reg [7:0] master_readdata,
|
86 |
|
|
input master_write,
|
87 |
|
|
input [7:0] master_writedata,
|
88 |
|
|
|
89 |
|
|
//slave pic 00A0-00A1
|
90 |
|
|
input slave_address,
|
91 |
|
|
input slave_read,
|
92 |
|
|
output reg [7:0] slave_readdata,
|
93 |
|
|
input slave_write,
|
94 |
|
|
input [7:0] slave_writedata,
|
95 |
|
|
*/
|
96 |
|
|
|
97 |
|
|
top->master_read = 0;
|
98 |
|
|
top->master_write= 0;
|
99 |
|
|
|
100 |
|
|
top->slave_read = 0;
|
101 |
|
|
top->slave_write = 0;
|
102 |
|
|
|
103 |
|
|
if(shared_ptr->combined.io_step == STEP_REQ && shared_ptr->combined.io_is_write &&
|
104 |
|
|
((shared_ptr->combined.io_address == 0x0020 && ((shared_ptr->combined.io_byteenable >> 2) & 3) == 0) || (shared_ptr->combined.io_address == 0x00A0 && ((shared_ptr->combined.io_byteenable >> 2) & 3) == 0)))
|
105 |
|
|
{
|
106 |
|
|
if(shared_ptr->combined.io_byteenable != 1 && shared_ptr->combined.io_byteenable != 2 && shared_ptr->combined.io_byteenable != 4 && shared_ptr->combined.io_byteenable != 8) {
|
107 |
|
|
printf("Vpic rd: combined.io_byteenable invalid: %x\n", shared_ptr->combined.io_byteenable);
|
108 |
|
|
exit(-1);
|
109 |
|
|
}
|
110 |
|
|
|
111 |
|
|
top->master_address = (shared_ptr->combined.io_address == 0x0020 && shared_ptr->combined.io_byteenable == 1)? 0 : 1;
|
112 |
|
|
top->slave_address = (shared_ptr->combined.io_address == 0x00A0 && shared_ptr->combined.io_byteenable == 1)? 0 : 1;
|
113 |
|
|
|
114 |
|
|
top->master_writedata = (shared_ptr->combined.io_byteenable == 1)? shared_ptr->combined.io_data & 0xFF : (shared_ptr->combined.io_data >> 8) & 0xFF;
|
115 |
|
|
top->slave_writedata = (shared_ptr->combined.io_byteenable == 1)? shared_ptr->combined.io_data & 0xFF : (shared_ptr->combined.io_data >> 8) & 0xFF;
|
116 |
|
|
|
117 |
|
|
if(shared_ptr->combined.io_address == 0x0020) {
|
118 |
|
|
top->master_read = 0;
|
119 |
|
|
top->master_write = 1;
|
120 |
|
|
}
|
121 |
|
|
if(shared_ptr->combined.io_address == 0x00A0) {
|
122 |
|
|
top->slave_read = 0;
|
123 |
|
|
top->slave_write = 1;
|
124 |
|
|
}
|
125 |
|
|
|
126 |
|
|
shared_ptr->combined.io_step = STEP_ACK;
|
127 |
|
|
}
|
128 |
|
|
|
129 |
|
|
if(read_cycle == false) {
|
130 |
|
|
if(shared_ptr->combined.io_step == STEP_REQ && shared_ptr->combined.io_is_write == 0 &&
|
131 |
|
|
((shared_ptr->combined.io_address == 0x0020 && ((shared_ptr->combined.io_byteenable >> 2) & 3) == 0) || (shared_ptr->combined.io_address == 0x00A0 && ((shared_ptr->combined.io_byteenable >> 2) & 3) == 0)))
|
132 |
|
|
{
|
133 |
|
|
if(shared_ptr->combined.io_byteenable != 1 && shared_ptr->combined.io_byteenable != 2 && shared_ptr->combined.io_byteenable != 4 && shared_ptr->combined.io_byteenable != 8) {
|
134 |
|
|
printf("Vpic wr: combined.io_byteenable invalid: %x\n", shared_ptr->combined.io_byteenable);
|
135 |
|
|
exit(-1);
|
136 |
|
|
}
|
137 |
|
|
|
138 |
|
|
top->master_address =(shared_ptr->combined.io_address == 0x0020 && shared_ptr->combined.io_byteenable == 1)? 0 : 1;
|
139 |
|
|
top->slave_address =(shared_ptr->combined.io_address == 0x00A0 && shared_ptr->combined.io_byteenable == 1)? 0 : 1;
|
140 |
|
|
|
141 |
|
|
top->master_writedata = 0;
|
142 |
|
|
top->slave_writedata = 0;
|
143 |
|
|
|
144 |
|
|
if(shared_ptr->combined.io_address == 0x0020) {
|
145 |
|
|
top->master_read = 1;
|
146 |
|
|
top->master_write = 0;
|
147 |
|
|
}
|
148 |
|
|
if(shared_ptr->combined.io_address == 0x00A0) {
|
149 |
|
|
top->slave_read = 1;
|
150 |
|
|
top->slave_write = 0;
|
151 |
|
|
}
|
152 |
|
|
|
153 |
|
|
read_cycle = true;
|
154 |
|
|
}
|
155 |
|
|
}
|
156 |
|
|
else {
|
157 |
|
|
if(shared_ptr->combined.io_step == STEP_REQ && shared_ptr->combined.io_is_write == 0 &&
|
158 |
|
|
((shared_ptr->combined.io_address == 0x0020 && ((shared_ptr->combined.io_byteenable >> 2) & 3) == 0) || (shared_ptr->combined.io_address == 0x00A0 && ((shared_ptr->combined.io_byteenable >> 2) & 3) == 0)))
|
159 |
|
|
{
|
160 |
|
|
uint32 val = 0;
|
161 |
|
|
|
162 |
|
|
if(shared_ptr->combined.io_address == 0x0020) {
|
163 |
|
|
val = top->master_readdata;
|
164 |
|
|
}
|
165 |
|
|
if(shared_ptr->combined.io_address == 0x00A0) {
|
166 |
|
|
val = top->slave_readdata;
|
167 |
|
|
}
|
168 |
|
|
|
169 |
|
|
if(shared_ptr->combined.io_byteenable & 1) val <<= 0;
|
170 |
|
|
if(shared_ptr->combined.io_byteenable & 2) val <<= 8;
|
171 |
|
|
if(shared_ptr->combined.io_byteenable & 4) val <<= 16;
|
172 |
|
|
if(shared_ptr->combined.io_byteenable & 8) val <<= 24;
|
173 |
|
|
|
174 |
|
|
shared_ptr->combined.io_data = val;
|
175 |
|
|
|
176 |
|
|
read_cycle = false;
|
177 |
|
|
shared_ptr->combined.io_step = STEP_ACK;
|
178 |
|
|
}
|
179 |
|
|
}
|
180 |
|
|
|
181 |
|
|
//----------------------------------------------------------------------
|
182 |
|
|
|
183 |
|
|
top->interrupt_input =
|
184 |
|
|
((shared_ptr->pit_irq_step == STEP_REQ)? 1 << 0 : 0) |
|
185 |
|
|
((shared_ptr->rtc_irq_step == STEP_REQ)? 1 << 8 : 0) |
|
186 |
|
|
((shared_ptr->floppy_irq_step == STEP_REQ)? 1 << 6 : 0) |
|
187 |
|
|
((shared_ptr->keyboard_irq_step == STEP_REQ)? 1 << 1 : 0) |
|
188 |
|
|
((shared_ptr->mouse_irq_step == STEP_REQ)? 1 << 12 : 0);
|
189 |
|
|
|
190 |
|
|
//----------------------------------------------------------------------
|
191 |
|
|
|
192 |
|
|
shared_ptr->irq_do_vector = top->interrupt_vector;
|
193 |
|
|
shared_ptr->irq_do = (top->interrupt_do && shared_ptr->irq_done == STEP_IDLE)? STEP_REQ : STEP_IDLE;
|
194 |
|
|
|
195 |
|
|
top->interrupt_done = 0;
|
196 |
|
|
|
197 |
|
|
if(shared_ptr->irq_done == STEP_REQ) {
|
198 |
|
|
top->interrupt_done = 1;
|
199 |
|
|
shared_ptr->irq_done = STEP_IDLE;
|
200 |
|
|
|
201 |
|
|
printf("irq_done: do: %02x done: %02x count: %d\n", shared_ptr->irq_do_vector, shared_ptr->irq_done_vector, ++irq_counter);
|
202 |
|
|
|
203 |
|
|
//if(shared_ptr->irq_do_vector == 0x5F) dump = 1;
|
204 |
|
|
}
|
205 |
|
|
|
206 |
|
|
//if(shared_ptr->bochs486_pc.instr_counter >= 24820000) dump = 1;
|
207 |
|
|
|
208 |
|
|
//----------------------------------------------------------------------
|
209 |
|
|
|
210 |
|
|
top->clk = 0;
|
211 |
|
|
top->eval();
|
212 |
|
|
if(dump) tracer->dump(cycle++);
|
213 |
|
|
|
214 |
|
|
top->clk = 1;
|
215 |
|
|
top->eval();
|
216 |
|
|
if(dump) tracer->dump(cycle++);
|
217 |
|
|
|
218 |
|
|
tracer->flush();
|
219 |
|
|
|
220 |
|
|
usleep(1);
|
221 |
|
|
}
|
222 |
|
|
tracer->close();
|
223 |
|
|
delete tracer;
|
224 |
|
|
delete top;
|
225 |
|
|
|
226 |
|
|
return 0;
|
227 |
|
|
}
|
228 |
|
|
|
229 |
|
|
//------------------------------------------------------------------------------
|
230 |
|
|
|
231 |
|
|
/*
|
232 |
|
|
input clk,
|
233 |
|
|
input rst_n,
|
234 |
|
|
|
235 |
|
|
//master pic 0020-0021
|
236 |
|
|
input master_address,
|
237 |
|
|
input master_read,
|
238 |
|
|
output reg [7:0] master_readdata,
|
239 |
|
|
input master_write,
|
240 |
|
|
input [7:0] master_writedata,
|
241 |
|
|
|
242 |
|
|
//slave pic 00A0-00A1
|
243 |
|
|
input slave_address,
|
244 |
|
|
input slave_read,
|
245 |
|
|
output reg [7:0] slave_readdata,
|
246 |
|
|
input slave_write,
|
247 |
|
|
input [7:0] slave_writedata,
|
248 |
|
|
|
249 |
|
|
//interrupt input
|
250 |
|
|
input [15:0] interrupt_input,
|
251 |
|
|
|
252 |
|
|
//interrupt output
|
253 |
|
|
output reg interrupt_do,
|
254 |
|
|
output reg [7:0] interrupt_vector,
|
255 |
|
|
input interrupt_done
|
256 |
|
|
*/
|