Oldring 0 18 апреля, 2007 Опубликовано 18 апреля, 2007 · Жалоба Спасибо всем за столь активное участие :) К сожалению, во всех предложенных вариантах возникает одно неприятная вещь - после окончания последовательности импульсов вылезает еще один пик, то есть длина строба на чуть-чуть больше,чем длина последовательности тактов. (Понятно. что это возникает при моделировании с учетом реальных задержек). Похоже, надо действительно делать синхронное устройство - по входу и выходу. Задача не такая тривиальная, как кажется с первого взгляда. Тактируемые по переднему фронту триггеры не могут сформровать спад сигнала по заднему фронту клока. Асинхронный ключ не может гарантировать отсутствие глитчей без детального анализа времен распространения сигналов. То есть, в любом случае нужно очень аккуратно учитывать особенности архитектуры, под которую пишется код. Другое дело - а нужно ли пропускать именно N импульсов именно клока? Может быть, достаточно сформировать сигнал разрешения длительностью в N импульсов клока, и использовать его непосредственно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 18 апреля, 2007 Опубликовано 18 апреля, 2007 · Жалоба Оно у вас и так синхронное. Просто вырезать импульсы временными воротами, которые сформированы этими же клоками - плохой том. В том числе и на микросхемах средней степени интеграции. Или впереди пичок или сзади. И делали так раньше только лишь из экономии ресурсов. А если ресурсов море. Работайте на удвоенной частоте и отсчитывайте счетчиком удвоенное значение интервала. Тогда младший разряд счетчика выдаст Вам искомую посылку клоков. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nya 0 18 апреля, 2007 Опубликовано 18 апреля, 2007 · Жалоба Оно у вас и так синхронное. Просто вырезать импульсы временными воротами, которые сформированы этими же клоками - плохой том. В том числе и на микросхемах средней степени интеграции. Или впереди пичок или сзади. И делали так раньше только лишь из экономии ресурсов. А если ресурсов море. Работайте на удвоенной частоте и отсчитывайте счетчиком удвоенное значение интервала. Тогда младший разряд счетчика выдаст Вам искомую посылку клоков. Точно, буду пробовать работать с удвоенной частотой, как раз такая возможность имеется. Спасибо. Другое дело - а нужно ли пропускать именно N импульсов именно клока? Может быть, достаточно сформировать сигнал разрешения длительностью в N импульсов клока, и использовать его непосредственно? Задача у меня такая: есть регистроподобное устройство, с последовательным считыванием. Нужно "выдвинуть" из него информацию, не используя дополнительных сигналов опустошения регистра, так что нужны именно импульсы тактовой частоты. Всем огромное спасибо за вклад в развитие аэрокосмической промышленности :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 18 апреля, 2007 Опубликовано 18 апреля, 2007 · Жалоба Точно, буду пробовать работать с удвоенной частотой, как раз такая возможность имеется. Спасибо. Задача у меня такая: есть регистроподобное устройство, с последовательным считыванием. Нужно "выдвинуть" из него информацию, не используя дополнительных сигналов опустошения регистра, так что нужны именно импульсы тактовой частоты. Всем огромное спасибо за вклад в развитие аэрокосмической промышленности :) Половинная частота клока допустима? Тогда все тривиально - формируете передний и задний фронты своего клока в синхронной схеме, тактуемой исходным клоком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nya 0 20 апреля, 2007 Опубликовано 20 апреля, 2007 · Жалоба Получилось! Сделал так: счет по удвоенной частоте, и считаем до (2n-1) тактов, где n - количество исходных тактов. Спасибо! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinnetu 0 23 апреля, 2007 Опубликовано 23 апреля, 2007 · Жалоба Мои 5 копеек. Хоть и запоздало, но, думаю, в тему. Подобные задачи возникают сплошь и рядом. По стробу выдать импульс определённой длины либо один раз, либо в цикле. Либо выдать или принять данные в последовательном коде для какого-либо устройства и пр.. Я нашёл для себя удачную конструкцию и всегда ею пользуюсь. Вот пример: ------------------------------------------------ LIBRARY ieee; USE ieee.std_logic_1164.all; -- Entity Declaration ENTITY REPLY_CONTROL IS PORT ( START : IN STD_LOGIC; CLK_IN : IN STD_LOGIC; DATA_OUT : OUT STD_LOGIC ); END REPLY_CONTROL; -- Architecture Body ARCHITECTURE REPLY_CONTROL_architecture OF REPLY_CONTROL IS signal count: integer range 0 to 15; BEGIN process (START, CLK_IN) -- declarations begin if START = '0' then -- Asynchronous reset code count <= 0; DATA_OUT <= '0'; elsif CLK_IN='0' and CLK_IN'event then -- synchronous code count <= count +1; if count > 8 then count <= 8; end if; case count is when 6 => DATA_OUT <= '1'; when 7 => DATA_OUT <= '1'; when others => DATA_OUT <= '0'; end case; end if; end process; END REPLY_CONTROL_architecture; ------------------------------------------------ Что получается? Пока START = '0', вся схема ждёт. Как только START отпускаем в '1', начинает работать счётчик count. Когда он досчитает до 6, на выходе появится импульс длиной в два такта, после чего схема остановится. Чтобы снова получить имаульс на выходе, нужно уронить START в '0' и снова поднять в '1'. Если нужно, чтобы импульсы шли постоянно, нужно только изменить условие: if count > 8 then count <= 0; end if; Понятно, что первая строчка определяет период следования импульсов. Так можно делать одновибраторы или делители частоты на произвольную величину, не кратную 2. Если программу немного изменить, то её можно использовать для программирования сериальных устройств. Например, программирование PLL: ------------------------------------------------ LIBRARY ieee; USE ieee.std_logic_1164.all; -- Entity Declaration ENTITY PLL_Program IS PORT ( START : IN STD_LOGIC; DATA_IN : IN STD_LOGIC_VECTOR(71 downto 0); CLK : IN STD_LOGIC; RST : IN STD_LOGIC; PLL_EN : OUT STD_LOGIC; PLL_DATA : OUT STD_LOGIC; PLL_CLK : OUT STD_LOGIC ); END PLL_Program; -- Architecture Body ARCHITECTURE PLL_Program_architecture OF PLL_Program IS signal count: integer range 0 to 226; BEGIN process (CLK, START, DATA_IN, RST) -- declarations begin if RST = '1' then count <= 222; elsif START = '1' then -- Asynchronous reset code count <= 0; PLL_EN <= '1'; PLL_DATA <= '0'; PLL_CLK <= '0'; elsif CLK='1' and CLK'event then -- synchronous code count <= count + 1; if count > 222 then count <= 222; end if; case count is -- Initialization Latch 11h when 0 => PLL_EN <= '1'; PLL_CLK <= '0'; PLL_DATA <= DATA_IN(71); when 1 => PLL_EN <= '0'; PLL_CLK <= '0'; PLL_DATA <= DATA_IN(71); when 2 => PLL_EN <= '0'; PLL_CLK <= '1'; PLL_DATA <= DATA_IN(71); when 3 => PLL_EN <= '0'; PLL_CLK <= '0'; PLL_DATA <= DATA_IN(70); when 4 => PLL_EN <= '0'; PLL_CLK <= '1'; PLL_DATA <= DATA_IN(70); .... when 210 => PLL_EN <= '0'; PLL_CLK <= '0'; PLL_DATA <= DATA_IN(1); when 211 => PLL_EN <= '0'; PLL_CLK <= '1'; PLL_DATA <= DATA_IN(1); when 212 => PLL_EN <= '0'; PLL_CLK <= '0'; PLL_DATA <= DATA_IN(0); when 213 => PLL_EN <= '0'; PLL_CLK <= '1'; PLL_DATA <= DATA_IN(0); when 214 => PLL_EN <= '0'; PLL_CLK <= '0'; PLL_DATA <= DATA_IN(0); when 215 => PLL_EN <= '1'; PLL_CLK <= '0'; PLL_DATA <= DATA_IN(0); when 216 => PLL_EN <= '1'; PLL_CLK <= '0'; PLL_DATA <= '0'; when 217 => PLL_EN <= '1'; PLL_CLK <= '0'; PLL_DATA <= '0'; when 218 => PLL_EN <= '1'; PLL_CLK <= '0'; PLL_DATA <= '0'; when 219 => PLL_EN <= '1'; PLL_CLK <= '0'; PLL_DATA <= '0'; when others => PLL_EN <= '1'; PLL_CLK <= '0'; PLL_DATA <= '0'; end case; end if; end process; END PLL_Program_architecture; ------------------------------------------------ Входные сигналы: RST - аппаратный сброс (Global Reset); DATA_IN - данные; CLK - задающая частота; START - сигнал запуска. Если RST = '1', пришёл сброс при включении питания, счётчик count сразу загоняется в верхнее значение. Схема молчит. Это значит, что по сбросу, когда данные ещё не готовы, никаких сигналов вырабатываться не будет. START = '1'. Приготовились! START = '0'. Начало передачи. Для программирования PLL нужно 3 сигнала: PLL_EN - если ='0', PLL выбран. PLL_DATA - последовательные данные, которые стробируются передним фронтом PLL_CLK. Циклы: 0 - готовим старший бит. 1 - опускаем PLL_EN в '0' (активный). 2 - стробируем данные. 3 - готовим следующий бит данных. 4 - стробируем. ... и так далее ... 213 - стробируем последний (младший бит). 214 - выжидаем 1 такт. 215 - поднимаем PLL_EN. Передача завершена. 216-219 - выжидаем небольшую паузу. ----------------------------------------------------- Подобным же образом можно делать и приёмные регистры. Данная конструкция очень универсальная. На её основе можно сделать миллион и одно устройство. Она легко читается и самое главное - не создаёт никаких проблем с гонками. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 8 23 апреля, 2007 Опубликовано 23 апреля, 2007 · Жалоба Не думаю, что это удачная конструкция. (Не говоря об асинхронном ресете и странном описании счетчика (нет приоритетности в описании)). Попробуйте в случае формирования периодической последовательности вставить параметр generic (PERIOD : integer := 15); и что то отличное, например generic (PERIOD : integer := 10); Получите разные приращения, неговоря уже о том, что приращений быть не должно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
john72 0 4 августа, 2016 Опубликовано 4 августа, 2016 (изменено) · Жалоба Пытаюсь переложить данный код на verilog. С обоими языками плохо знаком, помогите пожалуйста "доделать". Написал так: module ct_laa( input EN, input CLK, output LATCH ); reg [6:0] TEMP_Q = 7'b0; reg TEMP_EN = 1'b0; reg [2:0] shift = 3'b0; wire ena; always @(posedge CLK) begin shift <= {shift[1:0], EN}; if (ena == 1'b1) begin TEMP_EN <= 1'b1; TEMP_Q <= 7'b0000000; end else if (TEMP_Q == 7'b0000011); begin TEMP_EN <= 1'b0; end if (TEMP_EN == 1'b1); begin TEMP_Q <= TEMP_Q + 1; end end ena <= not shift[2], and shift[1]; На этой строке Quartus ругается: Error (10170): Verilog HDL syntax error at ct_laa.v(35) near text "<="; expecting ".", or "(" assign LATCH = TEMP_EN; endmodule Как правильно описать? Также не уверен, что все остальное правильно. Прошу проверить. Внизу оригинал. Заранее всем спасибо! Врядли найдется симулятор, который все что выше не поймет. Хотя можно и по другому. (относительно возможных изменений сигнала EN логика функционирования другая) library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.std_logic_unsigned.all; entity ct_laa is port ( EN : in std_logic; CLK : in std_logic; LATCH : out std_logic:='0' ); end entity; architecture count_latch_arch of ct_laa is signal TEMP_Q : std_logic_vector (6 downto 0):=(others =>'0'); signal TEMP_EN : std_logic:='0'; signal shift : std_logic_vector (2 downto 0):=(others =>'0'); signal ena : std_logic; begin process (CLK) begin if rising_edge (CLK) then shift <= shift (1 downto 0) & EN; if ena = '1' then TEMP_EN <='1'; TEMP_Q <="0000000"; else if TEMP_Q = "0000111" then -- n-1 TEMP_EN <='0'; end if; if TEMP_EN = '1' then TEMP_Q <= TEMP_Q+1; end if; end if; end if; end process; ena <= not shift(2) and shift(1); LATCH <=TEMP_EN; end architecture; Изменено 4 августа, 2016 пользователем Evgeny72 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 4 августа, 2016 Опубликовано 4 августа, 2016 · Жалоба ena <= ~ shift[2] & shift[1]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 4 августа, 2016 Опубликовано 4 августа, 2016 · Жалоба Задача вроде бы простая. но у меня не получается ни в какую - три дня бьюсь... Нужно сделать блок: на входе - тактовая частота. При подаче на разрешающий вход импульса - на выходе должно быть некоторое число тактовых периодов. Другими словами, должен получиться ключ, пропускающий определенное количество тактовых импульсов на выход. Может, кто подскажет, как эту штуку слепить? Вроде на первый взгляд так просто казалось... :( Я бы взял не "тактовая частота", а ровно вдвое больше. Потом сделал бы программируемый таймер, и на выходе - триггер. программируемый таймер должен давать разрешение на триггер, который бы и сделал на "выходе" нужное количество импульсов... И это нужно только если эти импульсы выдавать во вне кристалла. А если внутри кристалла, то вполне хватит и выхода таймера, как сигнала разрешения для чего-то... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
john72 0 4 августа, 2016 Опубликовано 4 августа, 2016 (изменено) · Жалоба Попробовал и получил: Error (10137): Verilog HDL Procedural Assignment error at ct_laa.v(33): object "ena" on left-hand side of assignment must have a variable data type. Если декларирую как reg ena, получаю дополнительный триггер в RTL схеме. В исходном коде триггера в RTL схеме нет. ena <= ~ shift[2] & shift[1]; Код на VHDL рабочий, свою задачу выполняет. :) Данный код, по изменению сигнала EN, выдает импульс длинною if (TEMP_Q == 7'bХ - 1). Я бы взял не "тактовая частота", а ровно вдвое больше. Потом сделал бы программируемый таймер, и на выходе - триггер. программируемый таймер должен давать разрешение на триггер, который бы и сделал на "выходе" нужное количество импульсов... И это нужно только если эти импульсы выдавать во вне кристалла. А если внутри кристалла, то вполне хватит и выхода таймера, как сигнала разрешения для чего-то... Изменено 4 августа, 2016 пользователем Evgeny72 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lyatte 0 4 августа, 2016 Опубликовано 4 августа, 2016 · Жалоба Нельзя просто так взять и использовать "<=" вне блока always. Почитайте про виды присвоений в verilog. assign ena = ~ shift[2] & shift[1]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
john72 0 4 августа, 2016 Опубликовано 4 августа, 2016 · Жалоба Спасибо, все ОК! Нельзя просто так взять и использовать "<=" вне блока always. Почитайте про виды присвоений в verilog. assign ena = ~ shift[2] & shift[1]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться