У меня есть компонент VHDL
, который подключен к приемнику UART
. uart
имеет 2 выходных сигнала, один для полученного байта и один для флага, который установлен в 1, когда байт завершен.
Я написал следующий модуль, который должен увеличивать счетчик для каждого нового символа и показывать, как загораются некоторые светодиоды.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
entity test is
port (
clk : in std_logic;
rst : in std_logic;
ena : in std_logic;
rx : in std_logic;
led0 : out std_logic;
led1 : out std_logic;
led2 : out std_logic;
led3 : out std_logic;
led4 : out std_logic;
led5 : out std_logic;
led6 : out std_logic;
led7 : out std_logic
);
end test;
architecture arch of test is
component UART_RX
generic (
g_CLKS_PER_BIT : integer := 115 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end component;
signal sig_Din : std_logic_vector(7 downto 0);
signal sig_Dout : std_logic_vector(7 downto 0);
signal sig_RxErr : std_logic;
signal sig_RxRdy : std_logic;
signal sig_TxBusy : std_logic;
signal sig_StartTx: std_logic;
begin
UUT : UART_RX
generic map (
g_CLKS_PER_BIT => 434
)
port map (
i_clk => clk,
i_rx_serial => rx,
o_rx_dv => sig_RxRdy,
o_rx_byte => sig_Dout
);
process(clk)
variable position : integer := 0;
variable position_v : std_logic_vector(7 downto 0) := "00000000";
begin
if(sig_RxRdy = '1') then
position := position + 1;
position_v := std_logic_vector((unsigned(position_v1), 1));
led0 <= position_v(0);
led1 <= position_v(1);
led2 <= position_v(2);
led3 <= position_v(3);
led4 <= position_v(4);
led5 <= position_v(5);
led6 <= position_v(6);
led7 <= position_v(7);
end if;
end process;
end arch;
Есть ли проблемы с реализацией? Каждый новый символ, который я отправляю, приводит к увеличению счетчика более чем на 1. И это даже не одно и то же значение каждый раз. Я, должно быть, не понимаю, как на самом деле работают FPGA
, потому что это просто, и я не могу заставить его работать.
if rising_edge(clk)
илиif falling_edge(clk)
, чтобы процесс запускался только на одном фронте тактов. - person Staszek   schedule 15.06.2018position_v1
? Что вообще означаетstd_logic_vector((unsigned(position_v1), 1))
. Опубликуйте РАБОТАЮЩИЙ минимально воспроизводимый пример. - person JHBonarius   schedule 15.06.2018position_v := std_logic_vector((unsigned(position_v1), 1));
у вас должно бытьposition_v := std_logic_vector(to_unsigned(position, 8));
Кроме того, ваш RTL не синтезирует использование переднего фронтаclk
, вместо этого создает осциллятор релаксации, управляемыйsig_RxRdy
, используемый в качестве защелки дляposition
с задержкой, обеспечиваемой цепочкой переноса для приращения, отмечая который всегда будет инвертировать хотя бы один бит. См. руководство пользователя XST для получения информации о распознаваемой последовательной логике, чувствительной к переднему фронту. - person   schedule 15.06.2018