Estoy tratando de sintetizar un diseño en VHDL en un FPGA ProASIC3 usando la herramienta Synplify Pro. El informe de síntesis me da la siguiente advertencia sobre los relojes inferidos.
@W:MT420 : | Found inferred clock counter_unit| pstate_inferred_clock[1] with period 10.00ns. Please declare a user-defined clock on object "n:bcu_ins.ctr_ins.pstate[1]"
Me remonté a la parte del código donde se está generando la advertencia y la misma se reproduce aquí como referencia.
p_fsm_clk : process(reset_n_in, clk_25mhz_in)
begin
if (reset_n_in = '0') then
pstate <= s0;
elsif rising_edge(clk_25mhz_in) then
pstate <= nstate;
end if;
end process p_fsm_clk;
p_fsm : process(pstate,restart_ctr,enable_ctr2,sys_fail)
begin
start_ctr1 <= '0';
start_ctr2 <= '0';
case pstate is
when s0 =>
--Reset state. All counters are reset
if (sys_fail = '0' and restart_ctr = '1') then
nstate <= s1; --move to start counter1
else
nstate <= s0;
end if;
when s1 =>
start_ctr1 <= '1'; --Initiate counter1
if (restart_ctr = '1') then
--restart the counters
start_ctr1 <= '0'; --reset counter1
nstate <= s1;
elsif (enable_ctr2 = '1') then
--move to start counter2
nstate <= s2;
else
nstate <= s1;
end if;
when s2 =>
--Save the counter1 value and start counter2
start_ctr2 <= '1'; --assert flag to start counter2
if (restart_ctr = '1') then
--restart the counters
nstate <= s1;
else
nstate <= s3;
end if;
when s3 =>
start_ctr2 <= '1';
if (sys_fail = '1') then
nstate <= s0;
elsif (restart_ctr = '1') then
--restart the counters
nstate <= s1;
else
nstate <= s3;
end if;
when others =>
nstate <= s0;
end case;
end process p_fsm;
--counter1
p_ctr1 : process(reset_n_in, clk_25mhz_in)
begin
if (reset_n_in = '0') then
ctr1 <= 0; --value on reset
elsif rising_edge(clk_25mhz_in) then
if (start_ctr1 = '1') then
--flag is asserted to start counter1
ctr1 <= ctr1 + 1; --increment counter
else
--flag de-asserted
ctr1 <= 0; --reset the counter
end if;
end if;
end process p_offset_cnt;
--save the value of counter1
offset_val <= ctr1 when pstate = s2;
La lógica contiene dos contadores: ctr1
y ctr2
. Los contadores se ejecutan cuando no hay fallas en el sistema. En la primera fase se ejecuta ctr1
, seguido de ctr2
. ctr1
deja de contar cuando ctr2
está habilitado. El valor de ctr1
determina cuánto más tarde se iniciará ctr2
(en términos de un período de reloj de 25MHz), denominado compensación. Este valor de compensación se almacena en un vector de señal, como se puede ver en la última línea del código. El estado s2
se utiliza para capturar el valor de ctr1
antes de restablecerse a 0.
offset_val <= ctr1 when pstate = s2;
Me di cuenta de que esta declaración de asignación está causando el reloj inferido en el diseño (pero no sé por qué). Cuando coloco la misma declaración dentro de un proceso temporizado, la advertencia de reloj inferido desaparece. Sin embargo, mi lógica no funciona correctamente.
Estoy buscando algunas aclaraciones al respecto.
- ¿Por qué hay un reloj inferido en pstate [1] en este diseño?
- ¿Está bien tener tales declaraciones en el diseño? ¿La presencia de relojes inferidos indica una mala práctica de diseño?
- Si no está bien tener relojes inferidos en el diseño, ¿cómo puedo solucionar esto al codificar la lógica de manera diferente?
- Si está bien tener relojes inferidos, ¿cómo puedo informarle a la herramienta? ¿Qué período de restricción puedo proporcionar para tales relojes inferidos? ¿Cómo puedo determinar un período significativo para dichos relojes inferidos?