Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Синхронизатор
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Страницы: 1, 2
AlphaMil
Гуру, подскажите, как правильно сделать:
есть одиночный импульс синхронный 100МГц, он должен породить одиночный импульс на 50МГц.
Весь проект нет смысла переводить на повышенную частоту.
Мур
Цитата(AlphaMil @ Apr 7 2011, 17:19) *
Гуру, подскажите, как правильно сделать:
есть одиночный импульс синхронный 100МГц, он должен породить одиночный импульс на 50МГц.
Весь проект нет смысла переводить на повышенную частоту.

На рисунке 8 в статье разгадка
А это базовый синхронизатор оттуда.
CODE

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity syn is
port(
clk : in STD_LOGIC;
in_level : in STD_LOGIC;
reset : in STD_LOGIC;
imp : out STD_LOGIC
);
end syn;
architecture syn_body of syn is
signal qqq : STD_LOGIC;
signal ddd : STD_LOGIC;
begin
tg: process (clk)
begin
if clk'event and clk = '1' then
if reset='1' then
qqq <= '0';
ddd <= '0';
else
qqq <= ddd;
ddd <= in_level;
end if;
end if;
end process;
imp <= ddd xor qqq;
end syn_body;

На входе in_level любая смена уровня порождает импульс привязанный к другой частоте.
На элементе xor (для этого in_level ) сделаете смену уровня на обратный по вновь поступающему импульсу....
В конце рабочего дня бдительность потерял. Тут просто Т-триггер(делитель)! Усталость... Извините!
Kuzmi4
2 AlphaMil
поищите по форуму - тут SM выкладывал как раз такой дизайн который вам нужен - там 3(4?) тригера и 1 лут вроде в минимальной комплектации..
AlphaMil
2 AndrewS6 и всем остальным спасибо очень интересное решение.
Мур
Цитата(Kuzmi4 @ Apr 7 2011, 18:25) *
2 AlphaMil
поищите по форуму - тут SM выкладывал как раз такой дизайн который вам нужен - там 3(4?) тригера и 1 лут вроде в минимальной комплектации..

"Мой" вариант с таким же ресурсом! ...Если глянуть внимательно....
Kuzmi4
2 Мур
Если взглянуть внимательнее ваш HDL модуль вообще один клок имеет biggrin.gif

А если мне не изменяет маразм то минимальная комплектация модуля от SM: 1 тригер на clkA, 3 тригера на clkB и 1 лут
Мур
Цитата(Kuzmi4 @ Apr 7 2011, 21:02) *
2 Мур
Если взглянуть внимательнее ваш HDL модуль вообще один клок имеет biggrin.gif

А если мне не изменяет маразм то минимальная комплектация модуля от SM: 1 тригер на clkA, 3 тригера на clkB и 1 лут

Вы не внимательны. HDL фрагмент только выходная часть базового синхронизатора. Вход(Т-триггер) на другой частоте. Его тут нет. А что его тут писать,-один триггер на входе?
Ещё раз - Рис 8.
Kuzmi4
2 Мур
посмотрел статейку и рисунок - слямзено с EDN, July 24, 2003.
Но суть в другом - не будет эта реализация работать для произвольных клоковых доменов. Там есчё handshake логику нужно добавлять wink.gif чтоб честно работало...
Ethereal
Цитата(Kuzmi4 @ Apr 9 2011, 14:44) *
2 Мур
посмотрел статейку и рисунок - слямзено с EDN, July 24, 2003.
Но суть в другом - не будет эта реализация работать для произвольных клоковых доменов. Там есчё handshake логику нужно добавлять wink.gif чтоб честно работало...

Имхо, для произвольных доменов будет. Там единственное условие, что частота запускающих импульсов в первом домене должна быть не больше, чем тактовая в принимающем.
Kuzmi4
Цитата(Ethereal @ Apr 9 2011, 14:23) *
....единственное условие....

Вот вот.. cool.gif
Ethereal
Цитата(Kuzmi4 @ Apr 9 2011, 15:32) *
Вот вот.. cool.gif

Ну, с хендшейком в этом случае оно тоже может не работать. Либо из двух импульсов на входе получится один на выходе, либо придется Ack тянуть в генератор.
А дальше зависит от исходной задачи. Можно там задержать генерацию импульса или нет )
Kuzmi4
2 Ethereal
я собственно это к чему, случался дизайн в которых клоковый домен А мог работать как на большей так и на меньшей скорости чем домен Б (задавалось конфигом). В таких случаях лучше иметь универсальную схему, которая будет передавать 1clk импульс из А в Б, а не исходить из того, что у кого то тактовая меньше а у кого то больше..
Ethereal
Цитата(Kuzmi4 @ Apr 9 2011, 15:50) *
2 Ethereal
я собственно это к чему, бывали дизайны в которых клоковый домен А мог работать как на большей так и на меньшей скорости чем домен Б (задавалось конфигом). В таких случаях лучше иметь универсальную схему, которая будет передавать 1clk импульс из А в Б.

Если это про тактовые, то дизайн работает при clkA<clbB, при clkA>clkB, при clkA=clkB. 1 1clk импульс передается в любую сторону.
sazh
Цитата(Kuzmi4 @ Apr 9 2011, 14:50) *
В таких случаях лучше иметь универсальную схему


Так у Тицца и Шенка еще 20 лет назад нарисовано.
И входного клока не надо.
Boris_TS
Тут как-то совсем не прозвучало в исходном задании - являются ли исходные clock (100М и 50М) связанными - т.е. понимает ли среда при Place&Route какие соотношения между этими частотами или это асинхронные тактовые частоты ?

Если есть асинхронщина, то будет и пара триггеров (метастабильный -> стабильный). Для достижения максимальной устойчивости работы проекта, как минимум, необходимо сделать так, чтобы линия данных между этими двумя триггерами была минимальной длины. А вот как это добиться уже зависит от конкретной ПЛИС (кстати, название среды разработки и семейство ПЛИС как-то тоже не были озвучены)...
AlphaMil
Да, частоты зависимы и генерируются от одного клока. Сейчас использую S3 и ISE 12.4. Среда понимает соотношение частот. Так может все было зря?
Boris_TS
Цитата(AlphaMil @ Apr 10 2011, 20:17) *
Да, частоты зависимы и генерируются от одного клока.
Сейчас использую S3 и ISE 12.4. Среда понимает соотношение частот.

Это хорошо, что от одного генератора. Теперь остаётся уточнить, как Вы получали эти частоты: при помощи DLL ? Хорошо бы схемку (ну или HDL описание) глянуть этого места.

Если всё сделать правильно, то и метастабильности не будет - а значит, всё будет тривиально (как функционально моделируется - так и работает,.. если, конечно all constraints are met).
sazh
Цитата(AlphaMil @ Apr 10 2011, 20:17) *
Да, частоты зависимы и генерируются от одного клока.


Тицце и Шенк на этот счет

Код
module in_out_flag
(
input  in_flag,
input  out_clk,
output ena_out_flag
);

reg          dff_a = 1'b0;
reg [1:0] shift_rg = 2'b00;

always @(posedge out_clk or posedge in_flag)
begin
if(in_flag)            dff_a <= 1'b1;
else                dff_a <= 1'b0;
end

always @(posedge out_clk)
begin
shift_rg <= {shift_rg[0], dff_a};
end

assign ena_out_flag = ~shift_rg[1] && shift_rg[0];

endmodule

Oldring
Цитата(sazh @ Apr 10 2011, 22:07) *
Код
if(in_flag)            dff_a <= 1'b1;
else                dff_a <= 1'b0;
end


В Верилоге нельзя написать проще?

Код
dff_a <= in_flag;


Кстати, не стоит бездумно доверять даже Т-Ш.
Его схема расширения импульсов с двумя триггерами хороша, но первый триггер тем не менее может порождать переход dff_a с нарушением сетапа выходного триггера, соответственно второй триггер может попасть в метастабильность, о чем Т-Ш забыли упомянуть. Соответственно, чтобы избежать риска метастабильности ena_out_flag, вам нужно добавить в сдвиговый регистр на вход еще один триггер, реализовав нормальный синхронизатор.
sazh
Цитата(Oldring @ Apr 10 2011, 21:54) *
Код
dff_a <= in_flag;


always @(posedge out_clk or posedge in_flag)


Это описание d триггера с асинхронной установкой в единицу.
Oldring
Цитата(sazh @ Apr 10 2011, 23:17) *
always @(posedge out_clk or posedge in_flag)


Это описание d триггера с асинхронной установкой в единицу.


Я понял. И что, это описание приводит к необходимости писать if?
sazh
Цитата(Oldring @ Apr 10 2011, 22:28) *
Я понял. И что, это описание приводит к необходимости писать if?


Да, в верилоге есть некая неистественность при описании асинхронной установки.
Но VHDL еще более неистественнен
process (C, CLR)
begin
if (CLR = ’1’)then
Q <= ’0’;
elsif (C’event and C=’0’)then
Q <= D;
end if;

Тот же if при описании асинхронной установки.
И еще круче if при описании фронта клока, да еще с закрытием end if
Фронт клока - это фронт клока, а не приоритетность в описании
Oldring
Цитата(sazh @ Apr 10 2011, 23:41) *
Да, в верилоге есть некая неистественность при описании асинхронной установки.
Но VHDL еще более неистественнен
process (C, CLR)
begin
if (CLR = ’1’)then
Q <= ’0’;
elsif (C’event and C=’0’)then
Q <= D;
end if;

Тот же if при описании асинхронной установки.
И еще круче if при описании фронта клока, да еще с закрытием end if
Фронт клока - это фронт клока, а не приоритетность в описании


Еще раз спрощу. в вашем коде if просто копирует один сигнал в другой. Неужели он необходим чтобы синтезатор синтезировал триггер с асинхронным сбросом?

в VHDL есть стандартные функции rising_edge, falling_edge, для приведения описания к "более естественному" if falling_edge( C ) then ... end if;
Необходимость писать end if - это хорошо.

Вы не упустили моё дополнение про ошибку в вашем коде?
sazh
Цитата(Oldring @ Apr 10 2011, 22:47) *
в вашем коде просто копирует один сигнал в другой.


Я реализовал схему из учебника. Эта схема отрабатывает импульс любой длительности в импульс длительностью нужного периода. Что и хотел иметь вопрошающий.
Все.
Victor®
Цитата(sazh @ Apr 10 2011, 22:41) *
Да, в верилоге есть некая неистественность при описании асинхронной установки.
Но VHDL еще более неистественнен
process (C, CLR)
begin
if (CLR = '1')then
Q <= '0';
elsif (C'event and C='0')then
Q <= D;
end if;

Тот же if при описании асинхронной установки.
И еще круче if при описании фронта клока, да еще с закрытием end if
Фронт клока - это фронт клока, а не приоритетность в описании


Ничего неестественного не вижу... если конечно Вы знаете, что c if... elsif порождаются приоритетные конструкции.
Т.е. получается если активен CLR, то все равно какое значение имеет C
и тригер будет установлен в 0, что и является асинхронным сбросом. А дальше, если CLR не равен 1 смотрится - произошло-ли событие на С.

Все четко и прозрачно, и честно говоря не понятно, что вызывает недоумение.

P.S.

Кстати, end if относится ко всей конструкции if... elsif,а не только к elsif.
rolleyes.gif
sazh
Цитата(Victor® @ Apr 10 2011, 22:51) *
Все четко и прозрачно, и честно говоря не понятно, что вызывает недоумение.


Да все прозрачно. Мне все равно, на каком языке читать.
Я подумал, что это наезд на верилог со стороны ярого сторонника VHDL.
А это он меня оказывается в ошибке уличил.
Смешно.
Oldring
Цитата(sazh @ Apr 10 2011, 23:50) *
Я реализовал схему из учебника. Эта схема отрабатывает импульс любой длительности в импульс длительность нужного периода.
Все.


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

В общем, еще раз повторю. Не стоит бездумно доверять учебникам.

Цитата(sazh @ Apr 10 2011, 23:57) *
Я подумал, что это наезд на верилог со стороны ярого сторонника VHDL.
А это он меня оказывается в ошибке уличил.
Смешно.


И в ошибке тоже уличил laughing.gif
А наезд был несерьезным. Понятно, что можно написать там и без if, и синтезатор наверняка поймет правильно.
Хотелось узнать причину использования вами такой конструкции.
sazh
Цитата(Oldring @ Apr 10 2011, 22:58) *
С риском метастабильности на выходе.


Да творчески я к их схеме подошел. О какой метастабильности речь идет, там 3 триггера на одном клоке сидят.
Да плюс к этому клоки порождаются одним модулем.
Эта ничуть не хуже уже предложенным. Вот и все.
Про ошибку не понял.
Пожалуста, приведите свой вариант исполнения. Я постараюсь понять.
Oldring
Цитата(sazh @ Apr 11 2011, 00:02) *
Да творчески я к их схеме подошел. О какой метастабильности речь идет, там 3 триггера на одном клоке сидят.
Да плюс к этому клоки порождаются одним модулем.
Эта ничуть не хуже уже предложенным. Вот и все.


Все три на одном клоке, и тем не менее, метастабильность из-за асинхронного входа.
Асинхронный фронт входа приводит к асинхронному изменению выхода первого триггера через его вход асинхронной установки. Если это асинхронное изменение выхода первого триггера попадет в окно setup-hold второго триггера, он может попасть в метастабильность. И через комбинационную схему эта метастабильность попадает непосредственно на выход, несмотря на то, что там есть еще и третий триггер. То есть триггера три, но из них нет ни одной полноценной пары-синхронизатора.

Я уже предложил добавить на вход вашего сдвигового регистра еще один триггер, чтобы породить там стандартный синхронизатор.

Чтобы безопасно передать импульс от быстрого к медленному синхронному с ним клоку можно обойтись двумя триггерами. И без использования асинхронных входов триггеров, что всегда чревато проблемами.
sazh
Цитата(Oldring @ Apr 10 2011, 23:08) *
Я уже предложил добавить на вход вашего сдвигового регистра еще один триггер, чтобы породить там стандартный синхронизатор.


Добавим.
Код
module in_out_flag
(
input  in_flag,
input  out_clk,
output ena_out_flag
);

reg          dff_a = 1'b0;
reg [2:0] shift_rg = 3'b000;

always @(posedge out_clk or posedge in_flag)
begin
if(in_flag)            dff_a <= 1'b1;
else                dff_a <= 1'b0;
end

always @(posedge out_clk)
begin
shift_rg <= {shift_rg[1:0], dff_a};
end

assign ena_out_flag = ~shift_rg[2] && shift_rg[1];

endmodule
Ethereal
Цитата(Oldring @ Apr 11 2011, 00:01) *
Понятно, что можно написать там и без if, и синтезатор наверняка поймет правильно.
Хотелось узнать причину использования вами такой конструкции.

Не поймет. Квартусовский, например, на такие конструкции ругается.

Нажмите для просмотра прикрепленного файла
Oldring
Цитата(Ethereal @ Apr 11 2011, 00:17) *
Не поймет. Квартусовский, например, на такие конструкции ругается.


Значит, я был лучшего мнения о вашем кактусе.

И про верилог я могу сказать только "фи". Описание асинхронного сброса через posedge in_flag - это экономия за счет естественности описания. В VHDL, конечно, требуются отдельно описывать списки чувствительности процесса, что иногда напрягает, но необходимо для симуляции, но сама логика с разделенными асинхронными и синхронной ветками if гораздо прозрачнее получается.
sazh
Цитата(Oldring @ Apr 10 2011, 23:21) *
Значит, я был лучшего мнения о вашем кактусе.


А причем тут квартус. Это конструкция рекомендована xst.pdf. И моделсим не против.
Приведите свой пример. Достойный ваших знаний.
Oldring
Цитата(sazh @ Apr 11 2011, 00:25) *
Приведите свой пример. Достойный ваших знаний.


Вот описание этой схемы синхронизатора на VHDL. В VHDL-2008 будут доступны некоторые дополнительные упрощения, но ISE его пока что не синтезирует.

Код
library ieee;
use ieee.numeric_bit.all;

entity in_out_flag is
    port(
        in_flag : in bit;
        
        out_clk : in bit;
        ena_out_flag : out bit
    );
end in_out_flag;

architecture Behavioral of in_out_flag is
    -- На S6 схема получается проще, если начальное состояние триггера с задействованной асинхронной установкой равно 1
    signal shift_reg : bit_vector( 1 to 4 ) := (others => '1');
begin

process( in_flag, out_clk )
begin
    if rising_edge( out_clk ) then
        shift_reg <= shift_reg srl 1;
    end if;
    
    if in_flag = '1' then
        shift_reg( 1 ) <= '1';
    end if;
end process;

ena_out_flag <= shift_reg( 3 ) and not shift_reg( 4 );

end Behavioral;


Пример на самом деле немного учебный, потому что в промышленном коде нужно вместо двух внутренних триггеров вставить обычный синхронизатор как отдельный компонент, тайминги в котором тщательно обконстрейнены, и прописаны у его триггеров все необходимые атрибуты, чтобы отключить оптимизацию через них логики.
ViKo
Цитата(Ethereal @ Apr 10 2011, 23:17) *
Не поймет. Квартусовский, например, на такие конструкции ругается.

А на такие (код от Oldring) - нет.
Кто из нас неправ?
Нажмите для просмотра прикрепленного файла
Надеюсь, честь Quartus'а спасена? sm.gif
Ethereal
Цитата(ViKo @ Apr 11 2011, 11:05) *
А на такие (код от Oldring) - нет.
Кто из нас неправ?
Надеюсь, честь Quatus'а спасена? sm.gif

Какая связь между кодом Oldring на VHDL и возможностью проглатывания синтезатором предложенной Oldring'ом же замены в верилоговском описании? o_O

Было
Код
always @(posedge C or posedge R)
begin
  if(R) O<=1;
  else O<=0;
end


Предложено
Код
always @(posedge C or posedge R)
begin
  O<=R;
end
sazh
Цитата(Oldring @ Apr 10 2011, 23:49) *
Вот описание этой схемы синхронизатора на VHDL.


Снимаю шляпу. Помню Вашу реализацию Barrel Shifters. Чтобы понять, что Вы написали, мне пришлось задействовать rtl просмотрщик.
И в этом примере Вы все поставили с ног на голову, применив сдвиг вправо.
Вы ведь прекрасно понимаете, что Ваше описание нечитаемо для пользователя среднего уровня развития.
(Два if в одном процессе). И опять я полез в RTL просмотрщик.
А потом гадай, как другие синтезаторы к такому описанию отнесутся.
Интересно, есть у Вас работники, которые в состоянии подхватить Ваши проекты.
ViKo
Цитата(sazh @ Apr 11 2011, 11:43) *
Чтобы понять, что Вы написали, мне пришлось задействовать rtl просмотрщик.
А потом гадай, как другие синтезаторы к такому описанию отнесутся.

Вот и я, из любопытства скомпилировал код Oldring и показал картинку.
sazh
Цитата(ViKo @ Apr 11 2011, 11:47) *
Вот и я, из любопытства скомпилировал код Oldring и показал картинку.


Картинка у него другая. Это не его код.
ViKo
Цитата(Ethereal @ Apr 11 2011, 10:53) *
Какая связь между кодом Oldring на VHDL и возможностью проглатывания синтезатором предложенной Oldring'ом же замены в верилоговском описании? o_O

Вы показали картинку, и написали, что на такое Quartus ругается. Я показал картинку, на которую Quartus "не ругается". Они что, сильно отличаются? Поясните, что вы хотели сказать в первом случае, и только что.

Цитата(sazh @ Apr 11 2011, 11:47) *
Картинка у него другая. Это не его код.

Как это не его? Скопировал. Создал файл *.vhd. Скомпилировал. Картинку извлек. В сообщение забросил.
Oldring
Цитата(sazh @ Apr 11 2011, 12:47) *
Картинка у него другая. Это не его код.


Мой! Сам писал! Мамой клянусь! biggrin.gif


Цитата(sazh @ Apr 11 2011, 12:43) *
Вы ведь прекрасно понимаете, что Ваше описание нечитаемо для пользователя среднего уровня развития.
(Два if в одном процессе). И опять я полез в RTL просмотрщик.


Да, к сожалению "средний уровень развития" желает лучшего.

Тем не менее, этот код не должен быть очень сложным для профессионального программиста, занявшегося HDL и не поленившегося прочитать стандарт языка. Люди "от железа" просто смотрят на HDL как на "описание схемы", от программирования - как на описание поведения. И, кстати, согласитесь, моё описание на VHDL проще и естественнее, когда в нём разобраться - просто сдвиговый регистр на 4 бита, у которого состояние первого регистра асинхронно устанавливается в единицу отдельным асинхронным входом.

Два if - кажется, встречал такое даже в рекомендациях по стилю не помню каких тулзов.
sazh
Цитата(ViKo @ Apr 11 2011, 11:51) *
Создал файл *.vhd. Скомпилировал. Картинку извлек. В сообщение забросил.


Тогда в догон версия пакета и целевой кристалл.
Мур
Цитата(ViKo @ Apr 11 2011, 11:05) *
..Кто из нас неправ?

Прямо буря в стакане воды!
Вот что требовалось ...по рис 8!
Код, предложенный мной в начале, описывает два выходных регистра. Первый триггер - делитель. Схема достаточно универсальна для любых частот...
sazh
Цитата(Oldring @ Apr 11 2011, 12:06) *
Да, к сожалению "средний уровень развития" желает лучшего.


Я бы сказал, золотая середина. Ведь на выходе - качественный продукт, понятный каждому.
Oldring
Цитата(Мур @ Apr 11 2011, 13:55) *
Схема достаточно универсальна для любых частот...


Для любых связанных частот без асинхронщины между ними.
Мне toggle тоже больше нравится, но обсуждалась в стакане воды именно схема из Т-Ш, растягивающая и синхронизирующая асинхронные импульсы произвольной длины, то есть без входного клока.

Цитата(sazh @ Apr 11 2011, 13:58) *
Я бы сказал, золотая середина. Ведь на выходе - качественный продукт, понятный каждому.


До тех пор, пока указанные вами условия не начинают вступать в противоречие друг с другом, вы, безусловно, правы. Поэтому схематики более понятны для "золотой середины", чем любой HDL.

Но, как как хорошо известно из истории развития программирования, по мере усложнения любой системы балланс неизбежно смещается в сторону использования более удобных языков с более продвинутой идеологией и, соответственно, более сложных в изучении.
Мур
Цитата(Oldring @ Apr 11 2011, 14:04) *
Для любых связанных частот без асинхронщины между ними.
Мне toggle тоже больше нравится, но обсуждалась в стакане воды именно схема из Т-Ш, растягивающая и синхронизирующая асинхронные импульсы произвольной длины, то есть без входного клока.

До тех пор, пока указанные вами условия не начинают вступать в противоречие друг с другом, вы, безусловно, правы. Поэтому схематики более понятны для "золотой середины", чем любой HDL.

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

И асинхронных тоже!(его основная функция по статье применяется для переходов между доменами и синхронизациями).
На HDL три триггера описываются легко.
Я в своих проектах разделяю эту схему на два фрагмента. Один я уже привёл(выходной), а второй, в большинстве своём, прячется в моих автоматах. События у меня- просто смена состоояния на противоположный!
Oldring
Цитата(Мур @ Apr 11 2011, 14:15) *
И асинхронных тоже!(его основная функция по статье применяется для переходов между доменами и синхронизациями).


Для асинхронных клоков ваша схема подвержена риску сбоев из-за метастабильности второго триггера.
Мур
Цитата(Oldring @ Apr 11 2011, 14:17) *
Для асинхронных клоков ваша схема подвержена риску сбоев из-за метастабильности второго триггера.

В наших силах держать эту пару рядом друг с другом biggrin.gif , чтобы уйти от проблемы метастабильности.

Мне важен факт события, а не момент...
Oldring
Цитата(Мур @ Apr 11 2011, 14:26) *
В наших силах держать эту пару рядом друг с другом biggrin.gif , чтобы уйти от проблемы метастабильности.


Эта метастабильность выходит через логику на выход этой схемы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.