16-/32-bit RISC
Even today, the venerable 68K is used as a measure of code density.
Many consider the 68K to set the standard for acceptable embedded system
code density. The 68K design team made a number of very effective architectural
decisions, decisions that have proved themselves over time.
The key design parameters for the 68K was that it had a 32-bit data
path (originally 32-bit registers with a 16-bit ALU and 16-bit memory interface)
and 16-bit instructions. Most instructions fit into 16-bits with extensions
for addressing and immediate data. This combination of 16-bit instructions
and 32-bit data gave the 68K 32-bit processing power with roughly 16-bit
ISA code density.
On the other hand 32-bit RISCs were designed to create a very tight
register-to-ALU cycle, a fast execution. To do this RISC designers minimized
the instruction set -- the less instructions, the less logic depth, and
thus faster execution. These techniques resulted in much simpler ISAs,
some with fewer than 50 basic instructions; and in load-store architectures
where most processing takes place between registers, and the only memory
operations are load/store of registers.
Crafting a 16-bit ISA from a 32-bit RISC ISA is not trivial. The smaller
instruction word has smaller fields. Thus, it can only execute a smaller
set of instructions using a smaller register set since the OP code field
and register fields need to reduce to create 16 bit instructions.
The first dynamic 16-/32-bit RISC was the brain child of the ARM design
team. They came up with Thumb, which took a very clever approach to running
a 16-bit ISA. The trick was to pick a 16-bit subset of the 32-bit ARM ISA,
with less registers and instructions to reduce the field sizes. All instructions,
16- and 32-bit, enter the CPU the same, but when a special mode bit is
set, the decoder decodes the 16-bit ISA, not the 32-bit ISA. The decoded
instructions are then passed through an expansion block, that expands the
decode to the 32-bit form, and the decoded 16-bit instructions are then
passed on to the next stage in the pipeline. The 16-bit instructions are
retrieved, decoded and then expanded to 32-bit instructions for execution.
The MIPS-16 takes a similar approach. Figure 2
shows the decode expansion block that expands the 16-bit instructions to
32-bitters.
The dynamic 16-/32-bit RISCs are different than some RISCs like the
Hitachi SH series. Those have fixed 16-bit ISAs and a 32-bit datapath.
The ARM Thumb and the MIPS-16 are 32-bit machines that can dynamically
switch to run with a reduced 16-bit ISA. A mode or status bit sets 16 or
32-bit ISA mode. That bit cannot be set at any time during execution. It
can only be set during a call or return, insuring that 16- or 32-bit ISA
operation is defined at the function or subroutine level, or higher.
The key to dynamic 16-/32-bitters is their compilers. They run compiled
code and the compiler compiles 16- or 32-bit ISA code. A switch or flag
is set, and that indicates whether to compile a function or file as 16-
or 32-bit code. With the GNU MIPS-16 assembler/compiler, the switch is
-mips16'. The decision of what is 16- or 32-bit ISA code is made
at compile time, not runtime. However, the generated code will set the
proper ISA mode bit when switching from 32- to 16-bit code or vice versa.
|