Professional Documents
Culture Documents
Introduction
This document is a quick introduction for creators of nanoprograms. All examples in this
document may be directly processed by nsim. Compile by `nsim my_program -b', debug by
`nsim my_program -i'.
Instructions are defined by `#define' directive. Before the first definition, there must be
`#instrlen' directive which determines the length of an instruction in bits.
Let's have a look at instruction1. It has two parameters; par1 is two bits long and par2 is three
bits long. Operation code is split by par1 into two parts: 11 and 01. The last three bits of
instruction1 are undetermined.
Writing a nanoprogram
Nanoprograms are written in programming language called Nanoprocessor Assembler (or shortly
Nanoassembler). Its full specification is available through [2] in REFERENCES. Following
examples will introduce you to its most important constructs.
This definition utilizes two most important automatic variables: ip (instruction pointer), code1
(compiled instruction). List of all automatic variables is in Appendix A of [1].
Often, we need to store the state of nanoprogram in a memory; usually, we emulate a memory
that actually exists in hardware. Following example shows how to declare a global variable.
Simulation of inputs and outputs is an important issue. One possible solution will be shown -- we
will only use two nanoprocessor assembler directives. The first one references a file with C
functions. The second one defines the initial part of the interpreter.
Important! There should not be any definitions of C variables below the initial part of the
interpreter.
The basic debugging functionality is to check and control the run of a program by the means of
instruction pointer and line number. The next step is to inspect whether the nanoprogram returns
correct results. That may be done by reading the file that stores output (see Example 8 in this
file). Another way is to check memory contents on the fly. The debugger can manage three
memories: input memory, internal memory and output memory and accesses them linearly. To
identify and handle these memories, nanoprocessor assembler source code must contain these
directives:
#define { #define PRINT_MEM memory}
#define { #define PRINT_TYPE type}
#define { #define PRINT_MIN minimum_address}
#define { #define PRINT_MAX maximum_address} Directives regarding input and output
memory are analogous, just replace PRINT by PRINTIN or PRINTOUT, respectively. These
directives are recommended to be placed in the file with instruction definitions.
If we debug a program that contains (directly or by the means of #include) definitions from
Example 9, we may use commands such as `print 1' or `print ACCUMULATOR'. These
commands will show contents of memory[1] and accumulator, respectively.