cycle_model.cpp revision 12855:588919e0e4aa
1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  cycle_model.cpp --
23
24  Original Author: Martin Janssen, Synopsys, Inc., 2002-02-15
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38//***************************************************************************
39// FILE: cycle_model.cc
40//
41// AUTHOR: Luc Semeria    September, 21, 1998
42//
43// ABSTRACT: cycle-accurate model based on the dw8051 architecture
44//
45//
46// MODIFICATION HISTORY:
47//         Luc Semeria: 21/9/98 created
48//
49//***************************************************************************
50//
51// DESCRIPTION
52//
53// During initialization, the model parses the Intel hex file and put the
54// program into memory.
55// Then the cycle-accurate model does the following operations:
56//
57//   main loop:
58//     fetch instruction
59//     decode instruction
60//     execute instruction                   /read instr mem
61//              |\- fetch operand 1 (and 2) <             /mem bus access
62//              |                            \fetch data <
63//              |                                         \read data mem
64//              |\- execute operation
65//              |                     /mem bus access
66//              |\- write back data  <
67//              |                     \write data mem
68//              |
69//               \- compute next address
70//
71//
72// The external instruction and data memories are part of the model
73// so these memory accesses are just read and write in internal memory
74// The simulation is then speeded up because no bus transactions occurs.
75// The model doesn't switch from one process to another.
76//
77// To communicate with peripheral on the memory bus, the bus can be
78// used and the model automatically switches to a real cycle-accurate mode
79// for a given number of cycle. This is implemented within the function:
80//   request_address(int addr);
81//
82// This cycle-accurate model implements only parts of the dw8051. The
83// limitations are the following:
84//       - some instructions are not supported (cf decode function)
85//       - SFR, timers, io_interface and interrupts are not supported
86//
87//***************************************************************************
88
89#include "cycle_model.h"
90#include <string.h>
91
92/* useful macros for sc_aproc */
93#define AT_POSEDGE(CLK) wait(); while(!clk.posedge()) wait();
94#define AT_NEGEDGE(CLK) wait(); while(!clk.negedge()) wait();
95
96bool ALL_CYCLES;         /* flag to execute all cycles */
97
98
99//-------------------------------------------------------------------------
100// void cycle_model::parse_hex(char *name)
101//
102// parse Intel HEX file
103// more information on hex format on-line at:
104//         http://www.8052.com/tutintel.htm
105//
106//------------------------------------------------------------------------
107void cycle_model::parse_hex(char *name) {
108  char line_buffer[MEM_SIZE];
109  FILE *hex_file;
110
111  // open file
112  hex_file = fopen(name,"r");
113  if(hex_file==NULL) {
114    fprintf(stderr,"Error in opening file %s\n",name);
115    exit(-1);
116  }
117
118  // read new line at each loop ------------------------------------------
119  while(fgets(line_buffer,MEM_SIZE,hex_file)!=NULL) {
120#ifdef DEBUG
121    printf("Read new line -> %s",line_buffer);
122#endif
123
124    // parse line --------------------------------------------------------
125
126    // parse ':' (line[0])
127    if(line_buffer[0]!=':') {
128      continue;
129    }
130
131
132    // parse length (line[1..2])
133    int length;
134    // char length_string[2];
135    char length_string[3];
136    if(strncpy(length_string,&(line_buffer[1]),2)==NULL) {
137      fprintf(stderr,"Error in parsing length\n");
138      exit(-1);
139    }
140    length_string[2] = 0;
141    length = (int)strtol(length_string, (char **)NULL, 16);
142#ifdef DEBUG
143    printf("length=%x\n",length);
144#endif
145
146    // parse address (line[3..6])
147    int address;
148    // char address_string[4];
149    char address_string[5];
150    if(strncpy(address_string,&(line_buffer[3]),4)==NULL) {
151      fprintf(stderr,"Error in parsing address\n");
152      exit(-1);
153    }
154    address_string[4] = 0;
155    address = (int)strtol(address_string, (char **)NULL, 16);
156#ifdef DEBUG
157    printf("address=%x\n",address);
158#endif
159
160
161    // parse Record Type (line[7..8])
162    int record_type;
163    // char record_string[2];
164    char record_string[3];
165    if(strncpy(record_string,&(line_buffer[7]),2)==NULL) {
166      fprintf(stderr,"Error in parsing record type\n");
167      exit(-1);
168    }
169    record_string[2] = 0;
170    record_type = (int)strtol(record_string, (char **)NULL, 16);
171#ifdef DEBUG
172    printf("record_type=%x\n",record_type);
173#endif
174    if(record_type==01) {
175      // end of file
176      // return;
177#ifdef DEBUG
178      printf("end of file => return\n");
179#endif
180      fclose(hex_file);
181      return;
182    }
183
184    // parse data bytes
185    char instr_string[3];
186    for(int i=0;i<length;i++) {
187      if(strncpy(instr_string,&(line_buffer[2*i+9]),2)==NULL) {
188	fprintf(stderr,"Error in parsing data byte %d\n",i);
189	exit(-1);
190      }
191
192    instr_string[2] = 0;
193    int temp = (int)strtol(instr_string, (char **)NULL, 16);
194    instr_mem[address++] = temp;
195#ifdef DEBUG
196    printf("data byte = %x\n",temp);
197#endif
198    }
199
200    // skip the checksum bits
201
202    // verify end of line
203    if(line_buffer[2*length+9+2]!='\n') {
204      fprintf(stderr,"Error in parsing hex file: end of line expected\n");
205      exit(-1);
206    }
207
208  }
209
210  fprintf(stderr,"Error in parsing hex file: end of file record type expected\n");
211  exit(-1);
212
213}
214
215
216//---------------------------------------------------------------------
217//void cycle_model::decode(int opcode, instr* i)
218//
219// take an opcode as an input and output the instruction with the
220// proper operand types.
221//
222//---------------------------------------------------------------------
223void cycle_model::decode(int opcode, instr* i) {
224
225  // default
226  i->type = i_nop;
227  i->n_src = 0;
228  i->src1.type = o_null;
229  i->src1.val = -1;
230  i->src2.type = o_null;
231  i->src2.val = -1;
232  i->dst.type = o_null;
233  i->dst.val = -1;
234
235  switch(opcode) {
236    // arithmetic operations -----------------------------------------
237  case 0x28:
238  case 0x29:
239  case 0x2A:
240  case 0x2B:
241  case 0x2C:
242  case 0x2d:
243  case 0x2e:
244  case 0x2f: {
245    // add register to A
246    i->type = i_add;
247    i->n_src = 2;
248    i->src1.type = o_reg;
249    i->src1.val = opcode&0x07;
250    i->src2.type = o_acc;
251    i->dst.type = o_acc;
252    i->cycle = 1;
253    break;
254  }
255  case 0x25: {
256    // add direct byte to A
257    i->type = i_add;
258    i->n_src = 2;
259    i->src1.type = o_dir;
260    i->src2.type = o_acc;
261    i->dst.type = o_acc;
262    i->cycle = 2;
263    break;
264  }
265  case 0x26:
266  case 0x27: {
267    // add data memory to A
268    i->type = i_add;
269    i->n_src = 2;
270    i->src1.type = o_ind;
271    i->src1.val = opcode&1;
272    i->src2.type = o_acc;
273    i->dst.type = o_acc;
274    i->cycle = 1;
275    break;
276  }
277  case 0x24: {
278    // add immediate to A
279    i->type = i_add;
280    i->n_src = 2;
281    i->src1.type = o_cst;
282    i->src2.type = o_acc;
283    i->dst.type = o_acc;
284    i->cycle = 2;
285    break;
286  }
287  case 0x98:
288  case 0x99:
289  case 0x9A:
290  case 0x9B:
291  case 0x9C:
292  case 0x9d:
293  case 0x9e:
294  case 0x9f: {
295    // sub register to A
296    i->type = i_sub;
297    i->n_src = 2;
298    i->src1.type = o_reg;
299    i->src1.val = opcode&0x07;
300    i->src2.type = o_acc;
301    i->dst.type = o_acc;
302    i->cycle = 1;
303    break;
304  }
305  case 0x95: {
306    // sub direct byte to A
307    i->type = i_sub;
308    i->n_src = 2;
309    i->src1.type = o_dir;
310    i->src2.type = o_acc;
311    i->dst.type = o_acc;
312    i->cycle = 2;
313    break;
314  }
315  case 0x96:
316  case 0x97: {
317    // sub data memory to A
318    i->type = i_sub;
319    i->n_src = 2;
320    i->src1.type = o_ind;
321    i->src1.val = opcode&1;
322    i->src2.type = o_acc;
323    i->dst.type = o_acc;
324    i->cycle = 1;
325    break;
326  }
327  case 0x94: {
328    // sub immediate to A
329    i->type = i_sub;
330    i->n_src = 2;
331    i->src1.type = o_cst;
332    i->src2.type = o_acc;
333    i->dst.type = o_acc;
334    i->cycle = 2;
335    break;
336  }
337  case 0x04: {
338    // increment A
339    i->type = i_inc;
340    i->n_src = 1;
341    i->src1.type = o_acc;
342    i->dst.type = o_acc;
343    i->cycle = 1;
344    break;
345  }
346  case 0x08:
347  case 0x09:
348  case 0x0A:
349  case 0x0B:
350  case 0x0C:
351  case 0x0d:
352  case 0x0e:
353  case 0x0f: {
354    // increment register
355    i->type = i_inc;
356    i->n_src = 1;
357    i->src1.type = o_reg;
358    i->src1.val = opcode&0x07;
359    i->dst.type = o_reg;
360    i->dst.val = opcode&0x07;
361    i->cycle = 1;
362    break;
363  }
364  case 0x05: {
365    // increment direct byte
366    i->type = i_inc;
367    i->n_src = 1;
368    i->src1.type = o_dir;
369    i->dst.type = o_dir;
370    i->cycle = 2;
371    break;
372  }
373  case 0x06:
374  case 0x07: {
375    // increment  data memory
376    i->type = i_inc;
377    i->n_src = 1;
378    i->src1.type = o_ind;
379    i->src1.val = opcode&1;
380    i->dst.type = o_ind;
381    i->dst.val = opcode&1;
382    i->cycle = 1;
383    break;
384  }
385  case 0x14: {
386    // decrement A
387    i->type = i_dec;
388    i->n_src = 1;
389    i->src1.type = o_acc;
390    i->dst.type = o_acc;
391    i->cycle = 1;
392    break;
393  }
394  case 0x18:
395  case 0x19:
396  case 0x1A:
397  case 0x1B:
398  case 0x1C:
399  case 0x1d:
400  case 0x1e:
401  case 0x1f: {
402    // decrement register
403    i->type = i_dec;
404    i->n_src = 1;
405    i->src1.type = o_reg;
406    i->src1.val = opcode&0x07;
407    i->dst.type = o_reg;
408    i->dst.val = opcode&0x07;
409    i->cycle = 1;
410    break;
411  }
412  case 0x15: {
413    // decrement direct byte
414    i->type = i_dec;
415    i->n_src = 1;
416    i->src1.type = o_dir;
417    i->dst.type = o_dir;
418    i->cycle = 2;
419    break;
420  }
421  case 0x16:
422  case 0x17: {
423    // increment  data memory
424    i->type = i_dec;
425    i->n_src = 1;
426    i->src1.type = o_ind;
427    i->src1.val = opcode&1;
428    i->dst.type = o_ind;
429    i->dst.val = opcode&1;
430    i->cycle = 1;
431    break;
432  }
433  // logic operation --------------------------------------------------
434  case 0x58:
435  case 0x59:
436  case 0x5A:
437  case 0x5B:
438  case 0x5C:
439  case 0x5d:
440  case 0x5e:
441  case 0x5f: {
442    // and register to A
443    i->type = i_and;
444    i->n_src = 2;
445    i->src1.type = o_reg;
446    i->src1.val = opcode&0x07;
447    i->src2.type = o_acc;
448    i->dst.type = o_acc;
449    i->cycle = 1;
450    break;
451  }
452  case 0x55: {
453    // and direct byte to A
454    i->type = i_and;
455    i->n_src = 2;
456    i->src1.type = o_dir;
457    i->src2.type = o_acc;
458    i->dst.type = o_acc;
459    i->cycle = 2;
460    break;
461  }
462  case 0x56:
463  case 0x57: {
464    // and data memory to A
465    i->type = i_and;
466    i->n_src = 2;
467    i->src1.type = o_ind;
468    i->src1.val = opcode&1;
469    i->src2.type = o_acc;
470    i->dst.type = o_acc;
471    i->cycle = 1;
472    break;
473  }
474  case 0x54: {
475    // and immediate to A
476    i->type = i_and;
477    i->n_src = 2;
478    i->src1.type = o_cst;
479    i->src2.type = o_acc;
480    i->dst.type = o_acc;
481    i->cycle = 2;
482    break;
483  }
484  case 0x52: {
485    // and A to direct byte
486    i->type = i_and;
487    i->n_src = 2;
488    i->src1.type = o_dir;
489    i->src2.type = o_acc;
490    i->dst.type = o_dir;
491    i->cycle = 2;
492    break;
493  }
494  case 0x53: {
495    // and immdiate to direct byte
496    i->type = i_and;
497    i->n_src = 2;
498    i->src1.type = o_dir;
499    i->src2.type = o_cst;
500    i->dst.type = o_dir;
501    i->cycle = 3;
502    break;
503  }
504  case 0x48:
505  case 0x49:
506  case 0x4A:
507  case 0x4B:
508  case 0x4C:
509  case 0x4d:
510  case 0x4e:
511  case 0x4f: {
512    // or register to A
513    i->type = i_or;
514    i->n_src = 2;
515    i->src1.type = o_reg;
516    i->src1.val = opcode&0x07;
517    i->src2.type = o_acc;
518    i->dst.type = o_acc;
519    i->cycle = 1;
520    break;
521  }
522  case 0x45: {
523    // or direct byte to A
524    i->type = i_or;
525    i->n_src = 2;
526    i->src1.type = o_dir;
527    i->src2.type = o_acc;
528    i->dst.type = o_acc;
529    i->cycle = 2;
530    break;
531  }
532  case 0x46:
533  case 0x47: {
534    // or data memory to A
535    i->type = i_or;
536    i->n_src = 2;
537    i->src1.type = o_ind;
538    i->src1.val = opcode&1;
539    i->src2.type = o_acc;
540    i->dst.type = o_acc;
541    i->cycle = 1;
542    break;
543  }
544  case 0x44: {
545    // or immediate to A
546    i->type = i_or;
547    i->n_src = 2;
548    i->src1.type = o_cst;
549    i->src2.type = o_acc;
550    i->dst.type = o_acc;
551    i->cycle = 2;
552    break;
553  }
554  case 0x42: {
555    // or A to direct byte
556    i->type = i_or;
557    i->n_src = 2;
558    i->src1.type = o_dir;
559    i->src2.type = o_acc;
560    i->dst.type = o_dir;
561    i->cycle = 2;
562    break;
563  }
564  case 0x43: {
565    // or immediate to direct byte
566    i->type = i_or;
567    i->n_src = 2;
568    i->src1.type = o_dir;
569    i->src2.type = o_cst;
570    i->dst.type = o_dir;
571    i->cycle = 3;
572    break;
573  }
574  case 0x68:
575  case 0x69:
576  case 0x6A:
577  case 0x6B:
578  case 0x6C:
579  case 0x6d:
580  case 0x6e:
581  case 0x6f: {
582    // xor register to A
583    i->type = i_xor;
584    i->n_src = 2;
585    i->src1.type = o_reg;
586    i->src1.val = opcode&0x07;
587    i->src2.type = o_acc;
588    i->dst.type = o_acc;
589    i->cycle = 1;
590    break;
591  }
592  case 0x65: {
593    // xor direct byte to A
594    i->type = i_xor;
595    i->n_src = 2;
596    i->src1.type = o_dir;
597    i->src2.type = o_acc;
598    i->dst.type = o_acc;
599    i->cycle = 2;
600    break;
601  }
602  case 0x66:
603  case 0x67: {
604    // xor data memory to A
605    i->type = i_xor;
606    i->n_src = 2;
607    i->src1.type = o_ind;
608    i->src1.val = opcode&1;
609    i->src2.type = o_acc;
610    i->dst.type = o_acc;
611    i->cycle = 1;
612    break;
613  }
614  case 0x64: {
615    // xor immediate to A
616    i->type = i_xor;
617    i->n_src = 2;
618    i->src1.type = o_cst;
619    i->src2.type = o_acc;
620    i->dst.type = o_acc;
621    i->cycle = 2;
622    break;
623  }
624  case 0x62: {
625    // and A to direct byte
626    i->type = i_xor;
627    i->n_src = 2;
628    i->src1.type = o_dir;
629    i->src2.type = o_acc;
630    i->dst.type = o_dir;
631    i->cycle = 2;
632    break;
633  }
634  case 0x63: {
635    // xor immdiate to direct byte
636    i->type = i_xor;
637    i->n_src = 2;
638    i->src1.type = o_dir;
639    i->src2.type = o_cst;
640    i->dst.type = o_dir;
641    i->cycle = 3;
642    break;
643  }
644  case 0xf4: {
645    // complement A
646    i->type = i_cpl;
647    i->n_src = 1;
648    i->src1.type = o_acc;
649    i->dst.type = o_acc;
650    i->cycle = 1;
651    break;
652  }
653  case 0x23: {
654    // rotate A left
655    i->type = i_rl;
656    i->n_src = 1;
657    i->src1.type = o_acc;
658    i->dst.type = o_acc;
659    i->cycle = 1;
660    break;
661  }
662  case 0x03: {
663    // rotate A right
664    i->type = i_rr;
665    i->n_src = 1;
666    i->src1.type = o_acc;
667    i->dst.type = o_acc;
668    i->cycle = 1;
669    break;
670  }
671  // data transfer -----------------------------------------------
672  case 0xe8:
673  case 0xe9:
674  case 0xeA:
675  case 0xeB:
676  case 0xeC:
677  case 0xed:
678  case 0xee:
679  case 0xef: {
680    // move register to A
681    i->type = i_mov;
682    i->n_src = 1;
683    i->src1.type = o_reg;
684    i->src1.val = opcode&0x07;
685    i->dst.type = o_acc;
686    i->cycle = 1;
687    break;
688  }
689  case 0xe5: {
690    // move direct bit to A
691    i->type = i_mov;
692    i->n_src = 1;
693    i->src1.type = o_dir;
694    i->dst.type = o_acc;
695    i->cycle = 2;
696    break;
697  }
698  case 0xe6:
699  case 0xe7: {
700    // move data memory to A
701    i->type = i_mov;
702    i->n_src = 1;
703    i->src1.type = o_ind;
704    i->src1.val = opcode&1;
705    i->dst.type = o_acc;
706    i->cycle = 1;
707    break;
708  }
709  case 0x74: {
710    // move immediate to A
711    i->type = i_mov;
712    i->n_src = 1;
713    i->src1.type = o_cst;
714    i->dst.type = o_acc;
715    i->cycle = 2;
716    break;
717  }
718  case 0xf8:
719  case 0xf9:
720  case 0xfA:
721  case 0xfB:
722  case 0xfC:
723  case 0xfd:
724  case 0xfe:
725  case 0xff: {
726    // move A to register
727    i->type = i_mov;
728    i->n_src = 1;
729    i->src1.type = o_acc;
730    i->dst.type = o_reg;
731    i->dst.val = opcode&0x07;
732    i->cycle = 1;
733    break;
734  }
735  case 0xa8:
736  case 0xa9:
737  case 0xaA:
738  case 0xaB:
739  case 0xaC:
740  case 0xad:
741  case 0xae:
742  case 0xaf: {
743    // move direct to register
744    i->type = i_mov;
745    i->n_src = 1;
746    i->src1.type = o_dir;
747    i->dst.type = o_reg;
748    i->dst.val = opcode&0x07;
749    i->cycle = 2;
750    break;
751  }
752  case 0x78:
753  case 0x79:
754  case 0x7A:
755  case 0x7B:
756  case 0x7C:
757  case 0x7d:
758  case 0x7e:
759  case 0x7f: {
760    // move immediate to register
761    i->type = i_mov;
762    i->n_src = 1;
763    i->src1.type = o_cst;
764    i->dst.type = o_reg;
765    i->dst.val = opcode&0x07;
766    i->cycle = 2;
767    break;
768  }
769  case 0xf5: {
770    // move A to direct byte
771    i->type = i_mov;
772    i->n_src = 1;
773    i->src1.type = o_acc;
774    i->dst.type = o_dir;
775    i->cycle = 2;
776  }
777  case 0x88:
778  case 0x89:
779  case 0x8A:
780  case 0x8B:
781  case 0x8C:
782  case 0x8d:
783  case 0x8e:
784  case 0x8f: {
785    // move register to direct byte
786    i->type = i_mov;
787    i->n_src = 1;
788    i->src1.type = o_reg;
789    i->src1.val = opcode&0x07;
790    i->dst.type = o_dir;
791    i->cycle = 2;
792    break;
793  }
794  case 0x85: {
795    // move direct byte to direct byte
796    i->type = i_mov;
797    i->n_src = 1;
798    i->src1.type = o_dir;
799    i->dst.type = o_dir;
800    i->cycle = 3;
801    break;
802  }
803  case 0x86:
804  case 0x87: {
805    // move data memory to direct byte
806    i->type = i_mov;
807    i->n_src = 1;
808    i->src1.type = o_ind;
809    i->src1.val = opcode&0x01;
810    i->dst.type = o_dir;
811    i->cycle = 2;
812    break;
813  }
814  case 0x75: {
815    // move immediate to direct byte
816    i->type = i_mov;
817    i->n_src = 1;
818    i->src1.type = o_cst;
819    i->dst.type = o_dir;
820    i->cycle = 2;
821    break;
822    }
823  case 0xf6:
824  case 0xf7: {
825    // move A to data memory
826    i->type = i_mov;
827    i->n_src = 1;
828    i->src1.type = o_acc;
829    i->dst.type = o_ind;
830    i->dst.val = opcode&1;
831    i->cycle = 1;
832    break;
833  }
834  case 0xa6:
835  case 0xa7: {
836    // move direct byte to data memory
837    i->type = i_mov;
838    i->n_src = 1;
839    i->src1.type = o_dir;
840    i->dst.type = o_ind;
841    i->dst.val = opcode&1;
842    i->cycle = 2;
843    break;
844  }
845  case 0x76:
846  case 0x77: {
847    // move immediate to data memory
848    i->type = i_mov;
849    i->n_src = 1;
850    i->src1.type = o_cst;
851    i->dst.type = o_ind;
852    i->dst.val = opcode&1;
853    i->cycle = 2;
854    break;
855  }
856  case 0xe2:
857  case 0xe3: {
858    // move external data to A
859    i->type = i_mov;
860    i->n_src = 1;
861    i->src1.type = o_ext;
862    i->src1.val = opcode&1;
863    i->dst.type = o_acc;
864    i->cycle = 2+stretch_cycles;
865    break;
866  }
867  case 0xf2:
868  case 0xf3: {
869    // move A to external data
870    i->type = i_mov;
871    i->n_src = 1;
872    i->src1.type = o_acc;
873    i->dst.type = o_ext;
874    i->dst.val = opcode&1;
875    i->cycle = 2+stretch_cycles;
876    break;
877  }
878  // branching ----------------------------------------------------
879  case 0x11:
880  case 0x31:
881  case 0x51:
882  case 0x71:
883  case 0x91:
884  case 0xb1:
885  case 0xd1:
886  case 0xf1: {
887    // absolute call to subroutine
888    i->type = i_call;
889    i->n_src = 1;
890    i->src1.type = o_add;
891    i->src1.val = (opcode>>5)&7;
892    i->cycle = 3;
893    break;
894  }
895  case 0x12: {
896    // Long call to subroutine
897    i->type = i_call;
898    i->n_src = 1;
899    i->src1.type = o_ladd;
900    i->cycle = 4;
901    break;
902  }
903  case 0x22: {
904    // return from subroutine
905    i->type = i_ret;
906    i->cycle = 4;
907    break;
908  }
909  case 0x01:
910  case 0x21:
911  case 0x41:
912  case 0x61:
913  case 0x81:
914  case 0xa1:
915  case 0xc1:
916  case 0xe1: {
917    // absolute jump unconditional
918    i->type = i_jmp;
919    i->n_src = 1;
920    i->src1.type = o_add;
921    i->src1.val = (opcode>>5)&7;
922    i->cycle = 3;
923    break;
924  }
925  case 0x02: {
926    // Long jump unconditional
927    i->type = i_jmp;
928    i->n_src = 1;
929    i->src1.type = o_ladd;
930    i->cycle = 4;
931    break;
932  }
933  case 0x60: {
934    // jump on accumulator = 0
935    i->type = i_jz;
936    i->n_src = 1;
937    i->src1.type = o_rel;
938    i->cycle = 3;
939    break;
940  }
941  case 0x70: {
942    // jump on accumulator != 0
943    i->type = i_jnz;
944    i->n_src = 1;
945    i->src1.type = o_rel;
946    i->cycle = 3;
947    break;
948  }
949  case 0xb5: {
950    // compare A,direct JNE
951    i->type = i_cjne;
952    i->n_src = 2;
953    i->src1.type = o_acc;
954    i->src2.type = o_dir;
955    i->dst.type = o_rel;
956    i->cycle = 4;
957    break;
958  }
959  case 0xb4: {
960    // compare A,immeditate JNE
961    i->type = i_cjne;
962    i->n_src = 2;
963    i->src1.type = o_acc;
964    i->src2.type = o_cst;
965    i->dst.type = o_rel;
966    i->cycle = 4;
967    break;
968  }
969  case 0xB8:
970  case 0xB9:
971  case 0xBa:
972  case 0xBb:
973  case 0xBc:
974  case 0xBd:
975  case 0xBe:
976  case 0xBf: {
977    // compare reg,immeditate JNE
978    i->type = i_cjne;
979    i->n_src = 2;
980    i->src1.type = o_reg;
981    i->src1.val = opcode & 0x7;
982    i->src2.type = o_cst;
983    i->dst.type = o_rel;
984    i->cycle = 4;
985    break;
986  }
987  case 0xb6:
988  case 0xb7: {
989    // compare memory byte,immeditate JNE
990    i->type = i_cjne;
991    i->n_src = 2;
992    i->src1.type = o_ind;
993    i->src1.val = opcode & 0x1;
994    i->src2.type = o_cst;
995    i->dst.type = o_rel;
996    i->cycle = 4;
997    break;
998  }
999  case 0xd8:
1000  case 0xd9:
1001  case 0xda:
1002  case 0xdb:
1003  case 0xdc:
1004  case 0xdd:
1005  case 0xde:
1006  case 0xdf: {
1007    // decrement reg, JNZ relative
1008    i->type = i_djnz;
1009    i->n_src = 2;
1010    i->src1.type = o_reg;
1011    i->src1.val = opcode & 0x7;
1012    i->src2.type = o_rel;
1013    i->cycle = 3;
1014    break;
1015  }
1016  case 0xd5: {
1017    // decrement direct byte, JNZ relative
1018    i->type = i_djnz;
1019    i->n_src = 2;
1020    i->src1.type = o_dir;
1021    i->src2.type = o_rel;
1022    i->cycle = 4;
1023    break;
1024  }
1025  // NOP --------------------------------------------------------------
1026  case 0x00: {
1027    break;
1028  }
1029  default: {
1030
1031    break;
1032    fprintf(stderr,"opcode 0x%x not supported\n",opcode);
1033    break;
1034  }
1035  }
1036
1037#ifdef DEBUG
1038  printf("decode instr type:%d, src1: %d, src2: %d, dest %d, nb_cycles: %d\n",i->type, i->src1.type, i->src2.type, i->dst.type, i->cycle);
1039#endif
1040}
1041
1042
1043//--------------------------------------------------------------------
1044// bool request_address(int ad);
1045//
1046//    return 0 if the memory adress is external (i.e. external peripheral)
1047//    update cycles2execute so that the simulation runs for a given
1048//    number of clock cycles.
1049//
1050//--------------------------------------------------------------------
1051bool cycle_model::request_address(int ad) {
1052  // add peripheral driver here
1053  //
1054  // if(ad==<ADDRESS OF THE PERIPH>) {
1055  //    if(cycles2execute<=<NB_CYCLES>)
1056  //        cycles2execute = <NB_CYCLES>;
1057  //    return 0;
1058  // }
1059
1060  if(ad==0x10) {
1061    if(cycles2execute<=30)
1062      cycles2execute = 30;
1063    return 0;
1064  }
1065
1066  if(ad==0x11) {
1067    return 0;
1068  }
1069
1070  return 1;
1071}
1072
1073
1074//--------------------------------------------------------------------
1075// exec_bus_cycle(bus_cycle_type op, int addr, int data, int* result)
1076//
1077//    executes a bus cycle (IDLE, MEM_READ, MEM_WRITE).
1078//       - IDLE: executes an idle cycle (4 clocks)
1079//       - MEM_READ: reads from the memory bus (stretch+1 clocks)
1080//       - MEM_WRITE: writes on the memory bus (stretch+1 clocks)
1081//
1082//--------------------------------------------------------------------
1083void cycle_model::exec_bus_cycle(bus_cycle_type op, int addr, int data, int* result) {
1084  int cycles = 0;
1085  int mem_idle =0;
1086
1087
1088  if(op==OP_IDLE) {
1089    // OP_IDLE
1090    if((cycles2execute>0)||ALL_CYCLES) {
1091      // wait 4 cycles
1092      mem_ale.write(0);
1093      mem_wr_n.write(1);
1094      mem_pswr_n.write(1);
1095      mem_rd_n.write(1);
1096      mem_psrd_n.write(1);
1097      p0_mem_reg_n.write(0);
1098      p0_addr_data_n.write(0);
1099      AT_POSEDGE(clk);
1100      AT_POSEDGE(clk);
1101      AT_POSEDGE(clk);
1102      AT_POSEDGE(clk);
1103      cycles2execute -= 1;
1104    }
1105
1106    cycle_count += 1;
1107    return;
1108  }
1109
1110
1111  // OP_MEM_READ or OP_MEM_WRITE
1112  do {
1113    cycles++;
1114
1115    // Cycle 1 *********************************************************
1116    if(mem_idle==0) {
1117      mem_ale.write(1);
1118      mem_wr_n.write(1);
1119      mem_pswr_n.write(1);
1120      mem_rd_n.write(1);
1121      mem_psrd_n.write(1);
1122      p0_mem_reg_n.write(0);
1123      p0_addr_data_n.write(0);
1124
1125      if(op==OP_MEM_WRITE) {
1126	mem_data_out.write( sc_bv<8>( data ) );
1127	p0_mem_reg_n.write(1);
1128	p0_addr_data_n.write(1);
1129      }
1130    }
1131
1132    AT_POSEDGE(clk);
1133
1134
1135    // Cycle 2 *********************************************************
1136    if(mem_idle==0) {
1137      switch (op) {
1138      case OP_MEM_READ: {
1139	mem_addr.write( sc_bv<16>( addr & 0x0000ffff ) );
1140	p0_mem_reg_n.write(1);
1141	p0_addr_data_n.write(1);
1142	p2_mem_reg_n.write(1);
1143	break;
1144      }
1145      case OP_MEM_WRITE: {
1146	mem_addr.write( sc_bv<16>( addr & 0x0000ffff ) );
1147	p0_addr_data_n.write(0);
1148	p2_mem_reg_n.write(1);
1149	break;
1150      }
1151      default: {
1152	// do nothing
1153	break;
1154      }
1155      }
1156    }
1157    if(mem_idle==0) {
1158      AT_NEGEDGE(clk);
1159      mem_ale.write(0);
1160    }
1161
1162    AT_POSEDGE(clk);
1163
1164
1165    // Cycle 3 *********************************************************
1166    if(mem_idle==0) {
1167      switch (op) {
1168      case OP_MEM_READ: {
1169	p0_mem_reg_n.write(0);
1170	p0_addr_data_n.write(0);
1171
1172	if(stretch_cycles==0)
1173	  mem_rd_n.write(0); // read RAM
1174	break;
1175      }
1176      case OP_MEM_WRITE: {
1177	if(stretch_cycles==0)
1178	  mem_wr_n.write(0); // write RAM
1179	break;
1180      }
1181      default: {
1182	// do nothing
1183	break;
1184      }
1185      }
1186    }
1187    AT_POSEDGE(clk);
1188
1189
1190    // Cycle 4 *********************************************************
1191    if (mem_idle==0) {
1192      switch (op) {
1193      case OP_MEM_READ: {
1194	if(stretch_cycles>0) {
1195	  mem_idle=stretch_cycles+1;
1196	  mem_rd_n.write(0); // read RAM
1197	}
1198	break;
1199      }
1200      case OP_MEM_WRITE: {
1201	if(stretch_cycles>0) {
1202	  mem_idle=stretch_cycles+1;
1203	  mem_wr_n.write(0); // write RAM
1204	}
1205	break;
1206      }
1207      default: {
1208	// do nothing
1209	break;
1210      }
1211      }
1212    }
1213    else if(mem_idle==1) {
1214      // read/write enable <- 1 when stretch>0
1215      switch (op) {
1216      case OP_MEM_READ: {
1217	if(stretch_cycles>0) {
1218	  // read value
1219	  *result = mem_data_in.read().to_uint();
1220	  // reset read enable
1221	  mem_rd_n.write(1); // read RAM
1222	}
1223	break;
1224      }
1225      case OP_MEM_WRITE: {
1226	if(stretch_cycles>0) {
1227	  // reset write enable
1228	  mem_wr_n.write(1); // write RAM
1229	}
1230	break;
1231      }
1232      default: {
1233	break;
1234      }
1235      }
1236    }
1237    AT_POSEDGE(clk);
1238
1239
1240    // Cycle 1 (1st part) **********************************************
1241    if(mem_idle>0)
1242      mem_idle--;
1243
1244    if(mem_idle==0){
1245      switch(op) {
1246      case OP_MEM_READ:
1247	if(stretch_cycles==0) {
1248	  mem_rd_n.write(1);
1249	  *result = mem_data_in.read().to_uint();
1250	}
1251	break;
1252      case OP_MEM_WRITE:
1253	if(stretch_cycles==0)
1254	  mem_wr_n.write(1);
1255	break;
1256      default:
1257	break;
1258      }
1259    }
1260  } while(mem_idle>0);
1261
1262  sc_assert(cycles==(stretch_cycles+1));
1263  cycle_count += cycles;
1264  cycles2execute-=cycles;
1265  return;
1266}
1267
1268
1269
1270
1271//------------------------------------------------------------------------
1272// int cycle_model::fetch_instr(int ad)
1273//
1274//    fetches data (1byte) from instruction memory
1275//
1276//------------------------------------------------------------------------
1277int cycle_model::fetch_instr(int ad) {
1278
1279  sc_assert((ad<MEM_SIZE)&&(ad>=0));
1280
1281  int temp;
1282  exec_bus_cycle(OP_IDLE, 0,0, &temp);
1283
1284  int opcode = instr_mem[ad];
1285#ifdef DEBUG
1286  printf("Fetch instruction @0x%x (= 0x%x)\n",ad,opcode);
1287#endif
1288  return opcode;
1289}
1290
1291//------------------------------------------------------------------------
1292// int cycle_model::fetch_data(int ad)
1293//
1294//   fetches data from memory which can be internal to the block or
1295//   external (case of an hardware peripheral)
1296//
1297//------------------------------------------------------------------------
1298int cycle_model::fetch_data(int addr) {
1299
1300  int data = 0, result;
1301
1302  bool is_internal = request_address(addr);
1303  if(is_internal) {
1304    // is internal
1305    if((cycles2execute>0)||ALL_CYCLES) {
1306      // Wait
1307      for(int i=0; i<stretch_cycles+1; i++) {
1308	exec_bus_cycle(OP_IDLE,addr,data,&result);
1309      }
1310    }
1311    result = ext_mem[addr];
1312  } else {
1313    // is external
1314    exec_bus_cycle(OP_MEM_READ,addr,data,&result);
1315  }
1316
1317  return result;
1318}
1319
1320
1321
1322//------------------------------------------------------------------------
1323// int cycle_model::write_data(int addr, int data)
1324//
1325//    writes data on data memory which can be internal to the block or
1326//    external (case of an hardware peripheral)
1327//
1328//------------------------------------------------------------------------
1329int cycle_model::write_data(int addr, int data) {
1330
1331  int result = 0;
1332
1333  bool is_internal = request_address(addr);
1334
1335  if(is_internal) {
1336    // is internal
1337    if((cycles2execute>0)||ALL_CYCLES) {
1338      for(int i=0; i<stretch_cycles+1; i++) {
1339	exec_bus_cycle(OP_IDLE,addr,data,&result);
1340      }
1341    }
1342    ext_mem[addr]=data;
1343  } else {
1344    // is external
1345    exec_bus_cycle(OP_MEM_WRITE,addr,data,&result);
1346  }
1347
1348  return result;
1349}
1350
1351
1352//--------------------------------------------------------------------
1353// int cycle_model::fetch_operand(operand* op)
1354//
1355//   returns the value of the operand
1356//
1357//--------------------------------------------------------------------
1358int cycle_model::fetch_operand(operand* op) {
1359  switch(op->type) {
1360  case o_acc: {
1361    return A;
1362    break;
1363  }
1364  case o_reg: {
1365    sc_assert((op->val<8)&&(op->val>=0));
1366#ifdef DEBUG
1367    printf("read R%d=%d\n",op->val,R[op->val]);
1368#endif
1369    return R[op->val];
1370    break;
1371  }
1372  case o_dir: {
1373    // fetch address
1374    my_stack->address += 1;
1375    int temp = fetch_instr(my_stack->address);
1376    sc_assert((op->val<INT_SIZE)&&(op->val>=0));
1377    return int_mem[temp];
1378    break;
1379  }
1380  case o_ind: {
1381    sc_assert((op->val==0)||(op->val==1));
1382    sc_assert((R[op->val]<INT_SIZE)&&(R[op->val]>=0));
1383    return int_mem[R[op->val]];
1384    break;
1385  }
1386  case o_ext: {
1387    sc_assert((op->val==1)||(op->val==0));
1388    int addr = R[op->val];
1389    sc_assert((addr<MEM_SIZE)&&(addr>=0));
1390
1391    int result = fetch_data(addr);
1392
1393    return result;
1394    break;
1395  }
1396  case o_cst: {
1397    // fetch next byte
1398    my_stack->address += 1;
1399    int temp = fetch_instr(my_stack->address);
1400    return temp;
1401    break;
1402  }
1403  case o_lcst: {
1404    // fetch next 2 bytes
1405
1406    my_stack->address += 1;
1407    int temp = fetch_instr(my_stack->address);
1408
1409    my_stack->address += 1;
1410    sc_assert(my_stack->address<=MEM_SIZE);
1411    temp = (temp<<8) +  fetch_instr(my_stack->address);
1412
1413    return temp;
1414    break;
1415  }
1416  case o_add: {
1417    // fetch next byte
1418    my_stack->address += 1;
1419    int temp = ((op->val)<<8) + fetch_instr(my_stack->address);
1420    return temp;
1421    break;
1422  }
1423  case o_ladd: {
1424    // fetch next 2 bytes
1425    my_stack->address += 1;
1426    int temp = fetch_instr(my_stack->address);
1427
1428    my_stack->address += 1;
1429    temp = (temp<<8) + fetch_instr(my_stack->address);
1430    return temp;
1431    break;
1432  }
1433  case o_rel: {
1434    // fetch next byte
1435    my_stack->address += 1;
1436    int temp = fetch_instr(my_stack->address);
1437    if(temp<0x80)
1438      return temp;
1439    else
1440      return -(0x100-temp);
1441    break;
1442  }
1443  default: {
1444    return -1;
1445    break;
1446  }
1447  }
1448  return -1;
1449}
1450
1451//--------------------------------------------------------------------
1452// int write_back(operand *op, int value)
1453//
1454//    write the value into the operand
1455//
1456//--------------------------------------------------------------------
1457int cycle_model::write_back(operand* op, int v) {
1458  switch(op->type) {
1459  case o_acc: {
1460    A = v;
1461    return A;
1462    break;
1463  }
1464  case o_reg: {
1465    sc_assert((op->val<8)&&(op->val>=0));
1466    R[op->val] = v;
1467#ifdef DEBUG
1468    printf("write R%d <- %d\n",op->val,R[op->val]);
1469#endif
1470    return R[op->val];
1471    break;
1472  }
1473  case o_dir: {
1474    // write address
1475    my_stack->address += 1;
1476    int temp = fetch_instr(my_stack->address);
1477    sc_assert((temp<INT_SIZE)&&(temp>=0));
1478    int_mem[temp] = v;
1479    return int_mem[temp];
1480    break;
1481  }
1482  case o_ind: {
1483    sc_assert((op->val==0)||(op->val==1));
1484    sc_assert((R[op->val]<INT_SIZE)&&(R[op->val]>=0));
1485    int_mem[R[op->val]] = v;
1486    return int_mem[R[op->val]];
1487    break;
1488  }
1489  case o_ext: {
1490    sc_assert((op->val==1)||(op->val==0));
1491    int addr = R[op->val];
1492    sc_assert((addr<MEM_SIZE)&&(addr>=0));
1493    int data, result;
1494    data = v;
1495    result = write_data(addr,data);
1496    return result;
1497    break;
1498  }
1499  default: {
1500    return -1;
1501    break;
1502  }
1503  }
1504  return -1;
1505}
1506
1507
1508
1509//--------------------------------------------------------------------
1510// void execute(instr *i)
1511//
1512//   execute consists of the following tasks:
1513//        - fetch the operands
1514//        - execute the operation in the intruction
1515//        - write the data back in the destination
1516//        - compute the next address for (jmp, call, return...)
1517//
1518//--------------------------------------------------------------------
1519void cycle_model::execute(instr *i) {
1520  int in1, in2, out = 0;
1521
1522  // fetch operands ---------------------------------------------------
1523  if(i->n_src>=1)
1524    in1 = fetch_operand(&(i->src1));
1525
1526  if(i->n_src>=2)
1527    in2 = fetch_operand(&(i->src2));
1528
1529#ifdef DEBUG
1530  printf("execute %d, with in1=%d and in2=%d\n",i->type,in1, in2);
1531#endif
1532
1533  // execute ----------------------------------------------------------
1534  switch(i->type) {
1535  case i_add: {
1536    out = in1 + in2;
1537    break;
1538  }
1539  case i_sub: {
1540    out = in1 - in2;
1541    break;
1542  }
1543  case i_inc: {
1544    out = in1+1;
1545    break;
1546  }
1547  case i_dec: {
1548    out = in1-1;
1549    break;
1550  }
1551  case i_mul: {
1552    out = in1 * in2;
1553    break;
1554  }
1555  case i_div: {
1556    out = in1/in2;
1557    break;
1558  }
1559  // logic operations
1560  case i_and: {
1561    out = in1 & in2;
1562    break;
1563  }
1564  case i_or: {
1565    out = in1 | in2;
1566    break;
1567  }
1568  case i_xor: {
1569    out = in1 ^ in2;
1570    break;
1571  }
1572  case i_rl: {
1573    out = in1<<1;
1574    break;
1575  }
1576  case i_rr: {
1577    out = in2>>1;
1578    break;
1579  }
1580  // data transfer
1581  case i_mov: {
1582    out = in1;
1583    break;
1584  }
1585  // branching (out==0 -> don't branch)
1586  case i_call:
1587  case i_ret:
1588  case i_jmp:
1589  case i_sjmp: {
1590    out = 1;
1591    break;
1592  }
1593  case i_jz: {
1594    out = (A==0);
1595    break;
1596  }
1597  case i_jnz: {
1598    out = (A!=0);
1599    break;
1600  }
1601  case i_cjne: {
1602    out = (in1!=in2);
1603    break;
1604  }
1605  case i_djnz: {
1606    out=in1-1; // decrement reg/direct and jump if != 0
1607    break;
1608  }
1609  default: {
1610    break;
1611  }
1612  }
1613
1614
1615  // write back --------------------------------------------------------
1616  write_back(&(i->dst),out);
1617
1618  // compute next address ----------------------------------------------
1619  switch(i->type) {
1620  case i_call: {
1621    stack_el *new_stack_el= (stack_el *) malloc(sizeof(stack_el));
1622    new_stack_el->up = my_stack;
1623    new_stack_el->address = in1;
1624    my_stack = new_stack_el;
1625
1626    /* wait additional cycles */
1627    int result;
1628    exec_bus_cycle(OP_IDLE,0,0,&result);
1629
1630    break;
1631  }
1632  case i_ret: {
1633    stack_el *new_stack_el = my_stack->up;
1634    free(my_stack);
1635    my_stack = new_stack_el;
1636    if(my_stack!=NULL)
1637      my_stack->address += 1; // increment address after jump
1638
1639    /* wait additional cycles */
1640    int result;
1641    exec_bus_cycle(OP_IDLE,0,0,&result);
1642    exec_bus_cycle(OP_IDLE,0,0,&result);
1643    exec_bus_cycle(OP_IDLE,0,0,&result);
1644    break;
1645  }
1646  case i_jmp: {
1647    my_stack->address = in1;
1648
1649    /* wait additional cycles */
1650    int result;
1651    exec_bus_cycle(OP_IDLE,0,0,&result);
1652
1653    break;
1654  }
1655  case i_sjmp:
1656  case i_jz:
1657  case i_jnz: {
1658    if(out!=0)
1659      my_stack->address += in1+1;
1660    else
1661      my_stack->address += 1;
1662
1663    /* wait additional cycles */
1664    int result;
1665    exec_bus_cycle(OP_IDLE,0,0,&result);
1666
1667    break;
1668  }
1669  case i_cjne: {
1670    int in3 = fetch_operand(&i->dst);
1671    if(out!=0)
1672      my_stack->address += in3+1;
1673    else
1674      my_stack->address += 1;
1675
1676    /* wait additional cycles */
1677    int result;
1678    exec_bus_cycle(OP_IDLE,0,0,&result);
1679
1680    break;
1681  }
1682  case i_djnz: {
1683    if(out!=0)
1684      my_stack->address += in2+1;
1685    else
1686      my_stack->address += 1;
1687
1688    /* wait additional cycles */
1689    int result;
1690    exec_bus_cycle(OP_IDLE,0,0,&result);
1691
1692    break;
1693  }
1694  default: {
1695     my_stack->address += 1;
1696     break;
1697  }
1698  }
1699}
1700
1701
1702
1703//---------------------------------------------------------------------
1704// cycle_model::init()
1705//
1706//   initialize the stack
1707//
1708//---------------------------------------------------------------------
1709void cycle_model::init() {
1710
1711  cycles2execute = 0;
1712  cycle_count = 0;
1713  stretch_cycles = 0;
1714
1715  // initialize stack
1716  my_stack = (stack_el *) malloc(sizeof(stack_el));
1717  my_stack->up = NULL;
1718  my_stack->address = 0;
1719}
1720
1721
1722
1723//------------------------------------------------------------------------
1724// void cycle_mode::entry()
1725//
1726// main loop: fetch instruction
1727//            decode opcode
1728//            execute instruction
1729//
1730//------------------------------------------------------------------------
1731void cycle_model::entry() {
1732
1733  wait();
1734
1735  mem_ale.write(0);
1736  mem_wr_n.write(1);
1737  mem_pswr_n.write(1);
1738  mem_rd_n.write(1);
1739  mem_psrd_n.write(1);
1740  p0_mem_reg_n.write(0);
1741  p0_addr_data_n.write(0);
1742  wait();
1743
1744  while(true) {
1745    instr the_instr;
1746    // fetch instruction
1747    if(my_stack==NULL) {
1748      // printf("cycles count = %d\n",cycle_count);
1749      sc_stop();
1750      wait();
1751    } else {
1752      int opcode = fetch_instr(my_stack->address);
1753
1754      // decode instruction
1755      decode(opcode, &the_instr);
1756
1757      // execute
1758      execute(&the_instr);
1759    }
1760  }
1761}
1762