Estoy tratando de implementar algo tan simple como el controlador para un solo semáforo usando dos contadores (uno para verde / rojo y otro para amarillo), pero parece que no estoy acertando con la sincronización.
Mi primer contador parecía algo así como
entity counter is
generic (
max_count : integer := 50
);
port (
clk : in std_ulogic;
rst : in std_ulogic;
count_value : out integer := '0';
flag : out std_ulogic := '0'
);
end entity;
architecture behav of counter is
signal count : natural := 0;
begin
count_value <= count
process (rst, clk)
begin
if rst = '0' then
flag <= '0';
count <= 0;
elsif rising_edge(clk) then
count <= (count + 1) mod max_count;
if count = 0 then
-- set flag value for one cycle
flag <= '1';
else
flag <= '0';
end if;
end if;
end process;
end architecture behav;
que también establece el valor de marca cuando comienza a contar .
Cuando intenté implementar el semáforo (simplemente una máquina de estado) por medio de este contador, me quedé atascado. Cuando acabo de iniciar el contador rojo / verde c_redgreen
una vez, es decir, el contador nunca se reinicia. El problema con este enfoque es, por supuesto, que el tiempo en que el semáforo está en amarillo no se tiene en cuenta (por ejemplo, la luz comienza con rojo y permanece en ese estado durante 50 ciclos, luego se vuelve amarillo durante 5 ciclos, pero luego hay solo 45 ciclos verde, porque el contador no se detuvo durante el tiempo amarillo, etc ...). Pensé que esto podría solucionarse simplemente reiniciando c_redgreen
mientras que la luz es amarilla, pero inmediatamente después del restablecimiento, la marca se establece de inmediato y, por lo tanto, no puedo usar algo como if rising_edge(rg_flag) then ...
, porque el borde ascendente llega inmediatamente ( porque el contador establece la bandera cuando comienza).
Después de estos problemas, pensé que sería mejor reformular mi contador de la siguiente manera
...
elsif rising_edge(clk) then
temp := (count + 1) mod max_count;
count <= temp
if temp = 0 then
...
para evitar que se establezca el indicador al iniciar , pero cuando inicio el reloj (en el banco de pruebas) con 0, la primera luz roja no dura 50 ciclos, sino solo 49. También estoy no estoy seguro de si es una buena idea que un contador no haga nada hasta que haya alcanzado max_count
.
Por lo tanto, mi pregunta es cómo puedo combinar dos contadores (con o sin indicador de inicio) para poder hacer que mis luces rojas / verdes brillen durante n
ciclos y mi luz amarilla para m
ciclos. Espero haber sido lo suficientemente claro. Si fuera necesario el código de mi semáforo, puedo agregarlo (simplemente no quise hacer esta pregunta por más tiempo). Tampoco necesariamente necesito un semáforo, solo quiero que estos contadores funcionen en paralelo de alguna manera. Gracias de antemano