GAYVER 2 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба в голове уже каша, поэтому обращаюсь к коллективному бессознательному. имеется 2 связанных сигнала (данные-строб). их надо перевести с бОльшей частоты на мЕньшую (кратность примерно 2,6). сначала взял старую проверенную заготовку и вкорячил ее на обе линии. а потом задумался - из-за того что переход в точке 0 затиган - рано или поздно вылезет ситуация, когда произойдет рассинхрон фронтов данных и строба, и на меньшей частоте по стробу защелкнется не то данное. и, собствено, вопрос - как этого избежать? зы я мог не точно выразиться - под стробом понимается сигнал валидности данных. грубо говоря WDATA+WVALID с акси Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба в fifo асинхронный записывать клок и данные не решит проблему? вроде бы я так делаю у себя.. с частоты 250 перехожу на 125, записываю и клок и данные Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lmx2315 2 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Я не понимаю как можно перевести тактирующий строб на "меньшую частоту" , я понимаю как данные можно перевести из одного клокового домена в другой, но чтоб строб? https://www.fpga4fun.com/CrossClockDomain.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 11 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Я не понимаю как можно перевести тактирующий строб на "меньшую частоту" , я понимаю как данные можно перевести из одного клокового домена в другой, но чтоб строб? См.: Figure 5-6. PS. Кроме того, вы всегда можете представить себе "тактирующий строб" в виде "данных" с разрядностью в один бит и передавать эти однобитные "данные" через FIFO с двумя клоками.. ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Приветствую! ... PS. Кроме того, вы всегда можете представить себе "тактирующий строб" в виде "данных" с разрядностью в один бит и передавать эти однобитные "данные" через FIFO с двумя клоками.. ;) А смысл этого ? Строб на высокой частоте просто показывает когда данные валидны для записи - бессмысленно его явно тащить через FIFO для этого случая. Не явно это и так делается через сигнал valid на выходе FIFO. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
quato_a 3 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба синхронизатор шин данных между частотными регионами 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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Приветствую! :bb-offtopic: Лучше использовать codebox тег для длинных блоков кода. синхронизатор шин данных между частотными регионами 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; Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 11 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба А смысл этого? А я где-то утверждал, что в этом есть смысл? Понятно, что если через FIFO тащат данные, то строб уже не нужен. Но для понимания логики CDC мой намек вопрошающему не повредит. :biggrin: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
quato_a 3 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Приветствую! :bb-offtopic: Лучше использовать codebox тег для длинных блоков кода. Удачи! Rob. Учту в дальнейшем :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GAYVER 2 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба фифо, конечно, круто, но в 6 спартане его нет... или я что то путаю )) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Приветствую! фифо, конечно, круто, но в 6 спартане его нет... или я что то путаю ))Зато там есть немного Block RAM поболее distributed RAM кучка регистров и тучка логики. Так что можно и не обращать внимание на IP core FIFO. :) Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GAYVER 2 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Приветствую! Зато там есть немного Block RAM поболее distributed RAM кучка регистров и тучка логики. Так что можно и не обращать внимание на IP core FIFO. :) Удачи! Rob. если вопрос стоит в том чтобы самому что то городить, то мне будет проще переписать входной блок под одинаковую частоту :). это если нет решения на пару строк кода или использование чего-то стандартного... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 3 августа, 2018 Опубликовано 3 августа, 2018 · Жалоба Приветствую! если вопрос стоит в том чтобы самому что то городить, то мне будет проще переписать входной блок под одинаковую частоту :). это если нет решения на пару строк кода или использование чего-то стандартного...Ну это Вам виднее что проще. По мне так в асинхронном FIFO нет никакой сложности кроме понимания принципов работы. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться