Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

литература / 1kamkin_a_s_vvedenie_v_logicheskoe_proektirovanie_apparatury

.pdf
Скачиваний:
0
Добавлен:
13.05.2026
Размер:
874.66 Кб
Скачать

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

D

SET

Q

 

 

CLR

Q

S

SET

Q

 

R CLR Q

J

SET

Q

 

K CLR Q

D-триггер является не чем иным, как единичной задержкой: он запоминает и воспроизводит на выходе (с задержкой) то, что подается ему на вход.

RS-триггер устанавливает состояние в 1, если S=1; сбрасывает состояние в 0, если R=1; не изменяет состояние, если RS=00; комбинация RS=11 запрещена.

JK-триггер работает как RS-триггер (где J=S, K=R), но при подаче на вход комбинации JK=11 инвертирует состояние.

Задание. Определить функцию перехода синхронных D-, RS- и JK-триггеров.

D: Q(t+1) = D(t)

RS: Q(t+1) = ~R(t)&(Q(t)|S(t)) | (x&S&R), x — неопределенное значение. JK: Q(t+1) = ~Q(t)&J(t) | Q(t)&~K(t)

Функция возбуждения памяти автомата строится в зависимости от типа используемых триггеров. Очевидно, что для D-триггеров эта функция совпадает с функцией переходов.

Задание. Реализовать единичную задержку через (D-триггер), используя:

1)синхронные RS-триггеры;

2)синхронные JK-триггеры.

Триггеры можно определить через схемы из функциональных элементов с обратными связями. Формально семантику таких схем мы определять не будем. Идея заключается в том, что выходное значение схемы стабилизируется не сразу, а после серии итераций (входы нужно держать неизменными некоторое время). Полученное стабильное состояние и есть выходное значение. Например, асинхронный RS-триггер можно представить следующей схемой.

R

Q

 

S

~Q

 

Эта схема на языке Verilog описывается следующим образом.

// асинхронный RS-триггер module rs_flipflop(q, n, r, s);

output q, n; input r, s;

nor gate1(q, r, n); nor gate2(n, s, q);

endmodule /* rs_flipflop */

Домашнее задание. Нарисовать схему для синхронного JK-триггера, описать схему на языке Verilog, написать функциональный тест.

Описание схем с памятью на языке Verilog

Рассмотрим пример D-триггера (D flip-flop).

// D-триггер с асинхронным сбросом

11

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

module d_flipflop(q, d, clk, rst); output q;

input d, clk, rst;

reg q; // возможность присваивания

always @(posedge clk or posedge rst) // список чувствительности if(rst)

q = 1’b0;

else

q = d; endmodule /* d_flipflop */

Моделирование памяти

Для моделирования памяти обычно используется конструкция reg.

Примеры

reg mem;

// один бит

reg

mem[0:15];

//

16-разрядный регистр

reg

[0:7] mem [0:31]; //

32 8-разрядных регистров

Ключевое слово reg можно использовать как в отношении внутренних данных, так и выходных сигналов (см. пример D-триггера).

Замечание. К регистрам нельзя применять непрерывное присваивание. Непрерывное присваивание можно применять только к проводам (net, в частности, wire). Для регистров следует использовать процедурное присваивание.

Процедурное присваивание

= — блокируемое присваивание;

<= — неблокируемое присваивание.

Примеры

// блокируемое присваивание a = 1; b = 2;

begin

a = b;

b = a; // a == 2, b == 2

end

// неблокируемое присваивание a = 1; b = 2;

begin

a <= b;

b <= a; // a == 2, b == 1

end

Always-блоки

Примеры

always // бесконечный цикл clk = #10 ~clk;

always @(posedge clk) // обработчик события

...

always @(posedge clk or posedge rst) // обработчик нескольких событий

...

// Гонка: возможны разные порядки always @(posedge clk) a = b;

12

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

always @(posedge clk) b = a;

// Гонки нет

always @(posedge clk) a <= b; always @(posedge clk) b <= a;

Конструкция @(событие1 or ... событиеn) называется списком чувствительности процесса.

Управляющие конструкции

Конструкция if

if(<expression1>) <statement1>;

else if(<expression2>) <statement2>;

...

else <default_statement>;

Конструкция case

case(<expression>) <alternative1>: <statement1>; <alternative2>: <statement2>;

...

default: <default_statement>; endcase

Пример. Мультиплексор 4-в-1.

module mux4_1(out, i0, i1, i2, i3, s1, s0); output out;

input i0, i1, i2, i3; input s1, s0;

reg out;

always @(s1 or s0 or i0 or i1 or i2 or i3) begin

case({s1, s0}) 2'b00: out = i0; 2'b01: out = i1; 2'b10: out = i2; 2'b11: out = i3; default: out = 1'bx; endcase

end

endmodule /* mux4_1 */

Задание. Описать на языке Verilog модуль управления пешеходным переходом.

`timescale 1s/1ms

Входы: button (импульсный сигнал).

Выходы: r1, y1, g1, r2, y2, g2 (потенциальные сигналы).

Домашнее задание. Модуль управления лифтом. Сформулировать требования. Продумать интерфейс. Описать на языке Verilog. Написать тест.

13

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

Лекция 3 «Примеры проектирования на языке Verilog»

В данной лекции будет рассмотрено несколько примеров проектирования аппаратуры. Цель лекции – продемонстрировать (пусть и в несколько упрощенной форме) основные этапы процесса проектирования аппаратуры (поведенческое проектирование и проектирование на уровне регистровых передач).

Пример 0. «Память прямого доступа на 4 слова»

`timescale 1ns/1ps

// RAM consisting of four 32-bit items

module ram(clk, rst, val_rd, val_wr, addr_in, data_in, val_out, data_out,

is_ready);

 

 

 

input

 

clk;

 

input

 

rst;

 

input

 

val_rd;

 

input

 

val_wr;

 

input

[1:0]

addr_in;

input

[31:0]

data_in;

output

 

val_out;

output

[31:0]

data_out;

output

 

is_ready;

reg

[31:0]

mem0;

 

reg

[31:0]

mem1;

 

reg

[31:0]

mem2;

 

reg

[31:0]

mem3;

 

reg

[31:0]

result;

 

reg

[1:0]

state;

 

// State encoding

 

parameter RAM_IDLE

= 2'b00;

parameter RAM_READ

= 2'b01;

parameter RAM_WRITE

= 2'b10;

parameter RAM_RESULT = 2'b11;

assign

is_ready = (state == RAM_IDLE);

assign

val_out

= (state == RAM_RESULT);

assign

data_out = (state == RAM_RESULT) ? result : 32'h0000_0000;

always @(posedge rst) begin

mem0 <= 32'hXXXX_XXXX; mem1 <= 32'hXXXX_XXXX; mem2 <= 32'hXXXX_XXXX; mem3 <= 32'hXXXX_XXXX; result <= 32'hXXXX_XXXX; state <= 2'b00;

end

always @(posedge clk) begin

if(state == RAM_IDLE) begin

// Read operation if(~rst & val_rd)

begin

state <= RAM_READ;

// Multiplexor 4-to-1 case(addr_in)

14

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

2'b00: result <= mem0; 2'b01: result <= mem1; 2'b10: result <= mem2; 2'b11: result <= mem3; endcase

end

// Write operation else if(~rst & val_wr)

begin

state <= RAM_WRITE; result <= 32'hXXXX_XXXX;

// Demultiplexor 1-to-4 case(addr_in)

2'b00: mem0 <= data_in; 2'b01: mem1 <= data_in; 2'b10: mem2 <= data_in; 2'b11: mem3 <= data_in; endcase

end

end else

begin

if(state == RAM_RESULT) begin

state <= RAM_IDLE; end

else begin

state <= RAM_RESULT; end

end

end endmodule /* ram */

Пример 1. «Очередь FIFO»

`timescale 1ns/1ps

// FIFO queue consisting of four 8-bit items

module fifo(clk, rst, val_rd, val_wr, data_in, val_out, data_out, is_full,

is_ready);

 

input

clk;

input

rst;

input

val_rd;

input

val_wr;

input [31:0] data_in;

output

val_out;

output [31:0] data_out;

output

is_full;

output

is_ready;

// RAM[i] is available

reg val0, val1, val2, val3;

reg

[1:0]

addr0;

reg

[1:0]

addr1;

reg

[1:0]

addr2;

reg

[1:0]

addr3;

reg

[1:0]

last;

wire [1:0]

free_addr;

wire [1:0]

addr_in;

15

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

assign is_full = val0 & val1 & val2 & val3;

assign free_addr = (~val0 ? 2'h0 : (~val1 ? 2'h1 : (~val2 ? 2'h2 :

(~val3 ? 2'h3 : 2'hX))));

assign addr_in = val_wr ? free_addr : (val_rd ? addr0 : 2'h0);

ram memory

(

.clk(clk),

.rst(rst),

.val_rd(val_rd),

.val_wr(val_wr),

.addr_in(addr_in),

.data_in(data_in),

.val_out(val_out),

.data_out(data_out),

.is_ready(is_ready)

);

always @(posedge rst) begin

val0 <= 1'b0; val1 <= 1'b0; val2 <= 1'b0; val3 <= 1'b0; addr0 <= 2'hX; addr1 <= 2'hX; addr2 <= 2'hX; addr3 <= 2'hX; last <= 2'h0;

end

always @(posedge clk) begin

if(~rst & val_wr) begin

@(val_out);

case(last) 2'h0: begin

addr0 <= free_addr; val0 <= 1'b1; last <= 2'h1; end

2'h1: begin

addr1 <= free_addr; val1 <= 1'b1; last <= 2'h2; end

2'h2: begin

addr2 <= free_addr; val2 <= 1'b1; last <= 2'h3; end

2'h3: begin

addr3 <= free_addr; val3 <= 1'b1; last <= 2'h3; end

endcase end

else if(~rst & val_rd) begin

case(addr0)

2'h0: val0 <= 1'b0; 2'h1: val1 <= 1'b0; 2'h2: val2 <= 1'b0; 2'h3: val3 <= 1'b0;

16

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

endcase

case(last)

2'h0: last <= 2'h0; 2'h1: last <= 2'h0; 2'h2: last <= 2'h1; 2'h3: last <= 2'h2; endcase

@(val_out);

addr0 <= addr1; addr1 <= addr2; addr2 <= addr3; addr3 <= 2'hX;

end

end

endmodule /* fifo */

Домашнее задание. Доделать модуль FIFO, написать базовый тест, результат отправить по почте.

Лекция 4 «Дискретно-событийное моделирование»

Введение

Как мы уже знаем, модели аппаратуры на HDL-языках можно выполнять в специальном программном окружении — симуляторе. Большинство симуляторов аппаратуры основано на парадигме дискретно-событийного имитационного моделирования (event-driven simulation),

называемой также принципом особых состояний. Суть этого подхода заключается в абстрагировании от непрерывной природы явлений (например, распространение электрического тока) и рассмотрении только основных событий в моделируемой системе (изменение уровня сигнала, окончание времени ожидания). Дискретно-событийное моделирование имеет огромную сферу приложений, включая рассматриваемое нами моделирование аппаратуры, а также моделирование бизнес-процессов, боевых действий, транспортных потоков. Основателем подхода считается Джеффри Гордон (1960-ые гг.).

Альтернативой событийному моделированию является моделирование по интервалам времени (cycle-driven simulation).

Дискретно-событийное моделирование аппаратуры

Основные понятия

Модельное время (время симулятора) — дискретная величина, не убывающая в процессе моделирования, значения которой кратны заданной точности моделирования.

Событие — это изменение значение сигнала, осуществляемое в определенное время. События вызываются присваиваниями и происходят мгновенно. Если присваивание не меняет значения сигнала, события не возникает.

Очередь присваиваний (транзакций) — упорядоченный по времени список запланированных присваиваний (с каждым присваиванием A ассоциировано время tA, когда оно осуществляется). Список является глобальным для всех сигналов модели.

Драйвер сигнала — проекция очереди присваиваний для данного сигнала, то есть драйвер сигнала — это список запланированных изменений этого сигнала.

Пример

A <= #2 1;

17

А.С. Камкин. Введение в логическое проектирование аппаратуры. Конспект лекций. 2012.

B <= #4 0;

C <= #8 1;

Очередь присваиваний: (A, 1, 2), (B, 4, 0), (C, 8, 1)

Обработчик события — множество процессов, которые запускаются при возникновении события. Обработчик события, может порождать новые присваивания (transaction generation), которые добавляются в очередь присваиваний. Важно отметить, что сами присваивания при этом не осуществляются.

Примеры

always @(posedge clk) ... // обработчик положительного фронта clk

assign z = #10 x & y // обработчик изменения x или y

Цикл работы симулятора

1.Получить очередное присваивание (или присваивания) A из очереди.

2.Изменить текущее время симулятора Tsim на время TA.

3.Осуществить присваивание (присваивания).

4.Если возникло событие, вызвать обработчик события.

Вначальный момент Tsim=0 и запускаются процессы инициализации (initial) и другие процессы, для которых не указан список чувствительности.

При обновлении очереди присваиваний (драйвера сигнала) возможны конфликты — одновременные присваивания различных значений. Разрешение конфликтов управляется типами соединений (например, wor и wand), которые в нашем курсе не рассматриваются.

Если несколько присваиваний имеют одно и то же время, их порядок не определен. Порядок вызова активных процессов также не определен. Для задания порядка «одновременных» присваиваний используются дельта-задержки.

Дельта-задержка

Дельта-задержка — это бесконечно малая задержка, используемая для упорядочивания событий, происходящих одновременно.

Примеры

initial A = 1;

initial A = 0; // порядок не определен

initial A = 1;

initial A = #0 0; // сначала A = 1, потом A = 0

Примеры

A <= #2 1; // в очередь добавляется <A, 1, Tsim+2>

A <= 1; // в очередь добавляется <A, 1, Tsim+1 >

Теоретически, любое конечное число дельта-задержек меньше одной единицы времени. На практике, максимальное число дельта-задержек, в одной единице времени является параметром симулятора.

Таким образом, в симуляторах используется двумерная модель времени. На оси абсцисс указываются моменты времени наступления событий. На оси ординат откладываются дельта-задержки. Например, (4, 2) означает, что событие происходит в момент времени 4 спустя две дельта-задержки.

18