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

Понимание операторов case в Verilog: эффективная реализация мультиплексоров

Оператор case проверяет, соответствует ли заданное выражение одному из вариантов в списке, и выполняет соответствующую ветвь. Обычно используется для реализации мультиплексоров. Конструкция if-else может быть неудобна при множестве условий и синтезируется в приоритетный энкодер, а не в мультиплексор.

Синтаксис

Verilog case начинается с case и заканчивается endcase. Выражение в скобках вычисляется ровно один раз и сравнивается с альтернативами в порядке записи. Операторы для совпавшей альтернативы выполняются. Блок из нескольких операторов группируется в begin и end.

// 'expression' должно совпасть с одним из элементов (item 1,2,3 или 4)
case (<expression>)
  case_item1 : <single statement>
  case_item2, case_item3 : <single statement>
  case_item4 : begin <multiple statements> end
  default : <statement>
endcase

Если ни один вариант не совпал, выполняется default. Он опционален, и в case может быть только один default. Case-блоки можно вкладывать.

Если совпадений нет и default отсутствует, выполнение просто выходит из case без действий.

Пример

Модуль ниже имеет 2-битный сигнал выбора sel для маршрутизации одного из трех 3-битных входов a, b, c на выход out. case назначает правильный вход на основе sel. Так как sel — 2 бита, возможно 4 комбинации (0–3). default устанавливает выход в 0, если sel = 3.

module my_mux (
  input [2:0] a, b, c,
  input [1:0] sel,
  output reg [2:0] out
);

always @ (a, b, c, sel) begin
  case(sel)
    2'b00 : out = a;
    2'b01 : out = b;
    2'b10 : out = c;
    default : out = 0;
  endcase
end
endmodule

Схема оборудования

RTL код разворачивается в схему 4-в-1 мультиплексора.

Выход равен 0 при sel=3 и соответствует входам для остальных значений.

Simulation Log

ncsim> run
[0] a=0x4 b=0x1 c=0x1 sel=0b11 out=0x0
[10] a=0x5 b=0x5 c=0x5 sel=0b10 out=0x5
[20] a=0x1 b=0x5 c=0x6 sel=0b01 out=0x5
[30] a=0x5 b=0x4 c=0x1 sel=0b10 out=0x1
[40] a=0x5 b=0x2 c=0x5 sel=0b11 out=0x0
ncsim: *W,RNQUIE: Simulation is complete.

В case сравнение успешно только при полном совпадении каждого бита выражения с альтернативой (включая 0, 1, x, z). В примере выше, если любой бит sel равен x или z, срабатывает default, так как ни одна альтернатива не совпала. Выход становится нулевым.

Simulation Log

ncsim> run
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x0
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x0
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x0
[30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x0
[40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x0
[50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x0
[60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x0
[70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0
[80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x0
[90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x0
ncsim: *W,RNQUIE: Simulation is complete.

Если в case альтернативы содержат x и z, результаты будут другими.

module my_mux (
  input [2:0] a, b, c,
  input [1:0] sel,
  output reg [2:0] out
);

always @ (a, b, c, sel) begin
  case(sel)
    2'bxz : out = a;
    2'bzx : out = b;
    2'bxx : out = c;
    default : out = 0;
  endcase
end
endmodule

Simulation Log

ncsim> run
[0] a=0x4 b=0x1 c=0x1 sel=0bxx out=0x1
[10] a=0x3 b=0x5 c=0x5 sel=0bzx out=0x5
[20] a=0x5 b=0x2 c=0x1 sel=0bxx out=0x1
[30] a=0x5 b=0x6 c=0x5 sel=0bzx out=0x6
[40] a=0x5 b=0x4 c=0x1 sel=0bxz out=0x5
[50] a=0x6 b=0x5 c=0x2 sel=0bxz out=0x6
[60] a=0x5 b=0x7 c=0x2 sel=0bzx out=0x7
[70] a=0x7 b=0x2 c=0x6 sel=0bzz out=0x0
[80] a=0x0 b=0x5 c=0x4 sel=0bxx out=0x4
[90] a=0x5 b=0x5 c=0x5 sel=0bxz out=0x5
ncsim: *W,RNQUIE: Simulation is complete.

Отличия case от if-else

case отличается от if-else-if двумя способами:

Verilog

  1. Освоение оператора switch в C#: синтаксис, примеры и лучшие практики
  2. Оператор break в C#: как и когда использовать
  3. Оператор continue в C#: как эффективно пропускать итерации циклов
  4. Оператор switch-case в C++: синтаксис, применение и практические примеры
  5. Освоение Verilog: полное руководство по проектированию цифровых схем
  6. Освоение конкатенации в Verilog: практическое руководство
  7. Понимание назначений в Verilog: типы, синтаксис и лучшие практики
  8. Блокирующие и неблокирующие назначения в Verilog: ключевые различия
  9. Мастерство функций в Verilog для эффективного RTL дизайна
  10. Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение