1 2-- Company: ZPU4 generic memory interface CPU 3-- Engineer: �yvind Harboe 4 5library IEEE; 6use IEEE.STD_LOGIC_1164.ALL; 7use IEEE.STD_LOGIC_UNSIGNED.ALL; 8use IEEE.STD_LOGIC_arith.ALL; 9 10library work; 11use work.zpu_config.all; 12use work.zpupkg.all; 13 14 15 16 17 18entity zpu_core is 19 Port ( clk : in std_logic; 20 areset : in std_logic; 21 enable : in std_logic; 22 mem_req : out std_logic; 23 mem_we : out std_logic; 24 mem_ack : in std_logic; 25 mem_read : in std_logic_vector(wordSize-1 downto 0); 26 mem_write : out std_logic_vector(wordSize-1 downto 0); 27 out_mem_addr : out std_logic_vector(maxAddrBitIncIO downto 0); 28 mem_writeMask: out std_logic_vector(wordBytes-1 downto 0); 29 interrupt : in std_logic; 30 break : out std_logic; 31 zpu_status : out std_logic_vector(63 downto 0)); 32end zpu_core; 33 34architecture behave of zpu_core is 35 36type InsnType is 37( 38State_AddTop, 39State_Dup, 40State_DupStackB, 41State_Pop, 42State_Popdown, 43State_Add, 44State_Or, 45State_And, 46State_Store, 47State_AddSP, 48State_Shift, 49State_Nop, 50State_Im, 51State_LoadSP, 52State_StoreSP, 53State_Emulate, 54State_Load, 55State_PushPC, 56State_PushSP, 57State_PopPC, 58State_PopPCRel, 59State_Not, 60State_Flip, 61State_PopSP, 62State_Neqbranch, 63State_Eq, 64State_Loadb, 65State_Mult, 66State_Lessthan, 67State_Lessthanorequal, 68State_Ulessthanorequal, 69State_Ulessthan, 70State_Pushspadd, 71State_Call, 72State_Callpcrel, 73State_Sub, 74State_Break, 75State_Storeb, 76State_Interrupt, 77State_InsnFetch 78); 79 80type StateType is 81( 82State_Idle, -- using first state first on the list out of paranoia 83State_Load2, 84State_Popped, 85State_LoadSP2, 86State_LoadSP3, 87State_AddSP2, 88State_Fetch, 89State_Execute, 90State_Decode, 91State_Decode2, 92State_Resync, 93 94State_StoreSP2, 95State_Resync2, 96State_Resync3, 97State_Loadb2, 98State_Storeb2, 99State_Mult2, 100State_Mult3, 101State_Mult5, 102State_Mult6, 103State_Mult4, 104State_BinaryOpResult 105); 106 107 108signal pc : std_logic_vector(maxAddrBitIncIO downto 0); 109signal sp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); 110signal incSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); 111signal incIncSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); 112signal decSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); 113signal stackA : std_logic_vector(wordSize-1 downto 0); 114signal binaryOpResult : std_logic_vector(wordSize-1 downto 0); 115signal multResult2 : std_logic_vector(wordSize-1 downto 0); 116signal multResult3 : std_logic_vector(wordSize-1 downto 0); 117signal multResult : std_logic_vector(wordSize-1 downto 0); 118signal multA : std_logic_vector(wordSize-1 downto 0); 119signal multB : std_logic_vector(wordSize-1 downto 0); 120signal stackB : std_logic_vector(wordSize-1 downto 0); 121signal idim_flag : std_logic; 122signal busy : std_logic; 123signal mem_readEnable : std_logic; 124signal mem_addr : std_logic_vector(maxAddrBitIncIO downto minAddrBit); 125signal mem_delayAddr : std_logic_vector(maxAddrBitIncIO downto minAddrBit); 126signal mem_delayReadEnable : std_logic; 127signal mem_busy : std_logic; 128signal decodeWord : std_logic_vector(wordSize-1 downto 0); 129 130 131signal state : StateType; 132signal insn : InsnType; 133type InsnArray is array(0 to wordBytes-1) of InsnType; 134signal decodedOpcode : InsnArray; 135 136type OpcodeArray is array(0 to wordBytes-1) of std_logic_vector(7 downto 0); 137 138signal opcode : OpcodeArray; 139 140 141 142 143signal begin_inst : std_logic; 144signal trace_opcode : std_logic_vector(7 downto 0); 145signal trace_pc : std_logic_vector(maxAddrBitIncIO downto 0); 146signal trace_sp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); 147signal trace_topOfStack : std_logic_vector(wordSize-1 downto 0); 148signal trace_topOfStackB : std_logic_vector(wordSize-1 downto 0); 149 150signal out_mem_req : std_logic; 151 152signal inInterrupt : std_logic; 153 154-- state machine. 155 156begin 157 158 zpu_status(maxAddrBitIncIO downto 0) <= trace_pc; 159 zpu_status(31) <= '1'; 160 zpu_status(39 downto 32) <= trace_opcode; 161 zpu_status(40) <= '1' when (state = State_Idle) else '0'; 162 zpu_status(62) <= '1'; 163 164 traceFileGenerate: 165 if Generate_Trace generate 166 trace_file: trace port map ( 167 clk => clk, 168 begin_inst => begin_inst, 169 pc => trace_pc, 170 opcode => trace_opcode, 171 sp => trace_sp, 172 memA => trace_topOfStack, 173 memB => trace_topOfStackB, 174 busy => busy, 175 intsp => (others => 'U') 176 ); 177 end generate; 178 179 180 -- the memory subsystem will tell us one cycle later whether or 181 -- not it is busy 182 out_mem_addr(maxAddrBitIncIO downto minAddrBit) <= mem_addr; 183 out_mem_addr(minAddrBit-1 downto 0) <= (others => '0'); 184 mem_req <= out_mem_req; 185 186 incSp <= sp + 1; 187 incIncSp <= sp + 2; 188 decSp <= sp - 1; 189 190 mem_busy <= out_mem_req and not mem_ack; -- '1' when the memory is busy 191 192 opcodeControl: 193 process(clk, areset) 194 variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0); 195 variable spOffset : std_logic_vector(4 downto 0); 196 variable tSpOffset : std_logic_vector(4 downto 0); 197 variable nextPC : std_logic_vector(maxAddrBitIncIO downto 0); 198 variable tNextState : InsnType; 199 variable tDecodedOpcode : InsnArray; 200 variable tMultResult : std_logic_vector(wordSize*2-1 downto 0); 201 begin 202 if areset = '1' then 203 state <= State_Idle; 204 break <= '0'; 205 sp <= spStart(maxAddrBitIncIO downto minAddrBit); 206 207 pc <= (others => '0'); 208 idim_flag <= '0'; 209 begin_inst <= '0'; 210 mem_we <= '0'; 211 multA <= (others => '0'); 212 multB <= (others => '0'); 213 mem_writeMask <= (others => '1'); 214 out_mem_req <= '0'; 215 mem_addr <= (others => DontCareValue); 216 mem_write <= (others => DontCareValue); 217 inInterrupt <= '0'; 218 elsif (clk'event and clk = '1') then 219 -- we must multiply unconditionally to get pipelined multiplication 220 tMultResult := multA * multB; 221 multResult3 <= multResult2; 222 multResult2 <= multResult; 223 multResult <= tMultResult(wordSize-1 downto 0); 224 225 226 spOffset(4):=not opcode(conv_integer(pc(byteBits-1 downto 0)))(4); 227 spOffset(3 downto 0):=opcode(conv_integer(pc(byteBits-1 downto 0)))(3 downto 0); 228 nextPC := pc + 1; 229 230 -- prepare trace snapshot 231 trace_opcode <= opcode(conv_integer(pc(byteBits-1 downto 0))); 232 trace_pc <= pc; 233 trace_sp <= sp; 234 trace_topOfStack <= stackA; 235 trace_topOfStackB <= stackB; 236 begin_inst <= '0'; 237 238 -- we terminate the requeset as soon as we get acknowledge 239 if mem_ack = '1' then 240 out_mem_req <= '0'; 241 mem_we <= '0'; 242 end if; 243 244 if interrupt='0' then 245 inInterrupt <= '0'; -- no longer in an interrupt 246 end if; 247 248 case state is 249 when State_Idle => 250 if enable='1' then 251 state <= State_Resync; 252 end if; 253 -- Initial state of ZPU, fetch top of stack + first instruction 254 when State_Resync => 255 if mem_busy='0' then 256 mem_addr <= sp; 257 out_mem_req <= '1'; 258 state <= State_Resync2; 259 end if; 260 when State_Resync2 => 261 if mem_busy='0' then 262 stackA <= mem_read; 263 mem_addr <= incSp; 264 out_mem_req <= '1'; 265 state <= State_Resync3; 266 end if; 267 when State_Resync3 => 268 if mem_busy='0' then 269 stackB <= mem_read; 270 mem_addr <= pc(maxAddrBitIncIO downto minAddrBit); 271 out_mem_req <= '1'; 272 state <= State_Decode; 273 end if; 274 when State_Decode => 275 if mem_busy='0' then 276 decodeWord <= mem_read; 277 state <= State_Decode2; 278 end if; 279 when State_Decode2 => 280 -- decode 4 instructions in parallel 281 for i in 0 to wordBytes-1 loop 282 tOpcode := decodeWord((wordBytes-1-i+1)*8-1 downto (wordBytes-1-i)*8); 283 284 tSpOffset(4):=not tOpcode(4); 285 tSpOffset(3 downto 0):=tOpcode(3 downto 0); 286 287 opcode(i) <= tOpcode; 288 if (tOpcode(7 downto 7)=OpCode_Im) then 289 tNextState:=State_Im; 290 elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then 291 if tSpOffset = 0 then 292 tNextState := State_Pop; 293 elsif tSpOffset=1 then 294 tNextState := State_PopDown; 295 else 296 tNextState :=State_StoreSP; 297 end if; 298 elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then 299 if tSpOffset = 0 then 300 tNextState :=State_Dup; 301 elsif tSpOffset = 1 then 302 tNextState :=State_DupStackB; 303 else 304 tNextState :=State_LoadSP; 305 end if; 306 elsif (tOpcode(7 downto 5)=OpCode_Emulate) then 307 tNextState :=State_Emulate; 308 if tOpcode(5 downto 0)=OpCode_Neqbranch then 309 tNextState :=State_Neqbranch; 310 elsif tOpcode(5 downto 0)=OpCode_Eq then 311 tNextState :=State_Eq; 312 elsif tOpcode(5 downto 0)=OpCode_Lessthan then 313 tNextState :=State_Lessthan; 314 elsif tOpcode(5 downto 0)=OpCode_Lessthanorequal then 315 --tNextState :=State_Lessthanorequal; 316 elsif tOpcode(5 downto 0)=OpCode_Ulessthan then 317 tNextState :=State_Ulessthan; 318 elsif tOpcode(5 downto 0)=OpCode_Ulessthanorequal then 319 --tNextState :=State_Ulessthanorequal; 320 elsif tOpcode(5 downto 0)=OpCode_Loadb then 321 tNextState :=State_Loadb; 322 elsif tOpcode(5 downto 0)=OpCode_Mult then 323 tNextState :=State_Mult; 324 elsif tOpcode(5 downto 0)=OpCode_Storeb then 325 tNextState :=State_Storeb; 326 elsif tOpcode(5 downto 0)=OpCode_Pushspadd then 327 tNextState :=State_Pushspadd; 328 elsif tOpcode(5 downto 0)=OpCode_Callpcrel then 329 tNextState :=State_Callpcrel; 330 elsif tOpcode(5 downto 0)=OpCode_Call then 331 --tNextState :=State_Call; 332 elsif tOpcode(5 downto 0)=OpCode_Sub then 333 tNextState :=State_Sub; 334 elsif tOpcode(5 downto 0)=OpCode_PopPCRel then 335 --tNextState :=State_PopPCRel; 336 end if; 337 elsif (tOpcode(7 downto 4)=OpCode_AddSP) then 338 if tSpOffset = 0 then 339 tNextState := State_Shift; 340 elsif tSpOffset = 1 then 341 tNextState := State_AddTop; 342 else 343 tNextState :=State_AddSP; 344 end if; 345 else 346 case tOpcode(3 downto 0) is 347 when OpCode_Nop => 348 tNextState :=State_Nop; 349 when OpCode_PushSP => 350 tNextState :=State_PushSP; 351 when OpCode_PopPC => 352 tNextState :=State_PopPC; 353 when OpCode_Add => 354 tNextState :=State_Add; 355 when OpCode_Or => 356 tNextState :=State_Or; 357 when OpCode_And => 358 tNextState :=State_And; 359 when OpCode_Load => 360 tNextState :=State_Load; 361 when OpCode_Not => 362 tNextState :=State_Not; 363 when OpCode_Flip => 364 tNextState :=State_Flip; 365 when OpCode_Store => 366 tNextState :=State_Store; 367 when OpCode_PopSP => 368 tNextState :=State_PopSP; 369 when others => 370 tNextState := State_Break; 371 372 end case; 373 end if; 374 tDecodedOpcode(i) := tNextState; 375 376 end loop; 377 378 insn <= tDecodedOpcode(conv_integer(pc(byteBits-1 downto 0))); 379 380 -- once we wrap, we need to fetch 381 tDecodedOpcode(0) := State_InsnFetch; 382 383 decodedOpcode <= tDecodedOpcode; 384 state <= State_Execute; 385 386 387 388 -- Each instruction must: 389 -- 390 -- 1. set idim_flag 391 -- 2. increase pc if applicable 392 -- 3. set next state if appliable 393 -- 4. do it's operation 394 395 when State_Execute => 396 insn <= decodedOpcode(conv_integer(nextPC(byteBits-1 downto 0))); 397 398 case insn is 399 when State_InsnFetch => 400 state <= State_Fetch; 401 when State_Im => 402 if mem_busy='0' then 403 begin_inst <= '1'; 404 idim_flag <= '1'; 405 pc <= pc + 1; 406 407 if idim_flag='1' then 408 stackA(wordSize-1 downto 7) <= stackA(wordSize-8 downto 0); 409 stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0); 410 else 411 out_mem_req <= '1'; 412 mem_we <= '1'; 413 mem_addr <= incSp; 414 mem_write <= stackB; 415 stackB <= stackA; 416 sp <= decSp; 417 for i in wordSize-1 downto 7 loop 418 stackA(i) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6); 419 end loop; 420 stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0); 421 end if; 422 else 423 insn <= insn; 424 end if; 425 when State_StoreSP => 426 if mem_busy='0' then 427 begin_inst <= '1'; 428 idim_flag <= '0'; 429 state <= State_StoreSP2; 430 431 out_mem_req <= '1'; 432 mem_we <= '1'; 433 mem_addr <= sp+spOffset; 434 mem_write <= stackA; 435 stackA <= stackB; 436 sp <= incSp; 437 else 438 insn <= insn; 439 end if; 440 441 442 when State_LoadSP => 443 if mem_busy='0' then 444 begin_inst <= '1'; 445 idim_flag <= '0'; 446 state <= State_LoadSP2; 447 448 sp <= decSp; 449 out_mem_req <= '1'; 450 mem_we <= '1'; 451 mem_addr <= incSp; 452 mem_write <= stackB; 453 else 454 insn <= insn; 455 end if; 456 when State_Emulate => 457 if mem_busy='0' then 458 begin_inst <= '1'; 459 idim_flag <= '0'; 460 sp <= decSp; 461 out_mem_req <= '1'; 462 mem_we <= '1'; 463 mem_addr <= incSp; 464 mem_write <= stackB; 465 stackA <= (others => DontCareValue); 466 stackA(maxAddrBitIncIO downto 0) <= pc + 1; 467 stackB <= stackA; 468 469 -- The emulate address is: 470 -- 98 7654 3210 471 -- 0000 00aa aaa0 0000 472 pc <= (others => '0'); 473 pc(9 downto 5) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(4 downto 0); 474 state <= State_Fetch; 475 else 476 insn <= insn; 477 end if; 478 when State_Callpcrel => 479 if mem_busy='0' then 480 begin_inst <= '1'; 481 idim_flag <= '0'; 482 stackA <= (others => DontCareValue); 483 stackA(maxAddrBitIncIO downto 0) <= pc + 1; 484 485 pc <= pc + stackA(maxAddrBitIncIO downto 0); 486 state <= State_Fetch; 487 else 488 insn <= insn; 489 end if; 490 when State_Call => 491 if mem_busy='0' then 492 begin_inst <= '1'; 493 idim_flag <= '0'; 494 stackA <= (others => DontCareValue); 495 stackA(maxAddrBitIncIO downto 0) <= pc + 1; 496 pc <= stackA(maxAddrBitIncIO downto 0); 497 state <= State_Fetch; 498 else 499 insn <= insn; 500 end if; 501 when State_AddSP => 502 if mem_busy='0' then 503 begin_inst <= '1'; 504 idim_flag <= '0'; 505 state <= State_AddSP2; 506 507 out_mem_req <= '1'; 508 mem_addr <= sp+spOffset; 509 else 510 insn <= insn; 511 end if; 512 when State_PushSP => 513 if mem_busy='0' then 514 begin_inst <= '1'; 515 idim_flag <= '0'; 516 pc <= pc + 1; 517 518 sp <= decSp; 519 stackA <= (others => '0'); 520 stackA(maxAddrBitIncIO downto minAddrBit) <= sp; 521 stackB <= stackA; 522 out_mem_req <= '1'; 523 mem_we <= '1'; 524 mem_addr <= incSp; 525 mem_write <= stackB; 526 else 527 insn <= insn; 528 end if; 529 when State_PopPC => 530 if mem_busy='0' then 531 begin_inst <= '1'; 532 idim_flag <= '0'; 533 pc <= stackA(maxAddrBitIncIO downto 0); 534 sp <= incSp; 535 536 out_mem_req <= '1'; 537 mem_we <= '1'; 538 mem_addr <= incSp; 539 mem_write <= stackB; 540 state <= State_Resync; 541 else 542 insn <= insn; 543 end if; 544 when State_PopPCRel => 545 if mem_busy='0' then 546 begin_inst <= '1'; 547 idim_flag <= '0'; 548 pc <= stackA(maxAddrBitIncIO downto 0) + pc; 549 sp <= incSp; 550 551 out_mem_req <= '1'; 552 mem_we <= '1'; 553 mem_addr <= incSp; 554 mem_write <= stackB; 555 state <= State_Resync; 556 else 557 insn <= insn; 558 end if; 559 when State_Add => 560 if mem_busy='0' then 561 begin_inst <= '1'; 562 idim_flag <= '0'; 563 stackA <= stackA + stackB; 564 565 out_mem_req <= '1'; 566 mem_addr <= incIncSp; 567 sp <= incSp; 568 state <= State_Popped; 569 else 570 insn <= insn; 571 end if; 572 when State_Sub => 573 begin_inst <= '1'; 574 idim_flag <= '0'; 575 binaryOpResult <= stackB - stackA; 576 state <= State_BinaryOpResult; 577 when State_Pop => 578 if mem_busy='0' then 579 begin_inst <= '1'; 580 idim_flag <= '0'; 581 mem_addr <= incIncSp; 582 out_mem_req <= '1'; 583 sp <= incSp; 584 stackA <= stackB; 585 state <= State_Popped; 586 else 587 insn <= insn; 588 end if; 589 when State_PopDown => 590 if mem_busy='0' then 591 -- PopDown leaves top of stack unchanged 592 begin_inst <= '1'; 593 idim_flag <= '0'; 594 mem_addr <= incIncSp; 595 out_mem_req <= '1'; 596 sp <= incSp; 597 state <= State_Popped; 598 else 599 insn <= insn; 600 end if; 601 when State_Or => 602 if mem_busy='0' then 603 begin_inst <= '1'; 604 idim_flag <= '0'; 605 stackA <= stackA or stackB; 606 out_mem_req <= '1'; 607 mem_addr <= incIncSp; 608 sp <= incSp; 609 state <= State_Popped; 610 else 611 insn <= insn; 612 end if; 613 when State_And => 614 if mem_busy='0' then 615 begin_inst <= '1'; 616 idim_flag <= '0'; 617 618 stackA <= stackA and stackB; 619 out_mem_req <= '1'; 620 mem_addr <= incIncSp; 621 sp <= incSp; 622 state <= State_Popped; 623 else 624 insn <= insn; 625 end if; 626 when State_Eq => 627 begin_inst <= '1'; 628 idim_flag <= '0'; 629 630 binaryOpResult <= (others => '0'); 631 if (stackA=stackB) then 632 binaryOpResult(0) <= '1'; 633 end if; 634 state <= State_BinaryOpResult; 635 when State_Ulessthan => 636 begin_inst <= '1'; 637 idim_flag <= '0'; 638 639 binaryOpResult <= (others => '0'); 640 if (stackA<stackB) then 641 binaryOpResult(0) <= '1'; 642 end if; 643 state <= State_BinaryOpResult; 644 when State_Ulessthanorequal => 645 begin_inst <= '1'; 646 idim_flag <= '0'; 647 648 binaryOpResult <= (others => '0'); 649 if (stackA<=stackB) then 650 binaryOpResult(0) <= '1'; 651 end if; 652 state <= State_BinaryOpResult; 653 when State_Lessthan => 654 begin_inst <= '1'; 655 idim_flag <= '0'; 656 657 binaryOpResult <= (others => '0'); 658 if (signed(stackA)<signed(stackB)) then 659 binaryOpResult(0) <= '1'; 660 end if; 661 state <= State_BinaryOpResult; 662 when State_Lessthanorequal => 663 begin_inst <= '1'; 664 idim_flag <= '0'; 665 666 binaryOpResult <= (others => '0'); 667 if (signed(stackA)<=signed(stackB)) then 668 binaryOpResult(0) <= '1'; 669 end if; 670 state <= State_BinaryOpResult; 671 when State_Load => 672 if mem_busy='0' then 673 begin_inst <= '1'; 674 idim_flag <= '0'; 675 state <= State_Load2; 676 677 mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); 678 out_mem_req <= '1'; 679 else 680 insn <= insn; 681 end if; 682 683 when State_Dup => 684 if mem_busy='0' then 685 begin_inst <= '1'; 686 idim_flag <= '0'; 687 pc <= pc + 1; 688 689 sp <= decSp; 690 stackB <= stackA; 691 mem_write <= stackB; 692 mem_addr <= incSp; 693 out_mem_req <= '1'; 694 mem_we <= '1'; 695 else 696 insn <= insn; 697 end if; 698 when State_DupStackB => 699 if mem_busy='0' then 700 begin_inst <= '1'; 701 idim_flag <= '0'; 702 pc <= pc + 1; 703 704 sp <= decSp; 705 stackA <= stackB; 706 stackB <= stackA; 707 mem_write <= stackB; 708 mem_addr <= incSp; 709 out_mem_req <= '1'; 710 mem_we <= '1'; 711 else 712 insn <= insn; 713 end if; 714 when State_Store => 715 if mem_busy='0' then 716 begin_inst <= '1'; 717 idim_flag <= '0'; 718 pc <= pc + 1; 719 mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); 720 mem_write <= stackB; 721 out_mem_req <= '1'; 722 mem_we <= '1'; 723 sp <= incIncSp; 724 state <= State_Resync; 725 else 726 insn <= insn; 727 end if; 728 when State_PopSP => 729 if mem_busy='0' then 730 begin_inst <= '1'; 731 idim_flag <= '0'; 732 pc <= pc + 1; 733 734 mem_write <= stackB; 735 mem_addr <= incSp; 736 out_mem_req <= '1'; 737 mem_we <= '1'; 738 sp <= stackA(maxAddrBitIncIO downto minAddrBit); 739 state <= State_Resync; 740 else 741 insn <= insn; 742 end if; 743 when State_Nop => 744 begin_inst <= '1'; 745 idim_flag <= '0'; 746 pc <= pc + 1; 747 when State_Not => 748 begin_inst <= '1'; 749 idim_flag <= '0'; 750 pc <= pc + 1; 751 752 stackA <= not stackA; 753 when State_Flip => 754 begin_inst <= '1'; 755 idim_flag <= '0'; 756 pc <= pc + 1; 757 758 for i in 0 to wordSize-1 loop 759 stackA(i) <= stackA(wordSize-1-i); 760 end loop; 761 when State_AddTop => 762 begin_inst <= '1'; 763 idim_flag <= '0'; 764 pc <= pc + 1; 765 766 stackA <= stackA + stackB; 767 when State_Shift => 768 begin_inst <= '1'; 769 idim_flag <= '0'; 770 pc <= pc + 1; 771 772 stackA(wordSize-1 downto 1) <= stackA(wordSize-2 downto 0); 773 stackA(0) <= '0'; 774 when State_Pushspadd => 775 begin_inst <= '1'; 776 idim_flag <= '0'; 777 pc <= pc + 1; 778 779 stackA <= (others => '0'); 780 stackA(maxAddrBitIncIO downto minAddrBit) <= stackA(maxAddrBitIncIO-minAddrBit downto 0)+sp; 781 when State_Neqbranch => 782 -- branches are almost always taken as they form loops 783 begin_inst <= '1'; 784 idim_flag <= '0'; 785 sp <= incIncSp; 786 if (stackB/=0) then 787 pc <= stackA(maxAddrBitIncIO downto 0) + pc; 788 else 789 pc <= pc + 1; 790 end if; 791 -- need to fetch stack again. 792 state <= State_Resync; 793 when State_Mult => 794 begin_inst <= '1'; 795 idim_flag <= '0'; 796 797 multA <= stackA; 798 multB <= stackB; 799 state <= State_Mult2; 800 when State_Break => 801 report "Break instruction encountered" severity failure; 802 break <= '1'; 803 804 when State_Loadb => 805 if mem_busy='0' then 806 begin_inst <= '1'; 807 idim_flag <= '0'; 808 state <= State_Loadb2; 809 810 mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); 811 out_mem_req <= '1'; 812 else 813 insn <= insn; 814 end if; 815 when State_Storeb => 816 if mem_busy='0' then 817 begin_inst <= '1'; 818 idim_flag <= '0'; 819 state <= State_Storeb2; 820 821 mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); 822 out_mem_req <= '1'; 823 else 824 insn <= insn; 825 end if; 826 827 when others => 828-- sp <= (others => DontCareValue); 829 report "Illegal instruction" severity failure; 830 break <= '1'; 831 end case; 832 833 834 when State_StoreSP2 => 835 if mem_busy='0' then 836 mem_addr <= incSp; 837 out_mem_req <= '1'; 838 state <= State_Popped; 839 end if; 840 when State_LoadSP2 => 841 if mem_busy='0' then 842 state <= State_LoadSP3; 843 out_mem_req <= '1'; 844 mem_addr <= sp+spOffset+1; 845 end if; 846 when State_LoadSP3 => 847 if mem_busy='0' then 848 pc <= pc + 1; 849 state <= State_Execute; 850 stackB <= stackA; 851 stackA <= mem_read; 852 end if; 853 when State_AddSP2 => 854 if mem_busy='0' then 855 pc <= pc + 1; 856 state <= State_Execute; 857 stackA <= stackA + mem_read; 858 end if; 859 when State_Load2 => 860 if mem_busy='0' then 861 stackA <= mem_read; 862 pc <= pc + 1; 863 state <= State_Execute; 864 end if; 865 when State_Loadb2 => 866 if mem_busy='0' then 867 stackA <= (others => '0'); 868 stackA(7 downto 0) <= mem_read(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8); 869 pc <= pc + 1; 870 state <= State_Execute; 871 end if; 872 when State_Storeb2 => 873 if mem_busy='0' then 874 mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); 875 mem_write <= mem_read; 876 mem_write(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8) <= stackB(7 downto 0) ; 877 out_mem_req <= '1'; 878 mem_we <= '1'; 879 pc <= pc + 1; 880 sp <= incIncSp; 881 state <= State_Resync; 882 end if; 883 when State_Fetch => 884 if mem_busy='0' then 885 if interrupt='1' and inInterrupt='0' and idim_flag='0' then 886 -- We got an interrupt 887 inInterrupt <= '1'; 888 889 sp <= decSp; 890 out_mem_req <= '1'; 891 mem_we <= '1'; 892 mem_addr <= incSp; 893 mem_write <= stackB; 894 stackA <= (others => DontCareValue); 895 stackA(maxAddrBitIncIO downto 0) <= pc; 896 stackB <= stackA; 897 898 pc <= conv_std_logic_vector(32, maxAddrBitIncIo+1); -- interrupt address 899 900 report "ZPU jumped to interrupt!" severity note; 901 else 902 mem_addr <= pc(maxAddrBitIncIO downto minAddrBit); 903 out_mem_req <= '1'; 904 state <= State_Decode; 905 end if; 906 end if; 907 when State_Mult2 => 908 state <= State_Mult3; 909 when State_Mult3 => 910 state <= State_Mult4; 911 when State_Mult4 => 912 state <= State_Mult5; 913 when State_Mult5 => 914 stackA <= multResult3; 915 state <= State_Mult6; 916 when State_Mult6 => 917 if mem_busy='0' then 918 out_mem_req <= '1'; 919 mem_addr <= incIncSp; 920 sp <= incSp; 921 state <= State_Popped; 922 end if; 923 when State_BinaryOpResult => 924 if mem_busy='0' then 925 -- NB!!!! we know that the memory isn't busy at this point!!!! 926 out_mem_req <= '1'; 927 mem_addr <= incIncSp; 928 sp <= incSp; 929 stackA <= binaryOpResult; 930 state <= State_Popped; 931 end if; 932 when State_Popped => 933 if mem_busy='0' then 934 pc <= pc + 1; 935 stackB <= mem_read; 936 state <= State_Execute; 937 end if; 938 when others => 939-- sp <= (others => DontCareValue); 940 report "Illegal state" severity failure; 941 break <= '1'; 942 end case; 943 end if; 944 end process; 945 946 947 948end behave; 949