Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Introduction_to_Hardware_Design.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
423.94 Кб
Скачать

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

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

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

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;

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. Написать тест.

Лекция 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)

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;

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;

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, написать базовый тест, результат отправить по почте.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]