Tengo un problema muy frustrante y realmente agradecería alguna ayuda.
Estoy tratando de probar un bloque de RAM usando los interruptores y los LED en la placa de desarrollo Nexys A7-100T FPGA. Mi código se sintetiza bien pero falla en la implementación debido a los errores que se muestran en la imagen a continuación.
También he mostrado mi archivo de restricciones y el archivo de código de nivel superior.
Soy nuevo en las placas FPGA y no estoy seguro de lo que estoy haciendo mal. He probado este código en testbench y funciona perfecto. Me gustaría mapearlo en el FPGA para aprender cómo hacerlo.
EDITAR
Tengo los relojes comentados en el archivo de restricciones, ya que causaron aún más errores.
¡Gracias!
archivo de restricciones
#create_clock -period 10.000 -name clk -waveform {0.000 5.000} [get_ports clk]
#set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk }];
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { Set_Button }]; #IO_L12P_T1_MRCC_14 Sch=btnl
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { Enable_Button }]; #IO_L10N_T1_D15_14 Sch=btnr
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { RAM_Address[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { RAM_Address[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { RAM_Address[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { RAM_Address[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { Data_out[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { Data_out[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { Data_out[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { Data_out[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
archivo de nivel superior
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.Architecture_size.ALL;
entity RAM_Block is
Port ( RAM_Address : in std_logic_vector (Data_width-1 downto 0);
Data_in : in std_logic_vector (Data_width-1 downto 0);
Set_Button : in std_logic;
Enable_Button : in std_logic;
Data_out : out std_logic_vector (Data_width-1 downto 0));
end RAM_Block;
architecture Behavioral of RAM_Block is
component Enabler_Block is
Port ( A : in std_logic_vector(Data_width-1 downto 0);
Enable : in std_logic;
Q : out std_logic_vector(Data_width-1 downto 0));
end component;
type memory is array (0 to 3) of std_logic_vector (Data_width-1 downto 0);
signal RAM : memory := ("0000" , "0000" , "0000" , "0000");
signal RAM_output : std_logic_vector (Data_width-1 downto 0);
signal RAM_Address_int : integer;
begin
Enabler_Block_instance : Enabler_Block port map (A => RAM_output , Enable => Enable_Button , Q => Data_out);
RAM_Address_int <= conv_integer(unsigned(RAM_Address));
Process (Set_Button , Enable_Button)
begin
if(rising_edge(Set_Button) and Set_Button = '1') then
RAM(RAM_Address_int) <= Data_in;
end if;
if(rising_edge(Enable_Button) and Enable_Button = '1') then
RAM_output <= RAM(RAM_Address_int);
end if;
end Process;
end Behavioral;
El problema son las declaraciones:
if(rising_edge(Set_Button) and Set_Button = '1')
.
.
if(rising_edge(Enable_Button) and Enable_Button = '1')
Cuando sintetiza este código, el sintetizador reconoce estas dos señales como los relojes en su diseño. Estos también son puertos de entrada en su módulo. Si estas señales fueran realmente entradas de reloj en su diseño (que no creo que tuviera la intención de hacerlo), debería asignarlas a pines con capacidad de reloj en el FPGA. De lo contrario, el sintetizador no podrá usar el enrutamiento de reloj dedicado desde los respectivos IO a través de BUFG, a los flip-flops sincronizados por ellos. Por lo tanto, los mensajes de error.
Bueno, de todos modos, no creo que tuviera la intención de usarlos como relojes, así que esto es lo que podría estar buscando en su lugar:
if rising_edge(clk) then
if Enable_button = '1' then
..
end if
if Set_button = '1' then
...
end if
end if
Su diseño tal como está no está cronometrado en absoluto.
Esto será difícil de sintetizar ya que los registros en los bloques lógicos tienen un reloj y una entrada de habilitación, y se supone que el FF cambia en un flanco ascendente del reloj mientras la habilitación está configurada.
En cambio, lo que está haciendo es tomar datos en el flanco ascendente de una señal de habilitación, que debe sintetizarse derivando la señal de "habilitación" a la entrada de reloj del FF. Dado que el enrutamiento del reloj es independiente (debido a que los relojes tienen requisitos estrictos de temporización y fanout alto), generalmente no existe un buen mecanismo para eso.
El mensaje de error que recibe se queja de que está enrutando un pin de entrada que no es compatible con el reloj a una red de reloj, lo que conduce a un enrutamiento muy complicado porque el único lugar para conectarlos es en el otro lado del chip.
La restricción que sugiere aclararía que no está solicitando que esta señal se inyecte en una red de distribución de reloj, lo que relajaría el problema de enrutamiento aquí, pero limitaría el despliegue de la señal.
Es probable que la restricción también genere el enrutamiento que espera, con el reloj atado alto y la habilitación enrutada al FF, pero sin restricción de tiempo en la habilitación, porque las restricciones se rastrean contra un reloj interno, que usted no tiene.
El problema debería desaparecer si realmente haces que este diseño esté cronometrado.
El mensaje le dice que uno de los pines se está utilizando como reloj, pero en realidad no es un buen pin para usar como reloj. Primero me desharía del extra "and Set_Button = '1')" y "and Enable_Button='1')". Solo necesita la parte "rising_edge".
También debe dividir el proceso en dos procesos y hacer que cada uno sea sensible a su reloj respectivo.
Si aún recibe el error, ¿puede elegir pines diferentes para "Set_Button" y "Enable_Button"?
Solo proporciona una actualización a esta pregunta. Según el consejo de todos, modifiqué mi VHDL para sincronizar el diseño y el problema está resuelto. Esto permitió que el sintetizador usara pines con capacidad de reloj para el reloj y los otros pines para establecer y habilitar la entrada.
Sin embargo, me ha causado más problemas a lo largo de mi diseño completo, ya que tengo este mismo problema en otro código VHDL. Gracias por la ayuda de todos. He aceptado una respuesta, sin embargo, la respuesta de todos fue muy útil y muy apreciada.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.Architecture_size.ALL;
entity RAM_Block is
Port ( Clock : in std_logic;
RAM_Address : in std_logic_vector (Data_width-1 downto 0);
Data_in : in std_logic_vector (Data_width-1 downto 0);
Set : in std_logic;
Enable : in std_logic;
Data_out : out std_logic_vector (Data_width-1 downto 0);
RAM_Address_LED : out std_logic_vector (Data_width-1 downto 0);
Data_in_LED : out std_logic_vector (Data_width-1 downto 0));
end RAM_Block;
architecture Behavioral of RAM_Block is
component Enabler_Block is
Port ( A : in std_logic_vector(Data_width-1 downto 0);
Enable : in std_logic;
Q : out std_logic_vector(Data_width-1 downto 0));
end component;
type ram_type is array (0 to 3) of std_logic_vector (Data_width-1 downto 0);
signal RAM : ram_type := (others => "0000");
signal RAM_output : std_logic_vector (Data_width-1 downto 0);
signal RAM_Address_int : integer;
begin
Data_in_LED <= Data_in;
RAM_Address_LED <= RAM_Address;
Enabler_Block_instance : Enabler_Block port map (A => RAM_output , Enable => Enable , Q => Data_out);
RAM_Address_int <= conv_integer(unsigned(RAM_Address));
Process (Clock)
begin
if(rising_edge(Clock)) then
if(Set = '1') then
RAM(RAM_Address_int) <= Data_in;
end if;
end if;
end process;
Process (Clock)
begin
if(rising_edge(Clock)) then
if(Enable = '1') then
RAM_output <= RAM(RAM_Address_int);
end if;
end if;
end Process;
end Behavioral;
```
máximo
máximo
mitu raj
David777