Домен быстрой тактовой частоты производит выборку быстрее, чем домен медленной тактовой частоты.,Другими словами, сигнал, поступающий из области медленных часов в область быстрых часов, определенно может быть собран. Поскольку быстрые часы должны иметь возможность собирать данные, распространяемые медленными часами.,Тогда остается только один вопрос: как обеспечить качество дискретизированного сигнала.!Наиболее часто используемый метод синхронизации — это метод двухуровневого триггерного кэша, широко известный как метод задержанного такта.。Прежде чем сигнал перейдет из одной тактовой области в другую,Буферизируйте этот сигнал дважды последовательно, используя двухуровневый триггер.,Это может эффективно уменьшить проблемы метастабильности, вызванные неудовлетворительным временем.
В частности, как показано на рисунке ниже: сигнал от медленного тактового сигнала clk1 дискретизируется несколько раз в clk2 (сигнал длится один тактовый цикл в clk1 и три тактовых цикла в clk2, если ему нужно длиться только один тактовый цикл в clk2). clk2, можно использовать обнаружение края. Вы можете получить signal4;
Медленная тактовая область имеет более низкую скорость выборки, чем быстрая тактовая область, а это означает, что сигналы, поступающие из быстрой тактовой области в медленную тактовую область, с большой вероятностью будут пропущены. Обычно требуется, чтобы сигнал выборки в принимающей тактовой области сохранялся в течение трех фронтов тактовой частоты (т. е. в 1,5 раза больше периода тактовой частоты выборки), чтобы избежать пропущенной выборки. То есть суть перехода от быстрого к медленному тактовому домену заключается в том, как увеличить длину сигнала!
Для сигналов уровня(Сигнал общего уровня держится достаточно долго),Длина сигнала может быть гарантирована,Поэтому вполне нормально использовать двухступенчатый синхронный сэмплер.
Для импульсных сигналов(Обычно длительность импульсного сигнала очень мала.),Длина не может быть гарантирована,Сигнал необходимо продлить. в настоящий момент,Существует два часто используемых метода расширения:
Однако, за исключением «протокола рукопожатия», два других метода имеют недостатки и ограничены, как показано на следующем рисунке:
Видно, что существуют ограничения на использование как уровневых, так и импульсных сигналов.,Потому что все они используют разомкнутые конструкции без обратной связи.(Более подробную информацию можно найти в сообщении в блоге.Межтактовая передача – один бит)。Принятие схемы обратной связи с обратной связью может избежать этих проблем.,Конкретный процесс заключается в следующем:
верилог-код
//Один бит от быстрого к медленному“соглашение о рукопожатии”
module cdc_sbit_handshake(
input aclk, //быстрые часы
input arst_n, //быстрые сигнал сброса домена часов
input signal_a,//быстрые сигнал домена часов
input bclk, //медленные часы
input brst_n, //медленные сигнал сброса домена часов
output signal_b//медленные выходной сигнал домена часов
);
//медленные сигнал домена часов Расширяйте до тех пор, пока сигнал обратной связи не вернется, а затем возобновите
reg req;//регистрируем сигнал медленного растяжения тактового домена
reg ack_r0;//сигнал обратной связи
always@(posedge aclk or negedge arst_n) begin
if(!arst_n) begin
req <= 1'b0;
end
else if(signal_a) begin
req <= 1'b1; //расширение сигнала
end
else if(ack_r0) begin
req <= 1'b0; //Восстанавливаемся при поступлении сигнала обратной связи
end
end
//Расширяем сигнал по тактовой синхронизации до медленной тактовой области
reg req_r0;
reg req_r1;
reg req_r2;
always@(posedge bclk or negedge brst_n) begin
if(!brst_n)begin
{req_r2,req_r1,req_r0} <= 3'b0;
end
else begin
{req_r2,req_r1,req_r0} <= {req_r1,req_r0,req};
end
end
//Генерируем сигнал обратной связи и отправляем его в область быстрых часов
reg ack;
always@(posedge aclk or negedge arst_n) begin
if(!arst_n) begin
{ack_r0,ack} <= 2'b0;
end
else begin
{ack_r0,ack} <= {ack,req_r1};
end
end
//Обнаруживаем нарастающий фронт сигнала и оставляем выходной сигнал на медленный тактовый цикл
assign signal_b = ~req_r2 & req_r1;
endmodule
Testbench
`timescale 1ns/1ps //Единица времени моделирования 1нс Точность времени моделирования 1 пс
module cdc_sbit_handshake_tb;
//Объявление сигнала
reg aclk;
reg arst_n;
reg signal_a;
reg bclk;
reg brst_n;
wire signal_b;
//создание экземпляра
cdc_sbit_handshake u_cdc_sbit_handshake(
.aclk (aclk),
.bclk (bclk),
.arst_n (arst_n),
.brst_n (brst_n),
.signal_a (signal_a),
.signal_b (signal_b)
);
//быстрые Часы домена, генерация медленных часов
always #5 aclk =~ aclk;
always #15 bclk =~ bclk;
//Назначение и стимуляция исходного сигнала
initial begin
signal_a = 0;
aclk = 0;
bclk = 0;
arst_n = 1;
brst_n = 1;
#15;
arst_n = 0;
brst_n = 0;
#15;
arst_n = 1;
brst_n = 1;
signal_a = 1;
#10;
signal_a = 0;
end
endmodule
Результаты моделирования
Сначала дайте заключение:Многобитовые сигналы не могут передаваться через такты с использованием вторичного синхронизатора, даже если в большинстве случаев используется код Грея. Они могут передаваться через такты только тогда, когда код Грея изменяется в своей самовозрастающей или самоубывающей последовательности.。Для многобитныхданные,Во время передачи все регистры не будут переворачиваться одновременно из-за проблем с синхронизацией.(Это не то, что не переворачивается, это значит, что не переворачивается одновременно.!),Следовательно, во время перекрестной тактовой передачи легко возникают промежуточные состояния. Этого явления можно избежать, используя код Грея.,Но когда код Грея не меняется в порядке отсчета(Непоследовательные изменения эквивалентны более чем одному изменению одновременно.),Это также не допускается,Потому что предпосылка, что одновременно изменяется только один бит кода Грея,,данные увеличиваются или уменьшаются. Например, код Грея в асинхронном FIFO может передаваться CDC через вторичный синхронный преобразователь.
от медленного к быстрому Эта ситуация в быстрых часахпринимающая сторона Его определенно можно получить путем отбора проб.,Но судя по вышеизложенному видно,Мультибит не подходит для прямой передачи семплов с использованием вторичного синхронного преобразователя.,Потому что в процессе передачи одновременно меняется много битов.,Так в чем же решение? Решение - не менять во время передачи! Так это должно быть написано в включении Передавайте, когда сигнал действителен!
При передаче асинхронных данных в принимающую тактовую область они соединяются с синхронным сигналом управления. Сигналы данных и управления передаются в принимающую тактовую область одновременно. В то же время сигнал управления синхронизируется с принимающей тактовой частотой. домен с использованием двухуровневого регистра в принимающем тактовом домене. После использования этого сигнала управления синхронизацией загрузите данные, чтобы данные можно было безопасно загрузить в регистр назначения.
Конкретные коды можно найти по ссылке.:Verilog Передача домена в перекрестном режиме: от медленного к быстрому
верилог-код
//синхронный модуль рабочих часов 100MHz модуль
//асинхронные пары от рабочих часов к 20MHz модуль
module delay_sample(
input rstn,
input clk1,
input [31:0] din,
input din_en,
input clk2,
output [31:0] dout,
output dout_en);
//sync din_en
reg [2:0] din_en_r ;
always @(posedge clk2 or negedge rstn) begin
if (!rstn) din_en_r <= 3'b0 ;
else din_en_r <= {din_en_r[1:0], din_en} ;
end
wire din_en_pos = din_en_r[1] && !din_en_r[2] ;
//sync data
reg [31:0] dout_r ;
reg dout_en_r ;
always @(posedge clk2 or negedge rstn) begin
if (!rstn)
dout_r <= 'b0 ;
else if (din_en_pos)
dout_r <= din ;
end
//dout_en delay
always @(posedge clk2 or negedge rstn) begin
if (!rstn) dout_en_r <= 1'b0 ;
else dout_en_r <= din_en_pos ;
end
assign dout = dout_r ;
assign dout_en = dout_en_r ;
endmodule
Временная структура показана на рисунке ниже:
Однако если в области медленной тактовой частоты нет сигнала разрешения данных din_en или сигнал разрешения данных всегда действителен, метод обнаружения нарастающего фронта сигнала разрешения данных в области быстрой тактовой частоты не будет работать. Поскольку сигнал разрешения данных всегда действителен, за исключением первых данных, домен быстрой синхронизации не сможет обнаружить момент передачи последующих данных.
Решение состоит в том, чтобы обнаружить границу медленного тактового сигнала в области быстрого тактового сигнала.
Переход от быстрого к медленному неизбежно будет сопровождаться риском пропуска выборки. Согласно методу однобитовой передачи CDC, мы можем знать, что способ избежать этого — увеличить длину сигнала, поэтому его необходимо увеличить. сигнал с письменным разрешающим сигналом. Здесь используется рукопожатие. Конкретный принцип полного рукопожатия показан на рисунке ниже:
Преимущества: он может решить проблему перехода от быстрой тактовой области к медленной тактовой области, а диапазон ее применения очень широк.
Недостатки: Реализация относительно сложна, особенно ее низкая эффективность. Ее следует использовать с осторожностью в ситуациях с высокими требованиями к производительности конструкции.
Подробности по этой части смотрите по ссылке:Примечания к исследованию FPGA - синхронизация многобитовых сигналов в перекрестной тактовой области (CDC)
верилог-код
module data_driver(
input clk_a, //Отправляем сигнал окончания синхронизации
input rst_n, //Сброс сигнала, активный низкий уровень
input data_ack, //данные Получить сигнал подтверждения
input clk_b, //Прием тактового сигнала
input rst_n, //Сброс сигнала, активный низкий уровень
input [3:0] data,//перениматьданные
input data_req, //Запрос на получение сигнала
output reg data_ack//данные Получить сигнал подтверждения
);
/********************** завершение отправки **********************/
reg [3:0] data; //отправлятьданные
reg data_req ; //Запрос на получение сигнала
reg [2:0] cnt_reg;
reg data_ack_sync1;
reg data_ack_sync2;
//считать
always@(posedge clk_a or negedge rst_n)
begin
if(!rst_n)
cnt_reg <= 3'd0;
else if(data_ack_sync1 && !data_ack_sync2 == 1'b1)
cnt_reg <= 3'd0;
else if(data_req == 1'b1)
cnt_reg <= cnt_reg;
else
cnt_reg <= cnt_reg + 1'b1;
конец
//data_ack два уровня синхронно
всегда@(положение clk_a or negedge rst_n)
begin
if(!rst_n)
begin
data_ack_sync1 <= 1'b0;
data_ack_sync2 <= 1'b0;
end
else
begin
data_ack_sync1 <= data_ack;
data_ack_sync2 <= data_ack_sync1;
end
end
//Запрос на получение сигнала
always@(posedge clk_a or negedge rst_n)
begin
if(!rst_n)
data_req <= 1'b0;
else if(cnt_reg == 3'd4)
data_req <= 1'b1;
else if(data_ack_sync2 == 1'b1)
data_req <= 1'b0;
else
data_req <= data_req;
end //отправлятьданные
always@(posedge clk_a or negedge rst_n)
begin
if(!rst_n)
data <= 4'd0;
else if(data == 4'd7 && data_ack_sync2 == 1'b1 && data_req == 1'b1 )
data <= 4'd0;
else
begin
if(data_ack_sync2 == 1'b1 && data_req == 1'b1 )
data <= data + 1'b1;
else
data <= data;
end
end
/********************** принимающая сторона **********************/
reg data_req_sync1;
reg data_req_sync2;
//data_reqдва уровнясинхронный
always@(posedge clk_b or negedge rst_n)
begin
if(!rst_n)
begin
data_req_sync1 <= 1'b0;
data_req_sync2 <= 1'b0;
end
else
begin
data_req_sync1 <= data_req;
data_req_sync2 <= data_req_sync1;
end
end
//данные Получить сигнал подтверждения
always@(posedge clk_b or negedge rst_n)
begin
if(!rst_n)
data_ack <= 1'b0;
else if(data_req_sync2 == 1'b1)
data_ack <= 1'b1;
else
data_ack <= 1'b0;
end
endmodule
оасинхронныйFIFOПодробности вы можете прочитать в этой статье:принципы проектирования асинхронного FIFO и методы проектирования, а также краткое изложение важных вопросов (включая верилог-код|Testbench|Результаты моделирования),Введение в асинхронный FIFO очень подробно и суммирует несколько важных вопросов.
FIFO — это очередь «первым пришел — первым ушел».,данные записываются с одного конца,читать с другого конца,Порядок чтения точно такой же, как и порядок записи. Поскольку место в очереди ограничено,Поэтому очередь обычно проектируется как кольцо. Для очереди,Самое главное – не снимать показания, когда очередь пуста.、Нельзя писать числа, когда очередь заполнена。Обычно читаю и пишу, сравниваяуказательполучить“Команда пуста”и“Команда полна”информация。Асинхронный FIFO часто используется в сценариях, где высокоскоростные данные охватывают тактовые домены.
Асинхронный FIFO в основном состоит из пяти частей: ОЗУ, терминала управления записью, терминала управления чтением и двух терминалов тактовой синхронизации.
Двухпортовый ОЗУ:Это подделка Двухпортовый ОЗУ осуществляет хранение и чтение данных.,Есть две группыданные Проволока、адресная строка、линия часов.
Напишите в консоль:Писатьуказательс полным генератором сигналов,Используется для определения возможности записи данных.,Во время операции записи,Разрешение записи активно, и FIFO не заполнен.
Чтение консоли:читатьуказательи генератор нулевого сигнала,Используется для определения возможности чтения данных.,Во время операции чтения,Разрешение чтения действительно, и FIFO не пуст.
Два терминала синхронизации часов:читатьуказательсинхронныйприезжать Писатьуказательдоменруководить“Писать Полный”суждение,Запишите указатель усинхронный в поле указатель чтения, чтобы принять решение «прочитано пусто».
верилог-код
//Глубина 8,данные Разрядность равна8изасинхронныйFIFO
module async_fifo #(
parameter DATA_DEPTH = 8, //Глубина 8
parameter DATA_WIDTH = 8, //данные разрядности равны 8
parameter PTR_WIDTH = 3 //Чтение и запись указателя, разрядность равна 3
)(
input [DATA_WIDTH - 1 : 0] wr_data,//Писатьданные
input wr_clk, //запись часов
input wr_rst_n, //запись часовперезагрузить
input wr_en, //разрешить запись
input rd_clk,//читатьданные
input rd_rst_n, //читаем сброс часов
input rd_en, //разрешить чтение
output reg fifo_full, //"полный" флаг
output reg fifo_empty, //"пустой" флаг
output reg [DATA_WIDTH - 1 : 0] rd_data //запись часов
);
/*-----------------------------------------------------------------
--------------------------------Псевдо-двухпортовый модуль оперативной памяти------------ ---- ----------
------------------------------------------------------------------*/
//Определяем RAM_FIFO шириной 8 и глубиной 8 DEPTH
reg [DATA_WIDTH - 1 : 0] ram_fifo [DATA_DEPTH - 1 : 0];
//Записываем количество указательов
reg [PTR_WIDTH : 0] wr_ptr; //Информационный бит + бит адреса, поэтому разрядность указателя равна 4
always@ (posedge wr_clk or negedge wr_rst_n) begin
if(!wr_rst_n) begin
wr_ptr <= 0;
end
else if(wr_en && !fifo_full) begin
wr_ptr <= wr_ptr + 1;
end
else begin
wr_ptr <= wr_ptr;
end
end
//RAMПисатьвходитьданные
wire [PTR_WIDTH -1 : 0] wr_addr;
assign wr_addr = wr_ptr[PTR_WIDTH -1 : 0]; // Для записи данных в ОЗУ требуются только биты адреса и никаких информационных битов, поэтому разрядность адресного адреса равна 3
always@ (posedge wr_clk or negedge wr_rst_n) begin
if(!wr_rst_n) begin
ram_fifo[wr_addr] <= 0; //Перезагрузить
end
else if(wr_en && !fifo_full) begin
ram_fifo[wr_addr] <= wr_data; //данные Писатьвходить end
else begin
ram_fifo[wr_addr] <= ram_fifo[wr_addr]; //остаемся неизменными
end
end
//Читаем счетчик указательов
reg [PTR_WIDTH : 0] rd_ptr;
always@ (posedge rd_clk or negedge rd_rst_n) begin
if(!rd_rst_n) begin
rd_ptr <= 0;
end
else if(rd_en && !fifo_empty) begin
rd_ptr <= rd_ptr + 1;
end
else begin
rd_ptr <= rd_ptr;
end
end
//RAMчитатьвнеданные
wire [PTR_WIDTH -1 : 0] rd_addr;
assign rd_addr = rd_ptr[PTR_WIDTH -1 : 0];//для чтения данных из ОЗУ требуются только биты адреса и нет информационных битов, поэтому разрядность адресного адреса равна 3
always@ (posedge rd_clk or negedge rd_rst_n) begin
if(!rd_rst_n) begin
rd_data <= 0; //Перезагрузить
end
else if(rd_en && !fifo_empty) begin
rd_data <= ram_fifo[rd_addr]; //читатьданные end
else begin
rd_data <= rd_data; //остаемся неизменными
end
end
/*--------------------------------------------------------------------
-------------------------- Преобразование чтения и записи указателя (кода Грея) с помощью синхронного модуля межтактовой области ------
---------------------------------------------------------------------------------------*/
//Чтение и запись указателя, преобразованного в код Грея
wire [PTR_WIDTH : 0] wr_ptr_gray;
wire [PTR_WIDTH : 0] rd_ptr_gray;
assign wr_ptr_gray = wr_ptr ^ (wr_ptr >> 1);
assign rd_ptr_gray = rd_ptr ^ (rd_ptr >> 1);
//Запись указательсинхронного в домен часов чтения
//Два удара
reg [PTR_WIDTH : 0] wr_ptr_gray_r1;
reg [PTR_WIDTH : 0] wr_ptr_gray_r2;
always@ (posedge rd_clk or negedge rd_rst_n) begin
if(!rd_rst_n) begin
wr_ptr_gray_r1 <= 0;
wr_ptr_gray_r2 <= 0;
end
else begin
wr_ptr_gray_r1 <= wr_ptr_gray;
wr_ptr_gray_r2 <= wr_ptr_gray_r1;
end
end
//Чтение указателясинхронного времени для записи часового домена
//Два удара
reg [PTR_WIDTH : 0] rd_ptr_gray_r1;
reg [PTR_WIDTH : 0] rd_ptr_gray_r2;
always@ (posedge wr_clk or negedge wr_rst_n) begin
if(!wr_rst_n) begin
rd_ptr_gray_r1 <= 0;
rd_ptr_gray_r2 <= 0;
end
else begin
rd_ptr_gray_r1 <= rd_ptr_gray;
rd_ptr_gray_r2 <= rd_ptr_gray_r1;
end
end
/*--------------------------------------------------------------------------------------
----------------------------------Модуль определения пустого и полного сигнала ------ ---- ------------------------
---------------------------------------------------------------------------------------*/
// Решение комбинированной логики заполнено
always@ (*) begin
if(!wr_rst_n) begin
fifo_full <= 0;
end
else if( wr_ptr_gray == { ~rd_ptr_gray_r2[PTR_WIDTH : PTR_WIDTH - 1],
rd_ptr_gray_r2[PTR_WIDTH - 2 : 0] }) begin
fifo_full <= 1;
end
else begin
fifo_full <= 0;
end
end
// Логическое решение комбинации для чтения пустым
always@ (*) begin
if(!rd_rst_n) begin
fifo_empty <= 0;
end
else if(rd_ptr_gray == wr_ptr_gray_r2) begin
fifo_empty <= 1;
end
else begin
fifo_empty <= 0;
end
end
endmodule
Testbench
`timescale 1ns/1ps;//Единица времени моделирования 1нс Точность времени моделирования 1 пс
module async_fifo_tb #(
parameter DATA_DEPTH = 8,
parameter DATA_WIDTH = 8,
parameter PTR_WIDTH = 3
);
//Объявление сигнала
reg [DATA_WIDTH - 1 : 0] wr_data;
reg wr_clk;
reg wr_rst_n;
reg wr_en;
reg rd_clk;
reg rd_rst_n;
reg rd_en;
wire fifo_full;
wire fifo_empty;
wire [DATA_WIDTH - 1 : 0] rd_data;
//создание экземпляра
async_fifo u_async_fifo (
.wr_clk (wr_clk),
.rd_clk (rd_clk),
.wr_rst_n (wr_rst_n),
.rd_rst_n (rd_rst_n),
.wr_en (wr_en),
.rd_en (rd_en),
.wr_data (wr_data),
.rd_data (rd_data),
.fifo_empty (fifo_empty),
.fifo_full (fifo_full)
);
//Чтение и запись генерации тактового сигнала
always #10 rd_clk = ~rd_clk;
always #5 wr_clk = ~wr_clk;
//Инициализация и назначение сигнала
initial begin
wr_clk = 0;
wr_rst_n = 1;
wr_en = 0;
rd_clk = 0;
rd_rst_n = 1;
rd_en = 0;
#10;
wr_rst_n = 0;
rd_rst_n = 0;
#10;
wr_rst_n = 1;
rd_rst_n = 1;
//only write
wr_en = 1;
rd_en = 0;
repeat(10) begin
@(negedge wr_clk) begin
wr_data = {$random}%30;
end
end
//only read
wr_en = 0;
rd_en = 1;
repeat(10) begin
@(negedge rd_clk);
end
rd_en =0;
//read and write
wr_en = 0;
rd_en = 0;
#80;
wr_en = 1;
rd_en = 1;
repeat(20) begin
@(negedge wr_clk) begin
wr_data = {$random}%30;
end
end
end
endmodule
Результаты моделирования
Сначала дайте заключение:Многобитовые сигналы не могут передаваться через такты с использованием вторичного синхронизатора, даже если в большинстве случаев используется код Грея. Они могут передаваться через такты только тогда, когда код Грея изменяется в своей самовозрастающей или самоубывающей последовательности.。Для многобитныхданные,Во время передачи все регистры не будут переворачиваться одновременно из-за проблем с синхронизацией.(Это не то, что не переворачивается, это значит, что не переворачивается одновременно.!),Следовательно, во время перекрестной тактовой передачи легко возникают промежуточные состояния. Этого явления можно избежать, используя код Грея.,Но когда код Грея не меняется в порядке отсчета(Непоследовательные изменения эквивалентны более чем одному изменению одновременно.),Это также не допускается,Потому что предпосылка, что одновременно изменяется только один бит кода Грея,,данные увеличиваются или уменьшаются. Например, код Грея в асинхронном FIFO может передаваться CDC через вторичный синхронный преобразователь.
Сигналы b_load и b_en объединяются в один сигнал b_lden в тактовой области b_clk, а затем синхронизируются с a_clk. Если его невозможно объединить, например, при декодировании информации, добавьте управляющий сигнал и подождите, пока два сигнала не станут стабильными, прежде чем производить выборку!
Мультибит:
от медленного к быстрому: рассмотрите только метастабильную проблему и примените метод задержанного биения. Оснастите данные, которые необходимо передать, функцией синхронного управления. сигнал,Сигналы данных и управления передаются одновременно в тактовую область приема.,Используйте управляющий сигнал после этого синхронно для загрузки данных (действующий управляющий сигнал указывает, что данные стабильны и не изменяются, чтобы избежать ошибок передачи),Таким образом, данные можно безопасно загрузить в регистр назначения. Мы называем этот метод синхронным методом MUX/синхронным методом многоциклового пути (значения аналогичны).
от быстрого к медленному: Потому что, учитывая скорость выборки часов,Так что надо продлить(включить сигнал)Длина сигнала。Чаще всего используетсяизвсе еще“соглашение о рукопожатии”,Волявключить сигналсинхронный, а затем загрузить многобитные данные.
Для обработки многобитной передачи данных через такты чаще всего используется асинхронный FIFO.,
Во-первых, асинхронный FIFO подходит как для быстрой-медленной, так и для медленной-быстрой передачи CDC;
Во-вторых, он также может лучше соответствовать требованиям более высокой скорости передачи потока данных.
Больше для просмотраСсылка на персональную страницу
Версия программного обеспечения: Modelsim 10.6c.
Время от времени вносятся исправления и дополнения, приветствуем общение в любое время.
Дата последнего изменения: 2023.6.8.
Следующие статьи очень подробные, и я рекомендую прочитать их подробно.
Межтактовая обработка домена — окончательная подробная версия
Передача сигналов в перекрестной тактовой области (2) – сигналы данных
Межтактовая передача – несколько битов
Verilog Передача домена в перекрестном режиме: от медленного к быстрому