4-битный счетчик переноса пульсаций в Verilog HDL

Опубликовано: 16 Сентября, 2022

Чтобы продолжить работу с кодом Verilog, мы сначала поймем структуру 4-битного счетчика пульсаций. Верхний дизайнерский блок состоит из четырех T-Flip Flop. Пока игнорируйте ввод и вывод T-Flip Flop. Давайте рассмотрим общую внешнюю структуру Ripple Counter. У нас есть два входа, т. е. часы и сброс, и q на выходе. Выход q находится в 4-битной векторной форме.

В Ripple Carry Counter сначала тактовый сигнал проходит через первый T-триггер. Для второго T-триггера выход первого T-триггера действует как часы и так далее. Сброс одинаков для всех Т-триггеров.

Давайте теперь реализуем блок ripplecounter.

module ripplecounter(clk,rst,q);
  input clk,rst;
  output [3:0]q;

  // initiate 4 T-FF to update the count
  tff tf1(q[0],clk,rst);
  tff tf2(q[1],q[0],rst);
  tff tf3(q[2],q[1],rst);
  tff tf4(q[3],q[2],rst);
endmodule

Поскольку мы создали экземпляр tff в ripplecounter, теперь давайте посмотрим на внутреннюю часть T Flip Flop. Внутри T-триггера у нас есть D-триггер и инвертор, т.е. не ворота. Чтобы реализовать T-триггер, нам нужно создать экземпляр d flip и flop, и у нас есть clk и reset в качестве входных данных и q в качестве выходных данных. Нам нужен дополнительный провод d, который в дальнейшем действует как вход для D-триггера.

module tff(q,clk,rst);
  // tff takes clk and reset as input
  // q is output
  input clk,rst;
  output q;
  wire d;
  // by referring the diagram of tff, 
  // instantiate d flip flop and not gate
  dff df1(q,d,clk,rst);
  not n1(d,q);
endmodule

Таблица истинности флип-флопа D для справки:

клик первый г д
1 Икс 0
0 0 0
0 1 1

Блок дизайна:

module ripplecounter(clk,rst,q);
  input clk,rst;
  output [3:0]q;

  // initiate 4 T-FF to update the count
  tff tf1(q[0],clk,rst);
  tff tf2(q[1],q[0],rst);
  tff tf3(q[2],q[1],rst);
  tff tf4(q[3],q[2],rst);
endmodule

module tff(q,clk,rst);
  // tff takes clk and reset as input
  // q is output
  input clk,rst;
  output q;
  wire d;
  // by referring the diagram of tff, 
  // instantiate d flip flop and not gate
  dff df1(q,d,clk,rst);
  not n1(d,q);
endmodule

module dff(q,d,clk,rst);
  input d,clk,rst;
  output q;
  reg q; // store the output value
  always @(posedge clk or posedge rst)
   begin
    // refer the truth table to provide
    // values to q based on reset.
    if(rst) q=1"b0;
    else q=d;
   endripplecounter
endmodule

Испытательный стенд:

Моделирование используется для проверки проектного блока путем предоставления входных значений тестируемому устройству. Нам нужно написать testbench со ссылкой на блок ripplecounter, где у нас на входе есть clk и reset.

Часы должны переключаться через определенную единицу времени, поэтому мы изначально указываем clk как 0. А затем после каждой 5-кратной единицы времени мы переключаем часы с 0 на 1 и наоборот в блоке всегда.

initial
 clk=0;
always
 #5 clk=~clk;

Вот симуляция счетчика пульсаций:

module tb;
    // input to be stored in reg and output as net(wire)
    reg clk;
    reg rst;
    wire [3:0]q;

    // instantiate the ripplecounter design block
    ripplecounter dut(clk,rst,q);

    // generate clock pulse
    // initially provide 0
    // then inside always block toggle 
    // clock every 5 time units
    initial
      clk = 0;
    always
      #5 clk = ~clk;

    // provide reset values as the input
    initial
       begin
         rst = 1;
         #15 rst = 0;
         #180 rst = 1;
         #10 rst = 1;
         #20 $finish;
       end
       initial
        $monitor("time=%g,rst=%b,clk=%b,q=%d",$time,rst,clk,q);
endmodule

Выход:

Как видно, когда сброс равен 0, на выходе q обновляются выходные данные счетчика и счетчик.