Правильный способ определения края сигнала в Verilog
Я хочу обнаружить нарастающий фронт сигнала от триггера AA
в BB
+----+
A ----------------| |----- OUT
+----+ | BB |
B ----| |------|> |
| AA | +----+
clk ----|> |
+----+
Verilog код:
module edge_detect (
input A,
input B,
input clk,
output OUT
);
reg AA;
reg BB;
always @(posedge clk) begin
AA <= B;
end
always @(posedge AA)begin
BB <= A;
end
assign OUT = BB;
endmodule
Выход из AA
используется как часы для BB
говоря это AA
сделал свою работу, а затем BB
Теперь можно продолжить свою работу.
Я редко вижу этот код. Это хорошая практика?
Если нет, есть ли какой-либо другой правильный способ определения границы сигнала?
2 ответа
Люди, как правило, не одобряют использование данных в качестве часов по разным причинам.
Лично, если бы я писал это, я бы пошел с:
module edge_detect (
input A,
input B,
input clk,
output OUT
);
reg AA;
reg BB;
wire enA;
always @(posedge clk) begin
BB <= B;
end
assign enA = !BB && B;
always @(posedge clk)begin
if (enA) begin
AA <= A;
end
end
assign OUT = AA;
endmodule
+----+
A ----------------------------|D |----- OUT
+---+ | AA |
/--------------| | | |
| +----+ |AND|------|E |
B ----| |------o| | | |
| BB | +---+ | |
clk ----|> | clk ----|> |
+----+ +----+
Поведение немного отличается, хотя.
Если вы хотите обнаружить нарастающий или падающий фронт в Verilog, просто передайте или задержите сигнал на 1 тактовый импульс. В цифровой среде ребро может рассматриваться как переход от 0 до 1 или от 1 до 0. Таким образом, вы можете проверить, совершил ли сигнал переход в какое-либо состояние, а затем установить высокий уровень выходного сигнала только для этого условия.
Например:
output out_flag;
reg temp;
reg temp_d;
always@(posedge clk)
temp_d <= temp;
always@(posedge clk)
begin
if (temp && ~temp_d)
out_flag<= 1'b1;
else
out_flag<= 1'b0;
end