1 00:00:00,989 --> 00:00:06,029 Having talked about the storage resources provided by the Beta ISA, let's design the 2 00:00:06,029 --> 00:00:08,580 Beta instructions themselves. 3 00:00:08,580 --> 00:00:12,809 This might be a good time to print a copy of the handout called the "Summary of Beta 4 00:00:12,809 --> 00:00:17,480 Instruction Formats" so you'll have it for handy reference. 5 00:00:17,480 --> 00:00:21,590 The Beta has three types of instructions: compute instructions that perform arithmetic 6 00:00:21,590 --> 00:00:26,960 and logic operations on register values, load and store instructions that access values 7 00:00:26,960 --> 00:00:32,830 in main memory, and branch instructions that change the value of the program counter. 8 00:00:32,830 --> 00:00:37,320 We'll discuss each class of instructions in turn. 9 00:00:37,320 --> 00:00:43,640 In the Beta ISA, all the instruction encodings are the same size: each instruction is encoded 10 00:00:43,640 --> 00:00:49,320 in 32 bits and hence occupies exactly one 32-bit word in main memory. 11 00:00:49,320 --> 00:00:54,620 This instruction encoding leads to simpler control-unit logic for decoding instructions. 12 00:00:54,620 --> 00:00:58,260 And computing the next value of the program counter is very simple: 13 00:00:58,260 --> 00:01:03,510 for most instructions, the next instruction can be found in the following memory location. 14 00:01:03,510 --> 00:01:07,770 We just need to add 4 to the current value of program counter to advance to the next 15 00:01:07,770 --> 00:01:09,280 instruction. 16 00:01:09,280 --> 00:01:14,000 As we saw in Part 1 of the course, fixed-length encodings are often inefficient in the sense 17 00:01:14,000 --> 00:01:19,609 that the same information content (in this case, the encoded program) can be encoded 18 00:01:19,609 --> 00:01:21,770 using fewer bits. 19 00:01:21,770 --> 00:01:26,408 To do better we would need a variable-length encoding for instructions, where frequently-occurring 20 00:01:26,408 --> 00:01:29,819 instructions would use a shorter encoding. 21 00:01:29,819 --> 00:01:35,090 But hardware to decode variable-length instructions is complex since there may be several instructions 22 00:01:35,090 --> 00:01:40,679 packed into one memory word, while other instructions might require loading several memory words. 23 00:01:40,679 --> 00:01:44,880 The details can be worked out, but there's a performance and energy cost associated with 24 00:01:44,880 --> 00:01:47,229 the more efficient encoding. 25 00:01:47,229 --> 00:01:52,520 Nowadays, advances in memory technology have made memory size less of an issue and the 26 00:01:52,520 --> 00:01:57,700 focus is on the higher-performance needed by today's applications. 27 00:01:57,700 --> 00:02:02,590 Our choice of a fixed-length encoding leads to larger code size, but keeps the hardware 28 00:02:02,590 --> 00:02:06,030 execution engine small and fast. 29 00:02:06,030 --> 00:02:11,540 The computation performed by the Beta datapath happens in the arithmetic-and-logic unit (ALU). 30 00:02:11,540 --> 00:02:16,290 We'll be using the ALU designed in Part 1 of the course. 31 00:02:16,290 --> 00:02:19,950 The Beta ALU instructions have 4 instruction fields. 32 00:02:19,950 --> 00:02:25,940 There's a 6-bit field specifying the ALU operation to be performed - this field is called the 33 00:02:25,940 --> 00:02:27,110 opcode. 34 00:02:27,110 --> 00:02:32,329 The two source operands come from registers whose numbers are specified by the 5-bit "ra" 35 00:02:32,329 --> 00:02:33,700 and "rb" fields. 36 00:02:33,700 --> 00:02:39,030 So we can specify any register from R0 to R31 as a source operand. 37 00:02:39,030 --> 00:02:44,020 The destination register is specified by the 5-bit "rc" field. 38 00:02:44,020 --> 00:02:49,120 This instruction format uses 21 bits of the 32-bit word, the remaining bits are unused 39 00:02:49,120 --> 00:02:51,540 and should be set to 0. 40 00:02:51,540 --> 00:02:55,510 The diagram shows how the fields are positioned in the 32-bit word. 41 00:02:55,510 --> 00:03:00,360 The choice of position for each field is somewhat arbitrary, but to keep the hardware simple, 42 00:03:00,360 --> 00:03:05,980 when we can we'll want to use the same field positions for similar fields in the other 43 00:03:05,980 --> 00:03:07,360 instruction encodings. 44 00:03:07,360 --> 00:03:14,470 For example, the opcode will always be found in bits [31:26] of the instruction. 45 00:03:14,470 --> 00:03:17,400 Here's the binary encoding of an ADD instruction. 46 00:03:17,400 --> 00:03:24,940 The opcode for ADD is the 6-bit binary value 0b100000 - you can find the binary for each 47 00:03:24,940 --> 00:03:28,870 opcode in the Opcode Table in the handout mentioned before. 48 00:03:28,870 --> 00:03:34,790 The "rc" field specifies that the result of the ADD will be written into R3. 49 00:03:34,790 --> 00:03:40,260 And the "ra" and "rb" fields specify that the first and second source operands are R1 50 00:03:40,260 --> 00:03:42,620 and R2 respectively. 51 00:03:42,620 --> 00:03:48,660 So this instruction adds the 32-bit values found in R1 and R2, writing the 32-bit sum 52 00:03:48,660 --> 00:03:51,270 into R3. 53 00:03:51,270 --> 00:03:56,320 Note that it's permissible to refer to a particular register several times in the same instruction. 54 00:03:56,320 --> 00:04:02,090 So, for example, we could specify R1 as the register for both source operands AND also 55 00:04:02,090 --> 00:04:04,470 as the destination register. 56 00:04:04,470 --> 00:04:10,380 If we did, we'd be adding R1 to R1 and writing the result back into R1, which would effectively 57 00:04:10,380 --> 00:04:14,860 multiply the value in R1 by 2. 58 00:04:14,860 --> 00:04:20,969 Since it's tedious and error-prone to transcribe 32-bit binary values, we'll often use hexadecimal 59 00:04:20,969 --> 00:04:25,830 notation for the binary representation of an instruction. 60 00:04:25,830 --> 00:04:32,240 In this example, the hexadecimal notation for the encoded instruction is 0x80611000. 61 00:04:32,240 --> 00:04:40,300 However, it's *much* easier if we describe the instructions using a functional notation, 62 00:04:40,300 --> 00:04:44,080 e.g., "ADD(r1,r2,r3)". 63 00:04:44,080 --> 00:04:47,560 Here we use a symbolic name for each operation, called a mnemonic. 64 00:04:47,560 --> 00:04:52,749 For this instruction the mnemonic is "ADD", followed by a parenthesized list of operands, 65 00:04:52,749 --> 00:04:59,460 in this case the two source operands (r1 and r2), then the destination (r3). 66 00:04:59,460 --> 00:05:05,199 So we'll understand that ADD(ra,rb,rc) is shorthand for asking the Beta to compute the 67 00:05:05,199 --> 00:05:10,629 sum of the values in registers ra and rb, writing the result as the new value of register 68 00:05:10,629 --> 00:05:12,569 rc. 69 00:05:12,569 --> 00:05:17,039 Here's the list of the mnemonics for all the operations supported by the Beta. 70 00:05:17,039 --> 00:05:21,650 There is a detailed description of what each instruction does in the Beta Documentation 71 00:05:21,650 --> 00:05:22,810 handout. 72 00:05:22,810 --> 00:05:27,301 Note that all these instructions use same 4-field template, differing only in the value 73 00:05:27,301 --> 00:05:29,719 of the opcode field. 74 00:05:29,719 --> 00:05:33,650 This first step was pretty straightforward - we simply provided instruction encodings 75 00:05:33,650 --> 00:05:38,159 for the basic operations provided by the ALU. 76 00:05:38,159 --> 00:05:42,800 Now that we have our first group of instructions, we can create a more concrete implementation 77 00:05:42,800 --> 00:05:44,319 sketch. 78 00:05:44,319 --> 00:05:46,430 Here we see our proposed datapath. 79 00:05:46,430 --> 00:05:51,639 The 5-bit "ra" and "rb" fields from the instruction are used to select which of the 32 registers 80 00:05:51,639 --> 00:05:55,060 will be used for the two operands. 81 00:05:55,060 --> 00:06:01,650 Note that register 31 isn't actually a read/write register, it's just the 32-bit constant 0, 82 00:06:01,650 --> 00:06:06,800 so that selecting R31 as an operand results in using the value 0. 83 00:06:06,800 --> 00:06:11,219 The 5-bit "rc" field from the instruction selects which register will be written with 84 00:06:11,219 --> 00:06:14,069 the result from the ALU. 85 00:06:14,069 --> 00:06:19,020 Not shown is the hardware needed to translate the instruction opcode to the appropriate 86 00:06:19,020 --> 00:06:24,270 ALU function code - perhaps a 64-location ROM could be used to perform the translation 87 00:06:24,270 --> 00:06:25,979 by table lookup. 88 00:06:25,979 --> 00:06:30,430 The program counter logic supports simple sequential execution of instructions. 89 00:06:30,430 --> 00:06:35,729 It's a 32-bit register whose value is updated at the end of each instruction by adding 4 90 00:06:35,729 --> 00:06:37,409 to its current value. 91 00:06:37,409 --> 00:06:40,860 This means the next instruction will come from the memory location following the one 92 00:06:40,860 --> 00:06:43,789 that holds the current instruction. 93 00:06:43,789 --> 00:06:47,069 In this diagram we see one of the benefits of a RISC architecture: 94 00:06:47,069 --> 00:06:51,330 there's not much logic needed to decode the instruction to produce the signals needed 95 00:06:51,330 --> 00:06:52,750 to control the datapath. 96 00:06:52,750 --> 00:06:56,389 In fact, many of the instruction fields are used as-is!