Сдвиги в Verilog: логический, арифметический и циклический

Содержание

Сводка

Программирование на языке Verilog – это отдельное искусство, требующее от разработчика глубокого понимания принципов работы цифровых устройств. Одним из важных аспектов при работе с Verilog являются операции со сдвигами, которые играют ключевую роль при разработке цифровых схем и алгоритмов.

Принцип работы

Существует 3 типа операторов сдвига:

  • логические операторы сдвига: << и >>
  • арифметические операторы сдвига: <<< и >>>
  • для циклических операторов нужен отдельный модуль

Операторы сдвига влево << и <<< сдвигают свой левый операнд влево на число на количество битовых позиций, заданных правым операндом. В логическом и арифметическом случаях освободившиеся битовые позиции должны быть заполнены нулями. Циклический сдвиг перемещает поочередно старшие биты на места младших, а их переносит вперед.

Операторы сдвига вправо >> и >>> сдвигают свой левый операнд вправо на количество битовых позиций, заданных правым операндом. Логический сдвиг вправо должен заполнить освободившиеся битовые позиции нулями. Он должен заполнить освободившиеся битовые позиции значением старшего (т.е. знакового) бита левого операнда, если тип результата знаковый. Если число знаковое, то заполнит 1, а если беззнаковое, то нулем. Если правый операнд имеет значение x или z, то результат будет неизвестен. Циклический сдвигает старшие биты вправо, заполняя их места младшими поочередно.

Примеры Сдвигов

Эти простые примеры демонстрирует основные принципы работы сдвигов в Verilog.

Пример 1 — Логический сдвиг. В этом примере результату reg присваивается двоичное значение 0100, которое представляет собой 0001, сдвинутое на две левые позиции и заполненное нулями.
module shift; reg [3:0] start, result; initial begin start = 1; result = (start << 2); end endmodule
Пример 2 — Арифметический сдвиг. В этом примере результату reg присваивается двоичное значение 1110, которое на 1000 сдвигается на две правые позиции и заполняется знаком.
module ashift; reg signed [3:0] start, result; initial begin start = 4'b1000; result = (start >>> 2); end endmodule
Пример 3 — Циклический сдвиг. В этом примере результату при numel равной 2 reg присваивается двоичное значение 0010, которое на 1000 сдвигается на две правые позиции поочередно перемещая биты. Отчет о компиляции модуля заняло 4 логические клетки.
module other(numel, result); input [1:0] numel; output [3:0] result; reg [3:0] start = 4'b1000; assign result = right_shift(start, numel); function [3:0] right_shift(input [3:0] reg_num, input [1:0] numel); reg [3:0] first_bits; reg [3:0] other_bits; integer i; begin first_bits = reg_num >> (3^(numel - 1)); other_bits = reg_num << (numel); right_shift = other_bits | first_bits; end endfunction endmodule

Заключение

Сдвиги в Verilog являются важным инструментом при разработке цифровых схем и программируемых устройств. Понимание различий между логическим, арифметическим и циклическим сдвигами позволяет эффективно использовать их в разработке и оптимизации цифровых алгоритмов. Работа со сдвигами требует внимания к деталям и понимания того, как они влияют на обработку данных в цифровых схемах.