0

I am trying to make a basic distance indicating module using ultrasonic sensor. When I dumped the code for the same into my FPGA board(Helium V1.1 developed by IIT-B) all the LEDs in the board started glowing since the clock frequency was too high. So now I am using a frequency divider to reduce my clock speed but I am not getting how to use the output of my frequency divider code as an input to my main code. Can someone help me since this is the first time I am working on FPGA and I dont quite understand VHDL yet?

Code for frequency divider

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity Clock_Divider is
port ( clk,reset: in std_logic;
clock_out: out std_logic);
end Clock_Divider;

architecture bhv of Clock_Divider is

signal count: integer:=1;
signal tmp : std_logic := '0';

begin

process(clk,reset)
begin
if(reset='1') then
count<=1;
tmp<='0';
elsif(clk'event and clk='1') then
count <=count+1;
if (count = 25000) then
tmp <= NOT tmp;
count <= 1;
end if;
end if;
clock_out <= tmp;

end process;

end bhv; 

Code to measure distance using ultrasonic:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity ultrasonic is
    port(
    CLOCK: in std_logic;
    LED: out std_logic_vector(7 downto 0);
    TRIG: out std_logic;
    ECHO: in std_logic
    );
end ultrasonic;

architecture rtl of ultrasonic is

signal microseconds: std_logic;
signal counter: std_logic_vector(17 downto 0);
signal leds: std_logic_vector(7 downto 0);
signal trigger: std_logic;

begin
    
    process(CLOCK)
    variable count0: integer range 0 to 7;
    begin
        if rising_edge(CLOCK) then
            if count0 = 5 then
                count0 := 0;
            else
                count0 := count0 + 1;
            end if;
            if count0 = 0 then
                microseconds <= not microseconds;
            end if;
        end if;
    end process;
    
    process(microseconds)
    variable count1: integer range 0 to 262143;
    begin
        if rising_edge(microseconds) then
            if count1 = 0 then
                counter <= "000000000000000000";
                trigger <= '1';
            elsif count1 = 10 then
                trigger <= '0';
            end if;
            if ECHO = '1' then
                counter <= counter + 1;
            end if;
            if count1 = 249999 then
                count1 := 0;
            else
                count1 := count1 + 1;
            end if;
        end if;
    end process;
    
    process(ECHO)
    begin
        if falling_edge(ECHO) then
            if counter < 291 then
                leds <= "11111111";
            elsif counter < 581 then
                leds <= "11111110";
            elsif counter < 871 then
                leds <= "11111100";
            elsif counter < 1161 then
                leds <= "11111000";
            elsif counter < 1451 then
                leds <= "11110000";
            elsif counter < 1741 then
                leds <= "11100000";
            elsif counter < 2031 then
                leds <= "11000000";
            elsif counter < 2321 then
                leds <= "10000000";
            else
                leds <= "00000000";
            end if;
        end if;
    end process;
    
    LED <= leds;
    TRIG <= trigger;
    
end rtl;

I am using Quartus for simulating these codes.

1 Answers1

1

welcome to the HDL languages :)

For simulation clock_out is missing from the sensitivity list process(...)

For synthesis/implementation you might need to check all processes as they should be dependent on your clock signal. I've learned it's considered bad practice to use rising/falling edge on other signals than clock signals.

You probably want to go for a pattern something like:

... 
-- entity declaration
    s : in std_logic;
... 
-- architecture declaration
    signal s_d : std_logic;
begin
...
process(clk)
begin
    if rising_edge(clk) then
        -- s_d is s one clock cycle delayed
        s_d <= s;

        -- detect s transition from 0 to 1 == rising edge
        if s = '1' and s_d = '0' then
            -- Code dependent on rising edge s
        end if;
    end if;
end process;

NOTE: s may be an internal signal and is not needed to come from entity. If s is a strobe (1 clock cycle long generated with the same clock) s_d is not needed as there is no need to detect the edge, just the signal state.

Halfow
  • 77
  • 8
  • What I did was, I pasted the architecture of the frequency divider code above my distance measuring code by declaring clock_out as inout in the entity and then by making the required changes in the code. I am getting the output but the delay is very huge i.e. 7-11 seconds. Any reason for that ? – Bojack Horseman Apr 18 '22 at 00:33
  • I assume that the time of 7-11 seconds are running a simulation tool. Check the clock freq in your simulation setup and do re calculation of divider counter to ensure you are in the right time domain. Providing the updated code and test methodology would help a loot to help diagnose your problem :) – Halfow Apr 18 '22 at 09:01