计数器不在FPGA中工作

时间:2018-06-15 02:50:30

标签: vhdl fpga spartan

我有一个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实际上是如何工作的,因为这很简单,我无法让它发挥作用。

1 个答案:

答案 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已与您的时钟同步时才有效。