реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> перевод 2 связанных сигналов с частоты на частоту
GAYVER
сообщение Aug 3 2018, 06:55
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 134
Регистрация: 3-04-13
Пользователь №: 76 333



в голове уже каша, поэтому обращаюсь к коллективному бессознательному.

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


зы
я мог не точно выразиться - под стробом понимается сигнал валидности данных. грубо говоря WDATA+WVALID с акси
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
new123
сообщение Aug 3 2018, 07:01
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 129
Регистрация: 30-11-17
Пользователь №: 100 438



в fifo асинхронный записывать клок и данные не решит проблему? вроде бы я так делаю у себя.. с частоты 250 перехожу на 125, записываю и клок и данные
Go to the top of the page
 
+Quote Post
Lmx2315
сообщение Aug 3 2018, 07:57
Сообщение #3


отэц
*****

Группа: Свой
Сообщений: 1 714
Регистрация: 18-09-05
Из: Москва
Пользователь №: 8 684



Я не понимаю как можно перевести тактирующий строб на "меньшую частоту" , я понимаю как данные можно перевести из одного клокового домена в другой, но чтоб строб?
https://www.fpga4fun.com/CrossClockDomain.html


--------------------
b4edbc0f854dda469460aa1aa a5ba2bd36cbe9d4bc8f92179f 8f3fec5d9da7f0
SHA-256
Go to the top of the page
 
+Quote Post
blackfin
сообщение Aug 3 2018, 08:06
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 042
Регистрация: 18-04-05
Пользователь №: 4 261



Цитата(Lmx2315 @ Aug 3 2018, 10:57) *
Я не понимаю как можно перевести тактирующий строб на "меньшую частоту" , я понимаю как данные можно перевести из одного клокового домена в другой, но чтоб строб?

См.: Figure 5-6.

PS. Кроме того, вы всегда можете представить себе "тактирующий строб" в виде "данных" с разрядностью в один бит и передавать эти однобитные "данные" через FIFO с двумя клоками.. wink.gif
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Aug 3 2018, 08:41
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 182
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!
Цитата(blackfin @ Aug 3 2018, 11:06) *
...
PS. Кроме того, вы всегда можете представить себе "тактирующий строб" в виде "данных" с разрядностью в один бит и передавать эти однобитные "данные" через FIFO с двумя клоками.. wink.gif
А смысл этого ? Строб на высокой частоте просто показывает когда данные валидны для записи - бессмысленно его явно тащить через FIFO для этого случая. Не явно это и так делается через сигнал valid на выходе FIFO.
Удачи! Rob.
Go to the top of the page
 
+Quote Post
quato_a
сообщение Aug 3 2018, 08:42
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 93
Регистрация: 27-07-11
Из: Зеленоград
Пользователь №: 66 439



синхронизатор шин данных между частотными регионами

Код
library ieee;
use ieee.std_logic_1164.all;

entity indpClkDataBufferStd is
    generic(
        DW : natural := 32;
        RST_ACTIVE_SRC : std_logic := '1';
        RST_ACTIVE_DEST : std_logic := '1'
    );
    port(
        clk_src     : in  std_logic;
        clk_dest    : in  std_logic;
        rst_src     : in  std_logic;
        rst_dest    : in  std_logic;
        src_rdy_i   : in  std_logic;
        src_data_i  : in  std_logic_vector(DW - 1 downto 0);
        dest_rdy_o  : out std_logic;
        src_rdy_o   : out std_logic;
        dest_data_o : out std_logic_vector(DW - 1 downto 0)
    );
end indpClkDataBufferStd;

architecture rtl of indpClkDataBufferStd is

    type state_src_t is (IDLE, WAIT_ACK, ACK);
    signal state_src : state_src_t;
    signal ack_b     : std_logic;       -- trigger for latching signal from dest_ctrl
    signal ack_b2    : std_logic;       -- trigger for latching signal from dest_ctrl

    type state_dest_t is (IDLE, ACK);
    signal state_dest : state_dest_t;
    signal req_b : std_logic;           -- trigger for latch signal from src_ctrl
    signal req_b2 : std_logic;          -- trigger for latch signal from src_ctrl

    signal ack_dest_src  : std_logic;
    signal req_src_dest  : std_logic;
    signal data_src_dest : std_logic_vector(DW - 1 downto 0);

begin

    src_ctrl_proc : process(clk_src, rst_src)
    begin
        if rst_src = RST_ACTIVE_SRC then
            data_src_dest <= (others => '0');
            req_src_dest  <= '0';
            src_rdy_o     <= '0';

            state_src <= IDLE;
            ack_b     <= '0';

        elsif rising_edge(clk_src) then

            ack_b  <= ack_dest_src;     -- base synchronize
            ack_b2 <= ack_b;

            case state_src is
                when IDLE =>
                    src_rdy_o <= '0';
                    if (src_rdy_i = '1') then
                        state_src     <= WAIT_ACK;
                        data_src_dest <= src_data_i; -- latching data bus from source to dest_ctrl
                        req_src_dest  <= '1';
                    end if;
                when WAIT_ACK =>
                    if (ack_b2 = '1') then -- when dest_ctrl get data, req_o = '0'
                        req_src_dest <= '0';
                        state_src    <= ACK;
                    end if;
                when ACK =>
                    if (ack_b2 = '0') then -- when dest_ctrl ack='0' go to IDLE
                        state_src <= IDLE;
                        src_rdy_o <= '1';
                    end if;
            end case;
        end if;
    end process;

    dest_ctrl_proc : process(clk_dest, rst_dest)
    begin
        if rst_dest = RST_ACTIVE_DEST then
            ack_dest_src <= '0';
            dest_data_o  <= (others => '0');

            state_dest <= IDLE;
            req_b      <= '0';
            req_b2     <= '0';
            dest_rdy_o <= '0';

        elsif rising_edge(clk_dest) then

            req_b  <= req_src_dest;
            req_b2 <= req_b;

            case state_dest is
                when IDLE =>
                    if (req_b2 = '1') then -- when request from src_cotrol, latch data bus, form acknowledge
                        dest_data_o  <= data_src_dest;
                        dest_rdy_o   <= '1';
                        ack_dest_src <= '1';
                        state_dest   <= ACK;
                    end if;
                when ACK =>
                    dest_rdy_o <= '0';
                    if (req_b2 = '0') then -- when req from src_ctrl is '0', ack_0 = '0', go to IDLE
                        ack_dest_src <= '0';
                        state_dest   <= IDLE;
                    end if;
            end case;
        end if;
    end process;

end rtl;


синхронизатор стробов между частотными регионами

Код
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;


entity IndpClkStb is
    generic(
        RST_ACTIVE_SRC : std_logic := '1';
        RST_ACTIVE_DEST : std_logic := '1'
    );
    port(
        clk_src  : in  std_logic;
        rst_src  : in  std_logic;
        data_i   : in  std_logic;
        clk_dest : in  std_logic;
        rst_dest : in  std_logic;
        data_o   : out std_logic
    );
end entity IndpClkStb;

architecture RTL of IndpClkStb is

    type state_src_t is (IDLE, WAIT_ACK, ACK);
    signal state_src : state_src_t;

    type state_dest_t is (IDLE, ACK);
    signal state_dest : state_dest_t;

    signal hardshake_req : std_logic;
    signal req_z         : std_logic;
    signal req_z2        : std_logic;

    signal handshake_ack : std_logic;
    signal ack_z         : std_logic;
    signal ack_z2        : std_logic;

begin

    --================================================================================
====================================
    --=========== автомат состояний входа
    --================================================================================
====================================
    proc_scr_ctrl : process(clk_src, rst_src)
    begin
        if (rst_src = RST_ACTIVE_SRC) then
            hardshake_req <= '0';
            state_src     <= IDLE;

        elsif rising_edge(clk_src) then

            ack_z  <= handshake_ack;
            ack_z2 <= ack_z;

            case state_src is
                when IDLE =>
                    if (data_i = '1') then
                        state_src     <= WAIT_ACK;
                        hardshake_req <= '1';
                    end if;

                when WAIT_ACK =>
                    if (ack_z2 = '1') then
                        hardshake_req <= '0';
                        state_src     <= ACK;
                    end if;

                when ACK =>
                    if (ack_z2 = '0') then
                        state_src <= IDLE;
                    end if;
            end case;

        end if;
    end process;

    --================================================================================
====================================
    --=========== автомат состояний выхода
    --================================================================================
====================================
    proc_dest_ctrl : process(clk_dest, rst_dest)
    begin
        if (rst_dest = RST_ACTIVE_DEST) then
            handshake_ack <= '0';
            state_dest    <= IDLE;

            data_o <= '0';

        elsif rising_edge(clk_dest) then

            req_z  <= hardshake_req;
            req_z2 <= req_z;

            case state_dest is
                when IDLE =>
                    if (req_z2 = '1') then
                        data_o        <= '1';
                        handshake_ack <= '1';
                        state_dest    <= ACK;
                    end if;
                when ACK =>
                    data_o <= '0';
                    if (req_z2 = '0') then
                        handshake_ack <= '0';
                        state_dest    <= IDLE;
                    end if;
            end case;

        end if;
    end process;

end architecture RTL;


--------------------
Суббота начинается в понедельник
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Aug 3 2018, 08:48
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 182
Регистрация: 23-12-04
Пользователь №: 1 643



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

bb-offtopic.gif Лучше использовать codebox тег для длинных блоков кода.
Цитата(quato_a @ Aug 3 2018, 11:42) *
синхронизатор шин данных между частотными регионами

CODE
library ieee;
use ieee.std_logic_1164.all;

entity indpClkDataBufferStd is
generic(
DW : natural := 32;
RST_ACTIVE_SRC : std_logic := '1';
RST_ACTIVE_DEST : std_logic := '1'
);
port(
clk_src : in std_logic;
clk_dest : in std_logic;
rst_src : in std_logic;
rst_dest : in std_logic;
src_rdy_i : in std_logic;
src_data_i : in std_logic_vector(DW - 1 downto 0);
dest_rdy_o : out std_logic;
src_rdy_o : out std_logic;
dest_data_o : out std_logic_vector(DW - 1 downto 0)
);
end indpClkDataBufferStd;

architecture rtl of indpClkDataBufferStd is

type state_src_t is (IDLE, WAIT_ACK, ACK);
signal state_src : state_src_t;
signal ack_b : std_logic; -- trigger for latching signal from dest_ctrl
signal ack_b2 : std_logic; -- trigger for latching signal from dest_ctrl

type state_dest_t is (IDLE, ACK);
signal state_dest : state_dest_t;
signal req_b : std_logic; -- trigger for latch signal from src_ctrl
signal req_b2 : std_logic; -- trigger for latch signal from src_ctrl

signal ack_dest_src : std_logic;
signal req_src_dest : std_logic;
signal data_src_dest : std_logic_vector(DW - 1 downto 0);

begin

src_ctrl_proc : process(clk_src, rst_src)
begin
if rst_src = RST_ACTIVE_SRC then
data_src_dest <= (others => '0');
req_src_dest <= '0';
src_rdy_o <= '0';

state_src <= IDLE;
ack_b <= '0';

elsif rising_edge(clk_src) then

ack_b <= ack_dest_src; -- base synchronize
ack_b2 <= ack_b;

case state_src is
when IDLE =>
src_rdy_o <= '0';
if (src_rdy_i = '1') then
state_src <= WAIT_ACK;
data_src_dest <= src_data_i; -- latching data bus from source to dest_ctrl
req_src_dest <= '1';
end if;
when WAIT_ACK =>
if (ack_b2 = '1') then -- when dest_ctrl get data, req_o = '0'
req_src_dest <= '0';
state_src <= ACK;
end if;
when ACK =>
if (ack_b2 = '0') then -- when dest_ctrl ack='0' go to IDLE
state_src <= IDLE;
src_rdy_o <= '1';
end if;
end case;
end if;
end process;

dest_ctrl_proc : process(clk_dest, rst_dest)
begin
if rst_dest = RST_ACTIVE_DEST then
ack_dest_src <= '0';
dest_data_o <= (others => '0');

state_dest <= IDLE;
req_b <= '0';
req_b2 <= '0';
dest_rdy_o <= '0';

elsif rising_edge(clk_dest) then

req_b <= req_src_dest;
req_b2 <= req_b;

case state_dest is
when IDLE =>
if (req_b2 = '1') then -- when request from src_cotrol, latch data bus, form acknowledge
dest_data_o <= data_src_dest;
dest_rdy_o <= '1';
ack_dest_src <= '1';
state_dest <= ACK;
end if;
when ACK =>
dest_rdy_o <= '0';
if (req_b2 = '0') then -- when req from src_ctrl is '0', ack_0 = '0', go to IDLE
ack_dest_src <= '0';
state_dest <= IDLE;
end if;
end case;
end if;
end process;

end rtl;[/code]

синхронизатор стробов между частотными регионами

[code]LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;


entity IndpClkStb is
generic(
RST_ACTIVE_SRC : std_logic := '1';
RST_ACTIVE_DEST : std_logic := '1'
);
port(
clk_src : in std_logic;
rst_src : in std_logic;
data_i : in std_logic;
clk_dest : in std_logic;
rst_dest : in std_logic;
data_o : out std_logic
);
end entity IndpClkStb;

architecture RTL of IndpClkStb is

type state_src_t is (IDLE, WAIT_ACK, ACK);
signal state_src : state_src_t;

type state_dest_t is (IDLE, ACK);
signal state_dest : state_dest_t;

signal hardshake_req : std_logic;
signal req_z : std_logic;
signal req_z2 : std_logic;

signal handshake_ack : std_logic;
signal ack_z : std_logic;
signal ack_z2 : std_logic;

begin

--================================================================================
====================================
--=========== автомат состояний входа
--================================================================================
====================================
proc_scr_ctrl : process(clk_src, rst_src)
begin
if (rst_src = RST_ACTIVE_SRC) then
hardshake_req <= '0';
state_src <= IDLE;

elsif rising_edge(clk_src) then

ack_z <= handshake_ack;
ack_z2 <= ack_z;

case state_src is
when IDLE =>
if (data_i = '1') then
state_src <= WAIT_ACK;
hardshake_req <= '1';
end if;

when WAIT_ACK =>
if (ack_z2 = '1') then
hardshake_req <= '0';
state_src <= ACK;
end if;

when ACK =>
if (ack_z2 = '0') then
state_src <= IDLE;
end if;
end case;

end if;
end process;

--================================================================================
====================================
--=========== автомат состояний выхода
--================================================================================
====================================
proc_dest_ctrl : process(clk_dest, rst_dest)
begin
if (rst_dest = RST_ACTIVE_DEST) then
handshake_ack <= '0';
state_dest <= IDLE;

data_o <= '0';

elsif rising_edge(clk_dest) then

req_z <= hardshake_req;
req_z2 <= req_z;

case state_dest is
when IDLE =>
if (req_z2 = '1') then
data_o <= '1';
handshake_ack <= '1';
state_dest <= ACK;
end if;
when ACK =>
data_o <= '0';
if (req_z2 = '0') then
handshake_ack <= '0';
state_dest <= IDLE;
end if;
end case;

end if;
end process;

end architecture RTL;

Удачи! Rob.
Go to the top of the page
 
+Quote Post
blackfin
сообщение Aug 3 2018, 09:00
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 042
Регистрация: 18-04-05
Пользователь №: 4 261



Цитата(RobFPGA @ Aug 3 2018, 11:41) *
А смысл этого?

А я где-то утверждал, что в этом есть смысл?

Понятно, что если через FIFO тащат данные, то строб уже не нужен. Но для понимания логики CDC мой намек вопрошающему не повредит. biggrin.gif
Go to the top of the page
 
+Quote Post
quato_a
сообщение Aug 3 2018, 10:36
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 93
Регистрация: 27-07-11
Из: Зеленоград
Пользователь №: 66 439



Цитата(RobFPGA @ Aug 3 2018, 11:48) *
Приветствую!

bb-offtopic.gif Лучше использовать codebox тег для длинных блоков кода.

Удачи! Rob.


Учту в дальнейшем sm.gif


--------------------
Суббота начинается в понедельник
Go to the top of the page
 
+Quote Post
GAYVER
сообщение Aug 3 2018, 11:10
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 134
Регистрация: 3-04-13
Пользователь №: 76 333



фифо, конечно, круто, но в 6 спартане его нет... или я что то путаю ))
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Aug 3 2018, 11:32
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 182
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!
Цитата(GAYVER @ Aug 3 2018, 14:10) *
фифо, конечно, круто, но в 6 спартане его нет... или я что то путаю ))
Зато там есть немного Block RAM поболее distributed RAM кучка регистров и тучка логики.
Так что можно и не обращать внимание на IP core FIFO. sm.gif
Удачи! Rob.
Go to the top of the page
 
+Quote Post
GAYVER
сообщение Aug 3 2018, 11:45
Сообщение #12


Частый гость
**

Группа: Свой
Сообщений: 134
Регистрация: 3-04-13
Пользователь №: 76 333



Цитата(RobFPGA @ Aug 3 2018, 14:32) *
Приветствую!
Зато там есть немного Block RAM поболее distributed RAM кучка регистров и тучка логики.
Так что можно и не обращать внимание на IP core FIFO. sm.gif
Удачи! Rob.



если вопрос стоит в том чтобы самому что то городить, то мне будет проще переписать входной блок под одинаковую частоту sm.gif. это если нет решения на пару строк кода или использование чего-то стандартного...
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Aug 3 2018, 12:04
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 182
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!
Цитата(GAYVER @ Aug 3 2018, 14:45) *
если вопрос стоит в том чтобы самому что то городить, то мне будет проще переписать входной блок под одинаковую частоту sm.gif. это если нет решения на пару строк кода или использование чего-то стандартного...
Ну это Вам виднее что проще. По мне так в асинхронном FIFO нет никакой сложности кроме понимания принципов работы.
Удачи! Rob.

Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th August 2018 - 09:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01088 секунд с 7
ELECTRONIX ©2004-2016