Assignment #3 Design of the Complete 8 bit CPU

CSE 141L, Winter 2000 Assignment #3 Design of the Complete 8 bit CPU Due: March 13, 2000 Using the ISA from Assignment #1 and the Central Processor d...
Author: Luke Harrington
1 downloads 2 Views 19KB Size
CSE 141L, Winter 2000

Assignment #3 Design of the Complete 8 bit CPU Due: March 13, 2000 Using the ISA from Assignment #1 and the Central Processor design from Assignment #2 as a basis, design the Control Unit to make a complete, one cycle, 8 bit CPU. Your design will contain at least a program counter (PC), a PC incrementor, an ALU, a memory and probably internal storage. The ALU and storage, as well as the ISA should be the ones you designed earlier. You may make minor changes to accommodate unforseen situations. The resulting CPU will correctly execute the programs you wrote for Assignment #1. As in Assignment #2, use a hierarchial design, with the highest level components on the top level, and the lower level designs of these components on separate schematics. The lowest level components should be in terms of basic LogicWorks components. Submit your ALU and register designs again as part of a complete package. It will simplify your design if you generate all control signals from a single place based on the instruction opcode. The text gives an example of this methodology. Memory locations need to be user-initializable. This can be accomplished by placing a MUX in front of the memory data in and another in front of the address lines. Your programs will be placed in ROM so you don’t have to hand enter the programs each time. Instructions for placing your programs in ROM are at the end of this assignment. You can have 3 different ROMS or place all of your programs in a single one, having 3 different initial values for the PC. Put an init signal into your design. This signal sets the PC to some predetermined value, and can be used to initialize some memory values, registers, etc. Also include a cycle counter which resets to zero on init. This counter will accurately record the number of cycles executed to aid us in determining the dynamic instruction count. Include time and provisions to debug your programs. It’s rare to have a program be correct as written. You might want to consider developing a translator to change your assembly language into machine language. This could save you hand coding errors. This, however, is not a requirement of the assignment. It is your responsibility to convince us that your design functions correctly. We do not have the time necessary to convince ourselves of that without a lot of help from you. Providing sufficient, clear information and results is a must! TURN IN: 1. Schematics of all circuits, including the ones you designed before. The highest level design must have all of the signals necessary to demonstrate correct program execution via the timing diagram. 2. A timing diagram for each of the three programs demonstrating correct operation and other crucial data. As a minimum, it should show results being generated (like the product, or the smallest and largest values being accumulated), the cycle counter, the PC, and the production of the final result. Show the timing for the first several instructions, including several iterations of the loop, and the last several instructions. These timing diagrams should be heavily annotated so that they are easy to decipher. 3. A review of your ISA 4. The assembly and machine code for your three programs. Also answer the following questions: 1. 2. 3. 4. 5.

What changes have you made to your original ISA? Why did you make these changes? What are the dynamic instruction counts for each of the three programs? What could you have done differently to better optimize for dynamic instruction counts? Give specific examples. How successful were you in optimizing for ease of design? Give examples. What could you have done differently to make the design easier?

6. 7.

Which instruction takes longest on your machine (the one that drove the length of the cycle)? What would you have done differently if you were being graded on short instruction cycle?

Program Data: Program #1. Data: 10101010 01010101 11110000 00001111 00111100 11000011 11001011 00010110 00000000 11010001 01001110 10010101 11100011 00011100 11010110 10001110 01100111 00010001 10101100 11100101 10000011 00110101 00010101 11101100 11110000 11010001 10010101 00010001 10101010 01010101 00000000 11111111 Program #2: A = 00000011 B = 00000100 Program #3: (in HEX; you convert to binary) 0: 1: 2: 3: 4: 5: 6:

A6 08 F7 83 67 B8 C7

7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:

07 F4 77 90 01 F7 D4 01 F6 D4 A6 33 65 EF B4 01 00 A9 C7 18 B5 EF D9 88 43 05 0A

CREATING RAM: The RAM is used as your Data Memory. To create RAM: 1. Create your own device library if you haven't already 2. Select the RAM item in the Tools menu 3. 3. A parameters dialog box appears. The following choices need to be made here: a) Ram Type Name: The device will be saved to the library under this name b) Save to Library: This drop-down menu allows you to select an open library to save the device to c) Address Lines: # of address lines. Typically in the case of this assignment should be 8 d) Bits per word: 8 for this assignment e) Chip Enables: 0, 1, 2 or 3 active low chip enables. 0 should be OK 4. Then click on the Build RAM button. 5. You can now drag and drop it into any of your designs from the Library you have created.

CREATING PROM:

In order to create ROMs in LogicWorks to hold your programs, follow these steps: 1. Translate your assembly code into machine code (binary). It might look something like this:

00111100 00001111 10101010 00001111 01110111 11110000 00110011 00001111 01110011

2. Then translate that into hexadecimal (by hand), and put it into a file that looks something like this (notice that comments are allowed in this file, preceded by a #):

# program 2 #divide # by me 3C # lda $3, $4 0F #add $1, $2, $7 AA #etc. 0F 77 F0 33 0F 73

The allowed format is actually more flexible than this, but there is no need to stress it. Now that you have your input file (I'll assume it is called prog_file), you need to:

3. Translate the hexadecimal file into something LogicWorks understands, which is the bizarre ihex format. To do that translation, Jeff Brown, a former student, has written the program which follows.

Copy the C file (ihex.c), compile it ("cc -o make_ihex ihex.c", for example, on Unix), and run it on your program file: make_ihex < prog_file > prog_file.ihex (having the .hex suffix allows LogicWorks to find the file a little easier).

4. Then, using an ftp program like "fetch" on the Macintosh, transfer the .hex file to the machine running LogicWorks. The rest of these instructions refer to LW 3.0 on the Mac, but I doubt that they are much different for the PC.

1. 2. 3. 4. 5.

6. 7. 8. 9.

Create your own device library, if you haven't already. Select PromPLA from the Tools menu Choose your custom library from "Save To Library:" Give your device a name Set number of inputs. This is the number of bits needed to address your biggest ROM. My nine-line (nine-instruction) ROM above would need 4 bits, a 256-line ROM would need 8 bits (8 inputs). Number of outputs is 8. Now it will let you select a file. Hit "Hex File" button and open your .hex file. Hit Build PROM Now you can select that device from your device library and put it in a circuit. Be sure to test it carefully.

CONVERSION PROGRAM: /* * This is a one-night hack with NO WARRANTY WHATSOEVER. * Jeff Brown, 02/08/1999 * (If you use this code without giving me credit, you suck.) */ #include #include #include #include #define RECSIZE 16

static int get_byte(FILE *input) { int ch, nybble; int value; int size; int in_comment; size = 0; value = 0; in_comment = 0; while ((ch = fgetc(input)) != EOF) { if (in_comment) { if (ch == '\n') { in_comment = 0; if (size > 0) { break; } } continue; } else if (ch == '#') { in_comment = 1; continue;

} else if (isspace(ch)) { if (size > 0) { break; } continue; } nybble = toupper(ch); value 0) && (size 0; size--) { sum += *data++; sum &= 0xff; } if (sum > 0) { sum = 0x100 - sum; } return(sum);

}

static int asc2hex(FILE *input, FILE *output) { unsigned char outbuf[5 + RECSIZE + 1]; unsigned char *inbuf; int byte; int address; int size; int i; inbuf = outbuf + 5; address = 0; outbuf[0] = ':'; do { size = 0; while (size < RECSIZE) { byte = get_byte(input); if (byte < 0) { if (byte < -1) { return(-1); } break; } inbuf[size++] = byte; } outbuf[1] = size; if (size > 0) { outbuf[2] = address >> 8; outbuf[3] = address & 0xff; outbuf[4] = 0; } else { outbuf[2] = 0; outbuf[3] = 0; outbuf[4] = 1; } outbuf[5 + size] = checksum(outbuf + 1, size + 4); fputc(outbuf[0], output); for (i=1; i 0)); return(0); }

int main(int argc, char *argv[]) {

FILE *input, *output; if ((argc != 1) && (argc != 3)) { fprintf(stderr, "usage: %s [asciifile outfile]\n" \ "This reads a sequence of byte values (in hex) and outputs them in the\n" \ "Intel \"HEX\" ROM format, starting at address 0.\n" \ "The comment character '#' causes the rest of a line to be ignored.\n" \ "\n" \ "(02-08-1999 JAB)\n", argv[0]); return(1); } if (argc == 1) { input = stdin; output = stdout; } else { input = fopen(argv[1], "r"); if (input == NULL) { perror("error opening input file"); return(1); } output = fopen(argv[2], "w"); if (output == NULL) { fclose(input); perror("error opening output file"); return(1); } } asc2hex(input, output); if (argc > 1) { fclose(input); fclose(output); } return(0); }