Introduction
to Digital Logic and Computer Design
Register Transfer Language
Register Transfer Language, RTL, (sometimes called register transfer
notation) is a powerful high level method of describing the
architecture of a circuit. VHDL code and schematics
are often created from RTL. RTL describes
the transfer
of data from register to register, known as microinstructions or
microoperations. Transfers may be conditional.
Each microinstruction completes in one clock
cycle.
A typical RTL statement will look like the following:
A v B --> R1 <-- R2;
This is read as "if signal A or signal B is true then register R2 is
transferred to register R1". The first part, A v B, is a
logical
expression that must be true for the transfer to take place.
The
--> symbol separates the logical expression from the
microinstruction. It is the if-then part of the statement.
If there isn't a logical expression, --> isn't in the
statement and the microinstruction will always take place. To
the
right of --> is the microinstruction. It describes a
transfer
of data and operations on the data from register to register.
The
above RTL statement is equivalent to the following schematic:
For RTL we will use the following symbols:
<-- |
Register transfer |
[ ] |
Word index |
< > |
Bit index |
n..m |
Index range |
--> |
If-then |
:= |
Definition |
# |
Concatenation |
: |
Parallel separator |
; |
Sequential separator |
@ |
Replication |
{ } |
Operation modifier |
( ) |
Operation or value grouping |
= != < <= > >= |
Comparison operators |
+ - * / |
Arithmetic operators |
^ v ' xor |
Logical operators |
RTL examples
Example 1
K1 --> R0 <-- R1 : K1' ^ K2 --> R0 <-- R2 ;
Example 2
R0 <-- R1 + R2' + 1
The above circuit is equivalent to R0 <-- R1 - R2
We will learn RTL with a very simple processor called a "special math
processor".
Special Math Processor
Processor Diagram
Processor State (using RTL)
RA<15..0>:
Register A (input to multiplier and adder)
RB<15..0>:
Register B (input to multiplier and adder)
RC<15..0>:
Register C (output from multiplier or adder)
PC<7..0>:
Program Counter (Address of next instruction)
RI<7..0>:
Register I (memory index register)
IR<11..0>:
Instruction Register
Reset:
Reset signal
op<3..0> := IR<11..8>: Operation
code field
M[255..0]<15..0>:
Main memory 255 words.
Processor Schematic
Processor Instructions
Instructions 0 through 3 are memory/register transfers
Instructions 4 is a register to register transfer
Instructions 5 through 8 are math instructions
Instruction 9 through B are processor control instruction
Code |
Instruction Syntax |
Operation |
0x00XX |
load RA=[XX+RI] |
Load RA from M[XX+RI<7..0>] |
0x01XX |
load RB=[XX+RI] |
Load RB from M[XX+RI<7..0>] |
0x02XX |
load RI=[XX] |
Load RI from M[XX] |
0x03XX |
load [XX+RI]=RC |
Load M[XX+RI<7..0>] from RC |
0x04XX |
mov RB=RC |
Move RC to RB |
0x05XX |
add |
Add RA and RB and put in RC |
0x06XX |
mult |
Multiply RA and RB and put in RC |
0x07XX |
inc |
Increment RA and put in RC |
0x08XX |
dec |
Decrement RA and put in RC |
0x09XX |
jmp XX |
Jump to XX |
0x0AXX |
jz XX |
Jump to XX if RI is zero |
0x0BXX |
halt |
Halt |
Fetch Execute Cycle (using RTL)
instruction_interpretation
:= (Reset --> (PC <-- 0: IR <-- 0: RI <--
0: RA <-- 0:
RB <-- 0: RC <-- 0); instruction_interpretation):
Reset' --> (IR
<-- M[PC<7..0>]<11..0>: PC
<-- PC + 1; instruction_execution))
instruction_execution := ( (ldra (:= op = 0) --> RA <--
M[(IR<7..0>+RI<7..0>)^0xff]:
Continue with remaining opcodes:
halt (:= op = 11) -->
instruction_execution);
instruction_interpretation)
Possible RTL Microinstructions
PC <-- 0x00
PC <-- IR<7..0>
PC <-- PC + 1
RA <-- M[(IR<7..0>+RI<7..0>)^0xff]
RB <-- M[(IR<7..0>+RI<7..0>)^0xff]
RB <-- RC
RC <-- RA - 1
RC <-- RA + 1
RC <-- RA * RB
RC <-- RA + RB
RI <-- M[IR<7..0>]<7..0>
RI <-- 0x00
IR <-- M[PC<11..0>]
IR <-- 0x00
M[(IR<7..0>+RI<7..0>)^0xff] <-- RC
Writing Assembly language programs for the special math
processor
Download the proc program
Here is the Windows proc executable.
You should
be able to download it using shift-left_mouse_button.
Here is the C++ source code
for the proc program.
On most Unix type systems with a C++ compiler just type:
make proc
Make sure the source filename has the correct extension for
your system.
Most Unix type systems use either a .C, .cxx, or .cpp extension.
You shouldn't need to edit much of the proc.cpp source. One
thing you may want
to do is increase the start-stop range of memory that is printed when
the
program ends. The function call, m_proc::print_memory() is near the end
of the file in the main() function. Just change the start and stop
arguments
to suit your needs and remake your program as shown above.
Let me know how well this program works for you along with any
changes you
would like to see. Don't forget to check back here often for updates.
Compiler Directives
Except for comments there can be only one compiler directive or
processor
instruction per line and the directive/instruction must be contained in
that
one line. Comment directives can appear on the same line as any
other instruction. As the program is compiled the address is
incremented after each data directive or processor instruction.
Directive |
Syntax |
Description |
Origin |
org: 0xXX |
Fixes memory address of next processor instruction or
data statement. |
Label |
label: |
A label that is translated to the current address
during compile time for use in load and jmp statements. |
Data |
0xXXXX |
Load data at current memory address. |
Comment |
! |
Begins a comment to end of line and can appear anywhere. |
Processor Emulation
Step 1. Edit your assembly program file with the instruction and data
you
want to run.
Step 2. You will need to open up a command prompt window,
change
directory to where the proc.exe (proc for unix/linux) file is located.
Step 3. Run your program with one of the following commands:
proc program_filename > output.txt
proc program_filename
The output of the proc program will be put in output.txt file
or standard out.
Sample Processor Programs