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

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


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

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



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

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


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


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

Группа: Свой
Сообщений: 95
Регистрация: 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
Сообщение #3


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

Группа: Свой
Сообщений: 1 214
Регистрация: 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



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

 


RSS Текстовая версия Сейчас: 24th August 2025 - 01:33
Рейтинг@Mail.ru


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