0
votes

After being yesterday and today I have managed to solve a few problems but I've gotten stuck again. When doing the counter I have put a loop so that it counts from 1 to 53 and then reset to zero again. The problem appears when to check that it works correctly I start the testbench and the signal is not updated at all.

-- Process incorporated in vhdl
entity semaforo is
Port ( sensor : in  STD_LOGIC;
       clk : in  STD_LOGIC;
       rst_n : in  STD_LOGIC;
       light_highway : out  STD_LOGIC_VECTOR (2 downto 0);
       light_farm : out  STD_LOGIC_VECTOR (2 downto 0));
 end semaforo;

architecture Behavioral of semaforo is

signal cuenta: std_logic_vector(6 downto 0):="0000000";

begin 

flip_flop: process (clk, rst_n)

begin

if (rst_n='0') then 

 light_highway <="001";

 light_farm <="100";

elsif (clk'event and clk='1') then 

 if (sensor='1') then   

  light_highway<="010";

 end if;

end if;

 end process;


contador : process (clk, rst_n)

begin

if rst_n = '0' then

  cuenta <= (others => '0');

elsif rising_edge(clk) then

  if sensor = '1' then

    if cuenta < 53 then

      cuenta <= cuenta + 1;

    else

      cuenta <= (others => '0');

    end if;  -- count/wrap

  end if;    -- clock enable

end if;      -- async reset/clock

 end process;

end Behavioral;

In the case that you remove the for and simply update the counter directly if it works but I need the counter to start adding up from the first time that sensor = '1' and that once the account started it does not stop (even if the sensor signal) until you reach the limit. Attached also capture of the testbench.

2

2 Answers

1
votes

This code won't compile. However, your basic problem is how processes work, and the loop. The process carries on executing until it suspends (in this case, at the end). When execution hits a variable assignment, the variable is updated immediately. When execution hits a signal assignment, the assignment is scheduled to take place at some point in the future, after the process suspends. Look up delta cycles and the scheduling model.

So, in this case, the entire loop is executed during one activation of the process, at a clock rising edge. Each scheduled ('non-blocking') assignment to account simply over-rides the previous scheduled assignment to account. The last assignment to account wins, so when we get to the end of the process, the scheduler has a single scheduled assignment: it assigns zero to account.

EDIT

I think you're just asking for a 6-bit counter, with an async reset, a count enable, and wrap-around. Generic code below. Note that this requires VHDL 2008 to read back the account output in order to increment it.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity E is
  port(
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    sensor  : in  std_logic;
    account : out unsigned(5 downto 0));
end entity E;

architecture A of E is
begin
  counter : process (clk, rst_n)
  begin
    if rst_n = '0' then
      account <= (others => '0');
    elsif rising_edge(clk) then
      if sensor = '1' then
        if account < 53 then
          account <= account + 1;
        else
          account <= (others => '0');
        end if;  -- count/wrap
      end if;    -- clock enable
    end if;      -- async reset/clock
  end process;
end architecture A;
0
votes

VHDL didn't have loop like c++. Delete loop statement. Every time CLK rising edge happen Your counter will count.