Jump to content
Tesla

Основы Синхронной Логики, Последовательное Включение Триггеров

Recommended Posts

Начинаю изучать ПЛИС, возник вопрос: допустим, у нас есть цепочка из двух последовательно соединённых D-триггеров с общим клоком. По положительному фронту клока первый триггер защёлкивает и передаёт на выход сигнал со своего входа, в этот же момент второй триггер защёлкивает сигнал с выхода первого.

Так вот, можно ли полагаться на то, что второй триггер гарантированно успеет защёлкнуть входной сигнал (являющийся выходным сигналом первого триггера) до того, как тот изменит своё значение?

Share this post


Link to post
Share on other sites

D-триггер - это ДВУХТАКТНЫЙ триггер. Он не передает на выход свое состояние по первому (активному фронту). Т.е. ему нужно для работы оба фронта.

Первый фронт защелкивает вход в первый триггер, а второй защелкивает состояние в выходной триггер.

Share this post


Link to post
Share on other sites

В ПЛИС D-триггеры работают по одному фронту. Достаточно перед активным фронтом установить сигнал и он будет зафиксирован с приходом фронта. По двум фронтам работают только FPGA последних поколений. Такие триггеры предназначаются для работы с памятью. В цифровой же технике в целом работа по двум фронтам D-триггеров используется в асинхронных схемах для уменьшения вероятности возникновения метастабильных состояний.

Так вот, можно ли полагаться на то, что второй триггер гарантированно успеет защёлкнуть входной сигнал (являющийся выходным сигналом первого триггера) до того, как тот изменит своё значение?

Это зависит от грейда быстродействия ПЛИС и от частоты тактового сигнала. Задержка распространения в D-триггере внутри ПЛИС, обычно, меньше 2 нс. Моделирование штатными средствами используемого ПО даст полный ответ. Кстати, если для описания используете VHDL, то учтите, что он несколько хитер в отношении выделения D-триггеров. Можно написАть код так, что компилятор и не будет использовать триггер. При составлении схемы или описании на AHDL (только для Altera) D-триггер указывается конкретно.

Share this post


Link to post
Share on other sites

Литиевые батарейки Fanso для систем телеметрии и дистанционного контроля

Системы телеметрии находят все более широкое применение во многих отраслях на промышленных и коммунальных объектах. Требования, предъявляемые к условиям эксплуатации приборов телеметрии и, как следствие, источников питания для них, могут быть довольно жесткими. Fanso предоставляет широкую линейку продукции, рассчитанной на различные условия эксплуатации, что позволяет подобрать батарейку для каждого конкретного применения, в том числе и для устройств телеметрии.

Подробнее

...есть цепочка из двух последовательно соединённых D-триггеров с общим клоком. По положительному фронту клока первый триггер защёлкивает и передаёт на выход сигнал со своего входа, в этот же момент второй триггер защёлкивает сигнал с выхода первого.

Так вот, можно ли полагаться на то, что второй триггер гарантированно успеет защёлкнуть входной сигнал (являющийся выходным сигналом первого триггера) до того, как тот изменит своё значение?

Можно. По фронту клока ОБА триггера защёлкнут те состояния, которые у них на входе, при этом у первого защёлкнутся внешние данные, у второго, состояние на выходе первого. Говоря иначе информация сдвинется.

Share this post


Link to post
Share on other sites

mazzi верно отметил, что по такому принципу строятся сдвиговые регистры. Однако о частоте тактового сигнала забывать не следует. Далеко не факт, что компилятор сможет разместить схему на кристалле так, что два триггера окажутся в соседних макроячейках. Моделировать всегда нужно. Для CPLD Altera гарантирует почти на 100% соответствие расчетных задержек реальным.

Share this post


Link to post
Share on other sites
                     

Приглашаем на вебинар Решения для построения ультразвуковых счетчиков жидкостей и газов на базе MSP430

Компэл совместно с Texas Instruments 23 октября 2019 приглашают на вебинар, посвященный системам-на-кристалле для построения ультразвуковых расходомеров жидкостей и газов на базе ядра MSP430. Вебинар проводит Йоханн Ципперер – эксперт по ультразвуковым технологиям, непосредственно участвовавший в создании данного решения. На вебинаре компания Texas Instruments представит однокристальное решение, позволяющее создавать точные недорогие счетчики жидкостей и газов.

Подробнее...

Всем спасибо за ответы. Хочу уточнить, допустим, я написал код на Verilog:

module d_ff(input clk, input d, output reg q);

always @(posedge clk)

q <= d;

endmodule

module testbench;

reg clk;
reg a;
wire b;
wire c;

d_ff d_ff1(clk, a, ;
d_ff d_ff2(clk, b, c);

/* ... */

endmodule

Тестирую его при помощи Icarus Verilog, там всё работает так, как и ожидалось. Но, насколько я понял из написанного выше, в реальном устройстве это может оказаться не так?

Share this post


Link to post
Share on other sites

Какая тактовая частота и что за кристалл? Если такт менее 100 МГц, то проблемы возникают редко. Встроенные средства моделирования хорошо рассчитывают тайминги, и делают это после компиляции.

Share this post


Link to post
Share on other sites

О конкретном железе пока не думаю, для начала хочу научиться писать переносимый код, не привязанный к железу. Реально ли это?

Share this post


Link to post
Share on other sites

Конечно, реально. Для ПЛИС класса CPLD ограничение только одно - объем. Для FPGA сложнее, так как "на борту" могут быть уже реализованы некоторые функции (ФАПЧ, вычислительные модули). Но это не всегда и не всем нужно, и уж тем более при освоении. Главное - это освоить язык описания цифровых схем, а он универсален и подходит к любому кристаллу. Для FPGA может потребоваться более глубокое изучение в будущем, так как тайминги внутри кристалла могут быть изменены проектировщиком за счет размещения функциональных блоков. Я сам в это глубоко не вдавался, так как FPGA ОЧЕНЬ с запасом для моих нужд. :)

Share this post


Link to post
Share on other sites

А подскажите такой момент: программировал плисину XC95288XL_PQ208_10I В ней нужно было организовать последовательное включение 10 триггеров по схеме, описанной в первом сообщении, т.е. выход каждого триггера идет на вход следующего, а с последнего на выход микросхемы.

Код основного файла:

entity XC95288XL_PQ208_10I is
Port ( clk : in STD_LOGIC;
d : in STD_LOGIC;
q: out STD_LOGIC);
end XC95288XL_PQ208_10I;

architecture Behavioral of XC95288XL_PQ208_10I is

component triger
port( c: in std_logic;
dd: in std_logic;
qq: out std_logic);
end component;

signal v: std_logic_vector (9 downto 0);
begin

tr0: triger port map (c=>clk, dd=>d, qq=>v(0));
tr1: triger port map (c=>clk, dd=>v(0), qq=>v(1));
tr2: triger port map (c=>clk, dd=>v(1), qq=>v(2));
tr3: triger port map (c=>clk, dd=>v(2), qq=>v(3));
tr4: triger port map (c=>clk, dd=>v(3), qq=>v(4));
tr5: triger port map (c=>clk, dd=>v(4), qq=>v(5));
tr6: triger port map (c=>clk, dd=>v(5), qq=>v(6));
tr7: triger port map (c=>clk, dd=>v(6), qq=>v(7));
tr8: triger port map (c=>clk, dd=>v(7), qq=>v(8));
tr9: triger port map (c=>clk, dd=>v(8), qq=>q);

end Behavioral; 

работа самого триггера описывается в отдельном файле:

entity triger is
Port ( c : in STD_LOGIC;
dd : in STD_LOGIC;
qq : out STD_LOGIC);
end triger;

architecture Behavioral of triger is

begin

process (c)
begin
if rising_edge(c) then
qq<=dd;
end if;
end process;

end Behavioral; 

А сам вопрос таков - если мне надо не 10 триггеров, а, например, 150, можно ли это как-то циклом организовать, чтоб не прописывать 150 раз всю цепочку? Пытался через generate и цикл for, но постоянно ошибки выскакивали. Тестирую в test-bench на ISE9.2

Share this post


Link to post
Share on other sites

А зачем Вы описываете триггеры, если они входят в состав любой ПЛИС? Нужно просто ими воспользоваться. Я не силен в VHDL, но следующий код представляет собой сдвиговый 150-и разрядный регистр и успешно работает в Altera Quartus:

LIBRARY	ieee;
USE ieee.std_logic_1164.all;
ENTITY reg150 IS
PORT
(
clkin : IN STD_LOGIC;
datai : IN STD_LOGIC;
datao : OUT STD_LOGIC
);
END reg150;
ARCHITECTURE descreg OF reg150 IS
SIGNAL cnt : STD_LOGIC_VECTOR (149 DOWNTO 0);
BEGIN
PROCESS (clkin)
BEGIN
IF (RISING_EDGE(clkin)) THEN
cnt(0) <= datai;
FOR n IN 149 DOWNTO 1 LOOP
cnt(n) <= cnt(n-1);
END LOOP;
END IF;
END PROCESS;
datao <= cnt(149);
END descreg;

Share this post


Link to post
Share on other sites

Хорошо, допустим, что в плисине доступно 288 макроячеек, я хочу задействовать все возможные из них как триггеры с последовательным выходом-входом (как описывал раньше). Каким образом их все задействовать?

А зачем Вы описываете триггеры, если они входят в состав любой ПЛИС? Нужно просто ими воспользоваться

Как к ним обратиться, чтоб воспользоваться? Я сам не сильно силен в VHDL и в этом деле только недавно начал копаться.

Share this post


Link to post
Share on other sites

Вы, видимо, с ПЛИС не очень давно работаете. Здесь есть некоторые моменты. Во-первых, всегда ПЛИС выбирается под проект, но никак не наоборот. Вы должны составить код с нужным функционалом, проверить его на функционирование и соответствие требования таймингов с любым семейством и только после этого подбирать подходящую по совокупности характеристик ПЛИС, после чего последует повторная компиляция и проверка таймингов. Во-вторых, ПЛИС нельзя загружать на 100%. В противном случае компиляция проекта может быть завершена с ошибкой о невозможности трассировки связей на кристалле. Самый худший вариант - компиляция будет удачной, но в процессе работы начнутся сбои. Чтобы этого избежать рекомендуется оставлять запас емкости не менее 20%.

Что же касается прямого обращения к триггерам в VHDL, то этот язык не подразумевает такового, как, например, Altera HDL (AHDL), где триггеры указываются явно. В VHDL компилятор выделит триггер в том случае, если в процессе будет задействовано поведение схемы по фронту или спаду тактового сигнала - RISING_EDGE(clk), FALLING_EDGE(clk).

Share this post


Link to post
Share on other sites

А зачем Вы описываете триггеры, если они входят в состав любой ПЛИС? Нужно просто ими воспользоваться.

Что же касается прямого обращения к триггерам в VHDL, то этот язык не подразумевает такового

Т.е. в первом сообщении имелось ввиду обратиться к триггеру на языке AHDL?

Во-первых, всегда ПЛИС выбирается под проект, но никак не наоборот. Вы должны составить код с нужным функционалом, проверить его на функционирование и соответствие требования таймингов с любым семейством и только после этого подбирать подходящую по совокупности характеристик ПЛИС, после чего последует повторная компиляция и проверка таймингов.

Это я знаю, но мне важен принцип описания, чтобы возможно было циклом описать любое количество последовательно построенных триггеров. Выше я приводил свой код для 10 триггеров, а мне надо задействовать 150. Можно, конечно, прописать 150 раз похожие строки, но хочется все-таки оптимизировать. Вопрос именно в том, как описать это в цикле, чтобы отделаться несколькими строками, а не 150?

Share this post


Link to post
Share on other sites
Т.е. в первом сообщении имелось ввиду обратиться к триггеру на языке AHDL?

Нет, не это. Тем более, что Xilinx не работает с AHDL. Я говорил о том, что не нужно создавать триггеры, так как они уже есть в ПЛИС и для этого к ним нужно просто обратиться. В частности, для VHDL это делается через использование в процессе поведения по перепаду сигнала - фронту или спаду.

Выше я приводил свой код для 10 триггеров, а мне надо задействовать 150. Можно, конечно, прописать 150 раз похожие строки, но хочется все-таки оптимизировать. Вопрос именно в том, как описать это в цикле, чтобы отделаться несколькими строками, а не 150?

Так я Вам привел выше VHDL код, в котором последовательно включены 150 триггеров. На вход первого поступает сигнал datai, с выхода последнего выходит datao. Это 150-и разрядный сдвиговый регистр. Создано с использованием цикла.

Share this post


Link to post
Share on other sites

Понял! Спасибо! А что делает оператор loop в цикле for? Поискал в инете, вроде бы как задает последовательное выполнение иттераций, но ведь цикл на то и цикл, чтоб быть изначально последовательным...Или я не правильно понял?

Share this post


Link to post
Share on other sites

LOOP - это оператор цикла. Сам по себе использоваться не может, так как обозначает бесконечный цикл. Должно быть условие выхода из цикла. В данном случае используется цикл с указанием количества повторений за счет оператора FOR. Об этом можно прочитать на странице 68 книги "Проектирование цифровых систем на VHDL" от авторов Е.А. Суворова, Ю.Е.Шейнин.

Share this post


Link to post
Share on other sites

Сделал по Вашему коду, но в тест-бенче не работает. тактовый и д-сигналы идут по заданным параметрам, а вот на выходе красная u-линия. Фото http://files.mail.ru/6358V7?t=1

код основного файла:

entity XC95288XL_10TQ144i is
Port ( clk : in STD_LOGIC;
d : in STD_LOGIC;
q : out STD_LOGIC);
end XC95288XL_10TQ144i;

architecture Behavioral of XC95288XL_10TQ144i is
signal tr: std_logic_vector(199 downto 0);
begin
process (clk)
begin
IF (RISING_EDGE(clk)) THEN
tr(0) <= d;
FOR n IN 199 DOWNTO 1 LOOP
tr(n) <= tr(n-1);
END LOOP;
END IF;
END PROCESS;
q <= tr(199);
end Behavioral;

код тест-бенча:

ENTITY test1_vhd IS
END test1_vhd;

ARCHITECTURE behavior OF test1_vhd IS

-- Component Declaration for the Unit Under Test (UUT)
COMPONENT XC95288XL_10TQ144i
PORT(
clk : IN std_logic;
d : IN std_logic;
q : OUT std_logic
);
END COMPONENT;

--Inputs
SIGNAL clk : std_logic := '0';
SIGNAL d : std_logic := '0';

--Outputs
SIGNAL q : std_logic;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: XC95288XL_10TQ144i PORT MAP(
clk => clk,
d => d,
q => q
);

tb : PROCESS
BEGIN


wait for 50 ns; clk<='1';
wait for 50 ns; clk<='0';

END PROCESS;
tb2: process
begin
wait for 20 ns; d<='1';
wait for 20 ns; d<='0';
end process;
END;

Share this post


Link to post
Share on other sites

Както писал проект под спартан и обратил внимание, что VHDL в ISE не воспринимает конструкцию rising_edge(clk). Вот clk'event and clk='1' он хорошо воспринимает.

Вообще можно обойтись и таким написанием tr( n downto 1):=tr( n-1 downto 0);

Работает без LOOP. Хотя, думаю, это не принципиально.

Share this post


Link to post
Share on other sites

Meteor77, вот это странно, так как события RISING_EDGE и FALLING_EDGE существуют с момента разработки языка, а событие EVENT было добавлено позже в какой-то из редакций. Хотя, удивляться программистам иногда не приходится.

в тест-бенче не работает. тактовый и д-сигналы идут по заданным параметрам, а вот на выходе красная u-линия

Я с тест-бенчем не работаю, но логика кажется понятной. Во-первых, у Вас для тактового сигнала выбран период 100 ns, а для сигнала данных - 40 ns. D-триггеры, конечно, будут работать, но корректнее моделировать так, чтобы тактовый сигнал был с меньшим периодом хотя бы в два раза относительно периода сигнала данных. Во-вторых, у Вас схема состоит из 200 последовательно включенных триггеров. Это стандартный регистр сдвига - данные продвигаются вперед с каждым тактом. Следовательно на выход схемы они попадут только после 200-го такта, а в среде моделирования видны только 10 тактов. Естественно, что на выходе лог. 0.

Совет на будущее. Когда моделируете работу с данными, лучше задавать их некоторое подобие. Например, 0100101101010011. Так гораздо нагляднее, особенно когда используются алгоритмы переноса данных и требуется контроль корректного выполнения операции.

Share this post


Link to post
Share on other sites
Както писал проект под спартан и обратил внимание, что VHDL в ISE не воспринимает конструкцию rising_edge(clk). Вот clk'event and clk='1' он хорошо воспринимает.

изменил в проекте, заработал в симуляции как надо, но вот только в RTL Schematic выдает такую конструкцию http://files.mail.ru/QTO2LJ?t=1 вместо последовательного соединения 200 тригеров :unknw:

Share this post


Link to post
Share on other sites
...только в RTL Schematic выдает такую конструкцию ...вместо последовательного соединения 200 тригеров

Откровенно говоря, натыкался на подобное отображение в квартусе. В ISE сейчас сварганил - получил почти такой же. Скорее всего это "оптимизированное" отображение. Я бы не стал обращать внимание, потому как нарисовать энное число триггеров- дело неблагодарное.

PS. Постарайтесь вкладывать скрины тут же. Зачем гонять за 3,5 МБ на другой ресурс, если достаточно разместить картинку "сотню" кБ?

Edited by Meteor77

Share this post


Link to post
Share on other sites

В дополнение.

Вот пример на ISE сдвиговый регистр из 16 регистров.

Смотрите в консоли отчет о ресурсах

post-95351-0-89175400-1352228198_thumb.jpg

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...