Beginner problems with MachXO2 - Page 1
Forum section: electronics / general

author: ion
author_rank: Regular Contributor
timestamp: August 26, 2014, 11:02:47 pm
content: I've been wanting to learn how to use FPGAs so I recently got a MachXO2 breakout board. I read up a bit on VHDL and decided to make an 8 bit counter to drive the LEDs on the board.The code runs fine in the simulator and gives the expected results, but once I got it to synthesize and uploaded the code to the board it didn't work. All the LEDs stay lit, but I suspected they were just running at a very high frequency so I took some readings.The LEDs were switching between 1.1MHz and 1.8MHz but not in any order - most around 1.5MHz. I also mapped the CLK port to one of the pins and it read ~1.7MHz (should be ~ 3 Hz). I'm not confident that these numbers are accurate other than they are far higher than they should be.It is quite possible I might have missed a step somewhere - although IthinkI've got the hang of the Diamond IDE.Or maybe I messed up the VHDL in a way that won't show up in the simulation?Code:library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned.all;library machxo2;use machxo2.all;entity COUNT isport( CLK : inout bit;CNT : buffer std_logic_vector (7 downto 0) := "00000000");end COUNT;library IEEE;use IEEE.std_logic_1164.all;entity Clk_gen isport(CLKsig : inout bit);end;architecture Clk_behv of Clk_gen issignal tick : std_logic;component OSCH isgeneric( nom_freq: string);port( STDBY : in std_logic;OSC : out std_logic);end component;beginInst0: OSCH generic map (nom_freq => "3.02")port map ('0', tick);process(tick)variable counter: integer Range 0 to 500000;beginif (tick = '1') thenif (counter< 500000) thencounter := counter + 1;elsecounter := 0;CLKsig <= not CLKsig;end if;end if;end process;end Clk_behv;architecture Count_behv of COUNT iscomponent Clk_gen isport( CLKsig : inout bit);end component;begininst1:Clk_gen port map (CLK);process(CLK)beginif(CLK = '1') thenif (CNT = "11111111") thenCNT <= (others => '0');elseCNT <= CNT + "1";end if;end if;end process;end Count_behv;THe vector CNT drives the LEDs. Any help is appreciated.

author: vvanders
author_rank: Regular Contributor
timestamp: August 27, 2014, 02:02:45 am
content: What's the on-chip osc set to? It can be pretty wide range, 2Mhz to 133Mhz from a quick peek at the docs.

author: ion
author_rank: Regular Contributor
timestamp: August 27, 2014, 06:37:18 pm
content: I set it to 3.02 MHz, or at least that's what I think this line is doing:Code:Inst0: OSCH generic map (nom_freq => "3.02")

author: c4757p
author_rank: Super Contributor
timestamp: August 27, 2014, 06:50:41 pm
content: Code:if (tick = '1')if(CLK = '1')These should really beCode:if (rising_edge (tick))if (rising_edge (CLK))Not sure what the exact behavior of the first will be, but I suspect not pretty. You're mapping your connectionswhenever tick and CLK are high, not just at the edge - that's non-sequential.Can you get the software to render a schematic of the logic it generated?

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: August 27, 2014, 07:14:14 pm
content: without the "if rising-edge" it's just a priority encoder, so nothing will be latched.

author: ion
author_rank: Regular Contributor
timestamp: August 27, 2014, 07:36:19 pm
content: Quote from: c4757p on August 27, 2014, 06:50:41 pmBut these are inCode:process(tick)andCode:process(CLK)If I understood correctly the process only executes when the corresponding trigger has changed value. If the value changed and is now a '1' then it must have been a rising edge right?That said, the rising_edge() function seems better for triggering off clocks, thanks for pointing it out.Quote from: c4757p on August 27, 2014, 06:50:41 pmYes, I've attached the schematics below. Actually, could someone let me know what the logic symbol for un4_tick represents?

author: ion
author_rank: Regular Contributor
timestamp: August 27, 2014, 07:39:47 pm
content: Quote from: mikeselectricstuff on August 27, 2014, 07:14:14 pmOk, I'll see if changing the code fixes it.

author: Bassman59
author_rank: Super Contributor
timestamp: August 27, 2014, 08:41:40 pm
content: Quote from: c4757p on August 27, 2014, 06:50:41 pmNo, actually it should be:Code:foo : process (clk) isbeginif rising_edge(clk) thenif (tick = '1') thenend if;end if;end process foo;Assuming that the signal tick is a one-clock-wide strobe. If not, then you need to delay it and look for an edge in the usual way:Code:bar : process (clk) isbeginif rising_edge(clk) thentick_d <= tick; -- delay flop for edge detectif tick = '1' and tick_d = '0' then -- on rising edge of tick.. do something ...end if;end if;end process bar;The point is that the rising_edge() function is used only on the clock signal. If you want to find the edge of a non-clock signal, you have to delay it and do the comparison.

author: ion
author_rank: Regular Contributor
timestamp: August 28, 2014, 08:58:38 am
content: Thanks guys, using the rising_edge() function got it working (sort of - didn't realise the FPGA was hooked up to the LED's cathodes, but that was an easy fix).Quote from: Bassman59 on August 27, 2014, 08:41:40 pmActually tick and clk are used is separate processes, not even in the same module. So replacing the= '1'withrising_edge()in each case was enough to make it work.Tick and clk are both clock signals - 3 MHz and 3 Hz respectively.QuoteGood to know, thanks.