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