Assignment 3: Attack of the Mutant SCRAM!

Overview

The third assignment is all about the SCRAM architecture we are covering in lecture. You’ll do two things: First you’ll fix all the bugs in the SCRAM and document your fixed version in detail (including all the newly revised microprograms). Second you’ll write a SCRAM assembler that can be used with the SCRAM disassembler and the SCRAM simulator we provide to develop actual SCRAM programs comfortably.

Please realize that this is a rather big assignment, you will not finish if you don’t start right away. Luckily you can start right away! You have all the original handouts for the SCRAM (see Piazza), so there’s no need to wait for a missing lecture or a partner (if you choose to have one). Just get going!

Speaking of partners, here are a few things for you to ponder:

Note that you’re required to solve the programming problem in C, no other language is allowed. You can use all of the C standard library but no additional libraries beyond that.

If you have any questions or concerns about this assignment, please contact us right away because there’s very little time and you have a lot to do. Get to it!

Problem 1: Fix the SCRAM (50%)

The SCRAM as discussed in lecture and as described in the PDF handout (available on Piazza) is full of bugs. Your task for this problem is to fix the SCRAM which means you’ll have to hand in the following:

  1. A corrected block diagram of the SCRAM at the same level of abstraction as the block diagram in the PDF handout and the diagram we worked on in lecture. Make sure you label all connections with the number of lines required. Make sure that you provide all connections necessary to correctly implement your micro programs. Make sure that you only make the minimal amount of changes to fix the SCRAM, do not develop an entirely new architecture.
  2. Corrected micro programs for the FETCH cycle as well as for all SCRAM instructions except the HLT instruction. Make sure your new micro programs do not trash registers they are not supposed to trash. Make sure your micro programs do not contain operations that your block diagram does not allow for. Make sure that your micro programs are compatible with the SCRAM simulator we provide. (The simulator is in turn based on the table of instructions from the SCRAM PDF that we declared correct by definition!)
  3. A narrative describing in detail the bugs you found, how you fixed them, and why your fix is the smallest possible correction within the parameters you were given.

You do not have to provide detailed gate-level circuit diagrams for anything, the block-level diagram is good enough. However, if you assume a new circuit somewhere, you should at least explain how it is built in principle. Note that you must hand in a diagram for this problem, and that diagram has to be in PDF format. Be careful with scanned diagrams, it’s easy to increase the file size of your archive beyond what is allowed for a submission!

Problem 2: The SCRAM Assembler (50%)

We provide a number of development tools for the SCRAM in an archive on the Piazza site. The SCRAM disassembler can be used to examine a SCRAM object file. The SCRAM simulator can be used to run a SCRAM object file. You can find more details about how these tools work in the archive itself.

Your job for this problem is to write a SCRAM assembler that can be used to develop SCRAM programs comfortably. You can see what this means by looking at the example files in the archive. The loop.scram object file contains a sequence of “raw” SCRAM instructions, the very bit patterns that would be in the memory (and thus the instruction register) of the SCRAM machine. So that’s a mess of zeros and ones: The only sensible way to look at this file is using a hexdump tool like xxd.

$ ls -la loop.scram
-rw-rw-r-- 1 phf phf 6 May 26  2015 loop.scram
$ xxd -g 1 loop.scram
0000000: 14 55 34 70 00 01                                .U4p..
$ xxd -b loop.scram
0000000: 00010100 01010101 00110100 01110000 00000000 00000001  .U4p..

As you can see, the object file contains only 6 bytes. The first xxd command displays those 6 bytes in hexademical notation, the second in binary notation. Now look at that first byte carefully: It’s actually an LDA instruction that loads from address 4! (Recall how the instruction encoding of the SCRAM works: upper 4 bits for the opcode, lower 4 bits for the address.) The SCRAM disassembler we provide translates those bytes back into SCRAM assembly language, at least approximately:

$ ./dis.py <loop.scram
0x00: LDA 0x04
0x01: ADD 0x05
0x02: STA 0x04
0x03: JMP 0x00
0x04: HLT 0x00
0x05: HLT 0x01

Don’t get confused by all the HLT instructions! The disassembler is rather simplistic and cannot figure out whether a byte in the object file is meant to be a piece of data or an instruction, so it always assumes an instruction even if the SCRAM never fetches that location for execution. Case in point: Addresses 4 and 5 are not really instructions here, they are just two 8-bit variables initialized to the values 0 and 1 respectively.

Nobody wants to write SCRAM programs by hand-crafting byte sequences like the above. Instead, we’d like to at least be able to write something like this (see loop.z in the archive):

LDA     4
ADD     5
STA     4
JMP     0
DAT     0
DAT     1

The assembler is a program that translates a textual description like the above into an “equivalent” 6-byte SCRAM object file. It does so by

Note the pseudo-instruction DAT! This is not a SCRAM instruction, rather it’s a way for the programmer to write down that a given byte is supposed to hold a certain data value. While the addresses after LDA, JMP, … can only be 4 bits long, the value after a DAT can be up to 8 bits long since that value is written directly into the object file without a 4 bit opcode before it!

However, even that notation is not really comfortable because the programmer still has to manually track the addresses of all the various instructions and data bytes. What we would really like the assembler to take as input is a file like this (see loop.s in the archive):

# Simple counter program in SCRAM assembly.

start:  LDA     count
        ADD     one
        STA     count
        JMP     start

count:  DAT     0       # counter variable
one:    DAT     1       # constant 1

There are two innovations here: comments that can be used to explain pieces of a program and labels that can be used to automate address computations. Most assembly languages, including this one, are line-based which means that they are processed line-by-line by the assembler. In general, the structure of a line is as follows:

label: instruction # comment

All of the components are optional: we can have lines that are empty, lines that are only comments, lines that only define a label, and lines that only contain an instruction; or any combination thereof. Comments start with the character “#” and continue to the end of the current line; anything between “#” and the end of the line is ignored by the assembler. Instructions consist of OPCODE address pairs separated by whitespace; to the list of actual SCRAM opcodes we add the DAT pseudo-opcode as described above; opcodes are always fully capitalized; addresses can be non-negative integers or label references. (Note that for the HLT instruction we could leave out the address part (why?); however, in the interest of making the assembler a little easier to write, we still require an address even for HLT.) Label definitions are sequences of letters (upper or lower case, but case matters!) that end with a colon; if a label definition is present, it has to come before the instruction in the same line (if any).

The way addresses are assigned to labels is straightforward: We start at address 0 for the first instruction; each (pseudo-)instruction will advance the current address by 1 since each of them occupies 1 byte of memory. So in the program above, the start label is 0 because there are no instructions preceeding it. The instructions following (LDA, ADD, STA, JMP) are each 1 byte long, meaning that the count label is address 4 whereas the one label is address 5.

The only problem with all of this is that a label may be referenced before it has been defined as is the case in the example program: When we process “LDA count” for the first time, we don’t know yet that count is actually 4. Most assemblers use a two-pass process to get around this: In the first pass they only process the addresses and not the instructions themselves, meaning the first pass determines what all the labels will be but doesn’t actually generate the finished object file yet. The second pass then uses this information to fill in the correct bit patterns for all instructions and write the final object file.

Your job is to write the SCRAM assembler. So you need to write a program that given something like loop.s on the standard input will produce a SCRAM object file like loop.scram on the standard output. Nothing more and nothing less. We suggest that you first write a version of the assembler that works only for inputs like loop.z and then extend it with comments and labels (and empty lines!) so it can also process inputs like loop.s. (If you’re feeling particularly mighty, you can of course also try to immediately hack the full version; but that’s not recommended.)

Please call your executable assembler sas (short for “Scram ASsembler”). Of course you actually submit the complete source code, not the executable. Note that the code we give you is not an example of good design or good programming style, whereas the code you hand in should be beautiful and excellently modular. Your code has to compile cleanly with -std=c11 -Wall -Wextra -Wpedantic -O2 in effect. We must be able to build your program using make with no additional arguments, so obviously you need to include a working Makefile for it. (Please remember that we use Lubuntu 16.04 as our reference Linux distribution for the course, so make sure it builds there.)

Note on Error Messages: Your assembler should do basic error checking for the input program. So if a label is used that has never been defined, there should be an error. If a label is defined twice, there should be an error. If a label is out of range, or if the program is too long for the SCRAM, or if a number is too large (4-bit unsigned for addresses, 8-bit unsigned for data) there should be an error. If an unknown opcode is used or if an address is missing, there should be an error. And so on, and so forth. Please include a line number (starting at 1) with your error message to help the programmer correct their code, and please make sure you print error messages to standard error and not to standard output! No input, however cleverly crafted, should make your assembler crash!

Note on Line/String Lengths: As a special concession to using C as the only implementation language for this assignment, you may assume that a line of input has at most 128 characters, excluding the final LF (line feed) character. Similarly, you may assume that a label has at most 32 characters, excluding the final : (colon) in case of a definition. However, you still need to stop with an error message if there is a longer line/label, your assembler may not crash!

Problem 3: Gold Star Multiplier (0%)

Write a SCRAM program mult.s that multiplies the integers 7 and 9 (stored in two memory locations) by repeated addition. The program should put the result (of 63 in this example) in a third memory location. Changing the factors should change the result appropriately. After the multiplication is done, the program should HLT. You can test your program with the SCRAM simulator. Here is the output of our mult.scram running:

$ ./sas.py <mult.s >mult.scram
$ ./scram.py <mult.scram
AC: 0x00 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x00 0x01 0x00 0x00
AC: 0x07 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x00 0x01 0x00 0x00
AC: 0x07 PC: 0x02   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x00 0x01 0x00 0x00
AC: 0x00 PC: 0x03   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x00 0x01 0x00 0x00
AC: 0x09 PC: 0x04   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x00 0x01 0x00 0x00
AC: 0x09 PC: 0x05   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x09 0x01 0x00 0x00
AC: 0x07 PC: 0x06   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x09 0x01 0x00 0x00
AC: 0x06 PC: 0x07   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x07 0x09 0x09 0x01 0x00 0x00
AC: 0x06 PC: 0x08   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x09 0x01 0x00 0x00
AC: 0x06 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x09 0x01 0x00 0x00
AC: 0x06 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x09 0x01 0x00 0x00
AC: 0x06 PC: 0x02   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x09 0x01 0x00 0x00
AC: 0x09 PC: 0x03   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x09 0x01 0x00 0x00
AC: 0x12 PC: 0x04   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x09 0x01 0x00 0x00
AC: 0x12 PC: 0x05   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x12 0x01 0x00 0x00
AC: 0x06 PC: 0x06   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x12 0x01 0x00 0x00
AC: 0x05 PC: 0x07   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x06 0x09 0x12 0x01 0x00 0x00
AC: 0x05 PC: 0x08   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x12 0x01 0x00 0x00
AC: 0x05 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x12 0x01 0x00 0x00
AC: 0x05 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x12 0x01 0x00 0x00
AC: 0x05 PC: 0x02   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x12 0x01 0x00 0x00
AC: 0x12 PC: 0x03   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x12 0x01 0x00 0x00
AC: 0x1b PC: 0x04   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x12 0x01 0x00 0x00
AC: 0x1b PC: 0x05   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x1b 0x01 0x00 0x00
AC: 0x05 PC: 0x06   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x1b 0x01 0x00 0x00
AC: 0x04 PC: 0x07   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x05 0x09 0x1b 0x01 0x00 0x00
AC: 0x04 PC: 0x08   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x1b 0x01 0x00 0x00
AC: 0x04 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x1b 0x01 0x00 0x00
AC: 0x04 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x1b 0x01 0x00 0x00
AC: 0x04 PC: 0x02   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x1b 0x01 0x00 0x00
AC: 0x1b PC: 0x03   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x1b 0x01 0x00 0x00
AC: 0x24 PC: 0x04   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x1b 0x01 0x00 0x00
AC: 0x24 PC: 0x05   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x24 0x01 0x00 0x00
AC: 0x04 PC: 0x06   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x24 0x01 0x00 0x00
AC: 0x03 PC: 0x07   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x04 0x09 0x24 0x01 0x00 0x00
AC: 0x03 PC: 0x08   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x24 0x01 0x00 0x00
AC: 0x03 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x24 0x01 0x00 0x00
AC: 0x03 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x24 0x01 0x00 0x00
AC: 0x03 PC: 0x02   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x24 0x01 0x00 0x00
AC: 0x24 PC: 0x03   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x24 0x01 0x00 0x00
AC: 0x2d PC: 0x04   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x24 0x01 0x00 0x00
AC: 0x2d PC: 0x05   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x2d 0x01 0x00 0x00
AC: 0x03 PC: 0x06   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x2d 0x01 0x00 0x00
AC: 0x02 PC: 0x07   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x03 0x09 0x2d 0x01 0x00 0x00
AC: 0x02 PC: 0x08   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x2d 0x01 0x00 0x00
AC: 0x02 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x2d 0x01 0x00 0x00
AC: 0x02 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x2d 0x01 0x00 0x00
AC: 0x02 PC: 0x02   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x2d 0x01 0x00 0x00
AC: 0x2d PC: 0x03   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x2d 0x01 0x00 0x00
AC: 0x36 PC: 0x04   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x2d 0x01 0x00 0x00
AC: 0x36 PC: 0x05   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x36 0x01 0x00 0x00
AC: 0x02 PC: 0x06   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x36 0x01 0x00 0x00
AC: 0x01 PC: 0x07   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x02 0x09 0x36 0x01 0x00 0x00
AC: 0x01 PC: 0x08   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x36 0x01 0x00 0x00
AC: 0x01 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x36 0x01 0x00 0x00
AC: 0x01 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x36 0x01 0x00 0x00
AC: 0x01 PC: 0x02   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x36 0x01 0x00 0x00
AC: 0x36 PC: 0x03   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x36 0x01 0x00 0x00
AC: 0x3f PC: 0x04   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x36 0x01 0x00 0x00
AC: 0x3f PC: 0x05   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x3f 0x01 0x00 0x00
AC: 0x01 PC: 0x06   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x3f 0x01 0x00 0x00
AC: 0x00 PC: 0x07   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x01 0x09 0x3f 0x01 0x00 0x00
AC: 0x00 PC: 0x08   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x00 0x09 0x3f 0x01 0x00 0x00
AC: 0x00 PC: 0x00   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x00 0x09 0x3f 0x01 0x00 0x00
AC: 0x00 PC: 0x01   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x00 0x09 0x3f 0x01 0x00 0x00
AC: 0x00 PC: 0x09   MEM:  0x1a 0x89 0x1c 0x5b 0x3c 0x1a 0x6d 0x3a 0x70 0x00 0x00 0x09 0x3f 0x01 0x00 0x00
HLT encountered @ 9

Deliverables

Please follow the submission instructions as detailed on Piazza. Make sure that your tarball contains no derived files whatsoever (i.e. no executable files), but allows building all required derived files. Also, be sure to include a Makefile that sets the appropriate compiler flags and builds all programs by default. Include a plain text README file that briefly explains what your programs do and contains any other notes you want us to check out before grading; your answers to written problems should be in this file as well. Finally, make sure to include your name and email address in every file you turn in (well, in every file for which it makes sense to do so anyway)!

Grading

For reference, here is a short explanation of the grading criteria; some of the criteria don’t apply to all problems, and not all of the criteria are used on all assignments.

Packaging refers to the proper organization of the stuff you hand in, following both the guidelines for Deliverables above as well as the general submission instructions for assignments on Piazza.

Style refers to C programming style, including things like consistent indentation, appropriate identifier names, useful comments, suitable documentation, etc. Simple, clean, readable code is what you should be aiming for. Make sure you follow the style guide posted on Piazza!

Design refers to proper modularization (functions, modules, etc.) and an appropriate choice of algorithms and data structures.

Performance refers to how fast/with how little memory your programs can produce the required results compared to other submissions.

Functionality refers to your programs being able to do what they should according to the specification given above; if the specification is ambiguous, ask for clarification! (It also refers to you simply doing the required work, which may not be programming alone.)

If your programs cannot be built you will get no points whatsoever. If your programs cannot be built without warnings using the required compiler options given on Piazza we will take off 10% (except if you document a very good reason). If your programs cannot be built using make we will take off 10%. If valgrind detects memory errors in your programs, we will take off 10%. If your programs fail miserably even once, i.e. terminate with an exception of any kind or dump core, we will take off 10% (for each such case).