В этой статье я расскажу про несколько совсем простых проектов платы Марсоход2bis. С готовыми проектами обычно легче начинать свой собственный, так как в исходном готовом проекте уже сделаны все важные настройки, задан тип микросхемы FPGA, сделаны назначения контактов ввода/вывода микросхемы, есть модуль верхнего уровня в котором описаны входные и выходные сигналы ПЛИС.
Исходные тексты приведенных ниже проектов можно получить на нашей странице github: https://github.com/marsohod4you/marsohod2bis
Внутри этого репозитория для каждого отдельного FPGA проекта создана отдельная папка, например, counter_verilog - это папка проекта для счетчика, vga_colors - папка проекта генерации VGA сигналов. Здесь есть еще проект сдвигового регистра, hello-world, serial-port эхо, а так же проект генератора сигналов и оцифровки сигнала с помощью АЦП платы. Проекты созданы в среде Intel Quartus Prime 18.1 Lite Edition, должны работать и более поздних версиях квартуса.
Далее есть краткое описание каждого из проектов.
Итак, репозиторий marsohod2bis. Внутри каждой папки проекта есть файл проекта project.qpf (Quartus Project File), который ссылается на два других файла m2bis_c4_6K_LE.qsf и m2bis_c4_10K_LE.qsf. Это файлы настроек (Quartus Settings File). Мы подготовили настройки для двух разных микросхем Cyclone IV: EP4CE6E22C8 и EP4CE10E22C8, на плате Марсоход2bis может быть установлена либо первая EP4CE6E22C8 с шестью тысячами логических элементов, либо вторая EP4CE10E22C8, с десятью тысячами логических элементов.
После того, как проект был открыт в среде Quartus Prime нужно выбрать конкретную ревизию проекта через меню Project => Revisions => выбор ревизии в диалоговом окне из списка и затем кнопка Set Current, вот так:
Или, проще, можно выбрать нужную ревизию проекта прямо в выпадающем меню на тулбаре квартуса:
Во всех представленных ниже проектах топ модуль m2bis (в файле m2bis.v или m2bis.bdf) имеет поименованные выводы микросхемы FPGA:
module m2bis(
input wire CLK100MHZ, //board 100MHz crystal
input wire KEY0, //board button with weak pull-up resistor, normally logical ONE
output wire [2:0]LED, //board LEDs
//FTDI serial port signals
input wire FTDI_BD0, //from FTDI, RxD
output wire FTDI_BD1, //to FTDI, TxD
input wire FTDI_BD2, //from FTDI, RTS
output wire FTDI_BD3, //to FTDI, CTS
//VGA interface
output wire [4:0]VGA_RED,
output wire [5:0]VGA_GREEN,
output wire [4:0]VGA_BLUE,
output wire VGA_HSYNC,
output wire VGA_VSYNC,
//ADC1175 interface
input wire [7:0]ADC_D,
output wire ADC_CLK,
//Shield I/O interface
inout wire [15:0]IO,
//SDRAM (MT48LC4M16A2-75) interface
output wire SDRAM_CLK,
inout wire [15:0]SDRAM_DQ,
output wire [11:0]SDRAM_A,
output wire SDRAM_LDQM,
output wire SDRAM_UDQM,
output wire SDRAM_BA0,
output wire SDRAM_BA1,
output wire SDRAM_RAS,
output wire SDRAM_CAS,
output wire SDRAM_WE,
//serial flash interface
output wire DCLK,
output wire NCSO,
output wire ASDO,
input wire DATA0
);
При этом, многие из этих выводов, хоть и описаны, не участвуют в проекте. Например, в приведенных ниже примерах нигде не используется внешняя память SDRAM или только в одном проекте используются сигналы VGA.. Однако, теперь начинать новый проект можно просто копируя имеющийся - все сигналы описаны и назначены в настройках - если они вам нужны, то просто используйте их.
Итак, простые проекты:
1. Проект "Двоичный счетчик".
Я подготовил даже 2 проекта с двоичным счетчиком: один в папке counter_verilog и второй counter_schema. Делают они одно и то же, но выполнены соответственно в Verilog HDL и в виде схемы. Тут все просто: на плате Марсоход2bis имеется кварцевый генератор 100МГц. Выход генератора подается на FPGA Cyclone IV, как сигнал CLK100MHZ. В проекте этот сигнал подается на двоичный счетчик. Три бита счетчика выходят на 3 светодиода платы. У счетчика есть сигнал разрешения счета, подключенный к кнопке KEY0. нажимая кнопку мы приостанавливаем счет.
reg [31:0]counter;
always @(posedge CLK100MHZ)
if( KEY0 )
counter <= counter+1;
assign LED = counter[25:23];
На GIF выше показано, как нажатие кнопки платы Марсоход2bis останавливает счет.
2. Проект "Сдвиговый регистр".
Это так же очень простой проект, папка shift_register. Тактовая частота CLK100MHZ делится до получения очень низкой частоты, 5Гц:
reg [31:0]divider;
always @(posedge CLK100MHZ)
divider <= divider+1;
wire low_freq_clock;
assign low_freq_clock = divider[24];
Далее, полученный новый сигнал тактовой частоты задвигает сигнал от кнопки KEY0 в трехбитный сдвиговый регистр, выход сдвигового регистра подается на светодиоды:
wire key_pressed; assign key_pressed = ~KEY0;
reg [2:0]shift;
always @(posedge low_freq_clock)
shift <= { shift[1:0], key_pressed };
assign LED = shift;
Получается, что при нажатии кнопки платы светодиоды последовательно загораются, но при отпускании кнопки так же оследовательно гаснут. Это показано на GIF анимации выше.
3. Проект "Передача в последовательный порт, Hello World!"
Это проект посложнее. Папка hello_world. На плате Марсоход2bis стоит микросхема FTDI FT2232H. Это двухканальный приемопередатчик. При подключении платы к компьютеру Windows обнаруживает два канала последовательного порта. Однако, первый канал используется JTAG программатором MBFTDI, он нужен для загрузки ПЛИС из среды Quartus Prime, а вот второй канал вполне может использоваться для последовательной передачи произвольных данных из компьютера в ПЛИС и из ПЛИС в компьютер.
В этом проекте данные передаются из FPGA в компьютер на скорости 12 мегабит.
В проекте стоит PLL, который из 100МГц входной тактовой частоты делает 12МГц, нужные для последовательного порта. По нажатию кнопки на плате активизируется конечный автомат (state machine), который передает в последовательный порт побайтно текстовую фразу "Hello world! ". Каждый раз, когда нажимается кнопка, фраза передается в компьютер. На компьютере нужно запустить программу терминала, например, Putty. Настройки для Putty: baud 12000000, 8bit, no parity, 1 stop bit.
GIF анимация показывает, как передается текст по нажатию кнопки платы.
4. Проект "Эхо"
Этот проект так же работает с последовательным портом. Принимает FPGA байт из последовательного порта (второй канал микросхемы FT2232H), прибавляет к значению принятого байта единицу и отправляет байт назад в компьютер. Скорость передачи и приема в этом проекте 115200. Если вы разберетесь с hello_world, то и этот проект наверное покажется вам не сложным.
5. Проект "Цветные полосы на VGA Мониторе"
Папка vga_colors.
В проекте реализован генератор видеосигнала для VGA в разрешении 1440x900, 60Гц. Для этой цели в PLL вырабатывается требуемая для этого разрешения по стандарту VGA частота пикселелей 106,5МГц. С использованием этой частоты генерируются синхросигналы строчной HSYNC и кадровой развертки VSYNC.
Видимая область экрана заполняется цветными полосами.
6. Проект "Генератор сигналов и оцифровка сигнала с помощью АЦП".
Папка проекта dac_adc. В этой подборке проектов это пожалуй самый сложный проект. Идея такая: на плате есть разъем VGA у которого есть три "аналоговых" сигнала: RED, GREEN, BLUE. На плате цифро-аналоговые преобразователи реализованы через цепочки R2R. При этом разрядность ЦАП соответствует режиму VGA HIGH-COLOR, 5-6-5, то есть у зеленого цвета разрядность 6 бит, а у синего и красного по 5 бит.
Шесть бит сигнала GREEN хоть и не очень много, но вполне достаточно, чтобы попробовать синтезировать аналоговый сигнал. Паттерны сигналов я решил разместить во встроенной памяти FPGA.
Из среды Quartus Prime через Ip Catalog я создал блок памяти типа ROM 1-PORT. Это 8-ми битная память в которой 64 ячейки. Вставил четыре экземпляра модулей rom в мой модуль signal_generator. Каждому экземпляру модуля rom я передаю Verilog параметром строку с именем MIF (Memory Initialization File) файла, содержащим выборки сигнала. На языке Verilog HDL модуль signal_generator выглядит вот так:
module signal_generator(
input wire clk,
input wire [2:0]selector,
output wire [7:0]signal
);
reg [5:0]addr;
always @(posedge clk)
addr <= addr + 1;
wire [7:0]s_meandr;
rom #(.MIF_FILE("./python/meandr.mif")) rom_inst1(
.address( addr ),
.clock( clk ),
.q(s_meandr)
);
wire [7:0]s_saw1;
rom #(.MIF_FILE("./python/saw1.mif")) rom_inst2(
.address( addr ),
.clock( clk ),
.q(s_saw1)
);
wire [7:0]s_saw3;
rom #(.MIF_FILE("./python/saw3.mif")) rom_inst3(
.address( addr ),
.clock( clk ),
.q(s_saw3)
);
wire [7:0]s_sin;
rom #(.MIF_FILE("./python/sin.mif")) rom_inst4(
.address( addr ),
.clock( clk ),
.q(s_sin)
);
reg [7:0]s_out;
always @( posedge clk )
case( selector[1:0] )
0: s_out <= s_meandr;
1: s_out <= s_saw1;
2: s_out <= s_saw3;
3: s_out <= s_sin;
endcase
assign signal = s_out;
endmodule
MIF файлы создаются питоновской программой python/make_mif.py. Запускайте этот файл и он создась несколько MIF файлов для разных типов сигналов: меандр - meandr.mif, пила - saw1.mif, другая пила - saw2.mif, синусоида - sine.mif. Вы можете исправить программу и создавать свои паттерны для сигналов.
По нажатию кнопки на плате генератор сигналов переключается на генерацию следующего типа сигнала. Частота сигналов на выходе ЦАП 1 МГц. Чтобы получилась такая выходная частота сигналов при количестве отсчетов 64, я подаю на адреса памяти rom тактовую частоту 64МГц.
На плату подключаю всего один проводок, который соединяет выход ЦАП сигнала VGA GREEN со входом АЦП платы. На плате стоит 8-ми разрядная АЦП типа ADC1175 (до 20ти мегагерц).
Таким образом, я собираюсь оцифровывать сигнал, который только что синтезирован тут же в FPGA. Выборки сигнала с АЦП передаются в комьютер через последовательный порт со скоростью передачи 12 мегабит. При такой скорости передачи я вполне могу оцифровывать сигнал на частоте 1МГц.
Чтобы на компьютере отобразить оцифрованный сигнал я написал программу на питоне read_adc_from_serial.py, которая читает из последовательного порта байты и постоянно рисует график на экране. Номер последовательного порта просто прописан в программе. Чтобы опробовать программу на своем ПК проверьте, какой номер порта присвоен операционной системой вашей плате. Исправьте программу соответствующим образом.
Пожалуйста помните, что если действовать по науке, то на самом деле перед входом АЦП обязательно нужен фильтр низких частот с частотой среза в половину от частоты оцифровки.
Видеодемонстрация этого проекта представлена вот здесь:
Музыка Blue Dot Session, трэк Hardboil, альбом Banana Cream.
PS: при подготовке этого материала решил вместо некоторых видео записать короткие GIF анимации. Долго пытался найти инструмент для создания таких гифок. Проще всего оказалось использовать просто ffmpeg из командной строки. Например вот так:
ffmpeg -i source_video.MTS -r 5 -vf scale=640:360 -ss 1 -t 10 output.gif -hide_banner
где -r 5 - это частота кадров, -ss 1 -t 10 начальное время и длительность в секундах.
Подробнее...