辅导案例-ECED 3403-Assignment 3
Dalhousie University
Department of Electrical and Computer Engineering
ECED 3403 – Computer Architecture
Assignment 3: The X-Makina emulator
1 Objectives
Before a new computer system is brought to market, hardware and software designers often
construct emulators to examine how the machine will operate under certain conditions. An
emulator “imitates the function of (another system), as by modifications to hardware or software
that allow the imitating system to accept the same data, execute the same programs, and achieve
the same results as the imitated system”.1
In addition to the emulation of the new computer, support software can be required if the
computer has an entirely new architecture. This software can include new compilers,
assemblers, linkers, and even operating systems.
To date, you have designed, implemented, and tested a preprocessor to translate legacy XM2
instructions to their XM3 equivalent (Assignment 1) and implemented a simple debugger with
64-kiB of memory (Assignment 2). This assignment requires you to design, implement, and test
an emulator for a subset of X-Makina’s instruction set architecture. The emulator is to execute
files containing S-records produced by the XM3 assembler.
The emulator and assembler can run on the machine of your choice. They do not have to run on
the same machine since the S-record code is portable and machine independent (why?).
2 The Emulator
The X-Makina’s ISA emulator is to include all its CPU registers (R0-R4, R5/LR, R6/SP, and R7/PC),
the program status word (PSW), encoded constants, and a subset of XM3’s instruction set. It will
also be necessary to add three new options to the debugger and include a control-C catcher.
The emulator is to be written in C or, with permission from Dr. Hughes, C++.
2.1 The instruction set
A total of 24 XM3 instructions are to be emulated (see Table 1). Some points to note:
• The memory and bus implemented in assignment 2 is to be used in this assignment.
• Memory access uses the LDR (load relative) and STR (store relative) instructions. No other
instructions access primary memory. These will allow three addressing modes: direct (zero-
value offset address), indexed (by incrementing or decrementing the register used to access
memory), and relative (non-zero value offset).
• Branching (BRA and BL) also uses relative addresses. How the offsets are interpreted is
described in the XM3 ISA document.

1 From the American Heritage® Dictionary of the English Language, Fifth Edition. (2011). Retrieved June 19 2020
from https://www.thefreedictionary.com/emulator
ECED 3403: Assignment 3 2

• The conditional execution instruction (CEX) affects the fetch-phase only if the instructions
being fetched are not being executed.
• Arithmetic instructions are to support both encoded constants and registers. The instructions
are to work on bytes (least-significant only) or words.
2.2 Instruction cycle
The instruction cycle is to be emulated: instructions are fetched from memory, decoded into their
opcode and operands, and executed. The emulator is to recognize each instruction and perform
its function. Any status changes should be indicated in the PSW’s status bits.
2.3 Accessing words and bytes
Arithmetic and logic instructions operate on data as either a word or a byte (least significant
only). A straightforward way of doing this is to use a union.
First, the union must be declared as an integer and an array of two bytes:
#define LSB 0
#define MSB 1
union word_byte
{
unsigned short word;
unsigned char byte[2];
};
Next, to access a data value as either a word or a byte, it is necessary to use the WB bit found in
the instruction. From this, we can operate on either the data, either as a word or a byte (the
code fragment shows addition with carry):
union word_byte srcnum, dstnum;

srcnum.word = src;
dstnum.word = dst;

if (wb == 0)
dstnum.word = (dstnum.word + srcnum.word) + carry;
else
/* Byte addition - ignore MSB */
dstnum.byte[LSB] = (dstnum.byte[LSB] + srcnum.byte[LSB]) + carry;

return dstnum.word;

2.4 System clock
A CPU (system) clock should be maintained to keep track of the number of clock-cycles a program
makes used during its execution. The CPU clock is independent of any external clock.
Execution times are summarized in the following table:
ECED 3403: Assignment 3 3

Activity
CPU clock
cycles
Memory access 3
Fetch cycle 1
Decode cycle 1
Execute cycle 1

3 Debugger and Control-C
Three new options are to be added to the debugger. Software to catch user-generated control-
Cs is also required.
Examples of the commands and control-C are shown in section 3.3.
3.1 New debugger commands
3.1.1 Breakpoint
An instruction breakpoint is a memory address that, when equal to the program counter (register
7), should cause the program to stop and return control to the debugger.
The command is ‘B’ followed by the address of the breakpoint.
3.1.2 Execute
The command ‘G’ (for ‘go’) starts the CPU from the address stored in the program counter
(register 7). The starting address should be taken from an S9 record supplied with the loaded
file.
3.1.3 Registers
The contents of the register file (i.e., registers R0 to R7) should be displayed when the user enters
an option of ‘R’. The output should be the register number and the contents of the register.
3.2 Control-C catcher
XM3 does not have a halt instruction (to be fair, most machines don’t). A program can be stopped
and control returned to the debugger using a breakpoint (described above) or by the user typing
CTRL (control) and ‘C’ simultaneously (often abbreviated to ‘^C’ or “Ctrl C”).
Normally you would expect ^C to return control to the operating system. However, ^C is a signal
that can be caught by a program to indicate that a certain condition has been met (the UNIX
system constant indicating a terminal interrupt is SIGINT). In our case, ^C means that the
emulator should stop running and control should be returned to the debugger.
The C code required to handle ^C is as follows:
1. Any reference to the signal function must include signal.h:
#include /* Signal handling software */

ECED 3403: Assignment 3 4

2. A variable indicating the state of ^C (i.e., detected or not detected) needs to be declared. It
should be a global (shared between the debugger and the CPU emulator):
/*
- volatile - do not cache
- sig_atomic_t - shared variable - handle possible race conditions
*/
volatile sig_atomic_t ctrl_c_fnd; /* T|F - indicates if ^C detected */

3. The SIGINT handler is called when ^C is detected. It is to set the control-C detected variable
to TRUE. The handler is the equivalent of an interrupt, interrupting the running program (in
our case, the emulator) and passing control to a handler within the program:
void sigint_hdlr()
{
/*
- Invoked when SIGINT (control-C) is detected
- changes state of waiting_for_signal
- signal must be reinitialized
*/
ctrl_c_fnd = TRUE;
signal(SIGINT, (_crt_signal_t)sigint_hdlr); /* Reset SIGINT */
}
Note that the handler must reset the signal so that SIGINT is called again on the next occurrence
of ^C.

4. Before ^C can be used, the debugger must indicate that ^C has not been detected (using the
global variable) and that SIGINT is bound to the SIGINT signal handler:
/* Call signal() - bind sigint_hdlr to SIGINT */
ctrl_c_fnd = FALSE;
signal(SIGINT, (_crt_signal_t)sigint_hdlr);

5. Finally, a very simplified version of the CPU instruction cycle emulation loop could look like
this, stopping when a ^C is detected or the PC equals the breakpoint:
while(!ctrl_c_fnd && pc != brkpt)
{
fetch();
decode();
execute();
}
Before the CPU can run, ctrl_c_fnd must be initialized to FALSE to allow the execution loop to
function.
ECED 3403: Assignment 3 5

3.3 Example
Figure 1 shows the three new debugger commands after loading the sample file A2.xme:
1. Setting a breakpoint at 100c (‘b’).
2. Executing a program (‘g’) to the breakpoint (100c).
3. Checking the registers (‘r’).
4. Changing the breakpoint to 0.
5. Running the program without a breakpoint, requiring ^C to stop the program.

Figure 1: An example of the debugger with its new commands and Control-C

4 Marking
The assignment will be marked using the following marking scheme:
Design: The design description must include a brief introduction as to the purpose of the software
(0.5), a design section (6), and a data dictionary (1.5).
Total points: 8.
^C
ECED 3403: Assignment 3 6

Software: A fully commented, indented, magic-numberless, tidy piece of software that meets the
requirements described above and follows the design description.
Total points: 14.
Testing: In addition to any test software supplied as part of the assignment, you will be
responsible for developing a minimum of three (3) distinct tests demonstrating that the
software operates according to the design description. Some of the tests should exercise the
software. The tests must include the name of the test, its purpose or objective, the test
configuration, and the test results.
It should be possible to drag-and-drop a file of debugger commands to the emulator to allow
batch testing.
Total points: 5.
All sections are to be submitted electronically via Brightspace. Software is to be submitted as
source modules for compilation and comparison.
5 Important Dates
Available: 24 June 2020
Design document due: 13 July 2020 (24h00 ADT)
Code and testing due: 1 August 2020 (24h00 ADT)
The last day this or any assignment can be accepted is 1 August 2020 at 24h00 ADT.
Submissions after that date will not be marked.
6 Miscellaneous
This assignment is to be completed individually.
If you are having any difficulty with this assignment or the course, please contact Dr. Hughes,
Gary, or Zach as soon as possible.
Since there will be no fourth assignment, this assignment is worth 20% of your overall course
grade. Assignments 1 and 2 are worth 10% and 15%, respectively.
This is a non-trivial assignment. It should be started as soon as it is made available.
Assignments that are found to be copies of work done by other students from either this year
or pervious years will result in the incident being reported to the Academic Integrity Office.


ECED 3403: Assignment 3 7

Table 1: XM3 Instruction Set to be implemented
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Mnemonic Instruction
0 0 0 OFF OFF OFF OFF OFF OFF OFF OFF OFF OFF OFF OFF OFF BL Branch with Link
0 0 1 0 0 0 OFF OFF OFF OFF OFF OFF OFF OFF OFF OFF BRA Unconditional branch (branch always)
0 0 1 0 0 1 C C C C T T T F F F CEX Conditional execution
0 1 0 0 0 0 0 0 R/C W/B S/C S/C S/C D D D ADD Add: DST = DST + SRC/CON
0 1 0 0 0 0 0 1 R/C W/B S/C S/C S/C D D D ADDC Add with Carry: DST = DST + (SRC/CON + Carry)
0 1 0 0 0 0 1 0 R/C W/B S/C S/C S/C D D D SUB Subtract: DST = DST + (¬SRC/CON + 1)
0 1 0 0 0 0 1 1 R/C W/B S/C S/C S/C D D D SUBC Subtract with Carry: DST = DST + (¬SRC/CON + Carry)
0 1 0 0 0 1 1 0 R/C W/B S/C S/C S/C D D D XOR Exclusive OR: DST = DST  SRC/CON
0 1 0 0 0 1 1 1 R/C W/B S/C S/C S/C D D D AND AND: DST = DST & SRC/CON
0 1 0 0 1 0 0 0 R/C W/B S/C S/C S/C D D D BIT Bit test: DST & SCR/CON
0 1 0 0 1 0 0 1 R/C W/B S/C S/C S/C D D D BIC Bit clear: DST = DST & ~SRC/CON
0 1 0 0 1 0 1 0 R/C W/B S/C S/C S/C D D D BIS Bit set: DST = DST | SRC/CON
0 1 0 0 1 1 0 0 0 W/B S S S D D D MOV DST = SRC
0 1 0 0 1 1 0 0 1 0 S S S D D D SWAP Swap SRC and DST
0 1 0 0 1 1 0 1 0 W/B 0 0 0 D D D SRA Shift DDD right (1 bit) arithmetic
0 1 0 0 1 1 0 1 1 W/B 0 0 0 D D D RRC Rotate DDD right (1 bit) through carry
0 1 0 0 1 1 1 0 0 0 0 0 0 D D D SWPB Swap bytes in DDD
0 1 0 0 1 1 1 0 0 0 0 0 1 D D D SXT Sign-extend byte to word in DDD
0 1 1 0 0 B B B B B B B B D D D MOVL DST.Low byte = BBBBBBBB; DST.High byte unchanged
0 1 1 0 1 B B B B B B B B D D D MOVLZ DST.Low byte = BBBBBBBB; DST.High byte = 00000000
0 1 1 1 0 B B B B B B B B D D D MOVLS DST.Low byte = BBBBBBBB; DST.High byte = 11111111
0 1 1 1 1 B B B B B B B B D D D MOVH DST.Low byte unchanged; DST.High byte = BBBBBBBB
1 0 OFF OFF OFF OFF OFF OFF OFF W/B S S S D D D LDR DST = mem[SRC + sign-extended 7-bit offset]
1 1 OFF OFF OFF OFF OFF OFF OFF W/B S S S D D D STR mem[DST + sign-extended 7-bit offset] = SRC

51作业君 51作业君

Email:51zuoyejun

@gmail.com

添加客服微信: IT_51zuoyejun