У меня очень неприятная проблема, и я был бы очень признателен за помощь.
Я пытаюсь протестировать блок оперативной памяти с помощью переключателей и светодиодов на плате разработки Nexys A7-100T FPGA. Мой код синтезируется нормально, но не работает из-за ошибок, показанных на изображении ниже.
Я также показал свой файл ограничений и файл кода верхнего уровня.
Я новичок в платах FPGA и не уверен, что делаю неправильно. Я проверил этот код на тестовом стенде, и он отлично работает. Хотел бы отобразить его на FPGA, чтобы узнать, как это сделать.
РЕДАКТИРОВАТЬ
Я закомментировал часы в файле ограничений, так как они вызвали еще больше ошибок.
Спасибо!
Файл ограничений
#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]
Файл верхнего уровня
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;
Проблема в утверждениях:
if(rising_edge(Set_Button) and Set_Button = '1')
.
.
if(rising_edge(Enable_Button) and Enable_Button = '1')
Когда вы синтезируете этот код, синтезатор распознает эти два сигнала как часы в вашем проекте. Это также входные порты в вашем модуле. Если эти сигналы действительно были тактовыми входами в вашем проекте (что я не думаю, что вы намеревались это сделать), вы должны сопоставить их с тактовыми выводами в FPGA. В противном случае синтезатор не сможет использовать выделенную тактовую маршрутизацию от соответствующих IO через BUFG к синхронизируемым ими триггерам. Отсюда и сообщения об ошибках.
Ну, в любом случае, я не думаю, что вы собирались использовать их как часы, так что это то, что вы могли бы искать вместо этого -
if rising_edge(clk) then
if Enable_button = '1' then
..
end if
if Set_button = '1' then
...
end if
end if
Ваш дизайн как таковой вообще не синхронизирован.
Это будет сложно синтезировать, так как регистры в логических блоках имеют тактовый сигнал и вход разрешения, и предполагается, что FF переключается по переднему фронту тактового сигнала, пока установлено разрешение.
Вместо этого вы принимаете данные по переднему фронту разрешающего сигнала, который должен быть синтезирован путем шунтирования «разрешающего» сигнала на тактовый вход FF. Так как маршрутизация часов является отдельной (поскольку часы имеют большое разветвление и строгие требования к времени), обычно для этого нет хорошего механизма.
Сообщение об ошибке, которое вы получаете, жалуется на то, что вы направляете входной контакт, который не поддерживает синхронизацию, к сети часов, что приводит к очень запутанной маршрутизации, поскольку единственное место для их подключения находится на другой стороне чипа.
Ограничение, которое он предлагает, поясняет, что вы не просите, чтобы этот сигнал вводился в сеть распределения часов, что ослабило бы здесь проблему маршрутизации, но ограничило бы разветвление сигнала.
Ограничение также, вероятно, генерирует ожидаемую маршрутизацию, при которой часы привязаны к высокому уровню, а разрешение перенаправляется на FF, но без ограничений по времени для разрешения, поскольку ограничения отслеживаются внутренними часами, которых у вас нет.
Проблема должна исчезнуть, если вы действительно сделаете этот дизайн синхронизированным.
В сообщении говорится, что один из выводов используется в качестве часов, но на самом деле этот вывод не подходит для использования в качестве часов. Я бы сначала избавился от лишних "и Set_Button = '1')" и "и Enable_Button = '1')". Вам нужна только часть «rising_edge».
Вы также должны разделить процесс на два процесса и сделать каждый из них чувствительным к своим часам.
Если вы все еще получаете сообщение об ошибке, можете ли вы выбрать разные контакты для «Set_Button» и «Enable_Button»?
Просто предоставив обновление для этого вопроса. По общему совету я изменил свой VHDL, чтобы синхронизировать дизайн, и проблема решена. Это позволило синтезатору использовать контакты, поддерживающие синхронизацию, для часов, а другие контакты — для установки и включения ввода.
Однако это вызвало у меня больше проблем во всем моем дизайне, поскольку у меня есть такая же проблема в другом коде VHDL. Спасибо всем за помощь. Я принял ответ, однако ответ каждого был очень полезен и очень ценен!
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;
```
максимус
максимус
Миту Радж
Давид777