The Electrical Engineer’s Guide to Instruction Set Architectures (ISAs)
This article explores some important details related to the design and functionality of processors.
This article explores some important details related to the design and functionality of processors.
There are few electrical engineers these days who do not regularly interact, at least indirectly, with embedded processors. Almost any design can benefit from the presence of a small microcontroller and, in many cases, there is need for a powerful microcontroller, a digital signal processor, or an embedded computer. These processors have transformed electronic design, and actually they have transformed the entire world.
There is no doubt that an engineer can successfully implement an embedded processor while knowing almost nothing about its low-level details. However, it is usually beneficial to have at least some understanding of the internal functionality of the integrated circuits that we use in our designs, and this applies to microprocessors as well. Also, a solid familiarity with the basic principles of processor design might help you to determine which devices are more appropriate for a given system.
CPU vs Processor vs Microprocessor
Terminology is helpful when it’s used consistently, so let’s define some relevant terms:
- A CPU (central processing unit) consists of a datapath and a control unit.
- The datapath is the place where binary data is manipulated by means of arithmetic operations, bit-shifting, and so forth.
- The control unit is responsible for managing the flow of data and generating control signals that cause the datapath to perform the operations specified by the instruction.
- A processor consists of a CPU and additional components that help the CPU to function more efficiently and to interact with the surrounding system. It seems to me that the bare minimum needed to turn a CPU into a processor is some memory and the logic required to manage the movement of data between the memory and the CPU. However, memory isn’t very useful unless you also have an input/output system that allows other ICs to write data into the memory or read data out of the memory.
- A processor isn’t necessarily a single device, and this is what distinguishes a processor from a microprocessor. Whereas a processor could be composed (for example) of separate CPU and memory modules connected via ribbon cables, a microprocessor will always be an integrated circuit.
- A microcontroller is an integrated device that combines a microprocessor with hardware-based peripherals (such as analog-to-digital converters, timers, and serial-communication circuitry).
What Is Machine Language?
So what language does a processor speak? Processors do not understand the lines of code that we call “software” or (in the case of embedded processors) “firmware,” and this is true even if you still belong to the rapidly dwindling group of engineers who use assembly language.
Processors speak machine language, i.e., the binary instructions that are stored in the program memory and implemented by the control unit. A machine-language instruction is composed of different fields:
- The essential field is the opcode (short for operation code). This sequence of bits tells the processor which particular action to perform (e.g., add two numbers, increment a register value, jump to a particular instruction).
- Other possible fields include a register number or memory location in which to store data, a numerical value (e.g., for mathematical operations), and an address in program memory. Numerical values are referred to as immediate data.
An example of a three-byte machine-language instruction.
Again, these fields are simply binary numbers. If you look at machine language, it is a mind-numbing collection of ones and zeros. The human version of machine language is called assembly language, which has intuitive combinations of letters (such as ADD, MOV, and JMP) instead of binary opcodes and uses decimal or hexadecimal numerals instead of binary numerals.
Examples of assembly-language instructions, taken from this Silicon Labs datasheet.
Reading and interpreting these instructions is doable but not particularly easy or enjoyable, and if you spend a lot of time working in assembly you will readily understand the popularity of high-level languages such as C.
Is a Processor a Device or a Design?
The definition given above implies that a processor is a specific, tangible electronic unit that uses memory, input/output, and a CPU to perform computational tasks. This is certainly true, but it also reflects a somewhat confined and perhaps antiquated perspective: confined, because it doesn’t account for the fact that the physical implementation of a processor isn’t necessarily an inherent part of that processor’s functionality; and antiquated, because nowadays a “processor” could be nothing more than a stream a bits that is loaded into an FPGA.
At this point I want to introduce the concept of an instruction set architecture (ISA). As the name implies, an ISA refers to a group of machine-language instructions and to the various functional details that combine this group of instructions into a coherent processing architecture. However, let’s go a step further and try to understand that, from a certain point of view, an ISA is a processor.
What I mean by this is the following: Things like package dimensions, pin count, transistor size, memory organization, and data bus implementation are not essential aspects of a processor. If the goal is to study the performance and characteristics of the processor itself, we need to focus on the ISA.
The Importance of the Instruction Set
Those of us who are accustomed to writing firmware for microcontrollers might be inclined to view instructions as merely one component of what makes a processor perform the required tasks. We have clocks, ADCs, serial I/O, supply-voltage monitors, etc., all of which work in conjunction with our C statements to create a fully functional embedded device. However, in the context of processors themselves, instructions are defining characteristics.
I can’t express this concept better than by quoting the following sentence that I found in an old textbook on digital design: “The logical structure of computers is normally described in assembly language reference manuals.” The assembly language, along with the way in which the processor implements this language, is the description of the processor’s internal functionality. Thus, you don’t (fully) understand how a particular processor really works until you understand the format, behavior, and implementation of its assembly-language instructions. In other words, you learn about a processor by studying its ISA.
RISC vs. CISC
This discussion of the defining nature of an instruction set architecture helps us to understand why a fundamental approach to processor categorization is based on the difference between a reduced instruction set computer (RISC) and a complex instruction set computer (CISC).
The following is my attempt to briefly summarize the characteristics of these two architecture types:
- RISC processors emphasize generic instructions that correspond to the more basic computational operations and that are more uniform in length and execution time. Implementation of the instructions is highly optimized, and pipelining is used to increase execution speed. More registers are included so that memory use can be minimized (instructions that access memory tend to be rather slow).
- CISC processors emphasize specialized instructions that can more directly implement the complex operations used in software. This makes it easier to translate from high-level languages to assembly and was an important consideration in the days before sophisticated compilers. Complex instructions also require less memory—for example, a RISC processor might need three instructions to perform the tasks that a CISC processor would do in response to one instruction.
A thorough comparison of the performance capabilities of RISC and CISC implementations would probably require a book rather than an article, but I think it’s fair to say that RISC is currently seen as the preferred architecture for most applications. Also, it’s important to point out that processors are not limited to the “RISC vs. CISC” mentality that we naturally adopt in the context of technical discussions and evaluations. Computer engineers can incorporate aspects of both architectures based on the intended use of the processor or other design constraints.
A diagram of an 8051 processor, taken from this Silicon Labs datasheet. I would say that the 8051 is primarily a CISC architecture.
Studying an ISA
You’re not likely to ever find yourself in a situation where your only means of assessing a particular processor is to read the entire instruction set manual. The manufacturer would, of course, be happy to indicate which devices are considered more suitable for a given application, and you might also have access to colleagues or supervisors whose experience would be far more valuable than an afternoon (or several afternoons) spent slogging through assembly-language minutiae.
Nevertheless, it’s worthwhile to develop some familiarity with ISA characteristics and how these might influence the performance or implementation of a given processor. Even if the information simply helps you to understand why a processor was designed a certain way, you are at least gaining insights that are increasingly relevant to electrical engineering. And of course you never know when you might decide to sit down and design your own FPGA-based soft processor...
Some Examples from RISC-V
One ISA that is attracting significant attention is called RISC-V. I honestly don’t know if there’s anything particularly innovative about its architecture or functionality, but it has a rather unusual characteristic among sophisticated processor architectures: it’s completely free and open source.
An example of a RISC-V-based processor. This is the RV12 architecture from Roa Logic.
This doesn’t mean that the physical processor device will be free; running a semiconductor fabrication plant is not exactly cheap, and one way or another someone has to pay for the chip that comes off the assembly line. The architecture, however, is available to everyone and can be freely used for any purpose.
The RISC-V Instruction Set Manual is 145 pages and is not exactly light reading. It’s a great resource, though, and I want to conclude this article by discussing some randomly selected characteristics of the RISC-V ISA.
- Address space (page 16 of the PDF file): The RISC-V architecture supports 32-bit and 64-bit address spaces, and it has been designed so as to ensure future compatibility with a 128-bit address space. However, the designers believe that a 32-bit address space is and will continue to be adequate for many applications, and it is the preferred implementation for low-power embedded devices because it reduces power consumption.
- Read-only counters (page 35): The specification considers three 64-bit read-only counters to be essential components of any RISC-V implementation. They don’t provide typical counter functionality because the user cannot modify the count value. Rather, these counters track processor activity and elapsed time, and they’re intended to ensure that the user has access to information that facilitates performance analysis and optimization.
- Miniaturization (page 39): RISC-V’s “RV32E” instruction set is a reduced version of the standard “RV32I” instruction set. It’s intended for embedded systems, where PCB real estate is often a scarce commodity. RV32E has 16 general-purpose registers (instead of the 32 registers used in RV32I), and apparently this modification can reduce the area required for the processor core by 25%.
- Error handling (page 48): Processors can incorporate an automatic response to error conditions; a “trap,” for example, causes program control to be transferred to a trap handler when some sort of problematic event occurs. This feature could be seen as desirable or undesirable based on the requirements and constraints of a given system. The designers of the RISC-V architecture chose to not implement a trap for divide-by-zero events, which means that in some cases the code must include an additional branch instruction for error handling.
Processor design involves specialized knowledge and skills that are not a high priority for most electrical engineers. However, knowledge of the basic principles and techniques can help us to understand the microcontrollers and DSPs that so frequently appear in our designs and to assess the pros and cons of different instruction set architectures.