Bar
SpaceWire UK
Specialist providers of VHDL Intellectual Property & Design Services
BarBarBarBar
Raptor-16 Assembler
The Raptor-16 Microprocessor Assembler looks and acts just like a static RAM for simulation, the main difference is that instead of it containing a pre-set content, it reads an assembly source file, compiles it and uses that to make up its content. Once compiled, the RAM content is written out to a number of Xilinx RAM files (CoreGen & initialized VHDL) that can then be used during the implementation phase to initialize the Block RAM's that make up the embedded (on-chip) memory.

It is entirely up to the user whether they want to simulate the Raptor-16 with the compiled source code or just use the Assembler to create the Xilinx RAM content file and then test the compiled code in hardware.

Although the Assembler does not offer all the features of commercial packages, it can detects and report syntax errors, provide warnings about optimizations and also produce binary listings. All these options are controlled by constants in the Behavioural VHDL.

Below are some brief details of things that are not fully covered by the examples in the Instruction Set.



Numbers
Numbers are used for both instructions and data and can be represented in three different forms; binary, decimal and hexadecimal.
  • Binary numbers start with a percent sign and are followed by 1's and 0's.
  • Decimal numbers start with a number and are followed by other numbers.
  • Hexadecimal numbers start with a dollar sign and are followed by 0-9 and A-F characters.
All number representations are extended by the Assembler to a full 16-bit value. Negative numbers can be used by adding a minus sign on the front of decimal number, however this is not allowed for Binary and Hexadecimal. To create a negative Binary or Hexadecimal number the full 16-bit value should be written in 2's compliment form.

Examples:-


Move #2048,SP ; Positive decimal number
LoadQ #-70,A0 ; Negative decimal number
Move $30(A4),D0 ; Positive hexadecimal number
MoveQ #$FFFF,D5 ; Negative hexadecimal number
AndQ D0,%011(A3) ; Positive binary number
And #%1000000100000011,D0 ; Negative binary number

Bytes 255, -128, 127, $FF, %11001100, 65, $55, %100
Words %11, $A, $00FF, 3, -32000, %0001, $FFFF, 45



Data
Data is created by using two commands; bytes and words, that define 8-bit and 16-bit values respectively. Both commands are used in exactly the same way and can be followed by any number of values separated by commas.

The bytes command supports an additional text string mode that can be used to create strings of text. Defining these strings is simply done by enclosing them in quotes. The bytes command does have a word-alignment restriction, that means an even number of bytes must follow the command.

The words command supports a additional pointer mode that can be used to create pointers within data. These pointers can point to anything that is labelled in the source code, be it code or other data.

Examples:-

SomeText Bytes "Hello World!", 13, 10, 0, 0 ; A string of text
SomeData Bytes 10, 20, 35, 64, 77, 84 ; A sequence of bytes
NewText Bytes "Hello",13,"There",13,0,0 ; A mixed byte sequence

Wordy Words $FFFF, $FFFE, 55, 65 ; A sequence of words
Something Words 40, -50, SomeText, -65 ; A mixed word sequence



Labels
Labels are used to mark lines in source code, that can then be referenced by instructions or data. A label is made up of alphabetical characters only and when used to mark a line must start on the very first character of that line. Referencing a label is simply achieved by using its name. The only restriction labels have is when they are used to mark lines, in this case they must be followed by either an instruction or data.

Working Example:-

DoStack Move #2048,SP ; Set-up Stack Pointer

Caller LoadQ #List,A0 ; Get address of data labelled by 'List'
Move Length(PC),D0 ; Get data from location labelled by 'Length'
BsrQ Average ; Branch to subroutine labelled by 'Average'

Infinite BraQ Infinite ; Something useful would go here...

Average MoveQ #0,D1 ; Set total to 0
Loop Add (A0)+,D1 ; Add list element to total
SubQ #1,D0 ; Decrement length
BraQ zrc,Loop ; Branch to location labelled by 'Loop' if length > 0
ShrQ #1,D1 ; Half total to get average
Rts ; Return

List Words 3, 406, 44, 60, 55, 10
Length Words 6



Commas
Commas are used to separate instruction operands and data values and can have any number of spaces before and after them, including none at all. The only restriction commas have is that something must follow them, unless they are inside a comment block.



Comments
Comments are used typically to describe code or to prevent code from being compiled. A comment can be inserted anywhere within the source code and is started with a semi-colon. The Assembler ignores everything that follows a semi-colon up to the end of the line where it appears. The only restriction comments have is when they follow instructions or data, at least one space must separate the end of an instruction or data from the start of a comment.

Working Example:-


Move #2048,SP ; Set-up Stack Pointer

LoadQ #DataA,A0 ; Set A0 to point to array 1
LoadQ #DataB,A1 ; Set A1 to point to array 2
BsrQ Adder ; Branch to add routine

; Something useful would go here...

Infinite BraQ Infinite ; Repeat forever

; Add together the values from two arrays and return the result in D0.
; A0 contains the pointer to array 1 and A1 contains the pointer to array 2.
; Both pointers are incremented by the subroutine ready for the next call.

Adder Move (A0)+,D0 ; Get value from array 1 and increment its pointer
Add (A1)+,D0 ; Add value from array 2 and increment its pointer
Rts ; Return from subroutine

;Adder Move (A0)+,D0 ; This code will not be compiled
; Add (A1)+,D1 ; This code will not be compiled
; Rts ; This code will not be compiled

DataA Words 302, 12, 59 ; Array 1 Data
DataB Words 100, 332, 1045 ; Array 2 Data



Options
The Raptor-16 Assembler (assembler.vhd) contains a number of options that can be changed by the user, these are described below.

Option Description
assembly_file Sets the filename of the source code that is to be compiled by the Assembler.
sp2_file Sets the filename of the Xilinx Spartan 2/2E initialized Block RAM VHDL that will be created by the Assembler.
sp3_file Sets the filename of the Xilinx Spartan 3 initialized Block RAM VHDL that will be created by the Assembler.
source_path Sets the location where the Xilinx Spartan 2/2E & 3 initialized Block RAM VHDL files will be written.
coe_file Sets the filename of the Xilinx CoreGen RAM Content (COE) that will be created by the Assembler.
xco_file Sets the filename of the Xilinx CoreGen RAM Configuration (XCO) that will be created by the Assembler.
coregen_path Sets the location where the Xilinx CoreGen RAM files will be written.
ram_size Sets the size of the RAM that is to be used to contain the compiled source code. This must be either 256, 512, 1024, 2048 & 4096, 8192, 16384, 32768 or 65536.
max_label_entries Sets the maximum number of labels that can be used in the source code.
max_label_length Sets the maximum number of characters that a label can have.
max_code_lines Sets the maximum number of lines that the source code can have.
max_code_length Sets the maximum character length that a source code line can be.
debug_msg When TRUE the Assembler will display the binary listing as it compiles the source code.
opt_msg When TRUE the Assembler will display all source code optimizations it finds.