Многократное чтение регистра в VHDL и инкапсуляция приводят к неправильному значению

В настоящее время я сталкиваюсь с одной проблемой при чтении двух регистров и отправляю их значение через прокси на плитку на ПЛИС. Есть три входных канала для кодированных сигналов, которые состоят из импульсов с частотой 50 кГц, затем сигнал дискретизировался с помощью локальной тактовой частоты 100 МГц на плате FPGA. В модуле были подсчитаны два канала по их импульсам, и я использую битовое смещение для инкапсуляции, чтобы поместить значение чтения из двух счетчиков в один 32-битный std_bit_vector для отправки через прокси.

Если я передаю только счетные значения одного канала и отправляю их через прокси-сигналы, это ведет себя всегда правильно. Однако при считывании двух значений счета из двух регистров и выполнении инкапсуляции 16 старших бит сдвинутого значения всегда увеличиваются быстрее, чем должно быть. Другими словами, процесс подсчета, если сам является правильным, в то время как также нет проблем со связью между модулем подсчета и плиткой.

Я не знаю, что проблема вызвана слишком быстрым чтением процесса из двух регистров и приводит к проблеме синхронизации. Входной сигнал одного канала увеличивается только на один на 500 отсчетов, а другой - на 500 на оборот. Одно вращение контролируется вручную на энкодере (тогда вы можете представить себе низкую частоту входных сигналов)

Затем инкапсуляция была помещена в последние две строки модуля. Заранее спасибо.

Модуль подсчета имеет следующую конструкцию:

 library rdt_dtl_proxy_targetlib;
use rdt_dtl_proxy_targetlib.rdt_dtl_proxy_target_cmp_pkg.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_ARITH.all; 
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;


entity dtl_pmod_rotary is
  generic (
    WIDTH_DTL_CMD_ADDR : natural:= 32;
    WIDTH_DTL_CMD_BLOCK_SIZE : natural:= 5;
    WIDTH_DTL_DATA : natural:= 32;
    WIDTH_DTL_WR_MASK : natural:= 4
  );
  port (
    clk : in std_logic;
    rst_n : in std_logic;
    rotary_a : in std_logic;
    rotary_b : in std_logic;
    rotary_i : in std_logic;
    dtl_cmd_valid_t_proxy0 : in std_logic;
    dtl_cmd_accept_t_proxy0 : out std_logic;
    dtl_cmd_addr_t_proxy0 : in std_logic_vector(WIDTH_DTL_CMD_ADDR - 1 downto 0);
    dtl_cmd_read_t_proxy0 : in std_logic;
    dtl_cmd_block_size_t_proxy0 : in std_logic_vector(WIDTH_DTL_CMD_BLOCK_SIZE - 1 downto 0);
    dtl_wr_valid_t_proxy0 : in std_logic;
    dtl_wr_last_t_proxy0 : in std_logic;
    dtl_wr_accept_t_proxy0 : out std_logic;
    dtl_wr_data_t_proxy0 : in std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
    dtl_wr_mask_t_proxy0 : in std_logic_vector(WIDTH_DTL_WR_MASK - 1 downto 0);
    dtl_rd_last_t_proxy0 : out std_logic;
    dtl_rd_valid_t_proxy0 : out std_logic;
    dtl_rd_accept_t_proxy0 : in std_logic;
    dtl_rd_data_t_proxy0 : out std_logic_vector(WIDTH_DTL_DATA - 1 downto 0)
  );
end dtl_pmod_rotary;

architecture rtl of dtl_pmod_rotary is
  signal dtl_rd_data_15 : std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
  signal dtl_rd_accept_14 : std_logic;
  signal dtl_cmd_block_size_6 : std_logic_vector(WIDTH_DTL_CMD_BLOCK_SIZE - 1 downto 0);
  signal dtl_wr_data_10 : std_logic_vector(WIDTH_DTL_DATA - 1 downto 0);
  signal dtl_cmd_read_5 : std_logic;
  signal dtl_rd_last_12 : std_logic;
  signal dtl_rst_n_1 : std_logic;
  signal dtl_wr_valid_7 : std_logic;
  signal dtl_wr_accept_9 : std_logic;
  signal dtl_wr_last_8 : std_logic;
  signal dtl_cmd_addr_4 : std_logic_vector(WIDTH_DTL_CMD_ADDR - 1 downto 0);
  signal dtl_cmd_valid_2 : std_logic;
  signal dtl_clk_0 : std_logic;
  signal dtl_rd_valid_13 : std_logic;
  signal dtl_wr_mask_11 : std_logic_vector(WIDTH_DTL_WR_MASK - 1 downto 0);
  signal dtl_cmd_accept_3 : std_logic;

  -- signals for counting
  signal cnt_r         : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
  signal cnt_r_a       : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
  signal cnt_r_b       : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
  signal cnt_r_i       : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";

  signal cnt_nxt_a     : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
  signal cnt_nxt_b     : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
  signal cnt_nxt_i     : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";
  signal cnt_ref_i     : std_logic_vector(WIDTH_DTL_DATA-1 downto 0) := X"00000000";

  signal rotary_a_r  : std_logic;                                    --register storing data from rotary_a.
  signal rotary_a_2r : std_logic;                                    --register storing data from rotary_a_r

  signal rotary_b_r  : std_logic;                                    --register storing data from rotary_b.
  signal rotary_b_2r : std_logic;                                    --register storing data from rotary_b_r

  signal rotary_i_r : std_logic;                                    --register storing data from rotary_i.
  signal rotary_i_2r : std_logic;                                    --register storing data from rotary_i_r



  begin
  dtl_clk_0 <= clk;
  dtl_rst_n_1 <= rst_n;
  dtl_cmd_valid_2 <= dtl_cmd_valid_t_proxy0;
  dtl_cmd_accept_t_proxy0 <= dtl_cmd_accept_3;
  dtl_cmd_addr_4 <= dtl_cmd_addr_t_proxy0;
  dtl_cmd_read_5 <= dtl_cmd_read_t_proxy0;
  dtl_cmd_block_size_6 <= dtl_cmd_block_size_t_proxy0;
  dtl_wr_valid_7 <= dtl_wr_valid_t_proxy0;
  dtl_wr_last_8 <= dtl_wr_last_t_proxy0;
  dtl_wr_accept_t_proxy0 <= dtl_wr_accept_9;
  dtl_wr_data_10 <= dtl_wr_data_t_proxy0;
  dtl_wr_mask_11 <= dtl_wr_mask_t_proxy0;
  dtl_rd_last_t_proxy0 <= dtl_rd_last_12;
  dtl_rd_valid_t_proxy0 <= dtl_rd_valid_13;
  dtl_rd_accept_14 <= dtl_rd_accept_t_proxy0;
  dtl_rd_data_t_proxy0 <= dtl_rd_data_15;

-- Begin child instances

    proxy0 : rdt_dtl_proxy_target
      generic map (
        DTL_DATA_WIDTH => WIDTH_DTL_DATA,
        DTL_ADDR_WIDTH => WIDTH_DTL_CMD_ADDR,
        DTL_BLK_SIZE_WIDTH => WIDTH_DTL_CMD_BLOCK_SIZE,
        DTL_WR_MASK_WIDTH => WIDTH_DTL_WR_MASK
      )
    port map (
      dtl_clk   => dtl_clk_0,
      dtl_rst_n => dtl_rst_n_1,

      dtl_cmd_accept_t      => dtl_cmd_accept_3,
      dtl_cmd_addr_t        => dtl_cmd_addr_4,
      dtl_cmd_block_size_t  => dtl_cmd_block_size_6,
      dtl_cmd_read_t        => dtl_cmd_read_5,
      dtl_cmd_valid_t       => dtl_cmd_valid_2,

      dtl_rd_accept_t   => dtl_rd_accept_14,
      dtl_rd_data_t     => dtl_rd_data_15,
      dtl_rd_last_t     => dtl_rd_last_12,
      dtl_rd_valid_t    => dtl_rd_valid_13,

      dtl_wr_accept_t   => dtl_wr_accept_9,
      dtl_wr_data_t     => dtl_wr_data_10,
      dtl_wr_last_t     => dtl_wr_last_8,
      dtl_wr_mask_t     => dtl_wr_mask_11,
      dtl_wr_valid_t    => dtl_wr_valid_7,

      cmd_accept => '1',    --target accept handshake,input port of Proxy
      cmd_addr => open,
      cmd_block_size => open,
      cmd_read => open,     --output port of Proxy
      cmd_valid => open,    --output port of Proxy


      rd_accept   => open,          --output port of Proxy, return the accept info from initializer
      --rd_data   => x"00000003",   --test value
      rd_data     => cnt_r,         --input port of proxy, for sending the counter value
      rd_last     => '1',
      rd_valid    => '1',

      wr_accept   => '0',   --return value to Proxy indicating prepared for receiving written data from initiator
      wr_data     => open,  --receive data from Proxy that written by initializer
      wr_last     => open,
      wr_mask     => open,
      wr_valid    => open
    );

  -- Counting pulses
    -- combinatorial process
    comb_counter_process_a : process(rotary_a_r, rotary_a_2r)
    begin
      if rotary_a_r = '1' and rotary_a_2r = '0' then
          cnt_nxt_a   <= cnt_r_a + 1;
      else
          cnt_nxt_a   <= cnt_r_a;
      end if;
    end process;

    -- sequential process with synchronous reset
    seq_counter_process_a : process(clk)
    begin
      if rising_edge(clk) then
        if rst_n = '0' then
          cnt_r_a       <= (others => '0');
          rotary_a_r  <= '0';
          rotary_a_2r <= '0';
        else      
          -- registering
          cnt_r_a     <= cnt_nxt_a ;
          rotary_a_2r <= rotary_a_r;
          rotary_a_r  <= rotary_a;
      --cnt_r <= cnt_r_a(8 downto 0);
        end if;
      end if;
    end process;


    comb_counter_process_b : process(rotary_b_r, rotary_b_2r)
    begin
      if rotary_b_r = '1' and rotary_b_2r = '0' then
          cnt_nxt_b   <= cnt_r_b + 1;
      else
          cnt_nxt_b   <= cnt_r_b;
      end if;
    end process;

    -- sequential process with synchronous reset
    seq_counter_process_b : process(clk)
    begin
      if rising_edge(clk) then
        if rst_n = '0' then
          cnt_r_b       <= (others => '0');
          rotary_b_r  <= '0';
          rotary_b_2r <= '0';
        else      
          -- registering
          cnt_r_b       <= cnt_nxt_b;
          rotary_b_2r <= rotary_b_r;
          rotary_b_r  <= rotary_b;
      --cnt_r(31 downto 16) <= X"ABCD";
        end if;
      end if;
    end process;

    comb_counter_process_i : process(rotary_i_r, rotary_i_2r)
    begin
      if rotary_i_r = '1' and rotary_i_2r = '0' then
          cnt_nxt_i   <= cnt_r_i + 1;
      else
          cnt_nxt_i   <= cnt_r_i;
      end if;
    end process;

    -- sequential process with synchronous reset
    seq_counter_process_i : process(clk)
    begin
      if rising_edge(clk) then
        if rst_n = '0' then
          cnt_r_i       <= (others => '0');
          rotary_i_r  <= '0';
          rotary_i_2r <= '0';
        else      
          -- registering
          cnt_r_i       <= cnt_nxt_i;
          rotary_i_2r <= rotary_i_r;
          rotary_i_r  <= rotary_i;
      --cnt_r(15 downto 0) <= X"1234";  --the digits for cnt_r_i may change
        end if;
      end if;
    end process;

   cnt_r(31 downto 16) <= cnt_r_b(15 downto 0);
   cnt_r(15 downto 0) <= cnt_r_i(15 downto 0);  

end rtl;

0 ответов

Другие вопросы по тегам