neanton28
Junior Member level 2
Greetings! I am trying to figure out why there is instable output of simple counter. I am using Sipeed Tang Primer 20k development board based on GW2A-LV18PG256C8/I7 FPGA. I created simple project, which uses clock divider to get output clock ~5.5 Mhz from input 27 Mhz global clock.
Top level design counter_tester.vhd looks like this:
Here is code of counter itself:
I may also include code of Gowin's generated Clock divider module, but it's nothing interesting in it and it just works:
All outputs except one pin in FPGA are configured to use same IO bank:
I connected logic analyzer which samples on 100 Mhz to output pins. First, this is overall image that we get on DSLogic analyzer. As we can see, counter in general works, bits are incremented:
Now let's zoom in
Here we see that clock frequency is only ~5 Mhz. In decoder settings I choose to decode data on rising edge of clock BT656_LLC_OUT.
But counter quite often misses with output values. Some of data lanes change after 20 ns of clock rising edge. I placed two markers, and in right bottom we can see calculated time difference.
I added colors to each data lane and zoomed it to demonstrate more clearly:
Line D5 changes 0 -> 1 same time as BT656_LLC_OUT changes 0 -> 1
But all other lines change 0 -> 1 only after 20 ns! I find it nonsense. This counter produces too much wrong values on rising edges of clock. Anyone knows what it could be the reason? I am trying to find solution for days...
Here how my dev board is connected with logic analyzer. Board to which probes are connected, is not connected by FFC to other board (ADV7391 coder)
I also have set timing constraints in Gowin EDA:
Would be thankful for any help!
Top level design counter_tester.vhd looks like this:
Code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity counter_tester is
port(
CLK_IN_27MHZ : in STD_LOGIC;
PROCESSOR_RST : in STD_LOGIC;
BT656_OUT : out STD_LOGIC_VECTOR(7 downto 0);
BT656_LLC_OUT : out STD_LOGIC
);
end counter_tester;
architecture counter_tester of counter_tester is
---- Component declarations -----
component Gowin_CLKDIV
port(
hclkin : in STD_LOGIC;
resetn : in STD_LOGIC;
clkout : out STD_LOGIC
);
end component;
component my_counter
port(
CLK : in STD_LOGIC;
RST : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR(7 downto 0)
);
end component;
---- Signal declarations used on the diagram ----
signal NET672 : STD_LOGIC;
signal NET693 : STD_LOGIC;
begin
---- Component instantiations ----
U1 : my_counter
port map(
CLK => NET672,
RST => NET693,
Q => BT656_OUT
);
NET693 <= not(PROCESSOR_RST);
U4 : Gowin_CLKDIV
port map(
hclkin => CLK_IN_27MHZ,
resetn => PROCESSOR_RST,
clkout => NET672
);
---- Terminal assignment ----
-- Output\buffer terminals
BT656_LLC_OUT <= NET672;
end counter_tester;
Here is code of counter itself:
Code:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity my_counter is
port(
CLK : in STD_LOGIC;
RST : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR(7 downto 0)
);
end my_counter;
architecture my_counter of my_counter is
signal s_Q_OUT: UNSIGNED (7 downto 0);
begin
Q <= STD_LOGIC_VECTOR(s_Q_OUT);
process( CLK )
begin
if (rising_edge(CLK)) then
if (RST = '1') then
s_Q_OUT <= (others => '0');
else
if(s_Q_OUT = x"FF") then
s_Q_OUT <= (others => '0');
else
s_Q_OUT <= s_Q_OUT + 1;
end if;
end if;
end if;
end process;
end my_counter;
I may also include code of Gowin's generated Clock divider module, but it's nothing interesting in it and it just works:
Code:
--Copyright (C)2014-2024 Gowin Semiconductor Corporation.
--All rights reserved.
--File Title: IP file
--Tool Version: V1.9.9.02
--Part Number: GW2A-LV18PG256C8/I7
--Device: GW2A-18
--Created Time: Sun Jul 21 23:14:25 2024
library IEEE;
use IEEE.std_logic_1164.all;
entity Gowin_CLKDIV is
port (
clkout: out std_logic;
hclkin: in std_logic;
resetn: in std_logic
);
end Gowin_CLKDIV;
architecture Behavioral of Gowin_CLKDIV is
signal gw_gnd: std_logic;
--component declaration
component CLKDIV
generic (
GSREN: STRING := "false";
DIV_MODE : STRING := "2"
);
port (
CLKOUT: out std_logic;
HCLKIN: in std_logic;
RESETN: in std_logic;
CALIB: in std_logic
);
end component;
begin
gw_gnd <= '0';
clkdiv_inst: CLKDIV
generic map (
GSREN => "false",
DIV_MODE => "5"
)
port map (
CLKOUT => clkout,
HCLKIN => hclkin,
RESETN => resetn,
CALIB => gw_gnd
);
end Behavioral; --Gowin_CLKDIV
All outputs except one pin in FPGA are configured to use same IO bank:
I connected logic analyzer which samples on 100 Mhz to output pins. First, this is overall image that we get on DSLogic analyzer. As we can see, counter in general works, bits are incremented:
Now let's zoom in
Here we see that clock frequency is only ~5 Mhz. In decoder settings I choose to decode data on rising edge of clock BT656_LLC_OUT.
But counter quite often misses with output values. Some of data lanes change after 20 ns of clock rising edge. I placed two markers, and in right bottom we can see calculated time difference.
I added colors to each data lane and zoomed it to demonstrate more clearly:
Line D5 changes 0 -> 1 same time as BT656_LLC_OUT changes 0 -> 1
But all other lines change 0 -> 1 only after 20 ns! I find it nonsense. This counter produces too much wrong values on rising edges of clock. Anyone knows what it could be the reason? I am trying to find solution for days...
Here how my dev board is connected with logic analyzer. Board to which probes are connected, is not connected by FFC to other board (ADV7391 coder)
I also have set timing constraints in Gowin EDA:
Code:
create_clock -name CLK_IN_27MHZ -period 37.037 -waveform {0 18.518} [get_ports {CLK_IN_27MHZ}] -add
Would be thankful for any help!