Author Topic: Vivado - ports not connected in implemented design  (Read 2398 times)

0 Members and 1 Guest are viewing this topic.

Offline JohnnyMalariaTopic starter

  • Super Contributor
  • ***
  • Posts: 1154
  • Country: us
    • Enlighten Scientific LLC
Vivado - ports not connected in implemented design
« on: March 09, 2021, 12:16:42 am »
Hi,

I have a Vivado design that completes bitstream generation without critical warnings or errors yet doesn't connect the external ports to the RTL module on the block design. The attached image shows this. There are external ports connected to the module in the block design and these are included in the constraints file. The VHDL snippet shows the port definitions.

The VHDL module simulates correctly under behavioral simulation.



Thanks.
 

Offline miken

  • Regular Contributor
  • *
  • Posts: 102
  • Country: us
Re: Vivado - ports not connected in implemented design
« Reply #1 on: March 09, 2021, 03:19:45 am »
Typically things get detached if there is no longer any logic attached to them. Open up your implemented design and see if everything's as you expect.

I don't quite understand what your picture is showing. Is the VHDL snippet your top level entity? Have you instantiated design_1 in it?

Also you might want to consolidate to one forum thread.
 

Offline JohnnyMalariaTopic starter

  • Super Contributor
  • ***
  • Posts: 1154
  • Country: us
    • Enlighten Scientific LLC
Re: Vivado - ports not connected in implemented design
« Reply #2 on: March 10, 2021, 02:18:54 am »
I'm utterly at a loss  |O I must be lacking some fundamental information.

Here's my block design:



I can make a bitstream and the "sampling_clock" RTL module works - I can see the signals on my oscilloscope. But the other RTL module does nothing. Behavioral simulation works perfectly. When I look at the elaborated, synthesized and implemented schematics, it is clear that the logic of that module simply is not being created:



Leading to a final implemented design:



The "sampling_clock" RTL is straightforward (it generates an approx. 80ns high pulse at 32.768kHz):

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity sampling_clock is
    Port ( clk_in : in STD_LOGIC;
           clk_out : out STD_LOGIC);
end sampling_clock;

architecture Behavioral of sampling_clock is

signal counter : integer := 0;

begin

process (clk_in)

begin
    if(rising_edge(clk_in)) then
        counter <= counter + 1;
        if (counter = 4069) then
            counter <= 0;
        end if;
       
        if (counter < 10) then
            clk_out <= '1';
        else
            clk_out <= '0';
        end if;

     end if;
end process;

end Behavioral;

The other RTL module is:

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity ltc2357 is

    Generic (
           datawidth     : integer := 24;
           softspanwidth : integer := 12
           );
    Port ( sdo0 : in STD_LOGIC;
           sdo1 : in STD_LOGIC;
           sdo2 : in STD_LOGIC;
           sdo3 : in STD_LOGIC;
           clk_in : in STD_LOGIC;
           busy : in STD_LOGIC;
           scki : out STD_LOGIC;
           sdi : out STD_LOGIC;
           data_valid : out STD_LOGIC;
           invalidate : in STD_LOGIC;
           softspan : in STD_LOGIC_VECTOR (softspanwidth - 1 downto 0);
           ch0 : out STD_LOGIC_VECTOR (datawidth - 1 downto 0);
           ch1 : out STD_LOGIC_VECTOR (datawidth - 1 downto 0);
           ch2 : out STD_LOGIC_VECTOR (datawidth - 1 downto 0);
           ch3 : out STD_LOGIC_VECTOR (datawidth - 1 downto 0)
           );
end ltc2357;

architecture Behavioral of ltc2357 is

type machine is (reset, wait_busy, wait_busyn, wait_clkn, transfer);

signal state : machine := reset;
signal count : integer := 0;
signal s_ch0 : STD_LOGIC_VECTOR (datawidth - 1 downto 0);
signal s_ch1 : STD_LOGIC_VECTOR (datawidth - 1 downto 0);
signal s_ch2 : STD_LOGIC_VECTOR (datawidth - 1 downto 0);
signal s_ch3 : STD_LOGIC_VECTOR (datawidth - 1 downto 0);
signal s_invalidate : STD_LOGIC := '0';

begin

    process (invalidate, busy, clk_in)
    begin
        if (rising_edge(invalidate)) then
            s_invalidate <= '1';
        end if;   

        if (state = wait_busy) then
            if (rising_edge(busy)) then
                state <= wait_busyn;
                if (s_invalidate = '1') then
                    data_valid <= '0';
                    s_invalidate <= '0';
                end if;
            end if;
        end if;
       
        if (state = wait_busyn) then
            if (falling_edge(busy)) then
                data_valid <= '0';
                s_ch0 <= (others => '0');
                s_ch1 <= (others => '0');
                s_ch2 <= (others => '0');
                s_ch3 <= (others => '0');
                count <= 0;
                state <= wait_clkn;
            end if;
        end if;
       
        if (falling_edge(clk_in) and (state = wait_clkn)) then
            s_ch0(0) <= sdo0;
            s_ch1(0) <= sdo1;
            s_ch2(0) <= sdo2;
            s_ch3(0) <= sdo3;
            state <= transfer;
        end if;

        if (falling_edge(clk_in) and (state = transfer)) then
            if (count < datawidth) then
                s_ch0 <= s_ch0(datawidth -2 downto 0) & sdo0;
                s_ch1 <= s_ch1(datawidth -2 downto 0) & sdo1;
                s_ch2 <= s_ch2(datawidth -2 downto 0) & sdo2;
                s_ch3 <= s_ch3(datawidth -2 downto 0) & sdo3;
            else
                ch0 <= s_ch0;
                ch1 <= s_ch1;
                ch2 <= s_ch2;
                ch3 <= s_ch3;
                data_valid <= '1';         
                state <= wait_busy;
            end if;
            scki <= '0';
        end if;

        if (rising_edge(clk_in) and (state = transfer)) then
            if (count < softspanwidth) then
                sdi <= softspan(softspanwidth - 1 - count);
            else
                sdi <= '0';
            end if;
            scki <= '1';
            count <= count + 1;   
        end if;

        if (rising_edge(clk_in) and (state = reset)) then
            scki <= '0';
            sdi  <= '0';
            data_valid <= '0';
            s_invalidate <= '0';           
            state <= wait_busy;   
        end if;

    end process;   

end Behavioral;

I've spent hours trying to work out what is so fundamentally different about this that none of it gets synthesized.
« Last Edit: March 10, 2021, 02:29:49 am by JohnnyMalaria »
 

Offline asmi

  • Super Contributor
  • ***
  • Posts: 2794
  • Country: ca
Re: Vivado - ports not connected in implemented design
« Reply #3 on: March 10, 2021, 04:05:53 am »
1. Have you tried simulating the code? If so - does it work as you expect it to?
2. If answer for p.1 is yes, then - go through synthesis logs to see if there are any clues as to what's going on. I bet there will be something for you to learn.

I don't know enough of VHDL to put my finger to it, but I suspect you are doing something wrong by using both edges of the clock in the same clocked process. In Verilog/SV it is not a legal syntax construct, and in any case there are no flip-flops in FPGA which are sensitive to both edges.
I will never get tired of saying this - when you write HDL, think about stuff being connected rather than a code being "executed" as the latter is a recipe for failure.
« Last Edit: March 10, 2021, 04:10:09 am by asmi »
 
The following users thanked this post: JohnnyMalaria

Offline miken

  • Regular Contributor
  • *
  • Posts: 102
  • Country: us
Re: Vivado - ports not connected in implemented design
« Reply #4 on: March 10, 2021, 04:36:27 am »
You can quite readily simulate things that won't synthesize (and vice versa, sometimes). There may be clues in the synthesis report, though they tend to be obscure to the uninitiated... In 7 Series, fabric flip flops can be clocked on either the rising or falling edge, not both. This is the case in all FPGA architectures I'm familiar with... you have to use special blocks to get DDR and they are only for I/O. So I'd suggest being orthodox and sticking to one clock edge.

I'd also suggest the orthodox way to do a state machine, where you have
  • a clocked process that just does state <= next_state
  • a combinational process that does a case(state) for all the next_states
  • a combinational process that does a case(state) for all the outputs

As it stands you'd probably get weird latch stuff, and while the tools will generate latches fine, I've had enough strange behavior in FPGA latch stuff that I'd suggest avoiding them.

There are different schools of thought for how many process blocks to expend on a state machine, but in my opinion doing a Moore machine with 3 process blocks is the least troublesome way to go.
 
The following users thanked this post: JohnnyMalaria

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15250
  • Country: fr
Re: Vivado - ports not connected in implemented design
« Reply #5 on: March 10, 2021, 04:34:52 pm »
This piece of code is just plain wrong.

- One process, one clock. Processes acting on edges of several different clocks and/or different edges of the same clock (and here, you have both!) just won't synthesize correctly in most cases. Never do that. There's little probability the synthesis report for this doesn't get filled with ugly warnings.
- Besides, you seem to be willing to act on edges of a "busy" signal which is likely just a flag - this is certainly not how things are done in this context.

It's very likely this process doesn't yield any logic (because it's not synthesizable), or just only partial logic of things the synthesis tool is able to process - which will yield to most logic being pruned and the associated signals to become unconnected.
 
The following users thanked this post: JohnnyMalaria

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9932
  • Country: us
Re: Vivado - ports not connected in implemented design
« Reply #6 on: March 10, 2021, 04:47:08 pm »
I have never seen a FSM coded that way but I haven't seen a lot of things.  One thing i am sure of is that every output of the FSM including 'nextstate' must be defined under ALL conditions.  If there is an 'if-then-else', all signals must be defined in each branch.  Under ALL conditions...  Miss just one signal and the FSM is likely broken.  It took me a while to tumble to this and the lesson was painful.  Now, it's the first thing I look for.

The easy way to do this is to specify the default values right after the 'begin' in the FSM code.  Every single output of the FSM including 'nextstate' must be included here.

I have never used the 3-process scheme for coding a FSM nor have I used the 1-process scheme.  There is logic involved at every state that determines the next state.  That same logic may be involved in creating the FSM output signals and having the logic spread all over the place doesn't appeal to me.  Other opinions clearly vary.  I haven't seen a compelling argument for one method over another.

 
The following users thanked this post: JohnnyMalaria

Offline JohnnyMalariaTopic starter

  • Super Contributor
  • ***
  • Posts: 1154
  • Country: us
    • Enlighten Scientific LLC
Re: Vivado - ports not connected in implemented design
« Reply #7 on: March 10, 2021, 07:09:13 pm »
THANK YOU for all your replies.

I used an example I found as the basis for my module. Based on your comments, I found a different one that uses a more conventional FSM design and it does synthesize correctly. I need to tweak it a bit now for my particular need.

Frustrating though these things are, they are very valuable lessons. I learned more about other aspects of VHDL and FPGA programming than I otherwise would have while trying to solve this problem.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15250
  • Country: fr
Re: Vivado - ports not connected in implemented design
« Reply #8 on: March 10, 2021, 08:03:29 pm »
Well, issues and mistakes are the best way to learn.

There have been many threads about similar topics, dealing with clock generation, multiple clocks/edges inside a process, and FSMs. I highly suggest to look them up in the forum.

Apart from what we already said, there's the clock generation point. Generating clocks with pure HDL code is generally not a good idea. Again I suggest looking this up in other threads, so we do not repeat the same kind of information all over the place.

Yet another point here is how you would handle master SPI in particular. Although tempting, clocking your process(es) for SPI transmit with the SPI clock directly is often not the best idea. A much easier to synthesize approach is to use a clock with twice the frequency, and generate the SPI clock from there. This way you don't need to mess with both edges, which is full of pitfalls.
 

Offline JohnnyMalariaTopic starter

  • Super Contributor
  • ***
  • Posts: 1154
  • Country: us
    • Enlighten Scientific LLC
Re: Vivado - ports not connected in implemented design
« Reply #9 on: March 10, 2021, 08:58:07 pm »
Thank you.

The code I'm using now is much more in line with what you suggest and I certainly heed what you say about clocks. For now, I'm just creating a crude 32.768kHz trigger for my ADC. Eventually, I will probably use a better-suited clock source for this and my other timing needs (e.g., driving a DDS). Ultimately, I'm measuring phase differences between signals but until I get all the components functioning and generating real-world data, I won't know how much jitter there'll be.

I'll spend some time looking at the rest of this section of the forum. It's a treasure trove, for sure.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf