#counter #verilog
#счетчик #verilog
Вопрос:
Краткое изложение моей цели: создать счетчик, запускаемый таймером автоматической перезагрузки переменной длины.
Немного подробнее: будет регистр со значением, которое изменяется (предсказуемо изменяется и фиксируется перед сигналом EN для модуля AutoReloadTimer), который устанавливает скорость, с которой увеличивается счетчик.
Вот таймер автоматической перезагрузки:
module AutoReloadTimer( clk, rst, EN, D, done );
input clk;
input rst;
input EN;
input [WIDTH-1:0] D;
output done;
parameter WIDTH = 8;
// OneShot EN -> load
wire load;
OneShotD OneShot_D(
.clk( clk ),
.rst( rst ),
.in( EN ),
.RE( load )
);
reg [WIDTH-1:0] counter, load_value;
always @( posedge clk ) begin
if ( rst ) begin
counter <= {WIDTH{1'b1}};
load_value <= {WIDTH{1'b1}};
end else if ( load ) begin
counter <= D;
load_value <= D;
end else if (counter == 0 ) begin
counter <= load_value;
load_value <= load_value;
end else begin
counter <= counter - 1'b1;
load_value <= load_value;
end
end
assign done = ( counter == 0 );
endmodule
А вот счетчик, запускаемый сигналом done от модуля AutoReloadTimer:
module Counter( clk, rst, EN, CLR, Q );
input clk;
input rst;
input EN;
input CLR;
output [WIDTH-1:0] Q;
parameter WIDTH = 8;
reg [WIDTH-1:0] ctr;
always @( posedge clk ) begin
if ( rst ) begin
ctr <= {WIDTH{1'b0}};
end else if ( CLR ) begin
ctr <= {WIDTH{1'b0}};
end else if ( EN ) begin
ctr <= ctr 1'b1;
end else begin
ctr <= ctr;
end
end
assign Q = ctr;
endmodule
А вот фрагмент формы сигнала с тестового стенда:
Что меня здесь интересует, так это стабильность моего счетчика — является ли проблемой то, что сигнал «Готово» становится низким на переднем крае часов? Я все еще новичок в Verilog и цифровом дизайне. Я знаком с этим термином и в некоторой степени с идеей метастабильности, но меня не совсем устраивает мое понимание этого.
Ищу информацию, критику и т.д.
Редактировать Я забыл указать, в какой конфигурации у меня были модули для создания этой диаграммы:
wire ART_done;
AutoReloadTimer ART0 (
.clk( clk ),
.rst( rst ),
.EN( EN ),
.D( 4 ),
.done( ART_done )
);
Counter uut (
.clk(clk),
.rst(rst),
.EN(ART_done),
.CLR(CLR),
.Q(Q)
);
Комментарии:
1. Я добавил в реализацию, которую я использую — есть только один тактовый сигнал, который они совместно используют. Все еще довольно ново для всего этого, но ответ Чиано прояснил часть моего замешательства.
Ответ №1:
Пока ваши модули AutoReloadTimer и Counter, а также любая логика, использующая сигнал done, работают на одном тактовом режиме, у вас не будет проблем с метастабильностью. У вас была бы полностью синхронная реализация. Естественно, вы также должны соответствовать требованиям синхронизации используемого вами устройства
Сигнал done фактически изменит некоторую небольшую комбинаторную задержку пути после увеличения тактового фронта, что приведет к тому, что счетчик достигнет 0. Любая логика, которая использует сигнал done, имеет оставшуюся часть тактового периода до следующего возрастающего фронта, чтобы делать то, что ей нужно (более комбинаторная логика), и при этом выдерживать время настройки любого ввода регистра, который обусловлен сигналом done.
Проблемы с метастабильностью будут возникать только в том случае, если входные данные в какие-либо регистры передаются правильно при переходе часов. Это может произойти, если регистрируемые данные поступают из регистра, в котором используется асинхронный тактовый сигнал, или если нарушена настройка или синхронизация удержания регистра.
Комментарии:
1. Это имеет гораздо больше смысла — у меня были проблемы (в моей голове) с пониманием того, как логика вела себя круглосуточно. Я связывал метастабильность с любым переходом, происходящим по тактовому фронту, но не учитывал небольшую комбинационную логическую задержку или порядок событий.