mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 17:20:10 +00:00
81 lines
7.3 KiB
Markdown
81 lines
7.3 KiB
Markdown
# Защелка
|
||
|
||
Очень важно при описании мультиплексора с помощью блока `case` описывать оставшиеся комбинации управляющего сигнала с помощью `default` (а при использовании блока `if` — описывать блок `else`) — в противном случае в вашей схеме может появиться [защелка](https://www.build-electronic-circuits.com/d-latch/) (даже несмотря на то, что для описания защелок в SytemVerilog есть отдельный блок `always`: `always_latch`).
|
||
|
||
Защелка представляет из себя элемент памяти, причем данные в нее записываются не по тактовому синхроимпульсу, а на протяжении относительно длинного промежутка времени, когда управляющий сигнал "открывает" защелку (в этом случае говорят, что защелка становится "прозрачной"). Из-за этого она не является ни комбинационной, ни синхронной схемой.
|
||
|
||
Защелка — это всего лишь элемент цифровой схемы и будет неправильно говорить о нем в терминах "плохой" или "хороший". Защелка имеет свои плюсы для [ASIC](https://ru.wikipedia.org/wiki/Интегральная_схема_специального_назначения)-проектирования. Однако защелка совершенно не подходит при проектировании устройств под ПЛИС.
|
||
|
||
Обычно появление защелки в цифровой схеме говорит об ошибке разработки: в случае, если планировалась комбинационная логика, добавление защелки приведет к непредвиденному удержанию предыдущих значений (поскольку защелка сохраняет предыдущее значение до прихода очередной комбинации управляющего сигнала, описанной в блоке `case`). Это особенно плохо, если сигнал, перед которым появилась защелка, чем-то управляет. Представьте, что он управляет сейфом, который должен открываться если ввели правильный пароль:
|
||
|
||
```SystemVerilog
|
||
always_comb begin
|
||
if(password_is_correct) begin
|
||
open_the_safe <= 1'b1;
|
||
end
|
||
end
|
||
```
|
||
|
||
Вроде бы вы все описали правильно: "если ввели правильный пароль — сейф откроется". Однако проблема в том, что это состояние сохранится, и сейф уже не закроется. Именно поэтому у каждого блока `if` должен быть свой блок `else`:
|
||
|
||
```SystemVerilog
|
||
always_comb begin
|
||
if(password_is_correct) begin
|
||
open_the_safe <= 1'b1;
|
||
end
|
||
else begin
|
||
open_the_safe <= 1'b0;
|
||
end
|
||
end
|
||
```
|
||
|
||
В случае синхронной логики, будет непредсказуемое поведение данных, т.к. информация в защелку будет записываться не синхронно, как это ожидается, а на протяжении длительного промежутка времени, пока защелка "открыта".
|
||
|
||
Ещё один пример:
|
||
|
||
```SystemVerilog
|
||
module unexpected_d_latch_ex(
|
||
input logic [1:0] S,
|
||
input logic D0,
|
||
input logic D1,
|
||
output logic R
|
||
);
|
||
|
||
always_comb begin
|
||
case(S)
|
||
2'b00: R <= D0;
|
||
2'b01: R <= D1;
|
||
// Поскольку сигнал S двухразрядный, осталось еще две комбинации:
|
||
// S == 2'b10
|
||
// S == 2'b11
|
||
endcase
|
||
end
|
||
|
||
|
||
endmodule
|
||
```
|
||
|
||

|
||
|
||
_Рисунок 1. Пример генерации защелки у неполного мультиплексора._
|
||
|
||
На _рис. 1_ различные её части обозначены следующим образом:
|
||
|
||
1. Мультиплексор, который мы хотели описать
|
||
2. Защелка
|
||
3. Мультиплексор, который был добавлен чтобы генерировать сигнал, "открывающий" защелку
|
||
4. Константная единица (питание)
|
||
5. Константный ноль (земля).
|
||
|
||
В случае, если `S == 0` или `S == 1`, на выход мультиплексора 3 будет подана единица, которая переведет защелку в "прозрачный" режим (данные с выхода мультиплексора 1 будут проходить сквозь защелку).
|
||
|
||
В случае, если `S > 1`, на выход мультиплексора 3 будет подан ноль, который переведет защелку в "непрозрачный" режим (данные с выхода мультиплексора 1 не будут идти сквозь защелку, вместо этого на выходе защелки останутся последние данные, которые шли через нее, пока она была "открыта").
|
||
|
||

|
||
|
||
_Рисунок 2. Пример удержания предыдущих значений защелкой._
|
||
|
||
Кроме того, защелка усложняет временной анализ и ухудшает временные характеристики, из-за чего схема может работать на меньших частотах, чем могла бы.
|
||
|
||
Таким образом, во избежание появления защелки, необходимо описывать все возможные комбинации в блоке `case` (при необходимости покрывая множество оставшихся комбинаций с помощью `default`) и для каждого блока `if` описывать блоки `else`. В случае, если подобная комбинация не планируется к использованию, можно присвоить сигналу значение ноль. Конечно, в этом случае будет создана избыточная логика для присваивания ненужного значения, которое никогда не должно произойти (и существуют способы описания аппаратуры, позволяющие этого избежать), но в данном случае это самый простой способ.
|