The tool works mostly by variable substitution into templates.
But some variables are special:
NUM_REGS for each module specifies the number of registers. The
tool will round it up to the next power of two, generate the decode
logic, and set the following variables:
BASEADDR (the address within the FPGA for the instance)
CS (a signal that does true with the instance is being accessed)
ADDR (a subset of the address bus that the instance can use for its internal decode)
DECODE (a one-hot vector that the instance can use for internal decode)
Any of those variables can be used in any template. BASEADDR is the
only one that would normally be used in the RAM template. The others
are more likely to be used in the VHDL template.
Also special are the variables that determine what physical pin is
connected to each port of a module. Ideally, logic to mux the pin
between its module-specific function(s) and GPIO would be generated
automatically. I'm not sure how the mux should be controlled. One
approach would be to have the module enabled/disabled by a post-FPGA
variable, and a disabled module would automatically grant use of the
pin to the next lower "priority" module (with GPIO as the lowest
priority).
SAMPLE MODULE SPECS:
module spec for stepgen:
[CONSTANTS]
ID_CODE=10
NUM_REGS=4
[PRE_FPGA_VARS]
step_up_phA : 0..71 : "connect stepgen $INSTANCE Step/Up/PhaseA output to pin number?"
dir_down_phB : 0..71 : "connect stepgen $INSTANCE Dir/Down/PhaseB output to pin number?"
[POST_FPGA_VARS]
enable : "no","yes"=0,1 : "enable step generator $INSTANCE?"
ctrl_type : "velocity","position"=0,1 : "position or velocity control mode?"
step_type : "step-dir","up-down","quadrature"=0,1,2 : "step type?" CHANGEABLE
[VHDL_TEMPLATE]
stepgen_$(INSTANCE): stepgen
port map (
clock => lclk,
enable => one,
ibus => wr_bus,
obus => rd_bus,
sel => $(CS),
write => write,
read => read,
addr => $(ADDRESS),
out0 => iobits.out($(step_up_phA)),
out1 => iobits.out($(dir_down_phB))
);
[RAM_TEMPLATE]
$(ID_CODE)
$(INSTANCE)
$(BASEADDR>>8)
$(BASEADDR)
$(ctrl_type) | $(step_type)<<2
$(step_up_phA)
$(dir_down_phB)
[END]
module spec for pin driver
[CONSTANTS]
<none?>
[PRE_FPGA_VARS]
<none?>
[POST_FPGA_VARS]
mode : "in","out","tri-state","open-collector"=0,1,2,3 : "pin driver mode"
invert : "active high","active low"=0,1 : "pin polarity"
gp : "general purpose (HAL pin)","dedicated"=0,1 : "pin output source"
hal_mode : "no","yes"=0,1 : "export HAL param for pin driver mode"
hal_invert : "no","yes"=0,1 : "export HAL param for polarity"
hal_input : "no","yes"=0,1 : "export HAL param for input value"
hal_output : "no","yes"=0,1 : "export HAL param for output value (and oe if mode is tristate)"
[VHDL_TEMPLATE]
<none>
[RAM_TEMPLATE]
$(mode) | $(invert)<<2 | $(gp)<<3 | $(hal_mode)<<4 | $(hal_invert)<<5 | $(hal_input)<<6 | $(hal_output)<<7
[END]