OpenCores
URL https://opencores.org/ocsvn/s6soc/s6soc/trunk

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [bench/] [cpp/] [zip_sim.cpp] - Blame information for rev 54

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 dgisselq
////////////////////////////////////////////////////////////////////////////////
2 2 dgisselq
//
3 10 dgisselq
// Filename:    zip_sim.cpp
4 2 dgisselq
//
5 10 dgisselq
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
6 2 dgisselq
//
7 10 dgisselq
// Purpose:     This provides a simulation capability for the CMod S6 SoC.
8 2 dgisselq
//
9 10 dgisselq
// Creator:     Dan Gisselquist, Ph.D.
10
//              Gisselquist Technology, LLC
11 2 dgisselq
//
12 10 dgisselq
////////////////////////////////////////////////////////////////////////////////
13 2 dgisselq
//
14 10 dgisselq
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
15 2 dgisselq
//
16 10 dgisselq
// This program is free software (firmware): you can redistribute it and/or
17
// modify it under the terms of  the GNU General Public License as published
18
// by the Free Software Foundation, either version 3 of the License, or (at
19
// your option) any later version.
20 2 dgisselq
//
21 10 dgisselq
// This program is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License along
27
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
28
// target there if the PDF file isn't present.)  If not, see
29
// <http://www.gnu.org/licenses/> for a copy.
30
//
31
// License:     GPL, v3, as defined and found on www.gnu.org,
32
//              http://www.gnu.org/licenses/gpl.html
33
//
34
//
35
////////////////////////////////////////////////////////////////////////////////
36
//
37
//
38 2 dgisselq
#include <stdio.h>
39
#include <sys/types.h>
40
#include <sys/stat.h>
41
#include <fcntl.h>
42
#include <signal.h>
43
#include <time.h>
44
#include <unistd.h>
45 10 dgisselq
#include <stdint.h>
46 2 dgisselq
 
47
#include "verilated.h"
48
#include "Vbusmaster.h"
49
 
50 10 dgisselq
#include "regdefs.h"
51 2 dgisselq
#include "testb.h"
52
// #include "twoc.h"
53
#include "qspiflashsim.h"
54
#include "uartsim.h"
55 49 dgisselq
#include "zipelf.h"
56
#include "byteswap.h"
57 2 dgisselq
 
58 10 dgisselq
typedef uint32_t        BUSW;
59
 
60 2 dgisselq
class   GPIOSIM {
61
public:
62
        unsigned operator()(const unsigned o_gpio) { return 0; }
63
};
64
 
65
class   KEYPADSIM {
66
public:
67
        unsigned operator()(const unsigned o_kpd) { return 0; }
68
};
69
 
70 49 dgisselq
#define tx_busy         v__DOT__tcvuart__DOT__r_busy
71
#define rx_stb          v__DOT__rx_stb
72
#define uart_setup      v__DOT__tcvuart__DOT__r_setup
73
#define cpu_regset      v__DOT__swic__DOT__thecpu__DOT__regset
74
#define cpu_gie         v__DOT__swic__DOT__thecpu__DOT__r_gie
75
#define cpu_ipc         v__DOT__swic__DOT__thecpu__DOT__ipc
76
#define cpu_upc         v__DOT__swic__DOT__thecpu__DOT__r_upc
77
#define cpu_op_Av       v__DOT__swic__DOT__thecpu__DOT__r_op_Av
78
#define cpu_op_Bv       v__DOT__swic__DOT__thecpu__DOT__r_op_Bv
79
#define cpu_iflags      v__DOT__swic__DOT__thecpu__DOT__w_iflags
80
#define cpu_uflags      v__DOT__swic__DOT__thecpu__DOT__w_uflags
81
#define cpu_pf_valid    v__DOT__swic__DOT__thecpu__DOT__pf_valid
82
#define cpu_pf_pc       v__DOT__swic__DOT__thecpu__DOT__pf_pc
83
#define cpu_pf_instruction_pc   v__DOT__swic__DOT__thecpu__DOT__pf_instruction_pc
84
#define cpu_pf_instruction      v__DOT__swic__DOT__thecpu__DOT__pf_instruction
85
#define cpu_op_valid    v__DOT__swic__DOT__thecpu__DOT__op_valid
86
#define cpu_op_sim      v__DOT__swic__DOT__thecpu__DOT__op_sim
87
#define cpu_sim_immv    v__DOT__swic__DOT__thecpu__DOT__op_sim_immv
88
#define cpu_alu_ce      v__DOT__swic__DOT__thecpu__DOT__alu_ce
89
//
90
#define pic_gie         v__DOT__pic__DOT__r_gie
91
#define pic_int_enable  v__DOT__pic__DOT__r_int_enable
92
#define pic_any         v__DOT__pic__DOT__r_any
93
#define pic_int_state   v__DOT__pic__DOT__r_int_state
94
#define wb_cyc          v__DOT__wb_cyc
95
#define wb_stb          v__DOT__wb_stb
96
#define wb_we           v__DOT__wb_we
97
#define wb_data         v__DOT__swic__DOT__thecpu__DOT__mem_data
98
#define wb_addr         v__DOT__w_zip_addr
99
//
100
#define wb_ack          v__DOT__wb_ack
101
#define wb_stall        v__DOT__wb_stall
102
#define wb_idata        v__DOT__wb_idata
103
//
104
#define watchdog_int    v__DOT__watchdog_int
105 2 dgisselq
 
106
// No particular "parameters" need definition or redefinition here.
107 49 dgisselq
class   ZIPSIM_TB : public TESTB<Vbusmaster> {
108 2 dgisselq
public:
109
        QSPIFLASHSIM    m_flash;
110
        UARTSIM         m_uart;
111
        GPIOSIM         m_gpio;
112
        KEYPADSIM       m_keypad;
113
        unsigned        m_last_led;
114 49 dgisselq
        unsigned        m_last_gpio, m_last_pf_pc;
115 2 dgisselq
        time_t          m_start_time;
116 17 dgisselq
        FILE            *m_dbg;
117 2 dgisselq
 
118 49 dgisselq
        ZIPSIM_TB(int serial_port, bool debug) : m_uart(serial_port) {
119 2 dgisselq
                m_start_time = time(NULL);
120 49 dgisselq
                if (debug)
121
                        m_dbg = fopen("dbg.txt","w");
122
                else    m_dbg = NULL;
123
 
124
                m_last_led = m_last_gpio = m_last_pf_pc = -1;
125 2 dgisselq
        }
126
 
127
        void    reset(void) {
128
                m_flash.debug(false);
129
        }
130
 
131 49 dgisselq
        void    close(void) {
132
                closetrace();
133
        }
134
 
135
        void dump(const uint32_t *regp) {
136
                uint32_t        uccv, iccv;
137
                fflush(stderr);
138
                fflush(stdout);
139
                printf("ZIPM--DUMP: ");
140
                if (m_core->cpu_gie)
141
                        printf("Interrupts-enabled\n");
142
                else
143
                        printf("Supervisor mode\n");
144
                printf("\n");
145
 
146
                iccv = m_core->cpu_iflags;
147
                uccv = m_core->cpu_uflags;
148
 
149
                printf("sR0 : %08x ", regp[0]);
150
                printf("sR1 : %08x ", regp[1]);
151
                printf("sR2 : %08x ", regp[2]);
152
                printf("sR3 : %08x\n",regp[3]);
153
                printf("sR4 : %08x ", regp[4]);
154
                printf("sR5 : %08x ", regp[5]);
155
                printf("sR6 : %08x ", regp[6]);
156
                printf("sR7 : %08x\n",regp[7]);
157
                printf("sR8 : %08x ", regp[8]);
158
                printf("sR9 : %08x ", regp[9]);
159
                printf("sR10: %08x ", regp[10]);
160
                printf("sR11: %08x\n",regp[11]);
161
                printf("sR12: %08x ", regp[12]);
162
                printf("sSP : %08x ", regp[13]);
163
                printf("sCC : %08x ", iccv);
164
                printf("sPC : %08x\n",m_core->cpu_ipc);
165
 
166
                printf("\n");
167
 
168
                printf("uR0 : %08x ", regp[16]);
169
                printf("uR1 : %08x ", regp[17]);
170
                printf("uR2 : %08x ", regp[18]);
171
                printf("uR3 : %08x\n",regp[19]);
172
                printf("uR4 : %08x ", regp[20]);
173
                printf("uR5 : %08x ", regp[21]);
174
                printf("uR6 : %08x ", regp[22]);
175
                printf("uR7 : %08x\n",regp[23]);
176
                printf("uR8 : %08x ", regp[24]);
177
                printf("uR9 : %08x ", regp[25]);
178
                printf("uR10: %08x ", regp[26]);
179
                printf("uR11: %08x\n",regp[27]);
180
                printf("uR12: %08x ", regp[28]);
181
                printf("uSP : %08x ", regp[29]);
182
                printf("uCC : %08x ", uccv);
183
                printf("uPC : %08x\n",m_core->cpu_upc);
184
                printf("\n");
185
                fflush(stderr);
186
                fflush(stdout);
187
        }
188
 
189
        void    execsim(const uint32_t imm) {
190
                uint32_t        *regp = m_core->cpu_regset;
191
                int             rbase;
192
                rbase = (m_core->cpu_gie)?16:0;
193
 
194
                fflush(stdout);
195
                if ((imm & 0x03fffff)==0)
196
                        return;
197
                // fprintf(stderr, "SIM-INSN(0x%08x)\n", imm);
198
                if ((imm & 0x0fffff)==0x00100) {
199
                        // SIM Exit(0)
200
                        close();
201
                        exit(0);
202
                } else if ((imm & 0x0ffff0)==0x00310) {
203
                        // SIM Exit(User-Reg)
204
                        int     rcode;
205
                        rcode = regp[(imm&0x0f)+16] & 0x0ff;
206
                        close();
207
                        exit(rcode);
208
                } else if ((imm & 0x0ffff0)==0x00300) {
209
                        // SIM Exit(Reg)
210
                        int     rcode;
211
                        rcode = regp[(imm&0x0f)+rbase] & 0x0ff;
212
                        close();
213
                        exit(rcode);
214
                } else if ((imm & 0x0fff00)==0x00100) {
215
                        // SIM Exit(Imm)
216
                        int     rcode;
217
                        rcode = imm & 0x0ff;
218
                        close();
219
                        exit(rcode);
220
                } else if ((imm & 0x0fffff)==0x002ff) {
221
                        // Full/unconditional dump
222
                        printf("SIM-DUMP\n");
223
                        dump(regp);
224
                } else if ((imm & 0x0ffff0)==0x00200) {
225
                        // Dump a register
226
                        int rid = (imm&0x0f)+rbase;
227
                        printf("%8ld @%08x R[%2d] = 0x%08x\n", m_tickcount,
228
                                m_core->cpu_ipc, rid, regp[rid]);
229
                } else if ((imm & 0x0ffff0)==0x00210) {
230
                        // Dump a user register
231
                        int rid = (imm&0x0f);
232
                        printf("%8ld @%08x uR[%2d] = 0x%08x\n", m_tickcount,
233
                                m_core->cpu_ipc, rid, regp[rid+16]);
234
                } else if ((imm & 0x0ffff0)==0x00230) {
235
                        // SOUT[User Reg]
236
                        int rid = (imm&0x0f)+16;
237
                        printf("%c", regp[rid]&0x0ff);
238
                } else if ((imm & 0x0fffe0)==0x00220) {
239
                        // SOUT[User Reg]
240
                        int rid = (imm&0x0f)+rbase;
241
                        printf("%c", regp[rid]&0x0ff);
242
                } else if ((imm & 0x0fff00)==0x00400) {
243
                        // SOUT[Imm]
244
                        printf("%c", imm&0x0ff);
245
                } else { // if ((insn & 0x0f7c00000)==0x77800000)
246
                        uint32_t        immv = imm & 0x03fffff;
247
                        // Simm instruction that we dont recognize
248
                        // if (imm)
249
                        // printf("SIM 0x%08x\n", immv);
250
                        printf("SIM 0x%08x (ipc = %08x, upc = %08x)\n", immv,
251
                                m_core->cpu_ipc, m_core->cpu_upc);
252
                } fflush(stdout);
253
        }
254
 
255 2 dgisselq
        void    tick(void) {
256
                if ((m_tickcount & ((1<<28)-1))==0) {
257
                        double  ticks_per_second = m_tickcount;
258
                        time_t  nsecs = (time(NULL)-m_start_time);
259 49 dgisselq
                        if ((nsecs > 0)&&(ticks_per_second>0)) {
260 2 dgisselq
                                ticks_per_second /= (double)nsecs;
261
                                printf(" ********   %.6f TICKS PER SECOND\n",
262
                                        ticks_per_second);
263
                        }
264
                }
265
 
266
                // Set up the bus before any clock tick
267
 
268
                // We've got the flash to deal with ...
269
                m_core->i_qspi_dat = m_flash(m_core->o_qspi_cs_n,
270
                                                m_core->o_qspi_sck,
271
                                                m_core->o_qspi_dat);
272
 
273
                // And the GPIO lines
274
                m_core->i_gpio = m_gpio(m_core->o_gpio);
275
 
276
                m_core->i_btn = 0; // 2'b0
277
                // o_led, o_pwm, o_pwm_aux
278
 
279
                // And the keypad
280
                m_core->i_kp_row = m_keypad(m_core->o_kp_col);
281
 
282
                // And the UART
283 49 dgisselq
                m_core->i_uart_cts_n = 0;
284
                m_uart.setup(m_core->uart_setup);
285
                m_core->i_uart  = m_uart(m_core->o_uart);
286 2 dgisselq
 
287 49 dgisselq
                TESTB<Vbusmaster>::tick();
288 2 dgisselq
 
289 49 dgisselq
                if ((m_core->o_led != m_last_led)||(m_core->o_gpio != m_last_gpio)||(m_core->cpu_pf_pc != m_last_pf_pc)) {
290
                        printf("LED: %x\tGPIO: %04x\tPF-PC = %08x\r", m_core->o_led,
291
                                        m_core->o_gpio, m_core->cpu_pf_pc);
292
                        fflush(stdout);
293
                        m_last_led  = m_core->o_led;
294
                        m_last_gpio = m_core->o_gpio;
295 2 dgisselq
                }
296
 
297 49 dgisselq
                if (m_core->watchdog_int) {
298
                        printf("\nWATCHDOG-INT!!! CPU-sPC = %08x, TICKS = %08lx\n", m_core->cpu_ipc, m_tickcount);
299
                }
300 17 dgisselq
 
301 49 dgisselq
                if (m_dbg) fprintf(m_dbg, "%10ld - PC: %08x:%08x [%08x:%08x:%08x:%08x:%08x],%08x,%08x,%d,%08x,%08x (%x,%x/0x%08x)\n",
302
                        m_tickcount,
303
                        m_core->cpu_ipc,
304
                        m_core->cpu_upc,
305
                        m_core->cpu_regset[0],
306
                        m_core->cpu_regset[1],
307
                        m_core->cpu_regset[2],
308
                        m_core->cpu_regset[3],
309
                        m_core->cpu_regset[15],
310
                        m_core->v__DOT__swic__DOT__thecpu__DOT__instruction_decoder__DOT__r_I,
311
                        m_core->cpu_op_Bv,
312
                        m_core->v__DOT__swic__DOT__thecpu__DOT__instruction_decoder__DOT__w_dcdR_pc,
313
                        m_core->cpu_op_Av,
314
                        m_core->v__DOT__swic__DOT__thecpu__DOT__wr_gpreg_vl,
315
                        m_core->cpu_iflags,
316
                        m_core->cpu_uflags,
317
                        m_core->cpu_pf_pc);
318
                if ((!m_core->o_qspi_cs_n)&&(m_dbg))
319
                        fprintf(m_dbg, "QSPI: [CS,SCK,DAT (MOD)] = %d,%d,%02x,%d -> %04x %7s, state= %x/(%d)\n",
320
                                m_core->o_qspi_cs_n,
321
                                m_core->o_qspi_sck,
322
                                m_core->o_qspi_dat,
323
                                m_core->o_qspi_mod,
324
                                m_core->i_qspi_dat,
325
                                (m_core->v__DOT__flashmem__DOT__quad_mode_enabled)?"(quad)":"",
326
                                m_core->v__DOT__flashmem__DOT__state,
327
                                m_core->v__DOT__flashmem__DOT__lldriver__DOT__state);
328
 
329
                if ((m_core->wb_cyc)&&(m_dbg))
330 17 dgisselq
                fprintf(m_dbg, "WB: %s/%s/%s[@0x%08x] %08x ->%s/%s %08x\n",
331 49 dgisselq
                        (m_core->wb_cyc)?"CYC":"   ",
332
                        (m_core->wb_stb)?"STB":"   ",
333
                        (m_core->wb_we )?"WE ":"   ",
334
                        (m_core->wb_addr),
335
                        (m_core->wb_data),
336
                        (m_core->wb_ack)?"ACK":"   ",
337
                        (m_core->wb_stall)?"STL":"   ",
338
                        (m_core->wb_idata)
339 10 dgisselq
                        );
340 2 dgisselq
 
341 49 dgisselq
                if ((m_core->cpu_pf_valid)&&(m_dbg))
342 17 dgisselq
                        fprintf(m_dbg, "PC: %08x - %08x, uart=%d,%d, pic = %d,%04x,%0d,%04x\n",
343 49 dgisselq
                                m_core->cpu_pf_instruction_pc,
344
                                m_core->cpu_pf_instruction,
345
                                m_core->rx_stb, m_core->tx_busy,
346
                                m_core->pic_gie,
347
                                m_core->pic_int_enable,
348
                                m_core->pic_any,
349
                                m_core->pic_int_state);
350 2 dgisselq
 
351
 
352 49 dgisselq
// SIM instruction(s)
353
                if ((m_core->cpu_op_sim)&&(m_core->cpu_op_valid)
354
                        &&(m_core->cpu_alu_ce))
355
                        execsim(m_core->cpu_sim_immv);
356
        }
357 10 dgisselq
};
358
 
359 2 dgisselq
void    usage(void) {
360
        fprintf(stderr, "Usage: zip_sim flash_program\n");
361
}
362
 
363
int     main(int argc, char **argv) {
364
        Verilated::commandArgs(argc, argv);
365 49 dgisselq
        ZIPSIM_TB       *tb;
366
        const char      *codef = NULL, *trace_file = NULL;
367
        bool    debug_flag = false;
368
        int     serial_port = -1;
369 2 dgisselq
 
370
        for(int argn=1; argn<argc; argn++) {
371 49 dgisselq
                if (argv[argn][0] == '-') for (int j=1;
372
                                        (j<512)&&(argv[argn][j]); j++) {
373
                        switch(tolower(argv[argn][j])) {
374
                        case 'c': break; // no comms to copy to stdout break;
375
                        case 'd': debug_flag = true;
376
                                if (trace_file == NULL)
377
                                        trace_file = "trace.vcd";
378
                                break;
379
                        case 'p': break; // S6 has no fpga command port
380
                        case 's': serial_port=atoi(argv[++argn]); j=1000; break;
381
                        case 't': trace_file = (argn+1<argc)?argv[++argn]:NULL;j=1000; break;
382
                        case 'h': usage(); exit(EXIT_SUCCESS); break;
383
                        default:
384
                                fprintf(stderr, "ERR: Unexpected flag, -%c\n\n",
385
                                        argv[argn][j]);
386
                                usage(); exit(EXIT_FAILURE);
387
                        }
388
                } else if (iself(argv[argn])) {
389 2 dgisselq
                        codef = argv[argn];
390 49 dgisselq
                } else {
391
                        fprintf(stderr, "ERR: Unknown/unexpected argument: %s\n",
392
                                argv[argn]);
393
                        exit(EXIT_FAILURE);
394
                }
395 2 dgisselq
        }
396
 
397
        if ((!codef)||(!codef[0]))
398
                fprintf(stderr, "No executable code filename found!\n");
399
 
400 49 dgisselq
        if (serial_port < 0) {
401
                printf("Using the terminal as a SERIAL port\n");
402
                serial_port = 0;
403
        }
404
        tb = new ZIPSIM_TB(serial_port, debug_flag);
405
 
406 2 dgisselq
        if (access(codef, R_OK)!=0)
407
                fprintf(stderr, "Cannot read code filename, %s\n", codef);
408
 
409
        if (iself(codef)) {
410 49 dgisselq
                ELFSECTION      **secpp, *secp;
411
                BUSW            entry;
412 10 dgisselq
                elfread(codef, entry, secpp);
413 2 dgisselq
 
414 49 dgisselq
                assert(entry == RESET_ADDRESS);
415
 
416 10 dgisselq
                for(int i=0; secpp[i]->m_len; i++) {
417
                        secp = secpp[i];
418 49 dgisselq
                        tb->m_flash.write(secp->m_start, secp->m_len, (char *)&secp->m_data);
419 2 dgisselq
                }
420
        } else {
421 49 dgisselq
                fprintf(stderr, "%s is not a ZipCPU ELF executable\n", codef);
422
                exit(EXIT_FAILURE);
423 2 dgisselq
        }
424
 
425 49 dgisselq
        // if (debug_flag) { }
426
        if (trace_file)
427
                tb->opentrace(trace_file);
428
 
429 2 dgisselq
        tb->reset();
430
 
431
        while(1)
432
                tb->tick();
433
 
434
        printf("SUCCESS!\n");
435
        exit(0);
436
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.