Home/Announcements | Course Outline | Assignments | Lecture Notes |
Old Assignments/Exams | VHDL | Sim68k | Useful Links |
Here is a simulator for a processor called sim68k which is defined in Section
2. The sim68k processor has a subset of the addressing modes of MC68000 and has
32 instructions, most of which are derived from those of MC68000. The simulator
will take as input a program written in sim68k assembly/machine language and
will execute it, that is to say it will execute each of the sim68k machine
instructions in the input program.
What we provide is the following:
In this description of sim68k, the following type definitions are used:
In addition to MAR, MDR, RW and DS, the sim68k has the following registers:
sim68k has the following status bits:
During the execution of some instructions, some
of these bits are updated. See Section 6 for information on when and how these
bits are updated.
In the MC68000, the status bits are located in a special register (CC - Code
Condition). In your simulator, you will implement them as individual boolean variables to simplify
their manipulation.
In the simulator, the "controller" simulates the fetch-execute cycle with
the following algorithm:
1. Initialization
(* Set PC to $0000 and set the status bits to FALSE *)
2. Repeat
2.1 Fetch_OpCode
2.2 Decode_Instruction
(* According
to the fields in the opcode
*)
(* Example: OpName = bits 15 to 11 in OpCode
*)
(* NbOper
= bit 10 in OpCode + 1 *)
(*
DS = bits 9 and 8 in OpCode
*)
(*
M1 = bits 7 to 5 in OpCode
*)
(*
N1 = bit 4 in OpCode,
etc. *)
2.3 Fetch_Operands
(* In OpAddr1 and
OpAddr2, if operands are required. *)
2.4 If NOT(H)
Then
2.4.1 Execute_Instruction
(* Execution of most instructions follows these steps: *)
(* 1. Fill TMPS (if
necessary)
*)
(* 2. Fill TMPD (if
necessary)
*)
(* 3. Compute TMPR using TMPS and
TMPD
*)
(* 4. Update status bits HNZVC (if
necessary) *)
(* 5. Store result in the destination (if necessary) *)
Until (H = true) (* If
H = True, then halt *)
Six addressing modes are available to most instructions:
Several instructions are constrained to specific addressing modes:
IMPORTANT: Note that several assembly instructions in the test programs make use of labels (LABEL) as well as of variable definitions (DEF). All these names are preceded by an arobas symbol (@). The value of these labels/variables is the address where they have been defined. Hence, it becomes simple to define a loop label (LABEL @Loop ) and then reference it (BRA @Loop). The compiler (assembler) will compute the address of each label and variable name in the program. These names are then replaced by their address in the binary code.
The instruction set of sim68k contains 32 instructions where:
* ADD S, D
Binary integer addition (Regular). D
:= D + S;
* ADDQ data, D
Binary integer addition (Quick). D
:= D + data;
* SUB S, D
Binary integer subtraction (Regular). D := D - S;
* SUBQ data, D
Binary integer subtraction (Quick). D
:= D - data;
* MULS S, D
Binary integer multiplication (Signed). D.L := D.W * S.W;
* DIVS S, D
Binary integer division (Signed). LSW(D)
:= D.L DIV S.W;
MSW(D) := D.L MOD S.W;
* NEG D
Binary integer negation (Regular). D
:= 2's complement of D;
* CLR D
Clear (set to 0). D := 0;
* NOT D
Logical NOT. D := NOT(D);
* AND S, D
Logical
* OR S, D
Logical OR. D := D OR S;
* EOR S, D
Logical Exclusive-OR. D := D
XOR S;
* ASL data, D
Arithmetic Shift Left. D := D
SHL data;
* ASR data, D
Arithmetic Shift Right. D :=
D SHR data where the sign of the new value
of D is the same as that of the previous value
of D;
* ROL data, D
Rotate Left. D := D ROL data;
* ROR data, D
Rotate Right. D := D ROR
data;
* CMP S, D
Compare. (* Adjust HNZVC according to D - S *)
* TST D
Test. (* Adjust HNZVC according to D
*)
* BRA address
Branch unconditionally. PC :=
address;
* BVS address
Branch if overflow is set. if
V then PC := address;
* BEQ address
Branch if equal. if Z then PC
:= address;
* BCS address
Branch if carry is set. if C
then PC := address;
* BGE address
Branch if greater than or equal. if
(N XOR V)' then PC := address;
* BLE address
Branch if less than or equal. if
(N XOR V) OR Z then PC := address;
* MOVE S, D
Move (Regular). D := S;
* MOVEQ data, D
Move (Quick). D := data;
* EXG S, D
Swap S and D. S <--> D;
* MOVEA address, Ai
Move address to the register Ai. Ai := address;
* INP D
Input from keyboard.
* DSP S
Display on terminal (Source and its content).
System.out.println("S:", S);
* DSR
Display on terminal the contents of the status bits
(i.e., Display Status Register).
System.out.println("H:",H,"N:",N,"Z:",Z,"V:",V,"C:",C);
* HLT
Halt program. H := True;
All opcodes are on 16 bits. Opcodes may be of two formats.
In format F1, Opref-1 (reference to operand-1) and Opref-2 (reference
to operand-2) give information on operand-1 and operand-2, respectively.
In format F2, Opref-2 (reference to operand-2) gives information on
operand-2.
| OpCodeInfo
| Opref-1 | Opref-2 |
+----------+----+----+------+----+------+----+
F1: |
O | DS | P | M1 | N1 | M2
| N2 |
+----------+----+----+------+----+------+----+
| OpCodeInfo
| Opref-1 | Opref-2 |
+----------+----+----+-----------+------+----+
F2: |
O | DS | P | Data
| M2 | N2 |
+----------+----+----+-----------+------+----+
* O (5 bits) : Opcode name
(i.e., OpName)
* P (1 bit) : Number of operands minus 1 (i.e., NbOper)
(i.e., P = 0 ==> one operand; P = 1 ==> two operands)
As a special case if the number of operands is zero,
then P = 0.
* DS (2 bits) : Size ( i.e., 00 ==> Byte, 01 ==> Word,
10 ==> Long Word)
* M1 (3 bits) : Addressing mode of operand-1 (if any)
* N1 (1 bit) : Register number of operand-1 (if any)
(Not considered when M1 = 011)
* M2 (3 bits) : Addressing mode of operand-2 (if any)
* N2 (1 bit) : Register number of operand-2 (if any)
(Not considered when M2 = 011)
* Data (4 bits): 4-bit integer constant (i.e., $0..$F)
One has to form a byte by putting $0 to the left of
the hexadecimal digit
represented by "data".
For example, if "data" is $A, then form a
byte $0A.
If the size is .B then use the byte $0A.
If the size is .W or .L then
sign-extend the byte $0A
(by putting zeros to the left of $0A) to the required
length.
Addressing modes (M1 and M2) are encoded on 3 bits:
If M1 = 000 then N1 refers to
either D0 or D1, (i.e., N1=0 refers to D0, N1=1 refers to D1).
If M1 = 001 or 100 or 110 or 111 then N1 refers to either A0 or
A1, (i.e., N1=0 refers to A0, N1=1 refers to A1).
If one replaces M1 by M2 and N1 by N2, the above two statements
remain valid.
The following table contains more information on the
format and encoding of each instruction.
* Mnemo: Mnemonic
* Fmt: Format (F1 or F2)
* OpName: Opcode
name (in binary, 5 bits).
* P: Number of operands minus 1 (in binary, 1 bit).
* Size: Allowed Size(s). B = Byte, W = Word, L = Long.
* HNZVC: Status bits.
For updating the status bits, we will use the following notation:
* - : Not affected
* 0 : Set to false
* 1 : Set to true
* * : Affected as follows: N=true iff Rm=1; Z=true iff R=0
* ? : See comments
* Sm : the most significant bit of Source operand S
* Dm : the most significant bit of Destination operand
D
* Rm : the most significant
bit of Result R
* r : Shift count
When we refer to the most significant bit (Sm, Dm, or
Rm), we have to consider what size is in use. For
example, for Dm:
* If Size=B, then Dm is bit #07 of D
* If Size=W, then Dm is bit #15 of D
* If Size=L, then Dm is bit #31 of D
Mnemo Fmt OpName P Size HNZVC Comments
----- --- ------ - ----- -----
------------------------
ADD F1 00000 1 B,W,L
-**?? V=Sm.Dm.Rm' + Sm'.Dm'.Rm
C=Sm.Dm + Rm'.Dm + Sm.Rm'
ADDQ F2 00001 0
B,W,L -**?? V=Sm.Dm.Rm' + Sm'.Dm'.Rm
C=Sm.Dm + Rm'.Dm + Sm.Rm'
SUB F1 00010 1
B,W,L -**?? V=Sm'.Dm.Rm' + Sm.Dm'.Rm
C=Sm.Dm' + Rm.Dm' + Sm.Rm
SUBQ F2 00011 0
B,W,L -**?? V=Sm'.Dm.Rm' + Sm.Dm'.Rm
C=Sm.Dm' + Rm.Dm' + Sm.Rm
MULS F1 00100 1
W -**00
DIVS F1 00101 1
L -**?0 V=division overflow
NEG F1 00110 0 B,W,L
-**?? V=Dm.Rm, C=Dm+Rm
CLR F1 00111 0 B,W,L -**00
NOT F1 01000 0 B,W,L -**00
AND F1 01001 1 B,W,L -**00
OR F1 01010 1 B,W,L -**00
EOR F1 01011 1 B,W,L -**00
ASL F2 01100 0 B,W,L
-**?? V=Dm.Rm' + Dm'.Rm
If r > 0 then C=D(m-r+1)
else C=false
ASR F2 01101 0 B,W,L
-**0? If r > 0 then C=D(r-1)
else C=false
ROL F2 01110 0
B,W,L -**0? If r > 0 then C=D(m-r+1)
else C=false
ROR F2 01111 0 B,W,L
-**0? If r > 0 then C=D(r-1)
else C=false
CMP F1 10000 1
B,W,L -**?? V=Sm'.Dm.Rm' + Sm.Dm'.Rm
C=Sm.Dm' + Rm.Dm' +Sm.Rm
TST F1 10001 0 B,W,L -**00
BRA F1 10010 0
W ----- Operand is an address (M1=011)
BVS F1 10011 0
W ----- Operand is an address (M1=011)
BEQ F1 10100 0
W ----- Operand is an address (M1=011)
BCS F1 10101 0
W ----- Operand is an address (M1=011)
BGE F1 10110 0
W ----- Operand is an address (M1=011)
BLE F1 10111 0
W ----- Operand is an address (M1=011)
MOVE F1 11000 1 B,W,L -**00
MOVEQ F2 11001 0 B,W,L -**00
EXG F1 11010 1
L ---00 Both operands are registers
MOVEA F1 11011 1 W
-**00 Source operand is an address (M1=011)
Destination is an address register
INP F1 11100 0 B,W,L -**00
DSP F1 11101 0 B,W,L
-----
DSR F1 11110 0 B,W,L
----- Although P = 0, there is no operand.
HLT F1 11111 0
B,W,L 1---- Although P = 0, there is no operand.
Here are several types of errors that have to be detected while executing a
given program. When an error is detected, the H bit must be set to true after
your simulator displays an appropriate error message.
* Invalid number of operands (address and, if you want,
instruction):
For instance, if the address $0124 contains the opcode $0900,
i.e., (ADDQ.B #$0, D0), the following message could be
displayed:
*** ERROR *** Invalid number of operands for ADDQ at
address $0124.
* Invalid data size (address and, if you want, instruction):
For instance, if the address $0124 contains the opcode $9060,
i.e., (BRA.B $<some address>), the following
message could be
displayed:
*** ERROR *** Invalid data size for BRA at address
$0124.
* Invalid addressing mode (address and, if you want, instruction):
For instance, if the address $0124 contains the opcode $9200,
i.e., (BRA.W D0), the following message could be
displayed:
*** ERROR *** Invalid addressing mode for BRA at
address $0124.
* Division by 0 (address and, if you want, instruction):
For instance, if the address $0124 has a signed
division (DIVS)
with 0 as an operand, the following message could be
displayed:
*** ERROR *** Division by 0 for DIVS at address $0124.
Contains the source code in sim68k assembly language. comments start qith a semi-colon (;). It is advised to put only one instruction per line.
These tests in binary format (.68b) can be used to check the simulator. The source files are also provided.
You can also get all these files (together with
the HTML description) by downloading sim68k.zip .