Последовательная логика с всегда
В предыдущей статье были показаны различные примеры использования always
. блок для реализации комбинационной логики. always
блок также в основном используется для реализации последовательного логика, которая имеет элементы памяти, такие как триггеры, которые могут хранить значения.
JK Flip Flop
Триггер JK является одним из многих типов флопов, используемых для хранения значений, и имеет два входа данных j и k, а также один для сброса rstn и другой для тактового сигнала clk. Таблица истинности для флопа JK показана ниже и обычно реализуется с использованием вентилей И-НЕ.
первый | <й>кй> <й>кй>q | Комментарии |
---|---|---|
0 | <тд>0тд> <тд>0тд> <тд>0тд>При подтверждении сброса выход всегда равен нулю | |
1 | <тд>0тд> <тд>0тд>Удерживать значение | Когда j и k равны 0, вывод остается таким же, как и раньше |
1 | <тд>0тд> <тд>1тд> <тд>1тд>Когда k=1, вывод становится равным 1 | |
1 | <тд>1тд> <тд>0тд> <тд>0тд>Когда k=0, вывод становится равным 0 | |
1 | <тд>1тд> <тд>1тд>Переключить значение | Когда j=1,k=1, выход переключает текущее значение |
Поведенческий код Verilog для JK-триггера можно записать так, как показано ниже
module jk_ff ( input j, // Input J
input k, // Input K
input rstn, // Active-low async reset
input clk, // Input clk
output reg q); // Output Q
always @ (posedge clk or negedge rstn) begin
if (!rstn) begin
q <= 0;
end else begin
q <= (j & ~q) | (~k & q);
end
end
endmodule
Тестовый стенд
Сначала объявите все переменные, используемые в тестовом стенде, и запустите часы, используя простой always
блок, который можно загнать в конструкцию. Затем создайте экземпляр проекта и соедините его порты с соответствующими переменными тестового стенда. Обратите внимание, что q имеет тип wire
потому что он связан с выходом проекта, который будет активно им управлять. Все остальные входные данные для проекта имеют тип reg
. чтобы ими можно было управлять внутри процедурного блока, такого как initial
.
Стимул сначала инициализирует все входные данные для проекта нулем, а затем через некоторое время отменяет сброс. А for
Цикл используется для передачи различных значений j и k, которые задаются в случайное время. Как только цикл завершится, подождите еще некоторое время и завершите симуляцию.
module tb;
// Declare testbench variables
reg j, k, rstn, clk;
wire q;
integer i;
reg [2:0] dly;
// Start the clock
always #10 clk = ~clk;
// Instantiate the design
jk_ff u0 ( .j(j), .k(k), .clk(clk), .rstn(rstn), .q(q));
// Write the stimulus
initial begin
{j, k, rstn, clk} <= 0;
#10 rstn <= 1;
for (i = 0; i < 10; i = i+1) begin
dly = $random;
#(dly) j <= $random;
#(dly) k <= $random;
end
#20 $finish;
end
endmodule
Обратите внимание на волне моделирования, что в положении часов выход q изменяет значение в зависимости от состояния входов j и k, как указано в таблице истинности.
Счетчик по модулю 10
Счетчики Modulus (MOD) просто считают до определенного числа, прежде чем вернуться к нулю. Счетчик MOD-N будет считать от 0 до N-1, а затем вернется к нулю и снова начнет считать. Для таких счетчиков обычно требуется log2 N количество флопов для хранения значения счетчика. Ниже показан код Verilog для счетчика MOD-10, который продолжает считать вверх при каждом тактовом импульсе, пока сброс rstn не установлен.
Параметры Verilog можно использовать для создания более масштабируемого счетчика MOD-N.
module mod10_counter ( input clk,
input rstn,
output reg[3:0] out);
always @ (posedge clk) begin
if (!rstn) begin
out <= 0;
end else begin
if (out == 10)
out <= 0;
else
out <= out + 1;
end
end
endmodule
Тестовый стенд
Тестовый стенд сначала объявляет некоторые переменные, которым можно присвоить некоторые значения и передать их на входные данные проекта. Затем создается экземпляр модуля счетчика, который соединяется с сигналами испытательного стенда, которые позже управляются некоторыми значениями в стимуле. Поскольку для счетчика также требуются часы, часы тестового стенда моделируются с помощью always
блокировать. Стимул просто устанавливает значения по умолчанию в момент времени 0 нс, затем отменяет сброс через 10 нс, и проект может работать в течение некоторого времени.
module tb;
reg clk, rstn;
reg [3:0] out;
mod10_counter u0 ( .clk(clk), .rstn(rstn), .out(out));
always #10 clk = ~clk;
initial begin
{clk, rstn} <= 0;
#10 rstn <= 1;
#450 $finish;
end
endmodule
Убедитесь, что модуль счетчика считает от нуля до 9, переворачивается на ноль и снова начинает считать.
4-битный регистр сдвига влево
Ниже показан 4-битный регистр сдвига влево, который принимает ввод d в LSB, а все остальные биты будут сдвинуты влево на 1. Например, если d равно нулю, а начальное значение регистра равно 0011, оно станет 0110 в момент следующий край часов clk.
module lshift_4b_reg ( input d,
input clk,
input rstn,
output reg [3:0] out
);
always @ (posedge clk) begin
if (!rstn) begin
out <= 0;
end else begin
out <= {out[2:0], d};
end
end
endmodule
Тестовый стенд
Тестовый стенд следует аналогичному шаблону, подобному показанному ранее, где объявляются некоторые переменные, создается экземпляр модуля дизайна и подключается к сигналам тестового стенда. Затем запускаются часы, и стимул вводится в дизайн с помощью initial
. блокировать. В этом примере тестового стенда необходимо использовать разные значения d, и, следовательно, for
цикл используется для повторения 20 раз и применения случайных значений к дизайну.
module tb;
reg clk, rstn, d;
wire [3:0] out;
integer i;
lshift_4b_reg u0 ( .d(d), .clk(clk), .rstn(rstn), .out(out));
always #10 clk = ~clk;
initial begin
{clk, rstn, d} <= 0;
#10 rstn <= 1;
for (i = 0; i < 20; i=i+1) begin
@(posedge clk) d <= $random;
end
#10 $finish;
end
endmodule
Обратите внимание, что каждый бит сдвигается влево на 1, а новое значение d применяется к LSB.
Verilog
- Учебное пособие - Написание комбинационного и последовательного кода
- Схема с переключателем
- Интегральные схемы
- Программируемые логические контроллеры (ПЛК)
- Введение в логическую алгебру
- Упрощение логики с помощью карт Карно
- Цифровая логика с обратной связью
- Счетчик Verilog Mod-N
- Верилог Серый Счетчик
- Всегда гладкая поверхность с шлифовальными станками Okamoto