VHDL design - creating if loop within second process not working

287 Views Asked by At

I've written a VHDL design that halves the clock's frequency and outputs this 'data clock' onto the sclk pin. I also have a data pin called 'sda' that I'd like to send data out of. The following code works fine. I see the clock signal out of sclk and sda is permanently set to high. Enable is attached to a push button.

library  ieee;
use  ieee.std_logic_1164.all;
use  ieee.std_logic_unsigned.all;

-- For Main Clock --
library machXO3l;
use machXO3l.all;
--------------------

entity top is
    -- entity's pin out.
     port(
            enable  : in std_logic;
            sda     : out std_logic     := '0';
            sclk    : out std_logic     := '0'  
         );
end entity;

architecture top_behav of top is
    signal temp_sclk    :   std_logic   := '0';
    signal clk          :   std_logic;
    signal temp_sda     :   std_logic   := '1';
    signal stdby        :   std_logic   := '0';

    component OSCH
    -- Component description that is being used within the entity.
    -- synthesis translate_off
        generic (NOM_FREQ: string := "24.18");

    -- synthesis translate_on
        port(
                STDBY   : in std_logic;
                OSC     : out std_logic
            );
    end component;

attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCinst0 : label is "24.18";

begin

    OSCinst0: OSCH
    -- synthesis translate_off
    generic map( NOM_FREQ => "24.18" )

    -- synthesis translate_on
    -- mapping the OSCH component to our entity pin out.
    port map(  
                OSC     => clk,
                STDBY   => stdby
             );

    -- DATA CLOCK GENERATION
    sclk_p : process(clk, enable)
    begin
        if (enable = '0') then
            temp_sclk   <= '0';
        elsif (clk'event and clk = '1') then
            temp_sclk <= NOT temp_sclk;
        end if;
    end process;
    sclk    <= temp_sclk;   

    sda <= temp_sda;
end top_behav;

The problem is when I create the following process within the architecture, both lines are permanently set to 0. I don't understand why. Simulation works fine. I'm able to synthesize my code and program it on to the FPGA. But when monitoring the pins using a scope, they're just set to low.

sda_p : process(clk, enable)
begin
    if (enable = '0') then
        temp_sda <= '0';
    else
        temp_sda <= '1';
    end if;
end process;

The following works fine too:

sda_p : process(clk, enable)
begin
    temp_sda <= '1';
end process;

I'm using lattice diamond and machx03l evk

2

There are 2 best solutions below

0
On

In Lattice Diamond, first of all, look at the netlist analyzer (icon and image shown below)

Lattice Netlist Analyzer

Check to see that the synthesized logic is correct. If the netlist analyzer shows the correct logic, then you need to believe that this is what is going to be synthesized. Then you have removed your uncertainty and there are no more doubts.

Does it indeed show that you are connecting to ground or does it show the correct intended logic to be synthesized?

If it shows that it is correct, then your problem can only be because of your external hardware or your output settings. Please check:

  1. Output settings (red box below)
  2. Pull mode matches your external world (Purple highlight below)
  3. Drive strength (red highlight below)
  4. Check where your pin output is going to. What is your load? Is it affecting what you are driving?

enter image description here

You mentioned that you monitored the signals using a scope, is it the Lattice logic analyzer? or an actual oscilloscope?

If it is using the Lattice Logic Analyzer where you instantiate the analyzer as a logic block inside the FPGA, then the only other reason I can think of is that your clock is not correctly functioning.

If using an oscilloscope, there could still be a problem which can be plausibly explained by the above symptoms and potential problems

0
On

In the end, my code was correct but since the machx03l only allows limited RAM flash programming (compared to the machx03lf board), I am using the SPI flash programming interface. Using this interface is a pain - many a times, I have to keep doing a 'Background, flash, erase, verify' when programming the board. Other times the IDE complaints I've got a 'CHECK_ID' error, in which case I resort to use the 'Flash, erase, verify' method. If the latter does work and the board does nothing, always do the former and it should work, given one is confident of their code.