Jump to content

    

Задержка сигнала на Verilog

Добрый день.

 

Есть клок с частотой 10 МГц. И есть сигнал с произвольной скважностью, частотой 5 кГц. Необходимо данный сигнал задержать на 5 мкс. Возможно ли это сделать на Verilog? (Сильно не пинайте, Verilog и ПЛИС пока только осваиваю).

Share this post


Link to post
Share on other sites

Приветствую!

Есть клок с частотой 10 МГц. И есть сигнал с произвольной скважностью, частотой 5 кГц. Необходимо данный сигнал задержать на 5 мкс. Возможно ли это сделать на Verilog? (Сильно не пинайте, Verilog и ПЛИС пока только осваиваю).
Пинать пока не будем - так слегка похлопывать :)

Вам это для чего нужно ? Для использования в симуляции или для реальной (в возможном будущем) железки? Если для железки то просто кольцевой буфер на 5us/100ns=50 элементов (счетчик и блок памяти). Ну или сдвиговый регистр (для ленивых и нежадных ;) )

 

Удачи! Rob.

Share this post


Link to post
Share on other sites
Приветствую!

Пинать пока не будем - так слегка похлопывать :)

Вам это для чего нужно ? Для использования в симуляции или для реальной (в возможном будущем) железки? Если для железки то просто кольцевой буфер на 5us/100ns=50 элементов (счетчик и блок памяти). Ну или сдвиговый регистр (для ленивых и нежадных ;) )

 

Удачи! Rob.

Мне для реального железа.

Share this post


Link to post
Share on other sites
кольцевой буфер на 5us/100ns=50 элементов (счетчик и блок памяти). Ну или сдвиговый регистр (для ленивых и нежадных ;) )
Квартус, например, сам умеет делать сдвиговый регистр на кольцевом буфере. Это вариант для ленивых и жадных.

Share this post


Link to post
Share on other sites
Квартус, например, сам умеет делать сдвиговый регистр на кольцевом буфере. Это вариант для ленивых и жадных.

Vivado тоже так умеет:

SRL_STYLE instructs the synthesis tool on how to infer SRLs that are found in the design. Accepted values are:

...

block: The tool infers the SRL inside a block RAM.

-------

SRL_STYLE Examples (Verilog):

 

(* srl_style = "block" *) reg [16:0] my_srl;

 

Share this post


Link to post
Share on other sites

на vhdl

 

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;

 

Share this post


Link to post
Share on other sites

Приветствую!

 

...
С учетом того что в большинстве FPGA память позволяет считать старое значение из той же ячейки куда пишешь можно обойтись одним указателем чтения/записи.

 

Удачи! Rob.

Share this post


Link to post
Share on other sites
On 7/9/2018 at 9:51 AM, blackfin said:

Vivado тоже так умеет:

никак не могу заставить вивадо "так уметь", т.е. не получается упаковать сдвиговый регистр в блочную память, вроде делаю всё по инструкции ...  Уже и директиву синтеза AreaMapLargeShiftRegToBRAM попробовал, но не помогло

пробовал так:

133579615_Screenshotfrom2019-05-1715-06-25.png.508a8ada95e0804bba870e02c4ecd9e8.png

и так:

741958861_Screenshotfrom2019-05-1715-25-16.png.e53c6f25d5dba94f0606242261e1dcd6.png

 

не помогло - никаких ворнингов/иных сообщений не пишет.

 

Синтезирую с директивой AreaOptimized_high, что означает (на форуме Х пишут так), что сдвиговые регистры должны перекочевать в BRAM автоматом!

делаю вывод, что они у меня по какой-то причине таковыми не распознаются.

 

Собственно вопрос - а как тогда описывать надо?

 

Share this post


Link to post
Share on other sites
20 minutes ago, Doka said:

никак не могу заставить вивадо "так уметь", т.е. не получается упаковать сдвиговый регистр в блочную память, вроде делаю всё по инструкции ...

На мой взгляд, размер блочной памяти (BRAM) слишком велик для такой упаковки, поэтому Vivado использует LUTRAM. Попробуйте увеличить размер вектора: reg [63:0] w6263 [0:127];

Share this post


Link to post
Share on other sites
12 minutes ago, Doka said:

Собственно вопрос - а как тогда описывать надо?

 

руками, через указатели записи/чтения и обращения к памяти.

Share this post


Link to post
Share on other sites
8 minutes ago, blackfin said:

На мой взгляд, размер блочной слишком велик для такой упаковки, поэтому Vivado использует LUTRAM. Попробуйте увеличить размер вектора: reg [63:0] w6263 [0:128]; 

разве прагма (* srl_style = "block" *) не должна работать принудительно?

 

попробовал увеличить - почему-то не срабатывает: только увеличивает количество использованных элементов SRL.

8 minutes ago, des00 said:

руками, через указатели записи/чтения и обращения к памяти.

выглядит не очень. ладно в одном-двух местах надо подправить, но все сорцы перепахивать да еще и без возможности быстро переключаться (ifdef не в счёт) между реализациями...

 

у альтеры это тоже штатная возможность кстати:

https://fpgawiki.intel.com/wiki/Mapping_SRLs_to_registers,_MLABs,_or_Block_RAMs

Share this post


Link to post
Share on other sites
9 minutes ago, Doka said:

выглядит не очень. ладно в одном-двух местах надо подправить, но все сорцы перепахивать да еще и без возможности быстро переключаться (ifdef не в счёт) между реализациями... 

 

у альтеры это тоже штатная возможность кстати:

https://fpgawiki.intel.com/wiki/Mapping_SRLs_to_registers,_MLABs,_or_Block_RAMs

вот как раз этот вариант, адекватен и нормален. для альтеры я поступаю точно также. Квартус тоже глючит, особенно с пользовательскими типами.

  always_ff @(posedge iclk) begin
    if (iclkena) begin
      if (ival) begin
        addr        <= addr + 1'b1;
        raddr       <= addr;
        waddr       <= addr + delay;
        //
        ram[waddr]  <= wdata;
        rdata       <= ram[raddr];
        //
        dat2out     <= rdata;
      end
    end
  end

на все случаи жизни, завернуть в компонент и использовать.

Более того, как видно из кода, задержка меньше трех тактов, на памяти не получится при полной конвейризации и двух без оной. Это сразу показывает например, почему софту не выгодно делать мелкие задержки на памяти)

Share this post


Link to post
Share on other sites
11 minutes ago, Doka said:

попробовал увеличить - почему-то не срабатывает: только увеличивает количество использованных элементов SRL.

Еще вопрос как подключены выходы ваших регистров. Для реализации на BRAM выход из "регистра сдвига" должен быть только один!. Если в вашей схеме используются выходы, скажем, w6263[1] и w6263[2], то сделать такое на BRAM, очевидно, уже не получится.

Share this post


Link to post
Share on other sites

Приветствую!

2 minutes ago, Doka said:

разве прагма (* srl_style = "block" *) не должна работать принудительно?

попробовал увеличить - почему-то не срабатывает: только увеличивает количество использованных элементов SRL.

Прагма это не закон для Vivado (да и другие синтезатора часто игнорируют их). 

Посмотрит в логе синтезатора что он пишет  при имплементации памяти из RTL.  К тому же (я уже вроде писал на форуме) IMHO синтез памяти в Vivado идет как бы в две стадии -  в первой если синтезатор видит "знакомый" шаблон памяти то  тогда и прагма работает и память синтезится предсказуемо.  А если нет - то синтезатор сначала синтезит типа набор регистров, а потом пытается это оптимизировать в память используя свои внутренние правила. Кладя на прагму при этом толстый болт warning :cray2:

Удачи! Rob.

 

Share this post


Link to post
Share on other sites
19 minutes ago, blackfin said:

Еще вопрос как подключены выходы ваших регистров. Для реализации на BRAM выход из "регистра сдвига" должен быть только один!. Если в вашей схеме используются выходы, скажем, w6263[1] и w6263[2], то сделать такое на BRAM, очевидно, уже не получится.

там всё без сюрпризов. используется выход с w6263[5].

 

13 minutes ago, RobFPGA said:

синтез памяти в Vivado идет как бы в две стадии -  в первой если синтезатор видит "знакомый" шаблон памяти то  тогда и прагма работает и память синтезится предсказуемо

вопрос - как бы так описать, чтобы он распознавал, грешил было на то, что двумерный верктор у меня - но переделал на одномерный в качестве эксперимента - результата не дало.

 

21 minutes ago, des00 said:

на все случаи жизни, завернуть в компонент и использовать.

для меня это имеет смылс только если эти регистры:

        ram[waddr]  <= wdata;
        rdata       <= ram[raddr];
        dat2out     <= rdata;

используются встроенны в блочную память,

поскольку соль всей задумки: поджать дизайн немного по регистрами логике за счёт переноса сдвиговых регистров из SLR+FF в BRAM

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now