05-13-2014 02:43 PM
Hello, I have an sbRIO board and i want to pass a clock through FPGA from one pin to another. I'm routed a clock to port, say DI (DIO63) and expecting it on another port, say DO (DIO46).
If a use direct connection of one DIO to another in an sctl (all DIOs are configured with 0 synchronization registers for write and read) clock is passing normally and I see it on DO:
Now I want to use a clip for this task. I've created a basic vhdl file:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity user_ip is
port (
clk_in : in std_logic;
clk_out1 : out std_logic
);
end user_ip;
architecture rtl of user_ip is
begin
clk_out1 <= clk_in;
end rtl;
Imported it to project using Component-level IP wizard (see below) with default configs and dropped it do diagram:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!-- National Instruments recommends that you do not change this CLIP declaration file outside of the Configure Component-Level IP wizard. You can modify this declaration file on the Component-Level IP page of the FPGA Target Properties dialog box. --> <CLIPDeclaration Name="user_ip"> <FormatVersion>4.2</FormatVersion> <Description/> <TopLevelEntityAndArchitecture> <SynthesisModel> <Entity>user_ip</Entity> <Architecture>rtl</Architecture> </SynthesisModel> <SimulationModel> <Entity>user_ip</Entity> <Architecture>rtl</Architecture> </SimulationModel> </TopLevelEntityAndArchitecture> <SupportedDeviceFamilies>Unlimited</SupportedDeviceFamilies> <InterfaceList> <Interface Name="LabVIEW"> <InterfaceType>LabVIEW</InterfaceType> <SignalList> <Signal Name="clk_in"> <HDLName>clk_in</HDLName> <HDLType>std_logic</HDLType> <Direction>ToCLIP</Direction> <SignalType>data</SignalType> <Description/> <DataType> <Boolean/> </DataType> <UseInLabVIEWSingleCycleTimedLoop>Allowed</UseInLabVIEWSingleCycleTimedLoop></Signal> <Signal Name="clk_out1"> <HDLName>clk_out1</HDLName> <HDLType>std_logic</HDLType> <Direction>FromCLIP</Direction> <SignalType>data</SignalType> <Description/> <DataType> <Boolean/> </DataType> <UseInLabVIEWSingleCycleTimedLoop>Allowed</UseInLabVIEWSingleCycleTimedLoop></Signal> </SignalList> </Interface> </InterfaceList> <ImplementationList> <Path Name="user_ip.vhd"> <TopLevel/> <MD5>dd489bfd1eb7be971758ad462c35b6fc</MD5> <SimulationFileList> <SimulationModelType>Same as synthesis</SimulationModelType> </SimulationFileList> </Path> </ImplementationList> <NumberOfDCMsNeeded>0</NumberOfDCMsNeeded> <NumberOfMMCMsNeeded>0</NumberOfMMCMsNeeded> <NumberOfBufGsNeeded>0</NumberOfBufGsNeeded> </CLIPDeclaration>
This implementation is running, BUT I do not see any activity on DO (all DIOs are configured with 0 synchronization registers for write and read). What's the problem? What do i need to add/remove/change in a vhdl file and overall clip to make it work?
Konstantin.
05-14-2014 11:07 AM
Hi Konstantin,
There are a couple of things that jump out at me with your LabVIEW FPGA code. You mentioned that you set the synchronization registers to 0 for the DIO, but you didn't mention doing this for the CLIP. I would recommend setting the synchronization registers to 0 for the CLIP as well. You can access this option by right-clicking the CLIP in the Project Explorer window and selecting Properties.
Another thing that jumps out at me is that you have a True constant wired to the Conditional Terminal. I would recommend using a False constant instead of a True so that the loop runs more than one time.
I believe the combination of these things is causing your issue. Since the loop only runs once then there aren't enough iterations for the signal to get through the synchronization register. We have run your CLIP on a device here and we don't encounter the problem when changing these two things.
We often find it helpful to use controls and indicators for troubleshooting purposes with CLIP. We used the VI shown in the picture below to initially trouble shoot your CLIP.
Hopefully this information is helpful!
05-14-2014 04:13 PM - edited 05-14-2014 04:13 PM
Hi Josh!
Yes, I've totally forgotten about synchronization registers in CLIP nodes. Let's continue some sort of investigation.
Now suppose we use the same CLIP and now the number of all the synchronization registers of DIO and CLIP nodes are 0. For tests I've connected 10 Mhz oscillator to DIO63.
Consider this code (yes, the True constant is wired to the Conditional Terminal):
It will work: we will see continuos 10 MHz clock on DIO46. And this will be true regardless of SCTL rate (default 40 Mhz or down to 2.5 Mhz) UNLESS we change the number of synchronizing registers of output enable for our DIOs from 1 to 0. Then the code above won't work and we will see logic low on DIO46 every time we load a bitstream to FPGA.
Now lets move the code above out of the SCTL:
When the synchronizing registers of output enable for our DIOs is 1 the code works an interesting way: we will see logic low or logic high on DIO46 from one load to another load of a bitstream (or system reset). When the synchronizing registers of output enable for our DIOs is 0 the code won't work at all: we will observe a logic low on DIO46 always.
Can you explain:
1) Why do we need to use the number of synchronizing registers of output enable = 1 to make codes above work?
2) Why do we need an SCTL running ONE iteration to make code with a CLIP work and why code with a CLIP outside and SCTL won't work properly? if we have zero triggers on digital path:
we do not need any iterations to pass a signal form input to ouput only routing delays will arise
3) Why so strange behavior of a code outside an SCTL with the number of synchronizing registers of output enable=1? Like a code one shots one single event on input and then stops (consider the 2'nd question)?
Konstantin.
05-15-2014 05:32 AM
ADD: maybe using number of synch registers of output enable set to 0 leads to improper DO work and that's why we see no activity on output (case ports are tristate configured and we must properly route tri state path of the same TBUF)?
05-15-2014 04:21 PM
Hi Konstantin,
Unfortunately I don't have an immediate answer for you. Give me some time to look into this behavior and I'll let you know when I have some good information to share.
05-16-2014 01:02 AM
Thank you in advance
05-21-2014 01:48 PM
Hi Konstantin,
I don't have a single, simple answer for you. It appears that your HDL code needs to have some additional connections if you want to have the code outside a SCTL. In addition, your HDL code would need to contain its own synchronization registers if ou want to select 0 for the Output Enable Synchronization registers. I will continue to look into some of this and will let you know if I find any more useful information. In the meantime though, I wanted to share the resources below.
http://zone.ni.com/reference/en-XX/help/371599J-01/lvfpgadialog/fpga_io_advcodegen_db/
http://www.ni.com/white-paper/3483/en/
http://digital.ni.com/public.nsf/allkb/453B248EC94DC7F98625766B0045DF15?OpenDocument
http://digital.ni.com/public.nsf/allkb/E2212E77DF6D63FA862576300000161B?OpenDocument
Hopefully some of this information is helpful!
05-22-2014 02:39 AM - edited 05-22-2014 02:41 AM
Josh, thank you for help. Any specific information will be helpful, i'll continue to monitor a topic.
05-22-2014 09:23 AM
Hi all,
This code is bending the rules of dataflow. The code is written more as if it were a hardware schematic rather than using a dataflow paradigm. Normally, LabVIEW code outside of a loop would only execute once, synchronous with the block diagram clock. Removing the synchronization registers should allow this code to 'continuously' execute asynchronous to the diagram, but this isn't the standard way of developing LabVIEW FPGA code.
What is driving the need to write this code outside of a single-cycle timed loop? It is difficult/impossible to compile your CLIP block at 40MHz?
Regarding suggestions, I have seen some similar behavior in the past with code like this and it had to do with the "Set Output Enable" method, similar to the path that you and Joshua are exploring. I would suggest explicitly setting the output enable method to TRUE and using dataflow to ensure this method is set true 'before' the asynchronous section of code. As you probably know, using the DIO output IO node will normally assert the output enable and drive the pin to the level input from the LabVIEW diagram. As you suspected, I also suspect the lack of synchronization registers to the IOBuffer is causing a problem with consistently setting output enable line to the buffer.
Hope this helps,