Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL. Failed Timing. Division

Status
Not open for further replies.

Giepup

Newbie level 2
Joined
Apr 29, 2018
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
16
Hello, I am new to VHDL. I want to make frequency meter from 1KHz to 300kHz and have one problem.
I use division which have great impact to timing. So maybe someone have some ideas how to solve this ?

Code:
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity Freq_Counter is
    Port (  Clk : in STD_LOGIC;
          Data : in STD_LOGIC;
           seg : out STD_LOGIC_VECTOR (6 downto 0);
           an: out STD_LOGIC_VECTOR (3 downto 0));
end Freq_Counter;

architecture Behavioral of Freq_Counter is
signal SD1 :  std_logic_vector(3 downto 0):="0000" ;
signal SD2 :  std_logic_vector(3 downto 0):="0000" ;
signal SD3 :  std_logic_vector(3 downto 0):="0000" ;
signal Freq:integer range 0 to 300 :=0;
signal N_Ticks: integer range 0 to 50000 :=0;
component Segment
port(
Clk : in STD_LOGIC;
Value1 : in STD_LOGIC_VECTOR (3 downto 0);
Value2 : in STD_LOGIC_VECTOR (3 downto 0);
Value3 : in STD_LOGIC_VECTOR (3 downto 0);
seg : out STD_LOGIC_VECTOR (6 downto 0);
an: out STD_LOGIC_VECTOR (3 downto 0));
end component;

begin

Segments : Segment
port map(
Clk => Clk,
Value1 => SD1,
Value2 => SD2,
Value3 => SD3,
seg => seg,
an => an);

process(Data,Clk)
Variable Ready : integer range 0 to 3 :=0;
Variable N_Tick: integer range 0 to 50000 :=0;
begin
--------------------------BEGIN----------------------------
if Clk'event and Clk ='1' then
case Ready is

when 0 =>

    if Data ='1' then
        Ready :=1;
    end if;

when 1 => 

    N_tick := N_tick +1;
    if Data ='0' then
        Ready:=2;
    end if;
   if N_tick > 100000 then
             N_tick:=0;
             Ready:=3;
             end if;

when 2 => 
    N_tick := N_tick +1;
    if Data ='1' then
     N_ticks <= N_tick;
     Ready:=3;
    end if;
    if N_tick > 100000 then
         N_tick:=0;
         Ready:=3;
         end if;
    
when 3 =>
 
 if Data ='0' then
 N_tick:=0;
 Ready:=0;
 end if;
 end case;
 end if;
 END PROCESS;
    
process(CLK)
constant Speed : integer:=100000;
Variable duom1 : integer range 0 to 100000 :=0;
begin
if Clk'event and Clk ='1' then
duom1:=duom1+1;
if duom1>10000 then
Freq <= Speed/N_ticks;
duom1:=0;
  end if;
  end if;
 END PROCESS;
 
 process(CLK)

 Variable D1 : integer range 0 to 9 :=0;
 Variable D2 : integer range 0 to 9 :=0;
 Variable D3 : integer range 0 to 9 :=0;
 Variable  duom2 : integer range 0 to 100000 :=0;
 begin
if Clk'event and Clk ='1' then
duom2:=duom2+1;
if duom2 > 10000 then
D3 := freq/100;
D2 :=(freq/10)mod 10 ;
D1 := freq mod 10;
if D1 = 1 then 
SD1 <= "0001";
elsif D1 = 2 then 
SD1 <= "0010";
elsif D1 = 3 then 
SD1 <= "0011";
elsif D1 = 4 then 
SD1 <= "0100";
elsif D1 = 5 then 
SD1 <= "0101";
elsif D1 = 6 then 
SD1 <= "0110";
elsif D1 = 7 then 
SD1 <= "0111";
elsif D1 = 8 then 
SD1 <= "1000";
elsif D1 = 9 then 
SD1 <= "1001";
else 
SD1 <= "0000";
end if;
-----------------------------------------------------
if D2 = 1 then 
SD2 <= "0001";
elsif D2 = 2 then 
SD2 <= "0010";
elsif D2 = 3 then 
SD2 <= "0011";
elsif D2 = 4 then 
SD2 <= "0100";
elsif D2 = 5 then 
SD2 <= "0101";
elsif D2 = 6 then 
SD2 <= "0110";
elsif D2 = 7 then 
SD2 <= "0111";
elsif D2 = 8 then 
SD2 <= "1000";
elsif D2 = 9 then 
SD2 <= "1001";
else 
SD2 <= "0000";
end if;
-----------------------------------------------------
if D3 = 1 then 
SD3 <= "0001";
elsif D3 = 2 then 
SD3 <= "0010";
elsif D3 = 3 then 
SD3 <= "0011";
elsif D3 = 4 then 
SD3 <= "0100";
elsif D3 = 5 then 
SD3 <= "0101";
elsif D3 = 6 then 
SD3 <= "0110";
elsif D3 = 7 then 
SD3 <= "0111";
elsif D3 = 8 then 
SD3 <= "1000";
elsif D3 = 9 then 
SD3 <= "1001";
else 
SD3 <= "0000";
end if;
duom2:=0;
end if;
end if;
end process;

end Behavioral;
 

For practical implementation, I would use a small FSM. Basically, a design where there is a counter that accumulates count for 1 second. After that, use the basic "can I subtract 100000, 10000, 1000?" FSM to count the number of 100000 that can be subtracted, then the number of 10000 that can be subtracted, then the number of 1000 that can be subtracted. These become the signals to the bcd converter. This is probably what the assignment wants you to do.
 

thank you. I have though about such solution, but i hoped that there is easier way to do it.
 

Ultimately, the divider timing problems are brought up because you want the result in a single clock cycle instead of enabling useful pipelining. The division is only needed once per measurement cycle and doesn't need to be particularly fast. An economic serial divider can be used for this purpose.

There are other design details that have negative timing effects like that usage of variables.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top