Author Topic: Lattice Mach XO2 strange behaviour in VHDL  (Read 6295 times)

0 Members and 1 Guest are viewing this topic.

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Lattice Mach XO2 strange behaviour in VHDL
« on: April 19, 2018, 08:05:03 am »
Hi there,
i have set up this Lattice breakout board: http://www.latticesemi.com/en/Products/DevelopmentBoardsAndKits/MachXO2BreakoutBoard , one of the older ones with the 'LCMXO2-1200ZE-1TG144' on  it. I wanted to create a simple Parallel in Serial out shift register in order to get Data in a DAC.
I came quite far ( i guess) but when i setup the prescaler for the system Clock (osc_clk) to generate the ''Component Clock'' (compclk) and a then a second prescaler to generate the "transmission clock" (sck_clk)  i ran into a problem that i can't figure out. Now i routed osc_clk, sck_clk and compclk to pins in order to measure the generated clocks. The scope shows now  "osc_clk" and "compclk" fine but sck_clk is odd. Where it semms, it should be '0' its all good but when it shall went to a steady '1' it instead begins to clock with half the osc_clk. The rising edge seems to be where it should and if the clocking part would be a steady one, the frequency would be correct. But the on time is not half a wavecycle rather than a short pulse.  What bugs me most ist that the code used for both prescalers are except the Names absolutely the same. I Also checked for differences in my toplayer, but the only one is the Prescale Value, which seems to has no effect on the Generated clock despite altering the generatet burst frequency. I know this is (should be)a simple task but i just don't get it.
I attached a few Pictures of all described and of course the used code (as whole project). I am using Lattice Diamond Version(64-bit) 3.7.0.96.1.
Can somebody explain me what is going on here? |O I am, after all, quite new to vhdl and haven't done a lot with it.
Thanks in foreward!
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #1 on: April 19, 2018, 10:15:17 am »
Your 'Prescaler' is much heavier on variables than I am use to. I am also not used to variables holding state. I had to simulate it, but it looks fine.

I would have also changed it so that the range for counter is one less (so if divider is 4, then it is only 0 to 3):

Code: [Select]
begin
Prescaler : process (compclk)
        variable counter : natural range 0 to divider-1 :=0;
        variable outx      : std_logic := '0';

    begin

        if (rising_edge(compclk)) then
            if counter=divider-1 then
                outx := not outx;
                counter:=0;
            else
                counter:=counter+1;
            end if;
        end if;
clkout <= outx;
    end process Prescaler;

In PISOsr, you should set the initial value of data_register and dout:

Code: [Select]
dout: out std_logic := '0' --Data Output
....
variable data_register : std_logic_vector(size+1 downto 0) := (others => '0');

I couldn't get 'trigger' to work, so I rewrote it with what it seems you are trying to do, but closer to my usual style:
Code: [Select]
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;


entity Trigger is   
generic (
cycles : natural := 1
);
port(
compclk: in std_logic;
key : in std_logic; --Clock with witch the Data are Output
cmd : out std_logic := '0' --Enables the Clock Input
);
end Trigger;

architecture Trigger_arch of Trigger is
    signal debounce : integer range 0 to cycles-1 :=0;
begin   

Trigger : process (compclk)
    begin
        if (rising_edge(compclk) ) then           
            if debounce = cycles-1 then
                cmd <= '1';
                debounce <= 0;
            else
                cmd <= '0';
                if debounce = 0 then
                    if(key='1') then
                        debounce <= 1;
                    end if;
                elsif debounce > 0 then
                    debounce <= debounce+1;
                end if;
            end if;
        end if;
end process Trigger;
end Trigger_arch;

But here is the most likely problem - the Serialiser and Trigger are being driven by compclk, when maybe it should be driven by sck_clk?
Code: [Select]
i_PISOsr: PISOsr
    generic map ( size => 23)
    port map(
        compclk => compclk,
        assign=> start,
        empty=> RegEmpty,
        din => DACData, --Data Input
        dout=> SOut --Data Output
    );

To me it looks like the serialiser (PISOsr) is sending out a very short burst of data very fast, much faster than SCLK.

Also, the input to trigger (key) is not synchronized by back-to-back flipflops. You might end up with intermittent behavior.

A really the cause for your problems may be that you have made three clocks where you only really need one.

As for the traces, what you say is SCLK looks very much like SOut in my simulation.
« Last Edit: April 19, 2018, 10:24:38 am by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #2 on: April 19, 2018, 11:09:45 am »
Here is a contrasting design I knocked up. To send x"AAAAAA" out over the serial port, MSB first.

Uses only one clock domain, and synchornizes the trigger pulse (which can be as short as a single clock cycle).

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

entity maf_serialiser is
    Port ( clk     : in STD_LOGIC;
           trigger : in STD_LOGIC;
           sclk    : out STD_LOGIC := '1';
           sync    : out STD_LOGIC := '1';
           sout    : out STD_LOGIC := '1');
end maf_serialiser;

architecture Behavioral of maf_serialiser is
    signal clk_divide        : unsigned(7 downto 0) := (others => '0');
    constant termincal_count : unsigned(7 downto 0) := to_unsigned(100-1,8);
    signal busy_sr: std_logic_vector(24 downto 0) := (others => '1');
    signal sync_sr: std_logic_vector(24 downto 0) := (others => '1');
    signal data_sr: std_logic_vector(24 downto 0) := (others => '1');
   
    signal trigger_sync : std_logic := '0';
    signal trigger_safe : std_logic := '0';
    signal phase        : std_logic := '0';
    signal clk_enable   : std_logic := '0';
begin
   sync <= sync_sr(sync_sr'high);
   sout <= data_sr(data_sr'high);
   
process(clk)
    begin
        if rising_edge(clk) then
            -- Transmit data in the shift registers
            if clk_enable = '1' then
                if clk_enable = '1' then
                    if phase = '1' then
                        busy_sr <= busy_sr(busy_sr'high-1 downto 0) & '0';
                        data_sr <= data_sr(busy_sr'high-1 downto 0) & '1';
                        sync_sr <= sync_sr(busy_sr'high-1 downto 0) & '1';
                        sclk    <= '0';
                        phase   <= '0';
                    else
                        sclk    <= '1';
                        phase   <= '1';
                    end if;
                end if;
            end if;

            -- Are in a state that we can accept new data?
            if busy_sr(24) = '0' and trigger_safe = '1' then
                -- move the new data into the shift registers
                busy_sr              <= (others => '1');
                sync_sr(23 downto 0) <= (others => '0');
                data_sr(23 downto 0) <= x"AAAAAA";
            end if;

            -- Generate the clock enable
            if clk_divide = termincal_count then
                clk_enable <= '1';
                clk_divide   <= (others => '0');
            else
                clk_enable <= '0';
                clk_divide   <= clk_divide+1;
            end if; 

            -- Synchronise trigger
            trigger_safe <= trigger_sync;
            trigger_sync <= trigger;
        end if;
    end process;
end Behavioral;

It is missing some ASYNC_REG attributes to make the best of the synchroniser.

Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #3 on: April 19, 2018, 12:25:35 pm »
Thank you very much for spending your time and the effort done!

In PISOsr, you should set the initial value of data_register and dout:
Yeah that true, i fixed that! Thanks!

I couldn't get 'trigger' to work, so I rewrote it with what it seems you are trying to do, but closer to my usual style
The Trigger is actually working, its more like a debounce thing which generates a cmd signal that starts the sequence. I don't know why it is not working for you, it is for me.

But here is the most likely problem - the Serialiser and Trigger are being driven by compclk, when maybe it should be driven by sck_clk?
The intention behind the 3 different clocks was that i need the Datapackets from the Sinetable transferred and updated with a frequency that corresponds to the desired output Sine, 2,08MHz is a bit too fast. The Second frequency was derived as i saw that my PISO seems to need two cmpclk cycles to update the output, the result was a 0101... instead of a 1100..... Therefore i wanted a ''SCK'' that is slower than the cmpclk.

To me it looks like the serialiser (PISOsr) is sending out a very short burst of data very fast, much faster than SCLK.

Also, the input to trigger (key) is not synchronized by back-to-back flipflops. You might end up with intermittent behavior.

A really the cause for your problems may be that you have made three clocks where you only really need one.

As for the traces, what you say is SCLK looks very much like SOut in my simulation.

I triple checked all leads and connections, i also have checked that the PISO kinda works. If i push the KeyA (TasterA) it puts one sequence on the bus. I can see that sequence so i am definitly shure that i have labeled the Net correctly. So the distortion definitely occuring on the SCL-Pin respectively the clock signal comming out of PrescalerSCK. My Simulation is showing all signals fine with no errors. The reallity though proofs it wrong.

There are some things i have changed in the meantime:
 - removed the file PescalerSCK and instead made a new instance of "Prescaler"
 -> no effect
 - i changed the sythesis tool inside of Diamond to "Synplify Pro"
 -> everything works great!  |O
so i guess it is some kind of degree of freedome for the synthesis tool to decide what it wants to do...but i don't see it. Because i do not need to start the PISO-Sequence in order to see the bursts i guess it won't be the initial values of the PISO, but i'll try anyway.
Thank again for your effort!
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #4 on: April 19, 2018, 12:34:31 pm »
Here is a contrasting design I knocked up. To send x"AAAAAA" out over the serial port, MSB first.

Uses only one clock domain, and synchornizes the trigger pulse (which can be as short as a single clock cycle).

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

entity maf_serialiser is
    Port ( clk     : in STD_LOGIC;
           trigger : in STD_LOGIC;
           sclk    : out STD_LOGIC := '1';
           sync    : out STD_LOGIC := '1';
           sout    : out STD_LOGIC := '1');
end maf_serialiser;

architecture Behavioral of maf_serialiser is
    signal clk_divide        : unsigned(7 downto 0) := (others => '0');
    constant termincal_count : unsigned(7 downto 0) := to_unsigned(100-1,8);
    signal busy_sr: std_logic_vector(24 downto 0) := (others => '1');
    signal sync_sr: std_logic_vector(24 downto 0) := (others => '1');
    signal data_sr: std_logic_vector(24 downto 0) := (others => '1');
   
    signal trigger_sync : std_logic := '0';
    signal trigger_safe : std_logic := '0';
    signal phase        : std_logic := '0';
    signal clk_enable   : std_logic := '0';
begin
   sync <= sync_sr(sync_sr'high);
   sout <= data_sr(data_sr'high);
   
process(clk)
    begin
        if rising_edge(clk) then
            -- Transmit data in the shift registers
            if clk_enable = '1' then
                if clk_enable = '1' then
                    if phase = '1' then
                        busy_sr <= busy_sr(busy_sr'high-1 downto 0) & '0';
                        data_sr <= data_sr(busy_sr'high-1 downto 0) & '1';
                        sync_sr <= sync_sr(busy_sr'high-1 downto 0) & '1';
                        sclk    <= '0';
                        phase   <= '0';
                    else
                        sclk    <= '1';
                        phase   <= '1';
                    end if;
                end if;
            end if;

            -- Are in a state that we can accept new data?
            if busy_sr(24) = '0' and trigger_safe = '1' then
                -- move the new data into the shift registers
                busy_sr              <= (others => '1');
                sync_sr(23 downto 0) <= (others => '0');
                data_sr(23 downto 0) <= x"AAAAAA";
            end if;

            -- Generate the clock enable
            if clk_divide = termincal_count then
                clk_enable <= '1';
                clk_divide   <= (others => '0');
            else
                clk_enable <= '0';
                clk_divide   <= clk_divide+1;
            end if; 

            -- Synchronise trigger
            trigger_safe <= trigger_sync;
            trigger_sync <= trigger;
        end if;
    end process;
end Behavioral;

It is missing some ASYNC_REG attributes to make the best of the synchroniser.



I want to be honest with you. I really don't know of which quality the code you provided is. Simply because i have no reference. But it seems to work, thats great  :-+
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #5 on: April 19, 2018, 01:57:31 pm »
The Prescaler and PrescalerSCK entities do exactly the same thing, so you don't need to define the two. Just instantiate Prescaler twice. Entities can be instantiated as many times as you wish.

Quick note: there is no need for first-level parentheses in 'if' clauses in VHDL, unlike C. VHDL is similar to Pascal derivatives syntax-wise and very close to ADA as a language.

The serializer: as I got it, you're using an extra bit to test for the end of transmission instead of using a counter. Why not.
The or_reduce() can be replaced with a simple comparison to 0.
Code: [Select]
if data_register(size downto 0)= 0 then
You're clocking the serializer with compclk, shouldn't it be with sck_clk?

I really don't like designs with no explicit reset signals. Signal initialization without explicit reset usually works on most FPGAs due to their internal structures, but would most likely fail on bare-metal targets such as ASICs, so I don't recommend doing this for portability reasons.

Since you seem to have issues with sck_clk, have you tried removing everything in your top-level unit except the two prescalers and just output the clocks on IOs?
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #6 on: April 19, 2018, 02:20:18 pm »
The Prescaler and PrescalerSCK entities do exactly the same thing, so you don't need to define the two. Just instantiate Prescaler twice. Entities can be instantiated as many times as you wish.

There are some things i have changed in the meantime:
 - removed the file PescalerSCK and instead made a new instance of "Prescaler"
 -> no effect

I already noticed that myself, but yeah that is much more convieniant.

The serializer: as I got it, you're using an extra bit to test for the end of transmission instead of using a counter. Why not.
The or_reduce() can be replaced with a simple comparison to 0.
Code: [Select]
if data_register(size downto 0)= 0 then
You got it right. I tried to do something like that at the beginning, it was something with (others=> '0') statement but that didn't work. So i replaced it with the 'or_reduce'. But i will try yours as well seems to be a bit shorter.

You're clocking the serializer with compclk, shouldn't it be with sck_clk?
Now thinking you are probably right. In the end i could toss the faulte component out. But then i still would not know what went wrong ;)

I really don't like designs with no explicit reset signals. Signal initialization without explicit reset usually works on most FPGAs due to their internal structures, but would most likely fail on bare-metal targets such as ASICs, so I don't recommend doing this for portability reasons.
You again are right, i will implement resets in the future and try to let it get a habit.

Since you seem to have issues with sck_clk, have you tried removing everything in your top-level unit except the two prescalers and just output the clocks on IOs?

I did strip it to the internal OSC and the two prescalers. No difference in the Outputs.  :(

I really appreciate your effort! Thanks.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #7 on: April 19, 2018, 03:18:26 pm »
I did strip it to the internal OSC and the two prescalers. No difference in the Outputs.  :(

So you mean that with a stripped down version of your design, the offending clock (sck_clk) still outputs what appears to be bursts of half frequency of compclk?
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #8 on: April 19, 2018, 08:44:49 pm »
Yes that is correct.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #9 on: April 19, 2018, 09:02:10 pm »
Yes that is correct.

That seems really odd. I still suspect that you have somehow got pins mixed up, as there is no way that your code can generate anything but a steady clock with 50% duty cycle.

Simulate it if at all possible.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #10 on: April 19, 2018, 10:14:21 pm »
Yeah, it's odd. I took a look at the .lpf file and there seems to be nothing odd with your pin attribution.

If I get it right, you said you're having this odd problem when using LSE but not with Synplify?

I have encountered a bug in LSE in the past but certainly not on something as trivial as a clock divider... so that's very odd. Have you tried updating Diamond? Your version is a bit dated.
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #11 on: April 20, 2018, 05:43:00 am »
Yes that is correct.

That seems really odd. I still suspect that you have somehow got pins mixed up, as there is no way that your code can generate anything but a steady clock with 50% duty cycle.

Simulate it if at all possible.

I simulated it already, and the simulation shows it fine. That i had Pins mixed up was one of my first ideas too, even before starting the Topic. So i removed all the probes and reconnected them triple checking the Pin assignment in the Spreadsheet against my Pobepoint and labels. The result was the same Signal. Against the "Mixed Up Testlead" theory is also the fakt that i can see the correctly prescaled clock when using "Syplifie Pro" as synthesis Tool.

Yeah, it's odd. I took a look at the .lpf file and there seems to be nothing odd with your pin attribution.

If I get it right, you said you're having this odd problem when using LSE but not with Synplify?

I have encountered a bug in LSE in the past but certainly not on something as trivial as a clock divider... so that's very odd. Have you tried updating Diamond? Your version is a bit dated.

Yes you get it right, using LSE -> bad ; using Synplify -> good.
It moaned something like "there is a newer version" but i usualy try to avoide this kind of updates, they mostly do more harm than good. But now facing this kind of trouble one can argue to do the update, but i am still not happy with it. As you said, a simple clock divider should be possible with either version, shouldn't it?
 

Offline ale500

  • Frequent Contributor
  • **
  • Posts: 415
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #12 on: April 20, 2018, 05:45:33 am »
Quote
I did strip it to the internal OSC and the two prescalers. No difference in the Outputs.

Nothing happens after recompile ?... there is something there: Clean generated files, if needed erase the implementation directory (be careful not to delete your source files!). And re-run the synthesizer: read all messages ! maybe there is something funny with your code. And yes, sometimes if you modify the source files externally (don't know if you did that), they seem to not trigger a full recompile.

You can use the LEDs on the breakboard to show you a version number, that way you can be sure that you run your most recent code.

Simulation alone is sadly not a proof that the "code" works on a real FPGA, but a strong indication.
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #13 on: April 20, 2018, 07:30:14 am »
Meanwhile i checked the NetlistViewer a bit more carfully and i think this proofs that the two instances are threated different(See attached Pictures).

Quote
I did strip it to the internal OSC and the two prescalers. No difference in the Outputs.

Nothing happens after recompile ?... there is something there: Clean generated files, if needed erase the implementation directory (be careful not to delete your source files!). And re-run the synthesizer: read all messages ! maybe there is something funny with your code. And yes, sometimes if you modify the source files externally (don't know if you did that), they seem to not trigger a full recompile.

You can use the LEDs on the breakboard to show you a version number, that way you can be sure that you run your most recent code.

Simulation alone is sadly not a proof that the "code" works on a real FPGA, but a strong indication.

I'll run a cleanup and recompile, but i am quite shure that i got the right Version, i can change things by changing the Synthesis tool inside of Diamond so the file picked should be correct. But i'll try anyway.
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #14 on: April 20, 2018, 07:44:29 am »
I'll run a cleanup and recompile, but i am quite shure that i got the right Version, i can change things by changing the Synthesis tool inside of Diamond so the file picked should be correct. But i'll try anyway.

So shure enough when i hit "cleanup process" and "rerunn all" the netlist view changes to that what one would expect. Two absolutely same built components (Picture Attached). But regardless, the output is still crap and as before.
I also attached my stripped Version of the Project.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #15 on: April 20, 2018, 08:29:49 am »
It moaned something like "there is a newer version" but i usualy try to avoide this kind of updates, they mostly do more harm than good. But now facing this kind of trouble one can argue to do the update, but i am still not happy with it.

Well, I usually update my tools on a regular basis, but before I do, I take a look at the change log to figure out if this is worth it.
Diamond 3.7 is a few minor versions behind, don't remember exactly but it may be 2 years old or something.

As you said, a simple clock divider should be possible with either version, shouldn't it?

Yes. I have used version 3.7 and never ran into any issue that I can remember. (The bug I was mentioning was with EBR when using LSE with version 3.9)
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #16 on: April 20, 2018, 09:24:25 am »
What is the frequency of the OSCH clock output? Is it 2.08MHz?

Because that is what the design is constrained for...

Edit: (Just looked at the screen shot, and that seems true).
« Last Edit: April 20, 2018, 09:29:13 am by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #17 on: April 20, 2018, 11:32:42 am »
Had a MachXO2 breakout board (1200ZE) lying in a drawer. So I checked (using Diamond 3.10). And I get exactly the same issue as you.

I added a reset signal, in hope that could be a flip-flop reset problem. Didn't change anything.
I compared the way LSE and Synplify synthesize this, and it's significantly different, but I don't get what's wrong yet. That's puzzling. :box:
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #18 on: April 20, 2018, 03:07:53 pm »
Ok, got it.

First, you may notice that the "optimize for area" goal gives a correct behavior with LSE, but not the 2 others (balanced, timing). YMMV depending on your version I guess.

This is a common issue with most FPGAs actually. Clocks generated this way tend to have excessive skew, particularly when using rather "big" counters (10 bits here). Excessive skew can lead to unwillingly creating several clock domains. Some synthesis tools are better than others at minimizing clock skew. And in this particular case, I would at least expect a warning from LSE - and we don't get any. That's bad.

But the only guaranteed way of keeping several derived clocks synchronized is to use the FPGA's embedded clock resources. You can try forcing synthesis to behave with timing constraints, but that's often in vain. (I tried several constraints but to no avail in this case.) LSE does NOT automatically map these dividers to the appropriate clock resources.

I usually use the embedded PLL(s) to generate several synchronized clocks in my designs. You may take a look at the PLL IP of the MachXO2. It's pretty flexible and guarantees clock synchronization.

If you still want to implement dividers "manually", one thing you can do is to do as you would for signals coming from different clock domains: resynchronize the output of your dividers to the same source clock. Another way that works is to clock all your processes from the same clock, and use enable signals to make some processes run slower (once every N clock pulses). That would seem exactly the same, but it's not: when doing this, you don't have clock skew issues.
 
The following users thanked this post: Detzi

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #19 on: April 20, 2018, 03:08:43 pm »
Had a MachXO2 breakout board (1200ZE) lying in a drawer. So I checked (using Diamond 3.10). And I get exactly the same issue as you.

I added a reset signal, in hope that could be a flip-flop reset problem. Didn't change anything.
I compared the way LSE and Synplify synthesize this, and it's significantly different, but I don't get what's wrong yet. That's puzzling. :box:
Thanks man for fighting along with me. I have some minor update, changing the build strategy to "area" does fix it too.

What is the frequency of the OSCH clock output? Is it 2.08MHz?

Because that is what the design is constrained for...

Edit: (Just looked at the screen shot, and that seems true).

I measure 2.273MHz on the output. 2.08MHz is intentionally, i constrained it that way.

It moaned something like "there is a newer version" but i usualy try to avoide this kind of updates, they mostly do more harm than good. But now facing this kind of trouble one can argue to do the update, but i am still not happy with it.

Well, I usually update my tools on a regular basis, but before I do, I take a look at the change log to figure out if this is worth it.
Diamond 3.7 is a few minor versions behind, don't remember exactly but it may be 2 years old or something.

As you said, a simple clock divider should be possible with either version, shouldn't it?

Yes. I have used version 3.7 and never ran into any issue that I can remember. (The bug I was mentioning was with EBR when using LSE with version 3.9)

I like my tools consistent as long as there is no security issue i just don't bother updating anything as long as it works. Nethertheless I did update to the newest Version, did have no effect. Besides changing the list order of the "Export Files"
« Last Edit: April 20, 2018, 03:27:22 pm by Detzi »
 

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #20 on: April 20, 2018, 03:26:02 pm »
Ok, got it.

First, you may notice that the "optimize for area" goal gives a correct behavior with LSE, but not the 2 others (balanced, timing). YMMV depending on your version I guess.

This is a common issue with most FPGAs actually. Clocks generated this way tend to have excessive skew, particularly when using rather "big" counters (10 bits here). Excessive skew can lead to unwillingly creating several clock domains. Some synthesis tools are better than others at minimizing clock skew. And in this particular case, I would at least expect a warning from LSE - and we don't get any. That's bad.

But the only guaranteed way of keeping several derived clocks synchronized is to use the FPGA's embedded clock resources. You can try forcing synthesis to behave with timing constraints, but that's often in vain. (I tried several constraints but to no avail in this case.) LSE does NOT automatically map these dividers to the appropriate clock resources.

I usually use the embedded PLL(s) to generate several synchronized clocks in my designs. You may take a look at the PLL IP of the MachXO2. It's pretty flexible and guarantees clock synchronization.

If you still want to implement dividers "manually", one thing you can do is to do as you would for signals coming from different clock domains: resynchronize the output of your dividers to the same source clock. Another way that works is to clock all your processes from the same clock, and use enable signals to make some processes run slower (once every N clock pulses). That would seem exactly the same, but it's not: when doing this, you don't have clock skew issues.


So if i get you right the fault, essentially is to genreate a clock not with normal logic becaus the skew and or delay can lead to unforseable behaviour.

I thought a bit about that. So when generating the Clocks, in this case non shared, with normal logic shouldn't that just result in a delayed signal? Or is it likely that the synthesis tool couples the signals somehow together?

« Last Edit: April 20, 2018, 04:40:05 pm by Detzi »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #21 on: April 20, 2018, 03:55:49 pm »
There are specific clock distribution structures inside FPGAs to minimize skew. But when implementing dividers in this way, you have no guarantee the tools will/or can use those resources, so they will use general-purpose logic that are not made for clock distribution. There are flip-flops everywhere in FPGAs and clocks have specific requirements that other kinds of signals don't.

I tried the two last methods I mentioned on your design and both worked.
One thing to consider is that you often don't really need several (synchronized) clocks in a design. You can embed your prescalers inside the processes themselves and clock them all with just one clock.

Cases where it would make sense to make them true clocks is if those clocks were distributed to a lot of modules in your design. If this is just for one serial communication block such as in your example, just embed the prescalers inside the processes and you won't have this kind of issues.

 
The following users thanked this post: Detzi

Offline DetziTopic starter

  • Regular Contributor
  • *
  • Posts: 60
  • Country: de
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #22 on: April 20, 2018, 04:40:54 pm »
To be honest i don't think i understand in depth but i understood that i am using the thing in a non intended way. Good thing to know! I am really grateful for your time and effort spend to solve my problem. Thank you!  :-+

But now, i implemented a single PLL instead of the Dividers, as mentioned earlier the second divider is not needed at all so one PLL is enough. The Ouptput Frequency seems to be rather limited what means it is not as slow as i wanted it to be but regardless it puts out 800kHz and works. But now the Crap is coming out of my 'Sync' signal! It drives me f****** mad! Any Ideas?
« Last Edit: April 20, 2018, 04:58:41 pm by Detzi »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #23 on: April 20, 2018, 06:14:11 pm »
The Ouptput Frequency seems to be rather limited what means it is not as slow as i wanted it to be but regardless it puts out 800kHz and works.

You can divide by more than this I think, but there's a limit indeed since it's based on a VCO. (It's just a matter of getting to know how to use the PLL IP which is a bit confusing. And don't forget to click on the "Calculate" button in the IP dialog (and you have to scroll down to see it) when you change any parameter and before you generate the IP, otherwise it doesn't take your changes into account.)

As I suggested, you can embed an additional prescaler inside your serializer.

But now the Crap is coming out of my 'Sync' signal! It drives me f****** mad! Any Ideas?

Not really. But I think using a simple bit counter instead of this extra bit in the data register to test for the end of transmission would be much easier to read (and not necessarily heavier: it would take only 5 bits instead of having to compare 24 bits.)

You're testing this:
Code: [Select]
if(data_register(size-1 downto 0)=0) then
and later on this:
Code: [Select]
if (data_register(size downto 0)=0) then
I admit I got confused upon the first reading of this process.
« Last Edit: April 20, 2018, 06:24:01 pm by SiliconWizard »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Lattice Mach XO2 strange behaviour in VHDL
« Reply #24 on: April 20, 2018, 07:06:19 pm »
Ok I tried your project on my board and the Sync output seems fine. It goes low for the duration of 24 bits, and then back high. Are you sure you didn't have a probe contact issue? ;)

What I modified though is the PLL. Got an error saying that the min output freq was 1.5 MHz or something, so I set 4 as a divider, which gives 1.75 MHz @7 Mhz osc.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf