The following figure shows the extraction of control logic and implementation of I/O ports for this code example:
void foo(int in[3], char a, char b, char c, int out[3]) {
int x,y;
for(int i = 0; i < 3; i++) {
x = in[i];
y = a*x + b + c;
out[i] = y;
}
}
This code example performs the same operations as the previous example. However,
it performs the operations inside a for-loop, and two of the function arguments are arrays.
The resulting design executes the logic inside the for-loop three times when the code is
scheduled. High-level synthesis automatically extracts the control logic from the C code and
creates an FSM in the RTL design to sequence these operations. Top-level function arguments
become ports in the final RTL design. The scalar variable of type char
maps into a standard 8-bit data bus port. Array arguments, such as in
and out
, contain an entire
collection of data.
In high-level synthesis, arrays are synthesized into block RAM by default, but other options are possible, such as FIFOs, distributed RAM, and individual registers. When using arrays as arguments in the top-level function, high-level synthesis assumes that the block RAM is outside the top-level function and automatically creates ports to access a block RAM outside the design, such as data ports, address ports, and any required chip-enable or write-enable signals.
The FSM controls when the registers store data and controls the state
of any I/O control signals. The FSM starts in the state C0
.
On the next clock, it enters state C1
, then state
C2
, and then state C3
.
It returns to state C1
(and C2
,
C3
) a total of three times before returning to
state C0
.
C0
,{C1, C2,
C3}
, {C1, C2, C3}
, {C1,
C2, C3}
, and return to C0
.The design requires the addition of b
and c
only one time. High-level synthesis moves the operation outside the for-loop
and into state C0
. Each time the design enters
state C3
, it reuses the result of the addition.
The design reads the data from in
and stores
the data in x
. The FSM generates the address for
the first element in state C1
. In addition, in
state C1
, an adder increments to keep track of
how many times the design must iterate around states C1
,
C2
, and C3
. In state C2
,
the block RAM returns the data for in and stores it as variable x
.
High-level synthesis reads the data from port a
with other values to perform the calculation and generates the first
y
output. The FSM ensures that the correct address
and control signals are generated to store this value outside the block. The design then
returns to state C1
to read the next value from the
array/block RAM in
. This process continues until all
outputs are written. The design then returns to state C0
to read the next values of b
and
c
to start the process again.