6.2. Understanding the Generated Structure
As we described in the preceding section, the outputs generated as a result of hardware generation will differ somewhat depending on the platform target you select, but at its core every generated hardware project includes both a top-level HDL module and one or more lower-level HDL modules representing the hardware process(es) that you have defined in C language and declared as hardware using co_process_config. When generated as VHDL, for example, the FIR filter presented in Chapter 5 is represented by two VHDL entity and architecture pairs, which are summarized in the listings shown in Figures 6-3 (the top-level file) and 6-4 (the lower-level file).
In the VHDL code shown (which has been modified to remove most of the details of the generated FIR filter logic), you can see that the FIR filter process has been converted into a VHDL top-level entity that in turn references a lower-level entity containing the actual function of the FIR filter as expressed in register transfer level (RTL) code.
Why these two levels in the generated VHDL files? First, if the application consists of multiple, parallel hardware processes, the top-level entity and its corresponding architecture are where these various processes are combined and interconnected.
The second reason for partitioning the generated hardware in this way is that the process itself (the FIR filter) is not directly connected to the outside world. Instead, the connections are made via buffered data streams, and these stream components must be referenced and instantiated in the top-level module. These stream interfaces are a critical aspect of the design and represent the hardware realization of the abstract streams used in the FIR filter process, and in fact for the majority of Impulse C applications.
In the generated VHDL top-level file, notice that the lower-level entity/architecture is referenced using a component declaration and is then instantiated using a component instantiation statement, along with two stream components from the Impulse hardware library. This represents the basic hierarchy of our application as it will exist in hardware: a top-level entity/architecture that references our generated FIR filter process and whatever stream components are needed to provide the I/O channels as specified in the original C code.
If you look carefully at this generated VHDL code (and you have some VHDL experience), you might notice a few other things. First, notice that the FIR process and the reference stream components have reset lines and clocks. Of course, no resets or clocks were defined in the original untimed C source code, but the hardware generation process has resulted in clocks and resets being generated. The compiler includes options that allow you to control this generation of clocks and resets to some extent. For example, if you will be clocking different hardware and software processes at different rates (as might be the case when one process must interface to an external device at a limited rate when compared to other processes), you can specify dual-clock streams. In this case, the compiler generates stream components with multiple clocks. There is one clock for each end of the stream, corresponding to the differing clock rates used by the producer and consumer processes. Understanding these various compiler options can help you better optimize your applications for specific types of platforms.
Also notice the use of generics to specify stream parametersspecifically, the width and depth of the streams. Generics are also used for generated hardware processes if parameters (of type co_parameter) are used in your Impulse C descriptions. This example does not make use of compile-time Impulse C parameters, so you do not see any corresponding generics applied to the filter_process component.
Last, notice that each of the two streams specified in the original C code has resulted in three control signals generated by the compiler in addition to the data input or output. These control signals are described in the next section. Note that signal interfaces (which are not used in this example) follow a similar pattern.
Figure 6-3. Top-level generated entity for the FIR filter application.
-- This file was automatically generated. -- library ieee; use ieee.std_logic_1164.all; library impulse; use impulse.components.all; entity fir_arch is port ( reset, sclk, clk : in std_ulogic; p_producer_process_waveform_raw_en : in std_ulogic; p_producer_process_waveform_raw_eos : in std_ulogic; p_producer_process_waveform_raw_data : in std_ulogic_vector (31 downto 0); p_producer_process_waveform_raw_rdy : out std_ulogic; p_consumer_process_waveform_filtered_en : in std_ulogic; p_consumer_process_waveform_filtered_data : out std_ulogic_vector (31 downto 0); p_consumer_process_waveform_filtered_eos : out std_ulogic; p_consumer_process_waveform_filtered_rdy : out std_ulogic); end; architecture structure of fir_arch is component fir is port ( reset, sclk, clk : std_ulogic; p_filter_in_rdy : in std_ulogic; p_filter_in_en : inout std_ulogic; p_filter_in_eos : in std_ulogic; p_filter_in_data : in std_ulogic_vector (31 downto 0); p_filter_out_rdy : in std_ulogic; p_filter_out_en : inout std_ulogic; p_filter_out_eos : out std_ulogic; p_filter_out_data : out std_ulogic_vector (31 downto 0) ); end component; signal p_filter_process_filter_in_rdy : std_ulogic; signal p_filter_process_filter_in_en : std_ulogic; signal p_filter_process_filter_in_eos : std_ulogic; signal p_filter_process_filter_in_data : std_ulogic_vector (31 downto 0); signal p_filter_process_filter_out_rdy : std_ulogic; signal p_filter_process_filter_out_en : std_ulogic; signal p_filter_process_filter_out_eos : std_ulogic; signal p_filter_process_filter_out_data : std_ulogic_vector (31 downto 0); signal local_reset : std_ulogic; begin local_reset <= reset; filter_process: fir port map ( local_reset, sclk, clk, p_filter_process_filter_in_rdy, p_filter_process_filter_in_en, p_filter_process_filter_in_eos, p_filter_process_filter_in_data, p_filter_process_filter_out_rdy, p_filter_process_filter_out_en, p_filter_process_filter_out_eos, p_filter_process_filter_out_data ); inst0: stream generic map (datawidth => 32, addrwidth => 1) port map ( reset => local_reset, clk => clk, input_en => p_producer_process_waveform_raw_en, input_rdy => p_producer_process_waveform_raw_rdy, input_eos => p_producer_process_waveform_raw_eos, input_data => p_producer_process_waveform_raw_data, output_en => p_filter_process_filter_in_en, output_rdy => p_filter_process_filter_in_rdy, output_eos => p_filter_process_filter_in_eos, output_data => p_filter_process_filter_in_data); inst1: stream generic map (datawidth => 32, addrwidth => 1) port map ( reset => local_reset, clk => clk, input_en => p_filter_process_filter_out_en, input_rdy => p_filter_process_filter_out_rdy, input_eos => p_filter_process_filter_out_eos, input_data => p_filter_process_filter_out_data, output_en => p_consumer_process_waveform_filtered_en, output_rdy => p_consumer_process_waveform_filtered_rdy, output_eos => p_consumer_process_waveform_filtered_eos, output_data => p_consumer_process_waveform_filtered_data); end;
Figure 6-4. Lower-level generated entity and architecture for the FIR filter (abbreviated).
-- This file was automatically generated. -- library ieee; use ieee.std_logic_1164.all; library impulse; use impulse.components.all; entity fir is port ( reset, sclk, clk : std_ulogic; p_filter_in_rdy : in std_ulogic; p_filter_in_en : inout std_ulogic; p_filter_in_eos : in std_ulogic; p_filter_in_data : in std_ulogic_vector (31 downto 0); p_filter_out_rdy : in std_ulogic; p_filter_out_en : inout std_ulogic; p_filter_out_eos : out std_ulogic; p_filter_out_data : out std_ulogic_vector (31 downto 0) ); end; architecture rtl of fir is type pipeStateType is (idle, run, flush); signal s_b1_state : pipeStateType; -- The remainder of the local signal delcarations have been removed for brevity -- ... process (clk,reset,stateEn) begin if (reset='1') then thisState <= init; elsif (clk'event and clk='1') then -- The remainder of the hardware description has been removed for brevity. -- ...