Company Events Academic NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Controlling Execution of the HDL Interface Node (FPGA Module)

LabVIEW FPGA Module 8.2 Help
August 2006

NI Part Number:
371599B-01

»View Product Info

You must control the execution of the HDL Interface Node differently depending on whether you place the node inside or outside a single-cycle Timed Loop on the block diagram. The single-cycle Timed Loop repeats the subdiagram inside it every clock cycle of the default FPGA clock until the conditional terminal, an input terminal, receives a particular Boolean value. LabVIEW can execute the subdiagram every clock cycle of the default FPGA clock because it removes the overhead of the enable chain for the LabVIEW functions.

Using the HDL Interface Node outside a Single-Cycle Timed Loop

If you do not use the HDL Interface Node in a single-cycle Timed Loop, select Single-Cycle Timed Loop Not Allowed on the Execution Control tab of the HDL Interface Node Properties dialog box. LabVIEW asserts enable_in to signal that the inputs are valid and the HDL code can begin executing. Be sure to assert enable_out in the HDL code when the code has valid outputs and LabVIEW has asserted enable_in. Do not change the values of the outputs or enable_out until enable_clr asserts. After enable_clr asserts, you must deassert enable_out on the next rising edge of clk.

The following sequence occurs if you run an FPGA VI with a While Loop and an HDL Interface Node inside the While Loop on an FPGA target. The HDL code properly controls the enable chain.

  1. LabVIEW asserts reset to initialize the HDL code.
  2. The While Loop asserts enable_in to the HDL Interface Node, indicating the HDL code can begin executing.
  3. The HDL code receives enable_in, executes, makes sure outputs are valid and held constant, and asserts enable_out.
  4. The While Loop receives enable_out. When all the nodes in the While Loop complete, the While Loop checks the conditional terminal. If the While Loop runs again, the loop asserts enable_clr to all the nodes in the loop.
  5. The HDL code no longer needs to hold the outputs valid, so it deasserts enable_out one clock cycle later.
  6. The While Loop reasserts enable_in, and steps 3, 4, and 5 repeat.

The following timing diagram illustrates the previous sequence. The HDL code executes between the first and second rising edges of the Clock signal and between the fourth and fifth rising edges of the Clock signal.

The following VHDL code defines the enable chain for the component. The VHDL code also defines a simple adder you can use outside a single-cycle Timed Loop.

process( clk, reset )
  begin
    if( reset = '1' ) then
      result <= (others=>'0');
      enable_out <= '0';
    elsif rising_edge(clk) then
      result <= x + y; -- result and enable_out follow input by 1 clock cycle
      if( enable_clr = '1' ) then
        enable_out <= '0';
      elsif( enable_in = '1' ) then
        enable_out <= '1';
      end if;
    end if;
end process;

Using the HDL Interface Node inside a Single-Cycle Timed Loop

If you use the HDL Interface Node in a single-cycle Timed Loop, you must connect enable_out directly to enable_in and ignore enable_clr. For example, you could include enable_out <= enable_in;. All code in the HDL Interface Node executes every clock cycle.

The HDL Interface Node is easiest to use in the single-cycle Timed Loop if you use purely combinatorial logic in the HDL code and you do not register data internally in the HDL code. If you do register data internally for pipelining or storing state information, outputs from the HDL Interface Node might not be valid for the first few iterations of the loop.

The HDL code might need to store state information or pipeline the HDL code. If so, you can use enable_in as a clock enable for flip-flops. For example, you might have a design with an output based on an input of a previous iteration. Implement the design in the HDL code using flip-flops. An embedded shift register is equivalent to a bank of flip-flops in hardware. The first one or more outputs from the HDL code to a terminal that come from an embedded shift register are invalid depending on the pipeline depth.

If you know that only the first output is invalid but the second output is valid, place a checkmark in the Outputs Embed Shift Registers checkbox on the Execution Control tab of the HDL Interface Node Properties dialog box. When you use this checkbox, wire the output of the HDL Interface Node to an uninitialized LabVIEW shift register on the right side of the single-cycle Timed Loop. Wire the left side of the shift register to the LabVIEW code. Typically, when a LabVIEW diagram is translated to HDL, LabVIEW replaces its own shift registers with flip-flops. However, when you place a checkmark in the Outputs Embed Shift Registers checkbox, LabVIEW does not replace the shift registers with flip-flops and instead relies on the flip-flops in the HDL code.

Note  If you pipeline the HDL code to a depth N, greater than one, you do not need to place a checkmark in the Outputs Embed Shift Registers checkbox. However, you must be aware that the outputs are not valid until N iterations have passed.

The following illustration demonstrates using the HDL Interface Node in a single-cycle Timed Loop and pipelining the result.

The following VHDL code is included on the Code tab of the HDL Interface Node Properties dialog box.

process( clk, reset )
  begin
    if( reset = '1' ) then
    result <= (others=>'0');
  elsif rising_edge(clk) then
    if enable_in = '1' then -- use enable_in as a clock enable
      result <= x + y; -- result follows the inputs by one clock cycle
    end if;
  end if;
end process;
enable_out <= enable_in; -- drive the enable_out with enable_in

The VHDL code defines a simple adder that you can use inside a single-cycle Timed Loop. Notice that in this implementation, the VHDL code is pipelined to a depth of one and the result of the calculation is valid only after the first iteration of the single-cycle Timed Loop is complete. Also notice that the VHDL code includes a line to drive enable_out with enable_in.

Because the output is registered, you can place a checkmark in the Outputs Embed Shift Registers checkbox on the Execution Control tab to indicate that the outputs must directly connect to uninitialized shift registers.

Select Single-Cycle Timed Loop Required on the Execution Control tab of the HDL Interface Node Properties dialog box if you use the HDL Interface Node only in a single-cycle Timed Loop. The InSingleCycle generic appears in the hdlnode entity on the Code tab, though you do not need to use the InSingleCycle generic in the HDL code if you select Single-Cycle Timed Loop Required.

If you want to access physical I/O, use the ports on the HDL Interface Node. R Series targets have synchronization registers by default between the physical FPGA and the LabVIEW block diagram. If you want the HDL code to have direct access to the top-level FPGA pin, configure the number of synchronization registers as 0 on the Advanced Code Generation FPGA I/O Properties page and Advanced Code Generation FPGA I/O Node Properties page.

Note  If you want to use I/O in the single-cycle Timed Loop, you must change the arbitration options to Never Arbitrate or Arbitrate if Multiple Requestors Only.

Using the HDL Interface Node inside or outside a Single-Cycle Timed Loop

Select Single-Cycle Timed Loop Allowed on the Execution Control tab to use the HDL Interface Node inside or outside a single-cycle Timed Loop. The InSingleCycle generic appears in the hdlnode entity on the Code tab. You must use the InSingleCycle generic in the HDL code and generate different code based on the value of the generic. Use the InSingleCycle generic to make sure only one of the two sections of HDL code executes for a particular instantiation of the HDL Interface Node. The following samples of VHDL code use the InSingleCycle generic and define a simple adder you can use inside or outside a single-cycle Timed Loop. The FPGA Module sets the value of the InSingleCycle generic during code generation. Only one of the blocks of code instantiates at a time based on the value of the InSingleCycle generic.

SingleCycleCode: -- if you use the HDL Interface Node in a single-cycle Timed Loop, use this code
if InSingleCycle generate
  result <= x + y;
  enable_out <= enable_in; -- drive the enable_out with enable_in
end generate;

NonSingleCycleCode: -- if you do not use the HDL Interface Node in a single-cycle Timed Loop, use this code
if not InSingleCycle generate
  process( clk, reset )
  begin
    if( reset = '1' ) then
      result <= (others>='0');
      enable_out <= '0';
    elsif rising_edge(clk) then
      result <= x + y; -- result and enable_out follow input by 1 clock cycle
      if( enable_clr = '1' ) then
        enable_out <= '0';
      elsif( enable_in = '1' ) then
        enable_out <= '1';
      end if;
    end if;
end process;
end generate;

The SingleCycleCode determines how the HDL Interface Node behaves when you place it in a single-cycle Timed Loop. The NonSingleCycleCode determines how the HDL Interface Node behaves when you do not place the node inside a single-cycle Timed Loop. Notice that the SingleCycleCode assigns enable_out to enable_in, and all the logic is combinatorial. Notice that the NonSingleCycleCode registers the output of the adder logic. The output then follows the input signals by one clock cycle. NonSingleCycleCode also places a one clock-cycle delay on the enable signal. Be sure to include code for each case if you select Single-Cycle Timed Loop Allowed.


Resources


 

Your Feedback! poor Poor  |  Excellent excellent   Yes No
 Document Quality? 
 Answered Your Question? 
Add Comments 1 2 3 4 5 submit