我有一个VHDL
组件连接到UART
接收器。 uart
有2个输出信号,一个用于接收字节,另一个用于接收字节时设置为1的标志。
我已经编写了以下模块,该模块应该为每个新的char增加一个计数器并显示它点亮了一些LED。
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;
实施有问题吗?每次发送的新char都会使计数器递增超过1.并且每次都不是相同的值。
我不能理解FPGA
实际上是如何工作的,因为这很简单,我无法让它发挥作用。
答案 0 :(得分:1)
您使用sig_RxRdy
作为递增条件。但我们无法看到该信号的行为是如何从我们没有代码的模块出来的。
根据您描述的行为o_rx_dv
输出(sig_RxRdy来自哪里)可能会超过一个clk周期。由于UART输入来自外部源,因此它的高时间可能是变量,这使得计数器增量不同。
解决方案是使用延迟版本检测sig_RxRdy
上的上升沿:
prev_sig_RxRdy <= sig_RxRdy;
sig_RxRdy_rising <= sig_RxRdy and not prev_sig_RxRdy;
然后在该信号上递增计数器。这仅在o_rx_dv已与您的时钟同步时才有效。