- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to write the VHDL code for it but it is not working, it shows always 00 ( cm1 = 0 and cm0 = 0). Can you pleaseee help me? Do you detect any problem in the code:
Summation of how the sensor works: you send 10 us trigger to the sensor and then wait for the echo signal from it. The width of the echo determines the distance. In 5800 clk cycles of echo you measure 1 cm( with 100 MHZ clk of BASYS 3). Here is the code:library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity sonar is
Port ( clk : in STD_LOGIC;
trig : out STD_LOGIC;--trigger
echo : in STD_LOGIC;
cm1 : out unsigned(3 downto 0); --most significant bit of distance in binary form
cm0 : out unsigned(3 downto 0));
end sonar;
architecture sonar_arch of sonar is
signal count: integer range 0 to 5800; -- I will only measure up to 100 cm
signal tmpcm1: unsigned(3 downto 0) := "0000"; --most significant bit of ditance
signal tmpcm0: unsigned(3 downto 0) := "0000";
signal sendTrig: std_logic := '1';
begin
process(clk)
begin
if rising_edge(clk) then
if sendTrig = '1' then -- send 10us trig
if count = 10000 then -- 10 us trig is completed, reset tmp signals for the new calculation
trig <= '0';
sendTrig <= '0';
count <= 0;
tmpcm0 <= "0000";
tmpcm1 <= "0000";
else
trig <= '1';
count <= count + 1;
end if;
else -- stop sending trig, do the calculation (5800 clk cycle = 1cm)(count enters here as 0)
if echo = '1' then -- we can start calculating the width of the echo
if count = 5799 then--we measuered 1 cm
if tmpcm0 = "1001" then
if tmpcm1 = "1001" then
sendTrig <= '1';--max distance to be measured(100 cm), stop measuring, re-send the trig(also update the output)
cm0 <= tmpcm0;
cm1 <= tmpcm1;
else
tmpcm1 <= tmpcm1 + "0001";
tmpcm0 <= "0000";
end if;
else
tmpcm0 <= tmpcm0 + "0001";
end if;
count <= 0;
else
count <= count + 1;
end if;
if echo = '0' then --equivalent of if falling_edge(echo), distance is measured, send another trig(also update te output)
sendTrig <= '1';
cm0 <= tmpcm0;
cm1 <= tmpcm1;
end if;
end if;
end if;
end if;
end process;
end sonar_arch;
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, for a start, you have the following structure:
if echo = '1' then
if echo = '0' then
--this is impossible, as echo cannot be '1' and '0' at the same time
This case will never occur. If you have a "working" simulation, but it's not working in hardware, then I suggest there is something wrong with how you're testing your code. Maybe you misunderstood how the echo works? or how some other interface should work?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes I realized that mistake. I edited my code accordingly this way, but it still does not work. It either shows 99 or 00 after each reprograming the FPGA. Also I don't know how to write the testbench:( I would appreciate if you write it for me( I believe it is quite easy for a given code, otherwise I wouldn't ask such a thing.). The new code is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity sonar is
Port ( clk : in STD_LOGIC;
trig : out STD_LOGIC;--trigger
echo : in STD_LOGIC;
cm1 : out unsigned(3 downto 0); --most significant bit of distance in binary form
cm0 : out unsigned(3 downto 0));
end sonar;
architecture sonar_arch of sonar is
begin
process(clk)
variable count: integer range 0 to 10000;
variable tmpcm1: unsigned(3 downto 0) := "0000";
variable tmpcm0 : unsigned(3 downto 0) := "0000";
variable sendTrig: std_logic := '1';
variable echoPrev: std_logic:= '0';
variable echoCurrent : std_logic:= '0';
begin
if rising_edge(clk) then
if sendTrig = '1' then -- send 10us trig
if count = 1000 then -- 10 us trig is completed, reset tmp signals for the new calculation
trig <= '0';
sendTrig := '0';
count := 0;
tmpcm0 := "0000";
tmpcm1 := "0000";
else
trig <= '1';
count := count + 1;
end if;
else -- stop sending trig, do the calculation (5800 clk cycle = 1cm)(count enters here as 0)
if echo = '1' then -- we can start calculating the width of the echo
if count = 5799 then--we measuered 1 cm
if tmpcm0 = "1001" then
if tmpcm1 = "1001" then
sendTrig := '1';--max distance to be measured(100 cm), stop measuring, re-send the trig(also update the output)
cm0 <= tmpcm0;
cm1 <= tmpcm1;
else
tmpcm1 := tmpcm1 + "0001";
tmpcm0 := "0000";
end if;
else
tmpcm0 := tmpcm0 + "0001";
end if;
count := 0;
else
count := count + 1;
end if;
if echoPrev = '1' and echoCurrent = '0' then --falling edge of echo, edit the output, start sending new trigger
sendTrig := '1';
cm0 <= tmpcm0;
cm1 <= tmpcm1;
end if;
end if;
end if;
echoPrev := echoCurrent;
echoCurrent := echo;
end if;
end process;
end sonar_arch;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are many tutorials on the internet on how to write a testbench.
I suggest having a go yourself, and coming back here with any issues you are having. One thing I would recommend is that you do not use variables. Use all signals
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page