snick snack A Working Computer Slides based on work by Bob Woodham and others Learning Goals: In-Class By the end of this unit, mostly from the lab, you should be able to: – Trace execution of an instruction through our computer: the basic fetch-decode-execute instruction cycle and the data flow to/from the arithmetic logic unit (ALU), the main memory, the Instruction Register (IR) and the Program Counter (PC) under control of the microController, down to individual wires and gates. 2 Where We Are in The Big Stories Theory How do we model computational systems? Now: Not really a theory show… Hardware How do we build devices to compute? Now: Done! A full working computer! 3 Computer Strategy Instead of a new DFA circuit for each problem: 1. Make a DFA with “instructions” as input. 2. Design a set of instructions that combine to solve many problems 3. Solve new tasks with new instructions, not a new circuit. With appropriate instructions, this design is “universal”: it can perform any conceivable computation. (We won’t prove this, but we did see it implement basic Java instructions!) A “Normal” DFA as a Sequential Circuit Sequence of inputs DFA with a bunch of states and with output on arcs clk Sequence of outputs Ultra-High-Level CPU View: Fetch, Decode, Execute Cycle, as DFA DFA with LOTS of states and output on arcs Sequence of outputs clk A stored-program computer includes data and code in its memory. Load memory with code/data and start the machine, and it “acts out” its program. Load new code/data, and restart, and it “acts out” a totally different program! A stored-program computer can simulate any other computer that we can now practically or theoretically envision! Ultra-High-Level CPU View: Fetch, Decode, Execute Cycle Memory: code and data Next instruction and data Combinational Circuitry, esp. ALU and controller Data to use in next instruction Data to store back in memory Address of next instruction Accumulator (ACC) Program Counter (PC) ACC and PC are “registers”: extra little pieces of fast memory. Updates to address and new data CPSC 121’s “circuits story” From the bottom up... • we can build digital logic in physical devices (remember the water computers and switches?) • we can use logic gates to organize our digital circuits • we can organize logic gates into combinational circuits that calculate any logical function of their inputs (any truth table) • we can use feedback to create sequential circuits that remember values and act on events • we can implement any DFA using a sequential circuit • we can build a working computer: a DFA with configurable memory that determines its own next instruction, which can perform any conceivable computation Wow! Too bad it’s a pain in the butt to program in our computer’s language! If only... CPSC 111’s “programming story” From the top down: • we can design algorithms to solve an enormous variety of computational problems • we can encode those algorithms into programs in high-level programming languages • compilers and interpreters can automatically transform those programs into low-level programming languages Any guesses what those low-level programming languages might look like? Here’s one we already saw... Java Byte Code Part of our Java code: // Let's do something a hundred times. int i = 100; do { // Make i one smaller. i--; } while (i > 0); Here’s a typical “hex” view of ~1/5th of the program’s byte code. 10 CPSC 111’s + 121’s Story... High-level languages all the way down to physical devices that compute. What’s left? HUGE TREMENDOUS AMAZING AMOUNTS OF STUFF: Software engineering: implementing incredibly complex systems as programs and helping programmers manage that complexity. Human-computer interaction: understanding how people work with computers and designing interfaces that are effective for them. Systems: building structures on top of the machine that knit computers together and let people and programs communicate and collaborate effectively. Artificial intelligence: recognizing, extracting, and acting on high-level patterns in complex and meaningful ways. Theory: analyzing the capabilities and limitations of computing systems to accomplish all of these tasks. Computer engineering: redesigning the machine to more efficiently (in terms of speed, power consumption, size, memory usage, etc.) execute programs. (And so on...) Learning Goals: In-Class By the end of this unit, mostly from the lab, you should be able to: – Trace execution of an instruction through our computer: the basic fetch-decode-execute instruction cycle and the data flow to/from the arithmetic logic unit (ALU), the main memory, the Instruction Register (IR) and the Program Counter (PC) under control of the microController, down to individual wires and gates. 12 snick snack Extra Slides Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } SOMETHING that can run on a bare bones computer?? Java Memory Model Hardware Memory x y 5 1 (int) (int) ??? in a memory that is just a numbered list of locations. Java Memory Model Hardware Memory x y 5 1 (int) (int) Pick “slots” for x and y, say memory locations 0x100 and 0x101: 0x000 0x001 . . . 0x0FF 0x100 0x101 . . 5 1 Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Start translating ?? ?? ?? ?? ?? ?? ?? ?? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Start translating // Note: x is in 100 // Note: y is in 101 ?? ?? ?? ?? ?? ?? Available Instructions ADD SUB MUL DIV MOD addr: addr: addr: addr: addr: ACC ACC ACC ACC ACC LOAD STORE addr: addr: ACC = M[addr] M[addr] = ACC JUMP addr: BRANCH addr: = = = = = ACC ACC ACC ACC ACC + * / % M[addr] M[addr] M[addr] M[addr] M[addr] ACC stands for “accumulator”. It’s a little extra piece of memory called a “register”. Think of it as the place where we store scratch work. go to line addr if ACC == 0, go to line addr else, go to next line And.. that’s it. Note: we will usually call “addr” an “immediate” or “imm”. Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate x = 5. // Note: x is in 100 // Note: y is in 101 ?? ?? ?? ?? ?? ?? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate x = 5. // Note: x is in 100 // Note: y is in 101 // Start w/5 in 200. LOAD 200 STORE 100 ?? ?? ?? ?? ?? Most computers have an instruction that makes this easier like: LOADI imm: ACC = imm Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate y = 1. // Note: x is in 100 // Note: y is in 101 // Start w/5 in 200. LOAD 200 STORE 100 ?? ?? ?? ?? ?? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate y = 1. // Note: x is in 100 // Note: y is in 101 // Start w/5 in 200. // Start w/1 in 201. LOAD 200 STORE 100 LOAD 201 STORE 101 ?? ?? ?? ?? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate “while”. // Note: x is in 100 // Note: y is in 101 // 5 in 200, 1 in 201. LOAD 200 STORE 100 LOAD 201 STORE 101 ?? ?? ?? ?? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate “while”. // Note: x is in 100 // Note: y is in 101 // 5 in 200, 1 in 201. 0x0 LOAD 200 0x1 STORE 100 0x2 LOAD 201 0x3 STORE 101 0x4 ?? 0x5 ?? 0x6 ?? 0x7 ?? Let’s start by translating the end. What happens at the end of a loop? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate “while”. // Note: x is in 100 // Note: y is in 101 // 5 in 200, 1 in 201. 0x0 LOAD 200 0x1 STORE 100 0x2 LOAD 201 0x3 STORE 101 0x4 ?? 0x5 ?? 0x6 ?? 0x7 JUMP 4 At the end of a loop, we jump back to the start. Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate “while”. // Note: x is in 100 // Note: y is in 101 // 5 in 200, 1 in 201. 0x0 LOAD 200 0x1 STORE 100 0x2 LOAD 201 0x3 STORE 101 0x4 ?? 0x5 ?? 0x6 ?? 0x7 JUMP 4 Now the beginning. How do we make a choice? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate “while”. // Note: x is in 100 // Note: y is in 101 // 5 in 200, 1 in 201. 0x0 LOAD 200 0x1 STORE 100 0x2 LOAD 201 0x3 STORE 101 0x4 BRANCH 8 0x5 ?? 0x6 ?? 0x7 JUMP 4 Choose based on whether x equals 0... But what’s wrong with this? Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate the rest. // Note: x is in 100 // Note: y is in 101 // 5 in 200, 1 in 201. 0x0 LOAD 201 0x1 STORE 101 0x2 LOAD 200 0x3 STORE 100 0x4 BRANCH 8 0x5 ?? 0x6 ?? 0x7 JUMP 4 BRANCH chooses based on what’s in the accumulator. With the loads for x and y switched, what’s in the ACC is now x. Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate the rest. // Note: x is in 100 // Note: y is in 101 // Put 5 in 200, 1 in 201. 0x0 LOAD 201 0x1 STORE 101 0x2 LOAD 200 0x3 STORE 100 0x4 BRANCH A 0x5 LOAD 101 // 101 is y 0x6 MUL 100 // x 0x7 STORE 101 // back in y 0x8 ?? 0x9 JUMP 4 To multiply x and y, we load in y and multiply in x. Then, we store the result back into y. Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate the rest. // Note: x is in 100 // Note: y is in 101 // Put 5 in 200, 1 in 201. 0x0 LOAD 201 0x1 STORE 101 0x2 LOAD 200 0x3 STORE 100 0x4 BRANCH A 0x5 LOAD 101 // 101 is y 0x6 MUL 100 // x 0x7 STORE 101 // back in y 0x8 ?? 0x9 JUMP 4 Java Program Machine Program // Put 5! in y. int x; int y; x = 5; y = 1; while (x != 0) { y = y * x; x = x - 1; } // Translate the rest. // Note: x is in 100 // Note: y is in 101 // Put 5 in 200, 1 in 201. 0x0 LOAD 201 0x1 STORE 101 0x2 LOAD 200 0x3 STORE 100 0x4 BRANCH C 0x5 LOAD 101 // 101 is y 0x6 MUL 100 // x 0x7 STORE 101 // back in y 0x8 LOAD 100 // x 0x9 SUB 201 // 1 0xA STORE 100 // back in x 0xB JUMP 4 Same style as the last step. Note that we already had the constant 1 stored in address 201. Java Program Machine Memory // Put 5! in y. int x; int y; x = 5; y = 1; do { y = y * x; x = x - 1; } while (x != 0); 0x000 0x001 0x002 0x003 0x004 0x005 0x006 0x007 0x008 0x009 0x00A 0x00B . . 0x100 0x101 . . . 0x200 0x201 0x20000200 0x21000100 0x20000201 0x21000101 0x4100000C 0x20000101 0x12000100 0x21000101 0x20000100 0x11000201 0x21000100 0x40000004 . . 0x00000000 0x00000000 . . . 0x00000005 0x00000001 The opcode references gives us the first two hex digits of each instruction. The rest is just the hex numbers we already had.