User manual

Tutorial: Handel-C and VGA graphics output
ram unsigned 8 Memory[4];
This will create a more efficient structure in hardware, but will now be limited to a single access per clock
cycle. The
rom keyword can be used if a read-only memory is required and can be declared as static to
allow initialization:
static rom unsigned 8 Memory[4] = {23, 25, 26, 29};
Block Memory
Many FPGAs have more than one method of implementing memories, optimized for different sizes. You
should investigate the memory types available on their target FPGA when choosing how they should
implement them. Typically memories larger than a few kbits should use the
{block = 1} setting to
make use of an FPGA’s support for larger memory structures as shown below. The number of block
memories available on an FGPA is limited, you should plan which parts of their design need to make use
of them.
ram unsigned 32 BigMemory[1024] with {block = 1};
Multi-port memory
If memory needs to be accessed more than once per clock cycle, it is possible to use multi-ported
memories. The number and type of ports depends on the type of FPGA being targeted, most support
two ports (see DK online help for detail). When a dual-port RAM is built in distributed memory (without
{block = 1}), it will take up twice the amount of hardware as a single-ported memory. The block
memories in many FPGAs are already dual-ported so if
{block = 1} is used, the dual port memory
may take up no further hardware.
Dual port memories are useful for the design of FIFO buffers, increasing the read/write bandwidth and
interfacing between clock domains (as the two ports can run at different clock rates).
Timing efficient use of memories
As a memory of any sort includes addressing logic, there is always an inherent delay in accessing it for
a read or write operation. Because of this, a memory access should be regarded as a complex operation
to include in a statement so the points explained in the section on
Complex statements (see page 71)
should be taken into account. In general it is best to use three single registers for the address, input and
output of a memory and to re-use these registers whenever the memory is accessed at different points in
the code as shown below:
ram unsigned 16 Memory[64];
unsigned 16 MemoryDataIn, MemoryDataOut, a, b, c;
unsigned 6 MemoryAddress;
par
{ /* set up data and address first */
MemoryDataIn = a * b;
MemoryAddress = c * 3;
}
par
{ /* access memory, and set up next address */
Memory[MemoryAddress] = MemoryDataIn;
MemoryAddress = c * 5;
}
a = Memory[MemoryAddress]; /* access memory again */
www.celoxica.com
Page 73