Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Verilog

Последовательная логика с всегда

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

JK Flip Flop

Триггер JK является одним из многих типов флопов, используемых для хранения значений, и имеет два входа данных j и k, а также один для сброса rstn и другой для тактового сигнала clk. Таблица истинности для флопа JK показана ниже и обычно реализуется с использованием вентилей И-НЕ.

<й>к <й>к <тд>0 <тд>0 <тд>0 <тд>0 <тд>0 <тд>0 <тд>1 <тд>1 <тд>1 <тд>0 <тд>0 <тд>1 <тд>1
первый q Комментарии
0 При подтверждении сброса выход всегда равен нулю
1 Удерживать значение Когда j и k равны 0, вывод остается таким же, как и раньше
1 Когда k=1, вывод становится равным 1
1 Когда k=0, вывод становится равным 0
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

  1. Учебное пособие - Написание комбинационного и последовательного кода
  2. Схема с переключателем
  3. Интегральные схемы
  4. Программируемые логические контроллеры (ПЛК)
  5. Введение в логическую алгебру
  6. Упрощение логики с помощью карт Карно
  7. Цифровая логика с обратной связью
  8. Счетчик Verilog Mod-N
  9. Верилог Серый Счетчик
  10. Всегда гладкая поверхность с шлифовальными станками Okamoto