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

2 лаба GPT

.docx
Скачиваний:
0
Добавлен:
26.01.2024
Размер:
11.14 Кб
Скачать

MASTER TB

Этот код на языке Verilog описывает тестовый бенч (testbench) для модуля master, который, вероятно, представляет собой часть системы для взаимодействия с внешней Flash-памятью. Давайте разберем основные части кода:

  1. timescale 1ns / 1ps: Устанавливает временной масштаб для симуляции, где 1ns - единица времени, а 1ps - единица задержки.

  2. module master_tb();: Определение тестового бенча с именем master_tb.

  3. Параметры модуля:

    • PERIOD: Период тактового сигнала (предположительно, 12 единиц времени).

    • LEN, LEN_D_FLASH, LEN_ADRESS_FLASH, LEN_DATA_FLASH: Различные параметры длины данных, адреса и т.д.

  4. Объявление сигналов:

    • logic clk: Сигнал тактового сигнала.

    • logic reset: Сигнал сброса.

    • logic [1:0] CS: Сигналы управления чипом Flash-памяти.

    • logic [3:0] address_for_flash: Сигнал адреса для доступа к Flash-памяти.

    • logic [255:0] data_buffer: Буфер данных.

  5. Объявление и инициализация памяти Flash:

    • logic [256-1:0] FLASH [0:16-1]: Объявление массива Flash-памяти размером 256 бит, представляющего 16 слов памяти.

  6. Присваивание данных в Flash-памяти:

    • assign FLASH[0] = 255'b11: Присваивание определенных данных в нулевую ячейку Flash-памяти.

  7. Инициализация и подключение модуля master:

    • master dut (...): Подключение и инициализация модуля master, где передаются сигналы для взаимодействия.

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

TB SPI

Этот код на языке Verilog представляет собой тестовый бенч (testbench) для некоторой системы, включающей в себя модуль master_spi, работу с Flash-памятью (W25Q16), индикаторы семисегментного дисплея (74HC595), и взаимодействие с датчиком (MPU6000). Давайте рассмотрим основные элементы кода:

  1. Параметры и объявление тестового бенча (tb_spi):

    • bits: Параметр, указывающий на длину битовых шин данных (32 бита по умолчанию).

    • Объявление различных сигналов, представляющих системные сигналы и данные для тестирования.

  2. Модуль master_spi и его подключение:

    • master_spi dut (...): Подключение и инициализация модуля master_spi с использованием портов тестового бенча.

  3. Генерация тактового сигнала (sys_clk):

    • always #2 sys_clk = !sys_clk;: Создание переключающегося тактового сигнала.

  4. Инициализация системных сигналов и данных:

    • Инициализация тактового сигнала, сброса, данных и других системных сигналов перед началом тестирования.

  5. Таск transact_test для взаимодействия с модулем master_spi:

    • Симулирует передачу данных между тестовым бенчем и модулем master_spi.

  6. Имитация работы с датчиком MPU6000:

    • Инициализация массива REGS для эмуляции данных, считываемых из регистров датчика MPU6000.

  7. Таск out_segm_task для работы с индикаторами 74HC595:

    • Эмулирует вывод данных на семисегментные индикаторы, преобразуя данные в семисегментный формат.

  8. Имитация работы с Flash-памятью W25Q16:

    • Инициализация массива FLASH для эмуляции данных, считываемых и записываемых в Flash-память.

  9. Инициализация данных для тестирования:

    • Запуск тестовых сценариев для взаимодействия с датчиком MPU6000, семисегментными индикаторами и Flash-памятью.

  10. Завершение симуляции ($finish):

Завершение симуляции после завершения тестов.

timescale 1ns / 1ps

parameter bits = 32;

module tb_spi();

// Объявление различных сигналов тестового бенча

logic sys_clk;

logic t_start;

logic [bits-1:0] d_in;

logic [bits-1:0] d_out;

logic [$clog2(bits):0] t_size;

logic cs;

logic rstn;

logic spi_clk;

logic miso;

logic mosi;

// Подключение модуля master_spi и инициализация портов

master_spi dut (

.sys_clk(sys_clk),

.t_start(t_start),

.d_in(d_in),

.d_out(d_out),

.t_size(t_size),

.cs(cs),

.rstn(rstn),

.spi_clk(spi_clk),

.miso(miso),

.mosi(mosi)

);

// Присвоение miso значения mosi

assign miso = mosi;

// Создание переключающегося тактового сигнала

always #2 sys_clk = !sys_clk;

// Инициализация системных сигналов и данных

initial begin

sys_clk = 0;

t_start = 0;

d_in = 0;

rstn = 0;

t_size = bits;

#4;

rstn = 1;

end

// Таск для взаимодействия с модулем master_spi

task transact_test;

input [bits-1:0] data;

begin

d_in = data[bits-1:0];

#3 t_start = 1;

#4 t_start = 0;

for (integer i = 0; i < bits; i++) begin

#4;

end

#16;

end

endtask

// Имитация работы с датчиком MPU6000

logic [7:0] REGS [0:117];

initial begin

int data_reg;

parameter DATA_BITS_NUM = $bits(data_reg);

for (int reg_num = 0; reg_num < 118; reg_num++) begin

data_reg = $urandom();

REGS[reg_num] = data_reg[7:0];

end

end

logic [7:0] address_for_MPU_from_TB;

logic [7:0] address_for_MPU_from_fpga;

logic [7:0] result_MPU;

// Имитация работы с индикаторами 74HC595

logic notOE = 1'b1;

logic [2:0] addr = 3'b000;

logic [7:0] segments [0:7];

task out_segm_task;

input [63:0] data;

begin

if (notOE) begin

for (int i = 0; i < 8; i++) begin

segments[i] <= (data[i*8 +: 8] === 8'hxx) ? 8'b0 : data[i*8 +: 8];

end

end

end

endtask

// Имитация работы с Flash-памятью W25Q16

logic [31:0] FLASH [0:7];

initial begin

int data_flash;

parameter DATA_BITS_NUM = $bits(data_flash);

for (int flash_page = 0; flash_page < 8; flash_page++) begin

for (int flash_32_bit = 0; flash_32_bit < 32; flash_32_bit += DATA_BITS_NUM) begin

data_flash = $urandom();

FLASH[flash_page][flash_32_bit +: DATA_BITS_NUM] = data_flash;

end

end

end

// Дополнительные сигналы для работы с Flash-памятью W25Q16

logic [23:0] address_for_W25_from_TB;

logic [23:0] address_for_W25_from_fpga;

logic [31:0] result_W25;

// Запуск тестовых сценариев

initial begin

#10;

// Чтение данных из датчика MPU6000

address_for_MPU_from_TB = 8'b0111_0100;

transact_test({2'b00, address_for_MPU_from_TB});

address_for_MPU_from_fpga = d_out[7:0];

result_MPU = REGS[address_for_MPU_from_fpga];

#100;

// Вывод данных на семисегментные индикаторы

out_segm_task({2'b00, result_MPU});

#100;

// Чтение данных из Flash-памяти W25Q16

address_for_W25_from_TB = 24'b0000_0000_0000_0010;

transact_test({2'b01, address_for_W25_from_TB});

address_for_W25_from_fpga = d_out[23:0];

result_W25 = FLASH[address_for_W25_from_fpga];

#100;

// Вывод данных на семисегментные индикаторы

out_segm_task({2'b01, result_W25});

#100;

// Запись данных в Flash-память W25Q16

address_for_W25_from_TB = 24'b0000_0000_0000_0101;

transact_test({2'b10, address_for_W25_from_TB});

address_for_W25_from_fpga = d_out[23:0];

data_for_W25_from_TB = 32'b1001_0000_0000_0000_0000_0000_0000_0110;

transact_test({2'b11, data_for_W25_from_TB});

data_for_W25_from_fpga = d_out[31:0];

FLASH[address_for_W25_from_fpga] = data_for_W25_from_fpga;

result_W25 = FLASH[address_for_W25_from_fpga];

#100;

// Вывод данных на семисегментные индикаторы

out_segm_task({2'b10, result_W25});

#100;

$finish;

end

endmodule

MASTER SV

Данный код на языке Verilog представляет собой модуль master, который реализует работу с интерфейсом Serial Peripheral Interface (SPI) для взаимодействия с устройствами. Давайте разберем его построчно:

  1. timescale 1ns / 1ps: Устанавливает масштаб времени для симуляции.

  2. verilogCopy code

`include "defines.v"

Включает файл defines.v, который вероятно содержит макроопределения (define) для различных значений, таких как FLASH_MEMORY, MPU_GYRO, и REGISTER. Это позволяет более чисто структурировать код и использовать символические имена вместо числовых значений.

  1. verilogCopy code

/

Комментарии, описывающие режим работы SPI (Mode 0) и характеристики тактовой последовательности.

  1. verilogCopy code

module master

Определение модуля master с входами CLK (тактовый сигнал), nRST (сигнал сброса), CS (Chip Select), address_for_flash (адрес для работы с Flash-памятью) и data_from_flash (данные, считанные из Flash-памяти).

  1. verilogCopy code

always_ff @(posedge CLK or negedge nRST) begin

Всегда активный блок, реагирующий на положительный фронт тактового сигнала или отрицательный фронт сброса. Если сброс активен, обнуляет данные.

  1. verilogCopy code

case (CS)

Кейс-структура, зависящая от сигнала CS (Chip Select), который, вероятно, указывает на тип устройства, с которым взаимодействует SPI. В данном случае, обрабатывается случай FLASH_MEMORY. Здесь вы можете вставить код для взаимодействия с Flash-памятью в зависимости от конкретных условий.

  1. verilogCopy code

en

Завершение определения модуля master.

MASTER SV

Этот код Verilog представляет собой описание модуля master_spi, который реализует интерфейс Serial Peripheral Interface (SPI). Давайте рассмотрим его построчно:

module master_spi

#(

parameter reg_width = 32,

parameter counter_width = $clog2(reg_width),

parameter reset = 0, idle = 1, load = 2, transact = 3, unload = 4

)

(

// System Side

input rstn,

input sys_clk,

input t_start,

input [reg_width-1:0] d_in,

input [counter_width:0] t_size,

output logic [reg_width-1:0] d_out,

// SPI Side

input miso,

output logic mosi,

output logic spi_clk,

output logic cs

);

Определение модуля master_spi с параметрами ширины регистра (reg_width), ширины счетчика (counter_width), исходного состояния и состояний (reset, idle, load, transact, unload). Он имеет входы и выходы для системной стороны (rstn, sys_clk, t_start, d_in, t_size, d_out) и стороны SPI (miso, mosi, spi_clk, cs).

Объявление внутренних сигналов для хранения предыдущих значений MOSI и MISO, счетчика и состояния. always @(state) begin

case (state)

// ...

endcase

end

Блок комбинаторной логики, который управляет состоянием конечного автомата в зависимости от текущего состояния.

always @(posedge sys_clk) begin

if (!rstn)

state = reset;

else

case (state)

// ...

endcase

end

Блок, реагирующий на положительный фронт системного тактового сигнала, определяющий переходы между состояниями в соответствии с логикой конечного автомата.

assign mosi = ( ~cs ) ? mosi_d[reg_width-1] : 1'bz;

assign spi_clk = ( state == transact ) ? sys_clk : 1'b0;

Присвоение значений MOSI и SPI Clock в зависимости от состояния и CS (Chip Select).

////

Обновление значения MISO при каждом положительном фронте SPI Clock во время транзакции.

always @(posedge spi_clk) begin

if ( state == transact )

miso_d <= {miso_d[reg_width-2:0], miso};

end

Обновление значения MOSI и уменьшение счетчика при каждом отрицательном фронте SPI Clock во время транзакции.

always @(negedge spi_clk) begin

if ( state == transact ) begin

mosi_d <= {mosi_d[reg_width-2:0], 1'b0};

count <= count-1;

end

end