DocsTech
/
NONEDISPLAY
/

~ cd case verilog

Case — это оператор выбора, который сравнивает значение переменной или выражения со случаем перечисленным в нем для выполнения блока кода при удачном совпадении или в ином случае по умолчанию, если был прописан соответствующий оператор. Оператор начинается с ключевого слова case и заканчивается endcase. Помимо определенных случаев можно указать исполнение по умолчанию через ключевое слово default, если совпадений не было найдено.

Принцип работы оператора case изложен следующих пунктах:

1) Вычисляется значение выражения или переменной.
2) Найденное значение в порядке возрастание сравнивается с константами выражениями из заданного списка.
3) Если находится совпадение с одним из случаев, то исполняется блок кода, связанный с этим ним.
4) Когда совпадений не было обнаружено, исполняется оператор по умолчанию, следующие за ключевым словом default.

Объявление случаев с одинаковыми значениями или не моделируемыми переменными является ошибкой. Если битовая ширина сравниваемых значения не равна, то значение меньшей длины дополняется нулями в старших битах до одинаковой длины.

Синтаксис

Синтаксис объявления оператора выбора case c блоком выполнения по умолчанию default.

...
Копировать
case (/* переменная или выражение */)
    (/* случай 1 */): begin
        // объявление кода
    end
    (/* случай 2 */): begin
        // объявление кода
    end
    (/* случай 3 */): begin
        // объявление кода
    end
    ...
    (/* случай n */): begin
        // объявление кода
    end
    default: begin
        // объявление кода
    end
endcase
Синтаксис 1 — Оператор case Verilog.

Примеры

Выбор оконечного устройства контроллером c сase

В примере реализован входной контроллер источника, в котором помощью оператора case выбираем получателя данных через интерфейс SPI. В потоке данных отлавливаем первый бит, который является адресом получателя. После получение всех слов потока и сохранение в памяти(см. 4.9.3 Память), производим сравнивание этого адреса через case. При совпадении данные отправляются одному из устройств: ЦАП(Цифро-аналоговый преобразователь), контроллер PMBUS, КМБО(Канал МежБлочного Обмена) и внутреннему регистру.
...
Копировать
module kon(mosi, oena0, oena1, oena2, oena3, data, ena, clk);

    parameter DW = 16; // битовая длина шин

    input [(DW - 1): 0] data; // шина данных
    input ena, clk; // сигнал включения и тактовый сигнал
    output [(DW - 1): 0] mosi;// сигнал MOSI(Master Out Slave In)
    // выходные сигналы включения интерфейса SPI 
    output oena0, oena1, oena2, oena3;

    // с тирггером на выходе
    reg oena0, oena1, oena2, oena3;

    reg [(DW - 1): 0] addr; // адрес команды
    reg ffbit; // флаг первого слова потока
    reg [4:0] sch_we, sch_re; // счетчики

    assign eram = ena & ~ffbit; // сигнал включения записи в память
    // экземпляр модуля памяти
    tram ram(data, clk, eram, sch_we, sch_re, mosi);

    always @(posedge clk) begin
        if (ena) begin
            // обнуление
            sch_re <= 0;
            oena0 <= 0;
            oena1 <= 0;
            oena2 <= 0;
            oena3 <= 0;
            if (ffbit) begin
                // первым словом ловим адресс
                addr <= data;
                ffbit <= 0;
            end else begin
                // увеличиваем счетчик записи
                sch_we <= sch_we + 1;
            end
        end else begin
            // обнуление
            ffbit <= 1;
            sch_we <= 0;
            // выбор подчиненного устройства SPI
            case (addr)
                0: begin
                    // отправляет цап
                    oena0 <= 1;
                end
                1: begin
                    // отправляет Контроллеру PMBUS
                    oena1 <= 1;
                end
                2: begin
                    // отправляет КМБО
                    oena2 <= 1;
                end
                default: begin
                    // отправляет внутреннему регистру
                    oena3 <= 1;
                end
            endcase
            // увелииваем счетчик чтения памяти
            sch_re <= sch_re + 1;
        end
    end

endmodule

// память
module tram(data, clk, we, addr_we, addr_re, out);

    parameter DW = 16;
    parameter AW = 4;

    input [(DW - 1): 0] data;
    input [(AW - 1): 0] addr_we, addr_re;
    input clk, we;
    output reg [(DW - 1): 0] out;

    reg [(DW - 1): 0] ram [(2**AW - 1): 0];

    always @(posedge clk) begin
        if (we)
            ram[addr_we] <= data;

        out = ram[addr_re];
    end

endmodule

Делить тактовой частоты на 5 c сase

Делитель тактовой частоты на дробное число возможно организовать только с помощью построения собственного счетчика, которого невозможно прописать без оператора case. Также важным элементом является запаздывающий сигнал. Временная диаграмма показаны на рисунке 1.

Временная диаграмма делителя на 5
Рисунок 1. Временная диаграмма делителя 5.
Принцип работы модуля: при каждом восходящем фронте тактового сигнала sig меняется значение счетчика sch написанного на case. Если значение достигается 3, на запаздывающий сигнала dl_sig подается высокий уровень на один такт низпадающего фронта. Дизъюнкция sch[0] и dl_sig дает деленный сигнал на 5.
...
Копировать
module div5x0(out, sig, reset);

    input sig; // тактовый сигнал
    input reset;  // асинхронный сброс
    output out; // деленный тактовый сигнал

    reg [2:0] sch = 1; // собственный счетчик
    reg dl_sig = 0;  // запаздывающий сигнал

    always @(posedge sig, posedge reset) begin
        if (reset) begin // сброс
            sch <= 1;
        end else begin // логика счетчика
            case (sch)
                1: sch <= 3;
                3: sch <= 4;
                4: sch <= 2;
                2: sch <= 6;
                6: sch <= 1;
                default: sch <= 1;
            endcase
        end
    end

    always @(negedge sig, posedge reset) begin
        if (reset) begin // сброс
            dl_sig <= 0;
        end else begin // логика запаздывающего сигнала
            if (sch == 3) begin
                dl_sig <= 1; 
            end else begin
                dl_sig <= 0; 
            end
        end
    end

    assign out = sch[0] | dl_sig;

endmodule
Главная
Курсы
Вебинары
Анализ рынка вакансий в сфере RTL-дизайна в России: тренды, спрос и перспективы
LinuxCNC: Преимущества и применение в станкостроении и автоматизации
Алгоритм Хаффмана: Теория, методология и практическая реализация для эффективного сжатия данных
Chisel vs. SystemVerilog: Новый взгляд на проектирование цифровых схем
Подключение датчика ZMPT101B к Arduino: схема, настройка и пример кода
Подключение MAX6675 к Arduino: схема, библиотеки и примеры кода
Подключение и настройка MPU6050 к Arduino: схема, библиотеки и скетч
Подключение VL53L0X к Arduino: полное руководство по лазерному датчику расстояния
Подключение компас HMC5883L к Arduino: схема, библиотеки и пример кода
Подключение ACS712 к Arduino: схема, библиотеки и скетчи
Подключение ADXL345 к Arduino: схема, библиотеки и код
Подключение датчика INA219 к Arduino: схема, библиотеки и примеры кода
HC-SR04 и Arduino: схема подключения, библиотеки и скетч
Assertion-Based Verification(ABV): основные понятия, принцип работы и примеры
Подключение HX711 к Arduino: схема, библиотеки и код
Подключение DHT22 к Arduino: схема, код и необходимые библиотеки
Как подключить RCWL-0516 к Arduino: схема, библиотеки и скетч
Универсальная Методология Верификации (UVM): Описание, Особенности и Пример Использования
DS18B20: Подключение к Arduino, Библиотеки и Скетч
Методологии верификации HDL-кода: Основы, Преимущества и Популярные Подходы
Роль ПЛИС в Алготрейдинге и Высокочастотной Торговле
Lint, CDC, RDC, LEC, Power Analyzer, STA и DFT для HDL
Пиратство плохо! Мне так сказали…
Применение Icarus Verilog для тестирования с входными данными
Ключевые параметры для выбора цифроаналогового преобразователя (ЦАП)
Все о КНФ и ДНФ: Понятие, Примеры и Применение
Импликация: Что Это, Таблица Истинности и Применение в Информатике
Стрелка Пирса: Что Это за Логическая Операция и Таблица Истинности
Штрих Шеффера: Полное Руководство
STM32F103 с использованием HAL и I2C: Подробная конфигурация и пример кода
Подключение DHT11 к ESP32: Схема, Библиотеки и Пример Кода
ESP8266 I2C: настройка для master и slave
Подключение DHT11 к Arduino и Вывод на LCD 1602 I2C: Схема и Скетч
Подключение DHT11 к Arduino: Схема, Библиотеки и Скетч
ESP32 I2C: Настройка кода под master и slave
TM1637 Подключение к Arduino: Полное Руководство
Подключение часов DS3231 к Arduino и LCD 1602 I2C
Arduino: Часы Реального Времени DS1302 на LCD 1602 I2C
ESP32 SPI: Объявление SPI на ESP32 с Примером Кода
ESP8266 SPI: полная инструкция SPI на ESP8266
Протокол SPI: Регистровая Логика, Передача Данных и Режимы
Демультиплексор: принцип работы, схема и основы
Счетчики с синхронным и асинхронным сбросом на Verilog
Знаковость signed в Verilog: примеры, синтаксис, оптимизация
Директива Define в Verilog: Синтаксис, Примеры и Применение
Таблицы истинности триггеров: JK, RS, D и T
Fork и begin в Verilog: обзор и различия
Posedge и Negedge в Verilog: Синтаксис и Функциональность
Verilog always: Синтаксис, Примеры и Применение
Wire в Verilog: Основы использования, синтаксис и примеры кода
Блокирующие и неблокирующие присваивания в Verilog
Verilog Assign: что делает этот оператор?
Verilog Parameter: Ключевой Инструмент Оптимизации
Многомерные массивы в Verilog
Case Verilog
Дешифратор. Принцип работы и Примеры
Модули в Verilog
Описание FIFO. Примеры на Verilog и С++
Закрыть