Juanea7
Juanea7

Reputation: 15

VHDL - My code is synthesizable and works the way i want on simulation, but it doesn't on the fpga

My VHDL-Code is functionaly correct, in simulation it does what it's thought for. I tested in many variations and the code works correct.

But when i program the fpga (Nexyx 4 ddr) everything works well except the preload of the counter.

I don't know if the load enable (load_e) output from the fsm doesn't reach the counter or if the output signal that sais the counter is loaded (counter_loaded) doesn't reach the fsm but when i program the fpga it never pases from state C or D (waiting for counter loaded) to state E or F (where it makes a countdown).

I tested the other parts of the code in the target and it works properly, so the only problema so far is that one and i can't find the error, i'm thinking about timming, but i have no idea of how to solve it.

I leave here the counter and fsm code, as well as the TOP code, i`m new in VHDL and it might be lots of bad practice mistakes.

I'm spanish, that's the reason of my bad English and also the spanish name of some signal, but i add a comment next to them.

--------COUNTER---------------------------------------

entity counter is
Generic (NBITS    : positive := 15
        );
Port    (clk      : in STD_LOGIC;
        rst      : in STD_LOGIC;
        ce       : in STD_LOGIC;
        load     : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
        load_e   : in STD_LOGIC;
        unit     : out STD_LOGIC_VECTOR(3 downto 0); 
        dec      : out STD_LOGIC_VECTOR(3 downto 0); 
        zero_n   : out STD_LOGIC;                   --true si cuenta = 0
        loaded   : out STD_LOGIC);
end counter;

architecture Behavioral of counter is
signal q_i : unsigned (NBITS-1 downto 0) := (others => '1');
begin  
    process(clk,rst)
        begin
            if rst = '1'    then
                q_i <= (OTHERS => '1');
                loaded <= '0';
            elsif rising_edge(clk)  then
                if CE = '1' then
                    if load_e = '1' then             --ONE OF MY GUESSES OF THE PROBLEM
                        q_i <= unsigned(load);
                        loaded <= '1';
                    else
                        q_i <= q_i - 1;
                        loaded <= '0';                        
                    end if;
                end if;
            end if;              
        end process;     
    dec <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) / 10),dec'length));      --first 5 bits are the tens        
    unit <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) rem 10),unit'length));  --fist 5 bits are the unit
    zero_n <= '1' WHEN q_i < "000010000000000" ELSE '0';        --cout is zero if the first 5 bits are less tan 1 in binary
end Behavioral;

------FINITE STATE MACHINE--------------------------------

entity maquina_estados is
Port ( 
    clk : in STD_LOGIC;
    rst : in STD_LOGIC;
    corto : in STD_LOGIC;
    largo : in STD_LOGIC;
    b_on : in STD_LOGIC;
    zero_n : in STD_LOGIC;
    counter_loaded : in STD_LOGIC;
    load_e : out STD_LOGIC;
    load : out STD_LOGIC_VECTOR(14 downto 0);
    bomba_led : out STD_LOGIC;
    indica_on : out STD_LOGIC);
end maquina_estados;

architecture Behavioral of maquina_estados is

type state_type is (A, B, C, D, E, F);  --define state(A = powered off, B = powered on, C = short coffee preload, D = large coffee preload, E = short coffee, F = large coffee)

signal state, next_state : state_type;  --type state signal

begin 
    process(clk,rst)
        begin
            if rst = '1' then
                state <= A;
            elsif rising_edge(clk) then
                state <= next_state;
            end if;
    end process;

    process(state, b_on, corto, largo, zero_n, counter_loaded)
        begin
            CASE state IS
                WHEN A =>   if b_on = '1' then
                                next_state <= B;
                            else
                                next_state <= A;
                            end if;
                WHEN B =>   if b_on = '0' then
                                next_state <= A;
                            elsif corto = '1' then
                                next_state <= C;
                            elsif largo = '1' then
                                next_state <= D;
                            else
                                next_state <= B;
                            end if;
                WHEN C =>   if counter_loaded = '1' then
                                next_state <= E;
                            else
                                next_state <= C;
                            end if;
                WHEN D =>   if counter_loaded = '1' then
                                next_state <= F;
                            else
                                next_state <= D;
                            end if;
                WHEN E =>   if zero_n = '1' then
                                next_state <= B;
                            else
                                next_state <= E;
                            end if;
                WHEN F =>   if zero_n = '1' then
                                next_state <= B;
                            else
                                next_state <= F;
                            end if;
                WHEN OTHERS => next_state <= A;
            end case;
    end process;

    process(state)
        begin
            CASE state IS
                WHEN A =>   load        <= "111111111111111";  --default value of the count 
                            load_e      <= '0';
                            bomba_led   <= '0';
                            indica_on   <= '0';
                WHEN B =>   load        <= "111111111111111";
                            load_e      <= '0';
                            bomba_led   <= '0';
                            indica_on   <= '1';
                WHEN C =>   load        <= "010101111111111";  --10 second, this in addition to a 1024 hz clock made posible to use the first 5 bits as the number
                            load_e      <= '1';
                            bomba_led   <= '0';
                            indica_on   <= '1';
                WHEN D =>   load        <= "101001111111111";  --20 seconds
                            load_e      <= '1';
                            bomba_led   <= '0';
                            indica_on   <= '1';
                WHEN E =>   load        <= "111111111111111";
                            load_e      <= '0';
                            bomba_led   <= '1';
                            indica_on   <= '1';
                WHEN F =>   load        <= "111111111111111";
                            load_e      <= '0';
                            bomba_led   <= '1';
                            indica_on   <= '1';
            end case;
    end process;
end behavioral;

------TOP-----------------------

entity TOP is
Generic(
FIN     : positive := 100000000;
FOUT    : positive := 1024);
Port ( clk : in STD_LOGIC;
       rst : in STD_LOGIC;
       corto : in STD_LOGIC;
       largo : in STD_LOGIC;
       b_on : in STD_LOGIC;
       display_number : out STD_LOGIC_VECTOR (6 downto 0);
       display_selection : out STD_LOGIC_VECTOR (7 downto 0);
       bomba_led : out STD_LOGIC;
       indica_on : out STD_LOGIC);
end TOP;

architecture Behavioral of TOP is



  --instancies

  component clk_divider is
   --  Port ( );
   generic(
FIN     :   positive;
FOUT    :   positive
);
port ( 
Clk     :   in STD_LOGIC;
Reset   :   in STD_LOGIC;
Clk_out :   out STD_LOGIC
);
end component;


component maquina_estados is
Port ( clk : in STD_LOGIC;
       rst : in STD_LOGIC;
       corto : in STD_LOGIC;
       largo : in STD_LOGIC;
       b_on : in STD_LOGIC;
       zero_n : in STD_LOGIC;
       counter_loaded : in STD_LOGIC;
       load_e : out STD_LOGIC;
       load : out STD_LOGIC_VECTOR(14 downto 0);
       bomba_led : out STD_LOGIC;
       indica_on : out STD_LOGIC);
end component;

component counter is
Generic (NBITS    : positive
        );
Port    (clk      : in STD_LOGIC;
        rst      : in STD_LOGIC;
        ce       : in STD_LOGIC;
        load     : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
        load_e   : in STD_LOGIC;
        unit     : out STD_LOGIC_VECTOR(3 downto 0); 
        dec      : out STD_LOGIC_VECTOR(3 downto 0); 
        zero_n   : out STD_LOGIC;                   
        loaded   : out STD_LOGIC);
end component;


component clk_manager is
generic(
CLK_FREQ : positive
);
Port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
strobe_1024Hz : out STD_LOGIC;
strobe_128Hz : out STD_LOGIC
);
end component;

component decoder is
Port ( code : in STD_LOGIC_VECTOR(3 downto 0);
       led : out STD_LOGIC_vector(6 downto 0)
      );
end component;

component display_refresh is
Port ( clk                  : in STD_LOGIC;
       ce                   : in STD_LOGIC;
       segment_unit         : in STD_LOGIC_VECTOR (6 downto 0);
       segment_dec          : in STD_LOGIC_VECTOR (6 downto 0);
       display_number       : out STD_LOGIC_VECTOR (6 downto 0);
       display_selection    : out STD_LOGIC_VECTOR (1 downto 0));   --cada elemento del vector corresponde a un 7 seg, true se ve false no
end component;                                                   


-- prescaler signals

signal prescaler_clk_out : STD_LOGIC;

--maquina estados signals
signal zero_n_fsm : STD_LOGIC;
signal load_e_fsm : STD_LOGIC;
signal load_fsm : STD_LOGIC_VECTOR(14 downto 0);
signal bomba_led_fsm: STD_LOGIC;
--counter signals
signal unit : STD_LOGIC_VECTOR(3 downto 0); 
signal dec      : STD_LOGIC_VECTOR(3 downto 0); 
signal zero_n_cntr : STD_LOGIC;
signal load_e_cntr : STD_LOGIC;
signal load_cntr : STD_LOGIC_VECTOR(14 downto 0);
signal counter_loaded : STD_LOGIC;
--clk_manager signals
signal strobe_1024Hz : STD_LOGIC;
signal strobe_128Hz : STD_LOGIC;

signal ce_clkm : STD_LOGIC;
signal rst_clkm : STD_LOGIC;

--decoders signals

signal unit_code : STD_LOGIC_VECTOR(6 downto 0);
signal dec_code : STD_LOGIC_VECTOR(6 downto 0);

--display refresh signals

signal display_refresh_number : STD_LOGIC_VECTOR(6 downto 0);
signal display_refresh_selection : STD_LOGIC_VECTOR(1 downto 0); 

begin

prescaler: clk_divider
    generic map(
    FIN     =>   FIN,
    FOUT    =>   FOUT
    )
    port map( 
    Clk     =>   clk,
    Reset   =>   rst,
    Clk_out =>   prescaler_clk_out
    ); 

sm: maquina_estados
    Port map( clk => prescaler_clk_out,
           rst => rst,
           corto => corto,
           largo => largo,
           b_on => b_on,
           zero_n => zero_n_fsm,
           counter_loaded => counter_loaded,
           load_e => load_e_fsm,
           load => load_fsm,
           bomba_led => bomba_led_fsm,
           indica_on => indica_on);

cntr: counter 
Generic map(NBITS    => 15
        )
Port map(clk      => clk,
        rst      => rst,
        ce       => strobe_1024Hz,
        load     => load_cntr,
        load_e   => load_e_fsm,
        unit     => unit,
        dec      => dec,
        zero_n   => zero_n_cntr,                 
        loaded   => counter_loaded);

   clk_m: clk_manager 
       generic map(
       CLK_FREQ => FIN
       )
       Port map(
       clk => clk,        
       rst => rst,
       strobe_1024Hz => strobe_1024Hz,
       strobe_128Hz => strobe_128Hz
       ); 

   unit_dcd: decoder 
       Port map( 
       code => unit,
       led => unit_code
       );

    dec_dcd: decoder 
      Port map( 
      code => dec,
      led => dec_code
      );

    dr: display_refresh 
     Port map(
     clk                  => clk,       
     ce                   => strobe_128Hz,
     segment_unit         => unit_code,
     segment_dec          => dec_code,
     display_number       => display_refresh_number,
     display_selection    => display_refresh_selection);   


    display_number <= display_refresh_number WHEN bomba_led_fsm = '1' ELSE "1111111";
    display_selection <= ("111111" & display_refresh_selection) WHEN bomba_led_fsm = '1' ELSE "11111111";
    zero_n_fsm <= zero_n_cntr;
    bomba_led <= bomba_led_fsm;
    load_cntr <= load_fsm;      
end Behavioral;

Here are all the reports that the implementation ans sythesis gave me:

Synthesis reports

implementation reports 1/6

implementation reports 2/6

implementation reports 3/6

implementation reports 4/6

implementation reports 5/6

implementation reports 6/6

I hope someone could find the problema and give me a solution or a way of how to debug this problem.

Thanks.

Upvotes: 0

Views: 361

Answers (1)

EML
EML

Reputation: 10280

Your FSM is clocked on prescaler_clk_out, and your counter is clocked on clk, which is a red flag. This could easily lead to an implementation failure.

  • Draw a timing diagram showing all your clocks and resets, and your lower-frequency enables (in particular, strobe_1024Hz)
  • Try to clock all the logic on the same clock, presumably clk, and make sure that everything is synchronous to this clock (in other words, inputs have sufficient setup and hold times relative to this clock)
  • Make sure you are actually resetting the chip

Once you've done the timing diagram, write a constraints file that tells the synthesiser what your clocks are. clk_manager and clk_divider may be an issue here, but hopefully everything will be clocked on just 'clk', and the contstraints file will contain only the clock name and frequency. If you still can't get it to work, ask a new question, showing your timing diagram, and your attempt at a constraints file.

Upvotes: 1

Related Questions