Forum: FPGA, VHDL & Verilog Implementing VHDL FSM in Quartus with “couldn't implement registers for assignments" freq_met

Author: Rafal Och (guiness)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Hi everyone,

I'm supposed to write code for simple frequency meter. What it is 
supposed to do is:
when you press button it should measure frequency of input signal based 
on 1Hz clock signal so the outcome won't need any dividing to get 
frequency. Basically measuring input signal "peaks" in 1s period. The 
result must be shown in kHz on 2 7digt displays (30-40kHz measurement).

I thought I'm gonna use state machine diagram but even if it is 
compileable in Active HDL, I get a "Error (10822): HDL error at 
Termometr_F.vhd(69): couldn't implement registers for assignments on 
this clock edge" in Quartus...

Is there a way to implement this diagram in Quartus software? I've tried 
another method: dividing input signal by 2 to get a gate signal and then 
counting pulses but dividing is also not compilable without using 
floating point operations for which I don't have liblaries for...

Here is the code:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity Termometr_F is
    port (
        Clock: in STD_LOGIC;
        input: in STD_LOGIC;
        measure: in STD_LOGIC;
        reset: in STD_LOGIC;
        ok: out STD_LOGIC;
        output: out INTEGER);
end Termometr_F;

architecture Termometr_F_arch of Termometr_F is

signal Count: INTEGER;

type Termometr_F_type is (
    S1, S2, S3, S4);

signal Termometr_F: Termometr_F_type;


Termometr_F_machine: process (Clock)
if Clock'event and Clock = '1' then

    case Termometr_F is
        when S1 =>
            output <= 0;
            Count <= 0;
            ok <= '0';
            if measure='1' then
                Termometr_F <= S2;
            end if;
        when S2 =>
            if rising_edge(Clock) then
                Termometr_F <= S3;
            end if;
        when S3 =>
            Count <= Count+1;
            if rising_edge(input) then
                Termometr_F <= S3;
            elsif rising_edge(Clock) then
                Termometr_F <= S4;
            end if;
        when S4 =>
            output <= count-1;
            Count <= 0;
            ok <= '1';
            if reset='1' then
                Termometr_F <= S1;
            end if;
        when others =>
    end case;
end if;
end process;

end Termometr_F_arch;

Thanks in advance

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Did you see in the synthesizers user guide that the synthesizer is able 
to translate such a thing into hardware:
if Clock'event and Clock = '1' then -- This here is a rising_edge already
    if rising_edge(Clock) then 
   if rising_edge(input) then
   elsif rising_edge(Clock) then
I did never ever see a synthesizer able to translate such a construct 
into hardware. Indeed the only hardware inside a FPGA you can use is 
LUTs (for logic) and simple D-flipflops.
And a simple D-flipflop does not have multiple clock inputs like that 
you want to have. To keep things short: kick that code away and look how 
everybody in the world writes a clocked process. Yes, there must be 
only 1 clock in the process , because the D-flipflop inside the FPGA has 
only 1 clock input.

Why don't you use human readable states like (RESET, IDLE,  MEASURE, 
DISPLAY) instead of that meaningless S1...4?


Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]

Bild automatisch verkleinern, falls nötig