Перейти к содержанию
    

pipeline delay

Всем привет

Мне надо разработать настраеваемую задержку сигнала, т.к. задержка максимальная большая больше 1000 может принимать значение, то решил делать на BRAM

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity delay_line is
generic(
  W                 : integer := 8;    -- data width
  L                 : integer := 1200);  -- delay length, shall be > 3
port(
  i_clk             : in  std_logic;
  i_sync_reset      : in  std_logic;
  i_data            : in  std_logic_vector(W-1 downto 0);
  o_data            : out std_logic_vector(W-1 downto 0));
end delay_line;

architecture rtl of delay_line is

type t_ram is array (L-2 downto 0) of std_logic_vector(W-1 downto 0);
signal m_ram : t_ram;

signal r_addr_wr         : integer range 0 to L-2;
signal r_addr_rd         : integer range 0 to L-2;
signal r_enable_read     : std_logic;

begin

p_write : process (i_clk)
begin
  if rising_edge(i_clk) then
    if(i_sync_reset='1') then
      r_addr_wr      <= 0;
      r_enable_read  <= '0';
    else
      m_ram(r_addr_wr) <= i_data;
      if(r_addr_wr<L-2) then
        r_addr_wr      <= r_addr_wr + 1;
      else
        r_addr_wr      <= 0;
        r_enable_read  <= '1';       -- enable reading section
      end if;
    end if;
  end if;
end process p_write;

p_read : process (i_clk)
begin
  if rising_edge(i_clk) then
    if(i_sync_reset='1') then
      r_addr_rd      <= 0;
    else
      if(r_enable_read='1') then
        o_data         <= m_ram(r_addr_rd) ; -- additional delay
        if(r_addr_rd<L-2) then
          r_addr_rd      <= r_addr_rd + 1;
        else
          r_addr_rd      <= 0;
        end if;
      end if;
    end if;
  end if;
end process p_read;


end rtl;

но в описании есть для меня ограничение что delay length, shall be > 3  Это связано с тем, что для обеспечения корректной работы задержки необходимо иметь как минимум 2 разных значения в памяти, а также задержать входной сигнал на минимум 1 такт.

L я сделаю как вход...

Как посоветуете лучше сделать чтоби обойти ограничение? Мне надо с L = 1, 2 и более

Думаю вначале поставить мультиплексор 

 process (all)
 begin
 
    if L = 0 then 
        o_data <= i_data;
    elsif L = 1 then 
        reg_data1 <= i_data;
    elsif L = 2 then
        reg_data2 <= i_data;
    elsif L = 3 then
        reg_data3 <= i_data;
    else
        reg_data <= i_data;
    end if;
    
 end process;

в котором для задержек меньше равно 3 - организовать свои задержки 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

update

получился такой "монстр"

 library IEEE;
 use IEEE.std_logic_1164.all;
 use IEEE.numeric_std.all;
 
 entity delay_line is
 generic
	(
	W               : integer := 8;    -- data width
	L				: integer := 10;    -- delay length
	); 
 port(
	clk             : in  std_logic;
	rst      		: in  std_logic;
	delay_len		: in  std_logic_vector(L-1 downto 0);   -- delay length, shall be > 3
	i_data          : in  std_logic_vector(W-1 downto 0);
	o_data          : out std_logic_vector(W-1 downto 0));
 end delay_line;
 
 architecture rtl of delay_line is
 
 --type t_ram is array (L-1 downto 0) of std_logic_vector(W-1 downto 0);
 type t_ram is array ((2**L)-1 downto 0) of std_logic_vector(W-1 downto 0);
 signal m_ram : t_ram;
 
 signal r_addr_wr       : unsigned(L-1 downto 0);
 signal r_addr_rd       : unsigned(L-1 downto 0);
 signal r_enable_read   : std_logic;
 
 signal reg_data1		: std_logic_vector(W-1 downto 0);
 signal reg_data2		: std_logic_vector(W-1 downto 0);
 signal reg_data		: std_logic_vector(W-1 downto 0);
 
 signal reg_o_data		: std_logic_vector(W-1 downto 0);
 signal reg_o_data1		: std_logic_vector(W-1 downto 0);
 signal reg_o_data2		: std_logic_vector(W-1 downto 0);
 signal reg_o_data3		: std_logic_vector(W-1 downto 0);
 
 begin

 process (all)
 begin
	if(rst = '1') then
		reg_data1      	 <=  (others => '0');
		reg_data2      	 <=  (others => '0');
		reg_data	   	 <=  (others => '0');
		reg_o_data1      <=  (others => '0');
		reg_o_data2      <=  (others => '0');
		reg_o_data3      <=  (others => '0');
	elsif rising_edge(clk) then
 
		if unsigned(delay_len) = 1 then 
			reg_o_data1 <= i_data;
		elsif unsigned(delay_len) = 2 then
			reg_data1 <= i_data;
			reg_o_data2 <= reg_data1;
		elsif unsigned(delay_len) = 3 then
			reg_data1 <= i_data;
			reg_data2 <= reg_data1;
			reg_o_data3 <= reg_data2;
		else
			reg_data <= i_data;
		end if;
   
	end if;
 end process;
 
 process (all)
 begin
	-- if(rst = '1') then
		-- reg_o_data1      <=  (others => '0');
		-- reg_o_data2      <=  (others => '0');
		-- reg_o_data3      <=  (others => '0');
	-- elsif rising_edge(clk) then 
 
		if unsigned(delay_len) = 1 then 
			o_data <= reg_o_data1;
		elsif unsigned(delay_len) = 2 then
			o_data <= reg_o_data2;
		elsif unsigned(delay_len) = 3 then
			o_data <= reg_o_data3;
		else
			o_data <= reg_o_data;
		end if;
   
--	end if;
 end process;
 
 p_write : process (all)
 begin
	if(rst = '1') then
		r_addr_wr      <=  (others => '0');
		r_enable_read  <= '0';
	elsif rising_edge(clk) then
	
		m_ram(r_addr_wr) <= reg_data;
      
		if(r_addr_wr < unsigned(delay_len)) then
			r_addr_wr      <= r_addr_wr + 1;
		else
			r_addr_wr      <= (others => '0');
			r_enable_read  <= '1';       -- enable reading section
		end if;
	  
    end if;
 end process p_write;

 p_read : process (all)
 begin
	if(rst = '1') then
		r_addr_rd		<= (others => '0');
		reg_o_data 		<= (others => '0');
    elsif rising_edge(clk) then
    
		if(r_enable_read = '1') then
			
			reg_o_data         <= m_ram(r_addr_rd) ; -- additional delay
			
			if(r_addr_rd < unsigned(delay_len)) then
				r_addr_rd      <= r_addr_rd + 1;
			else
				r_addr_rd      <= (others => '0');
			end if;
		end if;
	end if;
 end process p_read;

 end rtl;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 hours ago, RobFPGA said:

И зачем было делать отдельные указатели записи чтения? 

по другому я не знаю как сделать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а зачем вам именно 1-2 такта задержки этого сигнала? Это мультиплексоры рядом с памятью и все такое. Может быть лучше сделать задержку >= 3 и добавить задержку его оппонента?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

25 minutes ago, des00 said:

а зачем вам именно 1-2 такта задержки этого сигнала? Это мультиплексоры рядом с памятью и все такое. Может быть лучше сделать задержку >= 3 и добавить задержку его оппонента?

огромное спасибо des00 - я упустил из виду такую возможность - заработался...

действительно...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, Maverick_ said:

по другому я не знаю как сделать

Да так же как и сейчас сделали. Если память поддерживает режим old_data/read_first то одним указателем и читаем старое значение и пишем новое. 
А сам указатель крутится от 0 до delay-read_latency-1.
Или, чтобы не делать  лишнее вычитания, от read_latency+1  do delay
Или от delay do read_latency+1 чтобы  оптимизировать компаратор 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, RobFPGA said:

Да так же как и сейчас сделали. Если память поддерживает режим old_data/read_first то одним указателем и читаем старое значение и пишем новое. 
А сам указатель крутится от 0 до delay-read_latency-1.
Или, чтобы не делать  лишнее вычитания, от read_latency+1  do delay
Или от delay do read_latency+1 чтобы  оптимизировать компаратор 

спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 hours ago, RobFPGA said:

Если память поддерживает режим old_data/read_first 

вот это ключевое) модуль получается не универсальный, ценой экономии 10-20 плиток)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 hours ago, des00 said:

вот это ключевое) модуль получается не универсальный, ценой экономии 10-20 плиток)

Ничто не дается даром,  кроме сыра ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

еще вопрос - подскажите пожалуйста, как правильно описать pipeline задержку чтоби она размещалсь на LUTRAM

файл верхнего уровня

 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.NUMERIC_STD.ALL;

entity pipeline_delay_bus is
  generic (
    NUM_INSTANCES       : integer := 4; 
    PIPELINE_STAGES     : integer := 4;
    RESET_ACTIVE_LEVEL  : std_logic := '1'
  );
  port (
    Clock   : in std_logic;
    Reset   : in std_logic;
    valid     : in std_logic;
    Sig_in  : in std_logic_vector(NUM_INSTANCES-1 downto 0);
    Sig_out : out std_logic_vector(NUM_INSTANCES-1 downto 0);
    ready : out std_logic
  );
end entity pipeline_delay_bus;

architecture behavioral of pipeline_delay_bus is
begin

  gen_pipeline_inst : for i in 0 to NUM_INSTANCES-1 generate
    
    pipeline_inst : entity work.pipeline_delay
      generic map (
        PIPELINE_STAGES => PIPELINE_STAGES,
        RESET_ACTIVE_LEVEL => RESET_ACTIVE_LEVEL
      )
      port map (
        Clock => Clock,
        Reset => Reset,
        ena => valid,
        Sig_in => Sig_in(i),
        Sig_out => Sig_out(i)
      );
  end generate gen_pipeline_inst;
  
  process(all)
  begin
  if Reset = '1' then
        ready <= '0';
  elsif rising_edge(Clock) then
        ready <= valid;
   end if;
  end process;

end architecture behavioral;

файл самой задержки

 library IEEE;
 use IEEE.STD_LOGIC_1164.ALL;
 use IEEE.NUMERIC_STD.ALL;
 
 entity pipeline_delay is
	generic (
		PIPELINE_STAGES : integer;
		RESET_ACTIVE_LEVEL : std_logic := '1'
	);
   port (
		Clock   : in std_logic;
		Reset   : in std_logic;
		ena     : in std_logic;
		Sig_in  : in std_logic;
		Sig_out : out std_logic
   );
 end entity;
 
 architecture rtl of pipeline_delay is
 
 signal pl_regs : std_logic_vector(1 to PIPELINE_STAGES);
   
 begin
 process(all)
 begin
 if Reset = RESET_ACTIVE_LEVEL then
	pl_regs <= (others => '0');
 elsif rising_edge(Clock) then
    if ena = '1' then
	   if PIPELINE_STAGES = 1 then
		  pl_regs(1) <= Sig_in;
	   else
		  pl_regs <= Sig_in & pl_regs(1 to pl_regs'high-1);
	   end if;
	end if;
 end if;
 
 Sig_out <= pl_regs(pl_regs'high);
 
 end process;
 
 end architecture;

ситуация следующая если я в компоненте pipeline_delay 

комментирую строку -- if ena = '1' then то я у меня вивадо  2019,1 делает на LUtRAM

если нет то на регистрах.

как сделать сдвигающий регистр на SRL на LUTRAM с сигналом разрешения работи(valid)?

PS https://docs.xilinx.com/r/en-US/ug901-vivado-synthesis/32-Bit-Shift-Register-Coding-Example-One-VHDL видел...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

28 minutes ago, Maverick_ said:

еще вопрос - подскажите пожалуйста, как правильно описать pipeline задержку чтоби она размещалсь на LUTRAM

убрать reset и обеспечтить размер по глубине не больше 1-2 RAMD64

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 minutes ago, des00 said:

убрать reset и обеспечтить размер по глубине не больше 1-2 RAMD64

в самое яблочко)))

Спасибо Денис

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...