Intel® High Level Synthesis Compiler Pro Edition: Reference Manual

ID 683349
Date 4/01/2024
Public
Document Table of Contents

4.5.2. Agent Memories

By default, component functions access parameters that are passed by reference through an Avalon® Memory-Mapped (MM) Host interface. An alternative way to pass parameters by reference is to use an Avalon® MM Agent memory interface, which exists inside the component.
Having a pointer argument generate an Avalon® MM Host interface on the component has two potential disadvantages:
  • The host interface has a single port. If the component has multiple load-store sites, arbitration on that port might create stallable logic.
  • Depending on the system in which the component is instantiated, other hosts might use the memory bus while the component is running and create undesirable stalls on the bus.

Because an agent memory is internal to the component, the HLS compiler can create a memory architecture that is optimized for the access pattern of the component such as creating banked memories or coalescing memory accesses.

Agent memories differ from component memories because they can be accessed from an Avalon® MM Host outside of the component. Component memories are by definition restricted to the component and cannot be accessed outside the component.

You can explicitly control the structure of your agent memories by applying memory attributes to agent memory variable declarations.

A component can have many agent memory interfaces. Unlike agent register arguments that are grouped together in the CSR agent interface, each agent memory has a separate interface with separate data buses. The agent memory interface data bus width is determined by the width of the agent type. If the internal accesses to the memory have been coalesced, the agent memory interface data bus width might be a multiple of the width of the agent type.

You can apply component memory attributes to agent memories in your component to customize the memory architecture and lower the FPGA area utilization of your component. For details, refer to Component Memory Attributes.

The following diagram shows a component with two agent memory interfaces defined as follows:
component float myComponent(​
hls_avalon_agent_memory(64) float *a,
hls_avalon_agent_memory(64) float *b) {​
   return a[0]+b[0];​
}



Reads and writes to agent memories from outside of the component should occur only when your component is not executing, unless you mark the agent memory argument with the volatile keyword. Without the volatile keyword, you might experience undefined component behavior if an external Avalon MM Host accesses your component agent memory when your HLS component is executing. The undefined behavior can occur even if the external access is to a memory address that your HLS component does not access.

Volatile Agent Memories

Add the volatile keyword to an agent memory argument to allow an Avalon MM Host to access the memory while the component executes. The compiler builds a memory system that ensures functional correctness even if the memory is modified from outside the component while the component is running.

However, allowing concurrent memory accesses with the volatile keyword might prevent some optimizations that the compiler can perform on your component. Consider this trade-off carefully in your design.

Depending on how the agent memory is accessed from within the component, the compiler might infer arbitration logic between the external memory access and internal memory accesses. In this case, the external access always gets arbitration priority over internal accesses. This prioritization might prevent the data flow in the component from progressing when external requests arrive at every cycle.
Important:

You cannot verify the behavior of concurrent component memory access during simulation. To test the behavior, you must build a Verilog testbench to interact with your component. You can see an example of a Verilog testbench and how to use it in the following tutorial:

<quartus_installdir>/hls/examples/tutorials/interfaces/mm_agents_CSR_volatile

Avalon® MM Host Access Control

You can indicate how an external Avalon® MM Host interface accesses the component agent memory interface with the hls_readwrite_mode component macro:
  • Use hls_readwrite_mode("readonly") to indicate that the external Avalon® MM Host interface only ever reads from the agent memory. If you specify this macro, no write ports from outside of the component are created.
  • Use hls_readwrite_mode("writeonly") to indicate that the external Avalon® MM Host interface only ever writes to the agent memory. If you specify this macro, no read ports from outside of the component are created.

If you do not specify this macro, the compiler assumes that the external Avalon® MM Host interface can read or write to the agent memory.

You can use the macro to help the compiler create a more efficient memory system and potentially save FPGA area.

You can use the hls_readwrite_mode macro for both volatile and non-volatile agent memories.

The following example shows how you can apply the macro:
component void 
foo(hls_avalon_agent_memory_argument(128*sizeof(int)) 
hls_readwrite_mode(“writeonly”) int *A)

Agent Memory Component Macros

Component Macro Description
hls_avalon_agent_memory_argument Implement the parameter, in on-chip memory blocks, which can be read from or written to over a dedicated agent interface.
hls_readwrite_mode Indicate to the compiler how the agent memory interface is accessed by external Avalon® memory-mapped (MM) hosts.