This document describes the purpose and design methodology of the Small
Stack-Based Computer Compiler (SSBCC).
The system is designed to run a Forth-like assembly.
Introduction
The purpose of the SSBCC is to generate small microcontrollers for use in
FPGAs. This computer compiler is designed to generate FPGA-vendor
independent systems in either Verilog or VHDL. The resulting micro
controller is described by a single HDL file containing the processor core,
the program, data stack, return stack, and variable memory.
The archive consists of the computer compiler, micro computer cores and
assemblers, and libraries.
Processor Architecture
TODO -- RFS: describe the general architecture
8-bit Processor Example
This section demonstrates how to generate a 8-bit processor with 9-bit wide
instructions. The 8-bit data width was chosen because it is characteristic
of embedded systems controlling other processes and generating ascii output.
The 9-bit data width was chosen because the FPGAs produced by the three
major FPGA vendors produce memories with 8-bit data widths.
The processor is described by a regular text file with the following contents:
- A description of the program memory, the stack memory, the return
stack memory, the variable memory, and the I/O ports.
This part of the processor may be FPGA-dependent. For example, Altera's
Cyclone III FPGAs do not have distributed memory, so short memories in
those FPGAs are either extremely inefficient or are converted into an
M9K, in which case you ought to state that an M9K is going to be used
anyway. As another example, Xilinx' Spartan 6 has 6-input
LUTs that can be used as distributed memory, so a 128-word program can
be efficiently stored in 18 LUTs instead of occupying a precious
Block RAM. Additionally, if the program is between 129 and 192 words,
i.e., it would fit in 3 64x9 LUTs, then the program ROM can be
described as such, saving 9 LUT in this case.
- An instruction to load the processor core and its intrinsics.
This instruction loads the HDL instantiating processor core, i.e., its
opcode interpretation, ALU, stack manipulation, etc.
This instruction also loads the list of Forth operations supported
natively by the processor core and the instructions on how to construct
the machine opcodes from those instructions.
For example, the '+' instruction is translated directly to the
opcode 0_XXXX_XXXX.
TODO -- RFS: fill in the "X"s above.
As another example, the 9-bit opcodes for this particular machine use
a leading bit of '0' to indicate that an 8-bit value is to be
pushed onto the stack. An 8-bit opcode cannot put the full range
of 8-bit values onto the stack in a single instruction. Instead, a
7-bit, positive value is pushed onto the stack and then, if this is
not the desired value, an "invert" instruction immediately
follows and is used to invert the leading bit of the of the top of the
stack.
- An optional instruction to load definitions of the remaining Forth
instructions.
For example, a processor core could implement the Forth instructions
"0<" and "0=" and none of the remaining
comparison operators "0<=", "0>",
"0>=", and "0<>". The optional instructions
would include statements like:
: 0
Processor Description Syntax
Memory Description
Core Description Syntax
Opcode List
This section lists the opcodes and describes how the compiler is to
implement them.
TODO -- RFS: Determine this syntax
HDL Section(s)
Each of these sections lists the processor core implementation in the
specified language.
The languages currently supported by the compiler are Verilog and
VHDL.
Syntax: HDL {Verilog|VHDL} ... ENDHDL
Example:
HDL Verilog
always @ (posedge i_clk) begin
s_stack_addr <= s_stack_addr;
if (s_opcode[C_NBITS_OPCODE-1] = 1'b0) begin
s_stack[s_stack_addr] <= s_opcode[C_NBITS_OPCODE-2:0];
s_stack_addr <= s_stack_addr + 1;
else
end
end
ENDHDL