|
|
  |
перевод 2 связанных сигналов с частоты на частоту |
|
|
|
Aug 3 2018, 06:55
|
Частый гость
 
Группа: Свой
Сообщений: 139
Регистрация: 3-04-13
Пользователь №: 76 333

|
в голове уже каша, поэтому обращаюсь к коллективному бессознательному. имеется 2 связанных сигнала (данные-строб). их надо перевести с бОльшей частоты на мЕньшую (кратность примерно 2,6). сначала взял старую проверенную заготовку и вкорячил ее на обе линии. а потом задумался - из-за того что переход в точке 0 затиган - рано или поздно вылезет ситуация, когда произойдет рассинхрон фронтов данных и строба, и на меньшей частоте по стробу защелкнется не то данное. и, собствено, вопрос - как этого избежать? зы я мог не точно выразиться - под стробом понимается сигнал валидности данных. грубо говоря WDATA+WVALID с акси
Эскизы прикрепленных изображений
|
|
|
|
|
Aug 3 2018, 08:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(blackfin @ Aug 3 2018, 11:06)  ... PS. Кроме того, вы всегда можете представить себе "тактирующий строб" в виде "данных" с разрядностью в один бит и передавать эти однобитные "данные" через FIFO с двумя клоками..  А смысл этого ? Строб на высокой частоте просто показывает когда данные валидны для записи - бессмысленно его явно тащить через FIFO для этого случая. Не явно это и так делается через сигнал valid на выходе FIFO. Удачи! Rob.
|
|
|
|
|
Aug 3 2018, 08:42
|

Частый гость
 
Группа: Свой
Сообщений: 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;
--------------------
Суббота начинается в понедельник
|
|
|
|
|
Aug 3 2018, 08:48
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую!  Лучше использовать 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.
|
|
|
|
|
Aug 3 2018, 10:36
|

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

|
Цитата(RobFPGA @ Aug 3 2018, 11:48)  Приветствую!  Лучше использовать codebox тег для длинных блоков кода. Удачи! Rob. Учту в дальнейшем
--------------------
Суббота начинается в понедельник
|
|
|
|
|
Aug 3 2018, 11:32
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

|
Приветствую! Цитата(GAYVER @ Aug 3 2018, 14:10)  фифо, конечно, круто, но в 6 спартане его нет... или я что то путаю )) Зато там есть немного Block RAM поболее distributed RAM кучка регистров и тучка логики. Так что можно и не обращать внимание на IP core FIFO.  Удачи! Rob.
|
|
|
|
|
Aug 3 2018, 11:45
|
Частый гость
 
Группа: Свой
Сообщений: 139
Регистрация: 3-04-13
Пользователь №: 76 333

|
Цитата(RobFPGA @ Aug 3 2018, 14:32)  Приветствую! Зато там есть немного Block RAM поболее distributed RAM кучка регистров и тучка логики. Так что можно и не обращать внимание на IP core FIFO.  Удачи! Rob. если вопрос стоит в том чтобы самому что то городить, то мне будет проще переписать входной блок под одинаковую частоту  . это если нет решения на пару строк кода или использование чего-то стандартного...
|
|
|
|
|
Aug 3 2018, 12:04
|
Профессионал
    
Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643

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