Понимание операторов 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 двумя способами:
- Выражения в
if-elseболее общие; вcaseодно выражение сравнивается с множеством вариантов caseдает детерминированный результат при наличии X и Z в выражении
Verilog
- Освоение оператора switch в C#: синтаксис, примеры и лучшие практики
- Оператор break в C#: как и когда использовать
- Оператор continue в C#: как эффективно пропускать итерации циклов
- Оператор switch-case в C++: синтаксис, применение и практические примеры
- Освоение Verilog: полное руководство по проектированию цифровых схем
- Освоение конкатенации в Verilog: практическое руководство
- Понимание назначений в Verilog: типы, синтаксис и лучшие практики
- Блокирующие и неблокирующие назначения в Verilog: ключевые различия
- Мастерство функций в Verilog для эффективного RTL дизайна
- Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение