Доброго времени суток. В этой статье расскажу как интегрировать модули, на примере двух ультразвуковых датчиков HC-SR04 и Pmod MAXSONAR, в систему на кристалле на основе MIPSfpga. Также расскажу как написать программу для управления подключенных модулей.
Основываясь на моем примере вы сможете подключить ваши собственные модули, управлять ими при помощи программы. Создавать систему со своим набором периферии, на основе MIPSfpga.
Подключать будем вот такой датчик:
Документацию на него можно найти здесь. Данные будем выводить на семисегментные индикаторы на плате. Также будем генерировать звуковые сигналы различной длительности при помощи пьезодинамика.
Для начала, необходимы исходники MIPSfpga.
Инструкция по скачиванию:
> www.silicon-russia.com/2015/12/11/mipsfpga-download-instructions
Далее, нужно скачать надстройку MIPSfpga-plus, которая позволяет записывать программы по UARTу:
> github.com/MIPSfpga/mipsfpga-plus
Описание и инструкции по установке присутствуют, если коротко, то для того чтобы была возможность просто запустить скрипт и проект собрался, необходимо:
Поместить исходники MIPSfpga в папку:
А MIPSfpga-plus в:
Далее в папке C:\github\mipsfpga-plus\boards выбрать свою плату, у меня это de0_cv, и выполнить скрипт make_project. Проект, который нужно запускать будет находиться в C:\github\mipsfpga-plus\boards\de0_cv\project.
Если вашей платы нет, то можно выбрать наиболее подходящую по количеству логических ячеек и изменить назначения.
Также понадобятся компилятор, линковщик Codescape. И USB UART преобразователь. Например, pl2303hx или ch340.
Датчик имеет аналоговый выход, выход широтно-импульсной модуляции, последовательный интерфейс UART, который и будем использовать для подключения датчика к MIPSfpga. Подключение осуществляется путем подключения регистров, в которые отображаются данные с датчика, к шине, по которой процессор общается с памятью.
UART приемник будем использовать уже описанный, который используется для зашивки программ, изменив только параметр baud_rate на 9600, такую скорость передачи использует датчик.
Согласно даташиту[1], каждые 49мс, сонар отправляет четыре байта в ASCII формате, символ “R” и три символа измеренного расстояния, старшими разрядами вперед.
По каждому такту и флагу byte_ready(взводится, когда был принят байт) ожидаем символ “R” – 52 в шестнадцатеричном, далее переходим к приему следующих трех символов. По приему трех байт записываем в выходной регистр младшие полубайты, таким образом переводим из ASCII в двоично-десятичный формат.
Модуль для управления пьезодинамиком состоит из двух, в первом собственно генерируются импульсы с возможностью выбора частоты:
Считаем до div и инвертируем выходной сигнал. Div выбирается входным notein.
Div = Fclk/Fnote/2
Где Fclk – частота тактового сигнала, Fnote – требуемая частота выходного сигнала.
И модуль где регулируется длительность звуковых импульсов:
Каждый такт счетчик инкрементируется, при достижении значения div разрешается звуковой сигнал, при достижении значения div1 запрещается. Таким образом задается длительность, и частота звуковых сигналов. Также счётчик ограничен 60000000 для предотвращения длительного импульса, который может возникнуть при изменении div1 в момент, когда значение счётчика между div и div1.
В файле mfp_ahb_lite_matrix_config.vh который находится в папке C:\github\mipsfpga-plus.
Добавляем следующие строчки:
Собственно это и есть адреса по которым будут доступны регистры.
Исходники модулей, и измененные файлы доступны здесь:
> github.com/Denis-Kingit/UltraSonicToMIPSfpga
Далее компилируем проект и прошиваем плату. Подключаем датчик, преобразователь, пьезодинамик:
Пин GND преобразователя к GPIO_1[26], пин TX к GPIO_1[31]. Пьезодинамик к GPIO_0[34], GPIO_0[35]. Пин GND датчика к GPIO_0[3], VCC – GPIO_0[1], TX – GPIO_0[7]. Получается что-то вроде:
Копируем содержимое папки C:\github\mipsfpga-plus\programs\01_light_sensor или попросту работаем в ней. Добавим в файл mfp_memory_mapped_registers.h адреса регистров:
Теперь напишем программу, в которой будем считывать значения с регистра и выводить на семисегментные индикаторы. И в зависимости от считаного значения управляем звуковым сигналом. Изменим main.c:
Компилируем запустив скрипт:
Генерируем motorola_s_record файл:
Проверяем к какому СОМ порту подключен USB UART преобразователь:
Изменяем файл 12_upload_to_the_board_using_uart:
где а – номер СОМ порта, к которому подключен USB UART преобразователь.
И наконец загружаем программу:
Идея подключения такая же, отображаем данные с датчика в регистры, подключенные к шине.
Для измерения расстояния необходимо подать импульс длительностью 10мкс на сигнальный пин Trig, после чего ультразвуковой модуль будет излучать восемь пачек ультразвукового сигнала с частотой 40кГц и обнаруживать эхо.
Измеренное расстояние до объекта пропорционально ширине эха, которое кодируется длительностью электрического сигнала на выходе датчика (Echo). Рекомендованный период между измерениями не менее 50мс. Для того что бы рассчитать расстояние необходимо длительность импульса (эха) в микросекундах разделить на 58 для расстояния в сантиметрах или на 148 для расстояния в дюймах. Если никаких препятствий не обнаружено, то на выходе будет сигнал с длительностью 38мс [2].
С периодом 2500000 тактов (50мс) создаем импульс на выходе trig длительностью 500 тактов (10мкс), считаем длительность эха, делим на 2900 (на 50 для перевода в микросекунды и на 58 для перевода в сантиметры) и записываем результат в регистр (для то что бы не создавать дополнительный делитель можно переводить программно), если длительность импульса больше 36мс записываем 0хFFF, что будет означать что препятствий не обнаружено.
Подключим модуль в файле верхнего уровня проекта(de0_cv.v).
Аналогичным образом изменяем файлы: mfp_ahb_gpio_slave.v, mfp_ahb_lite_matrix.v, mfp_ahb_lite_matrix_with_loader.v, mfp_ahb_lite_matrix_config.vh, mfp_system.v в папке C:\github\mipsfpga-plus.
Для подключения датчика понадобится источник питания на 5В, пин trig подключаем к GPIO_0[33], так как датчик работает от 5В, пин echo необходимо подключить через делитель напряжения к GPIO_0[32], соединяем общий провод источника, датчика и платы.
Пишем программу:
Считываем значения с регистра, в зависимости от полученного значения управляем длительностью звука, выводим значение расстояния на семисегментные индикаторы.
Также необходимо добавить новый адрес в файл mfp_memory_mapped_registers.h
Описанным выше способом вы можете подключить ваши собственные модули, и управлять ими программно.
Основываясь на моем примере вы сможете подключить ваши собственные модули, управлять ими при помощи программы. Создавать систему со своим набором периферии, на основе MIPSfpga.
Подключать будем вот такой датчик:
Документацию на него можно найти здесь. Данные будем выводить на семисегментные индикаторы на плате. Также будем генерировать звуковые сигналы различной длительности при помощи пьезодинамика.
Для начала, необходимы исходники MIPSfpga.
Инструкция по скачиванию:
> www.silicon-russia.com/2015/12/11/mipsfpga-download-instructions
Далее, нужно скачать надстройку MIPSfpga-plus, которая позволяет записывать программы по UARTу:
> github.com/MIPSfpga/mipsfpga-plus
Описание и инструкции по установке присутствуют, если коротко, то для того чтобы была возможность просто запустить скрипт и проект собрался, необходимо:
Поместить исходники MIPSfpga в папку:
C:\MIPSfpga
А MIPSfpga-plus в:
C:\github\mipsfpga-plus
Далее в папке C:\github\mipsfpga-plus\boards выбрать свою плату, у меня это de0_cv, и выполнить скрипт make_project. Проект, который нужно запускать будет находиться в C:\github\mipsfpga-plus\boards\de0_cv\project.
Если вашей платы нет, то можно выбрать наиболее подходящую по количеству логических ячеек и изменить назначения.
Также понадобятся компилятор, линковщик Codescape. И USB UART преобразователь. Например, pl2303hx или ch340.
Датчик имеет аналоговый выход, выход широтно-импульсной модуляции, последовательный интерфейс UART, который и будем использовать для подключения датчика к MIPSfpga. Подключение осуществляется путем подключения регистров, в которые отображаются данные с датчика, к шине, по которой процессор общается с памятью.
Опишем модуль, который будет принимать и обрабатывать данные с датчика.
UART приемник будем использовать уже описанный, который используется для зашивки программ, изменив только параметр baud_rate на 9600, такую скорость передачи использует датчик.
Модуль uart receiver
module uart_receiver
(
input clock,
input reset_n,
input rx,
output reg [7:0] byte_data,
output byte_ready
);
parameter clock_frequency = 50000000;
parameter baud_rate = 9600;
localparam clock_cycles_in_symbol = clock_frequency / baud_rate;
// Synchronize rx input to clock
reg rx_sync1, rx_sync;
always @(posedge clock or negedge reset_n)
begin
if (! reset_n)
begin
rx_sync1 <= 1;
rx_sync <= 1;
end
else
begin
rx_sync1 <= rx;
rx_sync <= rx_sync1;
end
end
// Finding edge for start bit
reg prev_rx_sync;
always @(posedge clock or negedge reset_n)
begin
if (! reset_n)
prev_rx_sync <= 1;
else
prev_rx_sync <= rx_sync;
end
wire start_bit_edge = prev_rx_sync & ! rx_sync;
// Counter to measure distance between symbols
reg [31:0] counter;
reg load_counter;
reg [31:0] load_counter_value;
always @(posedge clock or negedge reset_n)
begin
if (! reset_n)
counter <= 0;
else if (load_counter)
counter <= load_counter_value;
else if (counter != 0)
counter <= counter - 1;
end
wire counter_done = counter == 1;
// Shift register to accumulate data
reg shift;
reg [7:0] shifted_1;
assign byte_ready = shifted_1 [0];
always @ (posedge clock or negedge reset_n)
begin
if (! reset_n)
begin
shifted_1 <= 0;
end
else if (shift)
begin
if (shifted_1 == 0)
shifted_1 <= 8'b10000000;
else
shifted_1 <= shifted_1 >> 1;
byte_data <= { rx, byte_data [7:1] };
end
else if (byte_ready)
begin
shifted_1 <= 0;
end
end
reg idle, idle_r;
always @*
begin
idle = idle_r;
shift = 0;
load_counter = 0;
load_counter_value = 0;
if (idle)
begin
if (start_bit_edge)
begin
load_counter = 1;
load_counter_value = clock_cycles_in_symbol * 3 / 2;
idle = 0;
end
end
else if (counter_done)
begin
shift = 1;
load_counter = 1;
load_counter_value = clock_cycles_in_symbol;
end
else if (byte_ready)
begin
idle = 1;
end
end
always @ (posedge clock or negedge reset_n)
begin
if (! reset_n)
idle_r <= 1;
else
idle_r <= idle;
end
endmodule
Согласно даташиту[1], каждые 49мс, сонар отправляет четыре байта в ASCII формате, символ “R” и три символа измеренного расстояния, старшими разрядами вперед.
Модуль sonar
module sonn
(
input clock,
input reset_n,
input rx,
output reg [15:0] hword
);
reg [1:0] count2;
wire [7:0] byte_data;
reg [31:0] wordd;
always @(posedge clock)
if (! reset_n)
wordd <= 32'b0;
else if (byte_ready)
case(count2)
2'd0:begin
wordd[31:24]<=byte_data;
if(byte_data==8'h52)
count2<=2'd1;
end
2'd1:begin wordd[23:16]<=byte_data; count2<=2'd2;end
2'd2:begin wordd[15:8]<=byte_data; count2<=2'd3;end
2'd3:begin wordd[7:0]<=byte_data; count2<=2'd0;
hword={4'b0000,wordd[19:16],wordd[11:8],wordd[3:0]};end
default begin
wordd[31:24]<=byte_data;
if(byte_data==8'h52)
count2<=count2+1'b1;
end
endcase
uart_receiver uart(clock,reset_n,rx,byte_data,byte_ready);
endmodule
По каждому такту и флагу byte_ready(взводится, когда был принят байт) ожидаем символ “R” – 52 в шестнадцатеричном, далее переходим к приему следующих трех символов. По приему трех байт записываем в выходной регистр младшие полубайты, таким образом переводим из ASCII в двоично-десятичный формат.
Модуль для управления пьезодинамиком состоит из двух, в первом собственно генерируются импульсы с возможностью выбора частоты:
Модуль tone
module note(clk,reset_n,notein,noteout);
input clk,reset_n;
input [6:0]notein;
output reg noteout;
reg [19:0]div;
reg [19:0]cnt;
reg eocnt;
always @*
begin
case (notein)
0: div = 191114; // C
1: div = 180385; // C#
2: div = 170262; // D
3: div = 160705; // D#
4: div = 151686; // E
5: div = 143173; // F
6: div = 135136; // F#
7: div = 127552; // G
8: div = 120389; // G#
9: div = 113636; // A
10:div = 107259; // A#
11:div = 101239; // H
12:div = 95558; // C
13:div = 90194; // C#
14:div = 85132; // D
15:div = 80354; // D#
16:div = 75845; // E
17:div = 71558; // F
18:div = 67567; // F#
19:div = 63775; // G
20:div = 60197; // G#
21:div = 28403; // A
22:div = 53629; // A#
23:div = 50619; // H
24:div = 47777; // C
25:div = 45097; // C#
26:div = 42566; // D
27:div = 40176; // D#
28:div = 37921; // E
default: div = 1; //
endcase
end
always @(posedge clk)
begin
if(~reset_n)
begin
noteout<=0;
cnt <= 0;
end
if(cnt == div)
begin
cnt <= 0;
noteout <= ~noteout;
end
else
cnt <= cnt + 1'b1;
end
endmodule
Считаем до div и инвертируем выходной сигнал. Div выбирается входным notein.
Div = Fclk/Fnote/2
Где Fclk – частота тактового сигнала, Fnote – требуемая частота выходного сигнала.
И модуль где регулируется длительность звуковых импульсов:
Модуль buzz
module buzz(clk,reset_n,en,tim,tone);
input clk,reset_n,en;
input [1:0]tim;
output reg tone;
wire [6:0]notein;
wire noteout;
assign notein=21;
reg [27:0]counter,div,div1;
reg ene;
note note1(clk,reset_n,notein,noteout);
always@(posedge clk)
if(~reset_n)
begin
counter<=28'b0;
ene<=1'b0;
end
else
begin
case(tim)
0:begin div<=28'd 5_000_000; div1<=28'd 12_000_000; end
1:begin div<=28'd 10_000_000; div1<=28'd 20_000_000; end
2:begin div<=28'd 25_000_000; div1<=28'd 35_000_000; end
3:begin div<=28'd 50_000_000; div1<=28'd 60_000_000; end
default begin div<=28'd 10_000_000; div1<=28'd 20_000_000; end
endcase
counter<=counter+1;
if(counter==div)
ene<=1'b1;
if(counter==div1 | counter>60_000_000)
begin
counter<=28'b0;
ene<=1'b0;
end
end
always@(posedge clk)
tone<=en¬eout&ene;
endmodule
Каждый такт счетчик инкрементируется, при достижении значения div разрешается звуковой сигнал, при достижении значения div1 запрещается. Таким образом задается длительность, и частота звуковых сигналов. Также счётчик ограничен 60000000 для предотвращения длительного импульса, который может возникнуть при изменении div1 в момент, когда значение счётчика между div и div1.
Подключаем к проекту файлы с описанными выше модулями.
- В файле верхнего уровня у меня это de0_cv.v добавим следующие строчки:
wire [15:0]hword; wire [31:0]control; sonn sonna ( .clock ( CLOCK_50 ), .reset_n ( RESET_N ), .rx ( GPIO_0[7] ), .hword ( hword ) ); buzz buzz ( .clk ( CLOCK_50 ), .reset_n ( RESET_N ), .en (control [0] ), .tim (control [2:1] ), .tone ( GPIO_0[35] ) );
Для входа RX UART приемника выделяем пин GPIO_0[7] и для выхода tone GPIO_0[35]. Регистры hword и control будем подключать к шине.
assign GPIO_0 [1] = 1'b1; //VCC for Sensor assign GPIO_0 [3] = 1'b0; //GND for Sensor assign GPIO_0 [34] = 1'b0; //GND for buzz
Выделим ножки GPIO_0 [1], GPIO_0 [3], GPIO_0 [34] для питания сенсора, общего провода для сенсора и пьезодинамика соответственно.
В описании модуля mfp_system добавим:
.IO_Sonar ( hword ), .IO_control ( control ),
- В файле mfp_system.v добавляем входы выходы:
input [15:0] IO_Sonar, output [31:0] IO_control,
В описании модуля mfp_ahb_lite_matrix_with_loader:
.IO_Sonar ( IO_Sonar ), .IO_control ( IO_control ),
- В файле mfp_ahb_lite_matrix_with_loader.v:
input [15:0] IO_Sonar, output [31:0] IO_control,
В описании модуля mfp_ahb_lite_matrix:
.IO_Sonar ( IO_Sonar ), .IO_control ( IO_control ),
- В файле mfp_ahb_lite_matrix.v:
input [15:0] IO_Sonar, output [31:0] IO_control,
В описании модуля mfp_ahb_gpio_slave
.IO_Sonar ( IO_Sonar ), .IO_control ( IO_control)
- В файле mfp_ahb_gpio_slave.v:
input [15:0]IO_Sonar, output reg[31:0]IO_control,
в предпоследнем always по! HRESETn
IO_control <=32'b0;
И в case (write_ionum)
`MFP_CONTROL_IONUM : IO_control <=HWDATA;
В последнем always в case (read_ionum)
`MFP_SONAR_SENSOR_IONUM : HRDATA = { 16'b0, IO_Sonar };
В файле mfp_ahb_lite_matrix_config.vh который находится в папке C:\github\mipsfpga-plus.
Добавляем следующие строчки:
`define MFP_SONAR_SENSOR_IONUM 4'h6
`define MFP_CONTROL_IONUM 4'h9
`define MFP_SONAR_SENSOR_ADDR 32'h1f800018
`define MFP_CONTROL_ADDR 32'h1f800024
Собственно это и есть адреса по которым будут доступны регистры.
Исходники модулей, и измененные файлы доступны здесь:
> github.com/Denis-Kingit/UltraSonicToMIPSfpga
Далее компилируем проект и прошиваем плату. Подключаем датчик, преобразователь, пьезодинамик:
Пин GND преобразователя к GPIO_1[26], пин TX к GPIO_1[31]. Пьезодинамик к GPIO_0[34], GPIO_0[35]. Пин GND датчика к GPIO_0[3], VCC – GPIO_0[1], TX – GPIO_0[7]. Получается что-то вроде:
Программная часть
Копируем содержимое папки C:\github\mipsfpga-plus\programs\01_light_sensor или попросту работаем в ней. Добавим в файл mfp_memory_mapped_registers.h адреса регистров:
#define MFP_SONAR_SENSOR_ADDR 0xBF800018
#define MFP_CONTROL_ADDR 0xBF800024
#define MFP_SONAR_SENSOR (* (volatile unsigned *) MFP_SONAR_SENSOR_ADDR )
#define MFP_CONTROL (* (volatile unsigned *) MFP_CONTROL_ADDR )
Теперь напишем программу, в которой будем считывать значения с регистра и выводить на семисегментные индикаторы. И в зависимости от считаного значения управляем звуковым сигналом. Изменим main.c:
Программа
#include "mfp_memory_mapped_registers.h"
int main ()
{
MFP_CONTROL = 1;
for (;;)
{
MFP_7_SEGMENT_HEX = MFP_SONAR_SENSOR;
if(MFP_SONAR_SENSOR<0x10)
MFP_CONTROL = 1;
else if (MFP_SONAR_SENSOR<0x12)
MFP_CONTROL = 3;
else if (MFP_SONAR_SENSOR<0x14)
MFP_CONTROL = 5;
else if (MFP_SONAR_SENSOR<0x16)
MFP_CONTROL = 7;
else
MFP_CONTROL = 0;
}
return 0;
}
Компилируем запустив скрипт:
02_compile_and_link
Генерируем motorola_s_record файл:
08_generate_motorola_s_record_file
Проверяем к какому СОМ порту подключен USB UART преобразователь:
11_check_which_com_port_is_used
Изменяем файл 12_upload_to_the_board_using_uart:
set a=7
mode com%a% baud=115200 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off type program.rec >\.\COM%a%
где а – номер СОМ порта, к которому подключен USB UART преобразователь.
И наконец загружаем программу:
12_upload_to_the_board_using_uart
Теперь подключим Ultrasonic HC-SR04
Идея подключения такая же, отображаем данные с датчика в регистры, подключенные к шине.
Для измерения расстояния необходимо подать импульс длительностью 10мкс на сигнальный пин Trig, после чего ультразвуковой модуль будет излучать восемь пачек ультразвукового сигнала с частотой 40кГц и обнаруживать эхо.
Измеренное расстояние до объекта пропорционально ширине эха, которое кодируется длительностью электрического сигнала на выходе датчика (Echo). Рекомендованный период между измерениями не менее 50мс. Для того что бы рассчитать расстояние необходимо длительность импульса (эха) в микросекундах разделить на 58 для расстояния в сантиметрах или на 148 для расстояния в дюймах. Если никаких препятствий не обнаружено, то на выходе будет сигнал с длительностью 38мс [2].
Модуль Sonic
module sonic(clk,trig,reset_n,en,echo,out);
input clk,echo,reset_n,en;
output reg trig;
output reg[23:0]out;
reg [23:0]count;
reg [23:0]countp;
always@(posedge clk)
if(~reset_n)
begin
countp<=24'b0;
count<=24'b0;
end
else
if(en)
begin
if(countp==0)
trig<=1'b1;
if(echo)
count<=count+1'b1;
if(countp==500)
trig<=1'b0;
if(countp==2500000)
begin
if (count>1800000)
out<=24'hfff;
else
out<=count/2900;
countp<=24'b0;
count<=24'b0;
end
countp<=countp+1'b1;
end
endmodule
С периодом 2500000 тактов (50мс) создаем импульс на выходе trig длительностью 500 тактов (10мкс), считаем длительность эха, делим на 2900 (на 50 для перевода в микросекунды и на 58 для перевода в сантиметры) и записываем результат в регистр (для то что бы не создавать дополнительный делитель можно переводить программно), если длительность импульса больше 36мс записываем 0хFFF, что будет означать что препятствий не обнаружено.
Подключим модуль в файле верхнего уровня проекта(de0_cv.v).
wire [23:0] usonic;
sonic sonica
(
.clk ( CLOCK_50 ),
.trig ( GPIO_0[33] ),
.reset_n ( RESET_N ),
.en ( control[3] ),
.echo ( GPIO_0[32] ),
.out ( usonic )
);
Аналогичным образом изменяем файлы: mfp_ahb_gpio_slave.v, mfp_ahb_lite_matrix.v, mfp_ahb_lite_matrix_with_loader.v, mfp_ahb_lite_matrix_config.vh, mfp_system.v в папке C:\github\mipsfpga-plus.
Для подключения датчика понадобится источник питания на 5В, пин trig подключаем к GPIO_0[33], так как датчик работает от 5В, пин echo необходимо подключить через делитель напряжения к GPIO_0[32], соединяем общий провод источника, датчика и платы.
Пишем программу:
Программа
#include "mfp_memory_mapped_registers.h"
int main ()
{
int k = 0;
for (;;)
{
//MFP_RED_LEDS = MFP_SONICR_SENSOR >> 4;
k=MFP_SONIC_SENSOR/58/50;
MFP_7_SEGMENT_HEX = k;
if(k<0x10)
MFP_CONTROL = 1;
else if (k<0x12)
MFP_CONTROL = 3;
else if (k<0x14)
MFP_CONTROL = 5;
else if (k<0x16)
MFP_CONTROL = 7;
else
MFP_CONTROL = 0;
}
return 0;
}
Считываем значения с регистра, в зависимости от полученного значения управляем длительностью звука, выводим значение расстояния на семисегментные индикаторы.
Также необходимо добавить новый адрес в файл mfp_memory_mapped_registers.h
#define MFP_SONIC_SENSOR_ADDR 0xBF800020
#define MFP_SONIC_SENSOR (* (volatile unsigned *) MFP_SONIC_SENSOR_ADDR )
Описанным выше способом вы можете подключить ваши собственные модули, и управлять ими программно.
Полезные ссылки
[1] LV-MaxSonar – maxbotix.com/documents/LV-MaxSonar-EZ_Datasheet.pdf
[2] Ultrasonic HC SR04 – robocraft.ru/blog/electronics/772.html
Исходники MIPSfpga-plus github.com/MIPSfpga/mipsfpga-plus
Codescape – Codescape
Инструкция по скачиванию mipsfpga – Инструкция
Исходники модулей, программ и измененных файлов:
github.com/Denis-Kingit/UltraSonicToMIPSfpga
Просто полезная книжка – Дэвид Харрис и Сара Харрис «Цифровая схемотехника и архитектура компьютера»
[2] Ultrasonic HC SR04 – robocraft.ru/blog/electronics/772.html
Исходники MIPSfpga-plus github.com/MIPSfpga/mipsfpga-plus
Codescape – Codescape
Инструкция по скачиванию mipsfpga – Инструкция
Исходники модулей, программ и измененных файлов:
github.com/Denis-Kingit/UltraSonicToMIPSfpga
Просто полезная книжка – Дэвид Харрис и Сара Харрис «Цифровая схемотехника и архитектура компьютера»
Поделиться с друзьями
Комментарии (13)
Kingit
03.12.2016 19:46Программу можно отладить в симуляторах MIPS. Проследить выполнение инструкций, отладить свои модули можно в ModelSim, также можно проследить за сигналами внутри кристалла c помощью Logic Tap signal analyzer в Quartus
GreenStore
04.12.2016 23:35Напишите, пожалуйста, в какое количество логических элементов компилируется MIPSfpga и сколько по времени занимает компиляция?
Kingit
04.12.2016 23:45На моем ноутбуке полная компиляция занимает восемь минут,
Количество ячеек в ALMs 7058, в LE где-то в 2-2,5 раза больше, регистров 8176
golf2109
а как с отладкой всего этого?
есть ли какие-то отладчики?
YuriPanchul
В качестве отладки можно использовать комбинацию EJTAG / BusBlaster / OpenOCD — см. http://www.silicon-russia.com/2015/08/25/mipsfpga-on-terasic-de0-cv/
golf2109
какова суммарная цена вопроса для этого?
YuriPanchul
Отладчика? $45 — http://store.hackaday.com/products/bus-blaster-v4
golf2109
BusBlaster — вещь хорошая, но этот проект уже заброшен (года 3 назад)
и не развивается,, тем более это любительский проект.
А более серьезного отладчика от разработчиков кристалла не существует?
YuriPanchul
Есть N серьезных отладчиков, которые поддерживают EJTAG (отладочный интерфейс ядер MIPS), но они довольно дорогие
golf2109
Очень жаль, что такая ситуация с отладчиками. Это кардинально тормозит порог вхождения
в те вещи, которые Вы описываете.
YuriPanchul
На самом деле мне нужно выяснить вопрос с отладчиками получше. Я сам ими практически не пользуюсь, так как пишу на Verilog-е, т.е. работаю в другой части таких проектов.
Для MIPS-based микроконтроллеров PIC32MZ, есть дешевые отладчики PICkit 3, но их нельзя подключить к MIPSfpga.
Но зададим вопрос шире: что вы имеете в виду когда говорите «в те вещи, которые Вы описываете»? В какие именно вещи? В упражнения с разработкой прототипа системы на кристалле используя FPGA? Для этих упражнений отладчик вообще имхо вещь не 100% нужная, так как в этих упражнениях главное не отладить софтвер, а получить представление как софтвер и хардвер (спроектированный на верилоге и синтезированный) работают вместе. Софтвера как такового в них немного, а хардверную часть вы через софтверный отладчик не отладите.
Даже если софтвера много, часто проще сделать custom средства трассировки чего-нибудь (скажем выдавать последовательность событий в системе через последовательный порт на консоль).
Отладчики наиболее полезны, когда нужно например делать reverse-engineering чего-нибудь, или скажем отлавливать баги в драйверах операционных систем, когда трассировка не спасает.
Какой сценарий использования отладчика вы рассматриваете для упражнений с конструированием простых SoC с реализацией на FPGA? Или вы говорите про использование отладчика, когда на основе прототипа на FPGA кто-то собирается делать ASIC? Так в последнем случае идут совсем другие суммы расходов, отладчик среди них — это копейки.
madprogrammer
А какого развития вы от него ждете? Это же такой же, как и многие другие более «серьезные» отладчики (Flyswatter2, Olimex ARM-USB-OCD, и др.) универсальный отладчик, использующий в своей основе примитивную схему на базе FTDI FT2232, только в нем еще и CPLD есть, что расширяет его возможности по сравнению с вышеупомянутыми аналогами. Кстати, такие отладчики используют в т. ч. в серьезных больших компаниях. Он просто работает, и особо развивать там нечего. Развиваться должен OpenOCD и другой софт, который с такими отладчиками (на FTDI) работает.
А по теме насчет серьезного недорогого отладчика, можно посмотреть на Segger J-Link EDU, J-Link BASE, только не уверен, что он поддерживает MIPSfpga.