COMP1721 - Higher Computing 1B

Assignment 1 - Emu - a simple AVR Emulator

  • Thu Sep 22 17:00 Version 0.10 - typos fixed and deadline changed
  • Sun Sep 11 23:00 Version 0.9 - link to starting point code added to Hints
  • Sat Sep 10 16:00 Version 0.8 - system call description clarified, examples added
  • Fri Sep 9 08:00 Version 0.7 - implementation&testing diary file changed
  • Thu Sep 01 21:30 Version 0.6 - STD assembler fixed
  • Tue Aug 30 16:30 Version 0.5 - minor clarifications and data example added
  • Tue Aug 30 15:30 Version 0.4 - important errors in MULS,RET,ICALL descriptions fixed, examples added
  • Sat Aug 27 18:30 Version 0.3 - various typos removed
  • Tue Aug 23 11:00 Version 0.2 - various stupid mistakes fixed
  • Fri Aug 19 11:00 Version 0.1 - initial release
  • Introduction

    Assignment 1 and 2 both revolve around the Emu CPU. The Emu CPU is a subset of the AVR architecture. Although he subset is very small to assist in implementation it is sufficient to implement any program.

    Emu Memory Layout

    The Emu machine has two sections of memory - program memory (flash memory) and SRAM (data space).

    Program memory is used only to hold program instructions. It consists of 32768 16-bit words. Their addresses range from 0 to 32767. Each 16-bit word can contain a single Emu instruction. Program memory can not be accessed directly by an executing program. It does not change during program execution.

    SRAM is used only to hold program data. It consists of 4096 8-bit bytes. Their addresses range from 256 to 4351. The contents of an SRAM byte can be accessed via the LDD instruction. The contents of an SRAM byte can be changed via the STD instruction. Note both LDD and STD instructions operate only on a single data space byte. It is not possible to access or change only part of a byte.

    The LDD and STD instructions provide general-purpose access to SRAM..

    The only other instructions which access SRAM, PUSH, POP, ICALL and RET, are more specialized.

    Emu Registers

    The Emu CPU has 32 8-bit general purpose registers.

    The Emu CPU has 3 special purpose registers.

    The upper 4 bits of the status register are unused on the Emu CPU and are always 0. The lower 4 bits of the status register have the same meaning as the AVR (CVNZ).

    Emu Instructions

    The Emu machine has 22 different instructions. It has has only integer arithmetic. There is no floating-point arithmetic.

    Emu Instruction Set
    Assembler Opcode Status
    Bits
    Semantics
    ADC Rd,Rr 0001 11rd dddd rrrrVNZC Rd = Rd + Rr + C
    ADD Rd,Rr 0000 11rd dddd rrrrVNZC Rd = Rd + Rr
    SBC Rd,Rr 0000 10rd dddd rrrrVNZC Rd = Rd - Rr - C
    SUB Rd,Rr 0001 10rd dddd rrrrVNZC Rd = Rd - Rr
    AND Rd,Rr 0010 00rd dddd rrrrVNZ Rd = Rd & Rr
    OR Rd,Rr 0010 10rd dddd rrrrVNZ Rd = Rd | Rr
    EOR Rd,Rr 0010 01rd dddd rrrrVNZ Rd = Rd ^ Rr
    MOV Rd,Rr 0010 11rd dddd rrrr Rd = Rr
    MULS Rd,Rr 0000 0010 dddd rrrrZC R1:R0 = R(d+16) * R(r+16)
    LSR Rd 1001 010d dddd 0110VNZC Rd = Rd >> 1
    ASR Rd 1001 010d dddd 0101VNZC Rd = (Rd & 0x80) | (Rd >> 1)
    LDI Rd,k 1110 kkkk dddd kkkk R(d+16) = k
    LDD Rd,Y+q 10q0 qq0d dddd 1qqq Rd = SRAM[r29:r28 + q]
    STD Y+q,Rd 10q0 qq1d dddd 1qqq SRAM[r29:r28 + q] = Rd
    BRBC s,k 1111 01kk kkkk ksss PC = PC + k + 1 if !STATUS_REGISTER[s]
    BRBS s,k 1111 00kk kkkk ksss PC = PC + k + 1 if STATUS_REGISTER[s]
    IJMP 1001 0100 0000 1001 PC = R31:R30
    ICALL 1001 0101 0000 1001 SRAM[SP:(SP-1)] = PC+1; SP = SP - 2; PC = R31:R30
    RET 1001 0101 0000 1000 SP = SP + 2; PC = SRAM[SP:(SP-1)]
    POP Rd 1001 000d dddd 1111 SP = SP + 1; Rd = SRAM[SP]
    PUSH Rd 1001 001d dddd 1111 SRAM[SP] = Rd; SP = SP - 1
    NOP 0000 0000 0000 0000
    If you need further information regarding the operations of these instructions refer to descriptions of the AVR instruction set.

    Emu System Calls

    Your Emu emulator must provide a simple operating system which implements 6 system calls. These system calls are invoked by an ICALL to the address 0x7000. Register 24 should contain value in the range 0..5 indicating the desired system call. Register 26 should contain the argument, if any, to be supplied. The return value, if any, is in placed in register 24.

    System call

    (R24)
    CMeaning
    0exit(0)terminate program execution
    1printf("%d\n", R26)print a signed integer (-128..127)
    2printf("%2x\n", R26)print an unsigned integer in hexadecimal
    3printf("%c", R26)print a character
    4scanf("%d", R24))read an signed integer (-128..127)
    5R24=getchar()read a character

    Note, system calls do not change memory or any register. The only exception is register 24 is changed by systems call 4 & 5 (only).

    Example Emu Programs

    We will write in Emu programs using the usual AVR assembler syntax For example:

    hello_world.asm (hex)Print "hello\n".
    iota.asm (hex)Print the integers 1 to 10.
    evenodd.asm (hex)Tets if a number is even/odd
    store_load.asm (hex)Simple use of SRAM
    sram.asm (hex)Store numbers in SRAM
    read_array.asm (hex)Read numbers into SRAM, then print
    fib.asm (hex)Simple recursive function using of ICALL, RET, PUSH & POP.
    call.asm (hex)Simple use of ICALL & RET.
    hello10.asm (hex)Another use of ICALL & RET.
    fib.asm (hex)Simple recursive function using of ICALL, RET, PUSH & POP.

    More examples will be added.

    You will need to convert Emu assembler to Intel hex (ihex) format. As Emu is a subset of the AVR architecture. Standard AVR tools can be used to Emu assembler to ihex. For example:

    % cat iota.asm
    ; for (i = 0;i != 10; i++) printf("%d\n", i);
    ; i in r16
    ;
        LDI    r16, 0      ; i = 0
        LDI    r24, 1      ; printf("%d\n", i);
        MOV    r26, r16    
        LDI    r31, 0x70  
        LDI    r30, 0x00  
        ICALL
        LDI    r17, 1
        ADD    r16, r17    ; i++
        LDI    r17, 10
        SUB    r17, r16
        BRBC   1, 2
        LDI    r24, 0      ; exit
        LDI    r31, 0x70  
        LDI    r30, 0x00  
        ICALL
    % /home/cs1721/bin/avr-as iota.asm -o iota.elf
    % /home/cs1721/bin/avr-ld iota.elf -o iota.exe
    % /home/cs1721/bin/avr-objcopy -O ihex iota.exe iota.hex
    % cat iota.ihex
    :1000000000E081E0A02FF0E7E0E0099511E0010FAA
    :0E00100014E6101BB1F780E0F0E7E0E0099580
    :00000001FF
    

    Read and decoding ihex format file will be covered in week 5 tutes/labs.

    Emu Emulator

    In assignment 1 you will construct a Emu Emulator. The Emu Emulator is an interactive program which allows to be run and examined in various ways.

    The input to the Emu Emulator is an ihex file containing SAVY machine code. The Emu Emulator allows a user to examine and run Emu programs.

    The emulator has nine interactive commands.

    Emulator Commands
    registersPrint the contents of registers
    data Print the contents of SRAM.
    data addressPrint the contents of the SRAM byte at address.
    data address1 address2Print the contents of th eSRAM bytes at address1 to address2.
    programPrint the contents of program memory
    stepPrint and execute the next instruction.
    runcontinue program execution from the next instruction. Do not print instructions or addresses.
    restartRe-initialize all registers and SRAM
    quitExit the emulator.

    Your emulator should initialize SRAM and unused program memory to zero. All registers including PC and SREG should also be initialized to 0, except the SP which should be initialized to 4351.

    Reference Implementation

    A reference implementation program has been provided for you to use for comparison. Your emulator should match its behaviour exactly. Given the same input, it should produce the same output character-for-character.

    It is very likely students will find bugs in the reference implementation. These will be fixed as reported. When testing your program, make sure you compare it to the latest version of the reference implementation.

    Here is an example of the reference implementation in operation.

    % /home/cs1721/bin/emu /home/cs1721/public_html/05s2/emu/examples/iota.hex
    Emu Reference Implementation v0.?
    > program
    0000: e000 LDI R16,0
    0001: e081 LDI R24,1
    0002: 2fa0 MOV R26,R16
    0003: e7f0 LDI R31,112
    0004: e0e0 LDI R30,0
    0005: 9509 ICALL
    0006: e011 LDI R17,1
    0007: 0f01 ADD R16,R17
    0008: e614 LDI R17,100
    0009: 1b10 SUB R17,R16
    000a: f7b1 BRBC 1,-10
    000b: e080 LDI R24,0
    000c: e7f0 LDI R31,112
    000d: e0e0 LDI R30,0
    000e: 9509 ICALL
    > registers
    PC=0000 SP=1100 SR=[C=0,Z=0,N=0,V=0]
    r00-r0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    r10-r1f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    > step
    0000: e000 LDI R16,0
    PC=0001 SP=1100 SR=[C=0,Z=0,N=0,V=0]
    r00-r0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    r10-r1f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    > run
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    > restart
    > run
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    > registers
    PC=000f SP=1100 SR=[C=0,Z=1,N=0,V=0]
    r00-r0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    r10-r1f 0a 00 00 00 00 00 00 00 00 00 09 00 00 00 00 70
    > restart
    > registers
    PC=0000 SP=1100 SR=[C=0,Z=0,N=0,V=0]
    r00-r0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    r10-r1f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    > step
    0000: e000 LDI R16,0
    PC=0001 SP=1100 SR=[C=0,Z=0,N=0,V=0]
    r00-r0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    r10-r1f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    > quit
    % /home/cs1721/bin/emu /home/cs1721/public_html/05s2/emu/examples/sram.hex
    Emu Reference Implementation v0.?
    > run
    0
    1
    ...
    99
    > data 280
    0x0118: 18
    > data  300 400
    0x012c: 2c 2d 2e 2f
    0x0130: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
    0x0140: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
    0x0150: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
    0x0160: 60 61 62 63 00 00 00 00 00 00 00 00 00 00 00 00
    0x0170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0190: 00
    > data
    0x0100: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
    0x0110: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
    0x0120: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
    0x0130: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
    0x0140: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
    0x0150: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
    0x0160: 60 61 62 63 00 00 00 00 00 00 00 00 00 00 00 00
    0x0170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x01a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x01b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x01c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x01d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x01e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x01f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    0x0200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    ...
    0x10f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a 00
    

    Given the argument -execute your emulator should immediately run the supplied program. Your emulator should exit when the program terminates. For example:

    % /home/cs1721/bin/emu -execute /home/cs1721/public_html/05s2/emu/examples/iota.hex
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    %
    

    Hints forDeveloping Your Program

    This assignment is much easier than it seems. However there is a great deal to understand before you can tackle the assignment.

    Make sure you understand the AVR machine and its instructions. These will be explained in lectures and tutes.

    You must understand the representation of numbers in the decimal, binary and hexadecimal.

    Note,tute/labs covered reading and decoding ihex format.

    Tackle some of the simple emulator functions first.

    There is some starting point code which you may care to use (or not) in emu.c and emu.h.

    Assumptions

    You can the spcified ihex files will be in the correct format and contain only valid EMU opcodes.

    In general, you should handle errors sensibly. If in doubt imitate the reference implementation. The automatic marking will not test error handling.

    Marking

    The marking scheme for this assignment will recognise the difficulty of the task. 80% of the marks for this assignment will come from testing your program automatically on a number of Emu programs You will receive marks according to how many Emu programs your emulator handles correctly. These programs will be different to the ones you have been supplied.

    20% of the marks for this assignment will come from hand marking by your tutor. These marks will be awarded on the basis of clarity, commenting, elegance and style. In other words, your tutor will assess how easy it is for a human to read and understand your program.

    Programs which implement little or none of the emulator correctly, but which contain some correct useful C will be entirely hand-marked and will likely receive marks of 30-45%.

    Here is an indicative marking scheme (out of 10).

    100%A well-documented and very readable program which works perfectly
    85+%All emulator functions work for all programs tested.
    75%Emulator largely working for most programs.
    65%Emulator largely working for some programs.
    55%Emulator partially working for some programs.
    45%Significant progress has been made on the assignment..
    -100%Knowingly supplying work to any other person which is subsequently submitted by another student.
    0 FL for COMP1721Submitting any another person's work with their consent. This includes joint work.
    academic misconductSubmitting another person's work without their consent.

    The lecturer may vary the above marking scheme after seeing the assignment submissions.

    The lecturer may vary the above marking scheme after seeing the assignment submissions.

    You program will be compiled and tested with dcc -O -Wall. It may be penalized if dcc produces compile-time warnings or un-time errors.

    The output from your program must be identical (character-for-character) to the reference implementation you have supplied. You may be penalized if your program produces output in another format or produces any extra output.

    Optional Advanced Component

    Up to 3 bonus marks are available for successfully completing an optional advanced component for the assignment.

    The optional advanced component is to implement a graphical user interface (GUI) for your emulator and provide the full AVR instruction set.

    As up to 3 bonus marks are available, so you may obtain a mark of up to 13/10 for the assignment. Note, the optional component is a large amount of work for few marks.

    Implementation Diary

    You must keep a record of all work on your assignment. The entries should include date, starting time, finishing time, general category, and a brief (one or two line) description of the work carried out. For example:

    DateStartStopActivityComments
    10/916:0017:30codingimplemented get_move function
    10/920:0010:30debuggingfound bug in legal_move method

    Your implementation diary should be placed in a file named diary.txt. The diary will not be marked but there is a 20% penalty if you fail to provide it.

    Testing and Defect History

    You also should also keep a record of your testing of your programs and a defect history for your work. This should give the general approach to testing you used and the results of your testing.

    This description should also contain a bug tracking report. This should describe when major bugs appeared and were removed from your program.

    When CreatedWhen DiscoveredWhen FixedActivityDescription
    10/913/9 10:0014/9 19:00codingincorrect array index in legal_move method

    Your testing description should be placed in a file named testing.txt. Again there is a 20% penalty if you fail to provide this section.

    Originality of Work

    The work you submit must be your own work. Submission of work partially or completely derived from any other person or jointly written with any other person is not permitted. The penalties for such an offence may include negative marks, automatic failure of the course and possibly other academic discipline. Assignment submissions will be examined both automatically and manually for such submissions.

    Relevant scholarship authorities will be informed if students holding scholarships are involved in an incident of plagiarism or other misconduct.

    Do not provide or show your assignment work to any other person - apart from the teaching staff of Higher Computing 1B. If you knowingly provide or show your assignment work to another person for any reason, and work derived from it is submitted you may be penalized, even if the work was submitted without your knowledge or consent. This may apply even if your work is submitted by a third party unknown to you.

    Note, you will not be penalized if your work is taken without your consent or knowledge.

    Submission

    You must submit your assignment using the give command, e.g.:

             give cs1721 emu a.h b.h a.c b.c c.c d.c
    

    Note, all files must be submitted together.

    Your assignment is tentatively due at 23:59pm Monday September 26

    Note, submission even one second after this deadline is considered as one day late.

    If your assignment is submitted after this date, each day it is late reduces the maximum mark it can achieve by 20%. For example if an assignment worth 76% was submitted one day late, the late submission would have no effect. If the same assignment was submitted 2 days late it would be awarded 60%, the maximum mark it can achieve at that date.


    Andrew Taylor (andrewt@cse.unsw.edu.au)
    Higher Computing 1B, Computer Science & Engineering, UNSW