unpredictable FPGA behaviour

Hi there,

I apologize for the unspecific subject, but for me it is like that.

I am working on an FPGA project which consists of a CPU (8bit), a UART, a sensor keypad controller, LCD module controller, and SPI flash controller. Since all these modules need a clock to run, but with different clock speeds I decided to do a dedicated "clock generator" module which divides the various frequencies from the master clock. The "unpredictable behaviour" manifests itself most prominently in this clock generator module; although I assume that there might be other effects as well. The sequence is this:

- I edit a VHDL source file (currently I am working on the keypad controller module)

- I compile the project

- I load the bitstream into the FPGA

- the CPU would not run, or maybe the LCD, or maybe the SPI or the UART

The point I quite do not understand is that the area I made the last changes definitely does have nothing to do with the affected design area (e.g. keypad - LCD). (ha, I am sounding like a SW developer...) Anyway, to give a bit more information here is like I implemented the clock dividers:

****************************** code ****************************** library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;

entity clock_generator is port ( rst : in std_logic; clk_in : in std_logic; -- input clock (25MHz) sel : in std_logic; nWR : in std_logic; ddrive : in std_logic; d_in : in std_logic_vector (7 downto 0); d_out : out std_logic_vector (7 downto 0); cpu_clk : out std_logic; -- CPU clock (3Hz .. 12.5MHz) uart_clk : out std_logic; -- UART clock (115.2kHz:38400b/sec) lcd_clk : out std_logic; -- LCD controller clock (1MHz) key_clk : out std_logic; -- keypad controller clock (333kHz) spi_clk : out std_logic -- SPI controller clock (6.25MHz) ); end clock_generator;

architecture divider of clock_generator is constant SYS_FREQ : integer := 25000000; -- 25MHz constant UART_FREQ : integer := 115200; -- 3*38.4kHz constant LCD_FREQ : integer := 1000000; -- 1MHz constant KEY_FREQ : integer := 333333; -- 333kHz constant SPI_FREQ : integer := 6250000; -- 6.25MHz signal uart_cnt : integer; signal lcd_cnt : integer; signal key_cnt : integer; signal spi_cnt : integer; signal cpu_cnt, cpu_end : std_logic_vector (23 downto 0); signal cpu_div : std_logic_vector (7 downto 0); signal wr_cpu_div : std_logic; begin -- write the clock divider wr_cpu_div

Reply to
Johannes Hausensteiner
Loading thread data ...

[snip]

The best advice you'll probably get here is to clock everything with your 25 MHz oscillator and use clock enables to slow down the various modules. This will avoid problems with clock domain crossings and simplify the clock distribution.

If you're comfortable with the clock crossing issues, and you still want to run with multiple clocks, make sure your implemetation is using the global clock routing resources (use the design planner to force use of primary clock distribution for as many clocks as this supports, usually 4). Also realize that although the clocks are generated from the same input clock, the delay from the

25 MHz rising edge to the generated clock rising edge may have significant differences from clock to clock, especially due to routing delays. So you'll need to treat clocks as asynchronous unless you make sure your various counters don't create more than one output clock rising edge on the same rising edge of 25 MHz. Finally realize that the timing from clock to clock will not be computed by the TRACE program unless you specify cross-clock analysis. It's unlikely that you will have setup violations at 25 MHz, but unless you deal with clock to clock skew issues you can easily end up with hold violations.

HTH, Gabor

Reply to
Gabor

Johannes I made a simple test bench using Xilinx ISE 8.2i. I made Reset briefly active. I loaded x"00" into "cpu_div". I simulated using ModelSim XE III (Xilinx Edition), vers 6.0d. Clock output results: cpu_clk = 12.5 MHz lcd_clk = 1.0 MHz spi_clk = 6.22 MHz uart_clk = 76.7 Mhz

I suggest you similate your code to see if you are getting the rusults you expect. The case statement in the "cpu_divider" process makes the process quite compilcated, and I'm not sure what the code is supposed to do. BTW, your "cpu_divider" process is missing "cpu_dev" in the process sensitivity list. HTH

-Dave Pollum

Reply to
Dave Pollum

Uzytkownik "Johannes Hausensteiner" napisal w wiadomosci news: snipped-for-privacy@news.aic.at...

Hi, I advice use of following code for generating signal UART CLK enable. Output is signal pulse which is active for one clock per N pulse of clock. This signal is using for enable your component, for example UART Core (in my projects:

formatting link
This IP block has 2 dedicated inputs: CLK and EN_16X_BAUD - this is the same enable signal). Eatch FPGA project which you create, must be synchronous - That means, that should have one global source clock (FPGA usually has several global lines for clock, reset, etc.) and lot of enable signals.

--UART_CLK

--CLK = 32.768 MHz

--UART BaudRate = 9600 => UART_CLK = 16 * BaudRate = 16 * CLK/x = CLK/N => N = 213, UART_CLK = ~153.84 kHz, UART BaudRate = ~9615 Hz process(CLK) variable CNT: std_logic_vector(8 downto 0) := (others => '0'); begin if (CLK = '1' and CLK'event) then if (CNT(CNT'left) = '1') then CNT := '0' & x"D3"; --N = 213 - 2 else CNT := CNT - 1; end if; end if; UART_EN_CLK

Reply to
Miro

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.