Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача данных из fpga в nios
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
_Anatoliy
Коллеги, я сначала передавал данные(содержимое нескольких регистров 16 бит) через PIO и всё было нормально. Но у заказчика аппетит растёт, проект развивается и уже делать десятки PIO вроде как нехорошо. Для записи я использую параллельную шину данных + шина адреса , прекрасно работает, прописываю таким образом десятки регистров по всему проекту. Вот бы так и для чтения соорудить интерфейс. Единственное что смущает - Z-состояние на выходе невыбранных регистров. Как решаете подобную задачу? Наверняка есть отработанное решение...
Realking
Цитата(_Anatoliy @ Nov 28 2017, 13:26) *
Коллеги, я сначала передавал данные(содержимое нескольких регистров 16 бит) через PIO и всё было нормально. Но у заказчика аппетит растёт, проект развивается и уже делать десятки PIO вроде как нехорошо. Для записи я использую параллельную шину данных + шина адреса , прекрасно работает, прописываю таким образом десятки регистров по всему проекту. Вот бы так и для чтения соорудить интерфейс. Единственное что смущает - Z-состояние на выходе невыбранных регистров. Как решаете подобную задачу? Наверняка есть отработанное решение...


Добавь в Qsys Avalon-MM Pipeline Bridge

через него и записать и прочитать можешь

в описании будет типа такого (System Verilog)

// FPGA IO Regs
.mm_ioreg_waitrequest(1'b0),
.mm_ioreg_byteenable(cpu_byteenable),
.mm_ioreg_address(cpu_address),
.mm_ioreg_read(cpu_read),
.mm_ioreg_readdata(cpu_readdata),
.mm_ioreg_readdatavalid(cpu_readdatavalid),
.mm_ioreg_write(cpu_write),
.mm_ioreg_writedata(cpu_writedata),
.mm_ioreg_burstcount(),
.mm_ioreg_debugaccess(),

для чтения (у меня 64 разрядная шина)

bit [2047:0] [7:0] ioreg_input;
assign ioreg_input = FPGA_Status_Registers;

always_ff @(posedge g_clk_100MHz, negedge g_reset_n) begin
if (!g_reset_n) begin
cpu_readdata <= '0;
cpu_readdatavalid <= 1'b0;
end
else begin
cpu_readdatavalid <= cpu_read;
cpu_readdata <= {
ioreg_input[{cpu_address, 3'b111}],
ioreg_input[{cpu_address, 3'b110}],
ioreg_input[{cpu_address, 3'b101}],
ioreg_input[{cpu_address, 3'b100}],
ioreg_input[{cpu_address, 3'b011}],
ioreg_input[{cpu_address, 3'b010}],
ioreg_input[{cpu_address, 3'b001}],
ioreg_input[{cpu_address, 3'b000}]
};
end
end

FPGA_Status_Registers - структура
_Anatoliy
Цитата(Realking @ Nov 28 2017, 14:07) *

Спасибо! Из описания пока не понял - ему пофигу Z-состояние на входе?
Realking
если альтера то там нет Z состояний
или я не правильно понял, и регистры вне ПЛИС?

в ниос определяешь

FPGA_Status_Registers* mFPGA_Status_Registers = (FPGA_Status_Registers*)(IO_REG_BASE + 0x80000000);

0x80000000 - для отключения хэширования
_Anatoliy
Цитата(Realking @ Nov 28 2017, 14:44) *
если альтера то там нет Z состояний
или я не правильно понял, и регистры вне ПЛИС?

в ниос определяешь

FPGA_Status_Registers* mFPGA_Status_Registers = (FPGA_Status_Registers*)(IO_REG_BASE + 0x80000000);

0x80000000 - для отключения хэширования

1). Для определения какой хедер нужно подключить?
2). Как на одну входную шину бриджа подключить выходы например 20-ти регистров?
Realking
Цитата(_Anatoliy @ Nov 28 2017, 14:55) *
1). Для определения какой хедер нужно подключить?
2). Как на одну входную шину бриджа подключить выходы например 20-ти регистров?


1.
system.h

там адрес этого бриджа

2. можно так (если регистры 32 разрядные например)

bit [2047:0] [7:0] ioreg_input;

assign ioreg_input[3:0] = reg0;
assign ioreg_input[7:4] = reg1;
assign ioreg_input[11:8] = reg2;

и тд

а уж выбор делается тут

always_ff @(posedge g_clk_100MHz, negedge g_reset_n) begin
if (!g_reset_n) begin
cpu_readdata <= '0;
cpu_readdatavalid <= 1'b0;
end
else begin
cpu_readdatavalid <= cpu_read;
cpu_readdata <= {
ioreg_input[{cpu_address, 3'b111}],
ioreg_input[{cpu_address, 3'b110}],
ioreg_input[{cpu_address, 3'b101}],
ioreg_input[{cpu_address, 3'b100}],
ioreg_input[{cpu_address, 3'b011}],
ioreg_input[{cpu_address, 3'b010}],
ioreg_input[{cpu_address, 3'b001}],
ioreg_input[{cpu_address, 3'b000}]
};
end
end

или

always_ff @(posedge g_clk_100MHz, negedge g_reset_n) begin
if (!g_reset_n) begin
cpu_readdata <= '0;
cpu_readdatavalid <= 1'b0;
end
else begin
cpu_readdatavalid <= cpu_read;

if (cpu_address == 0) cpu_readdata <= reg0;
else if (cpu_address == 1) cpu_readdata <= reg1;
...
end
end
_Anatoliy
Цитата(Realking @ Nov 28 2017, 15:01) *
1.
system.h

там адрес этого бриджа

Спасибо, туплю.
2. можно так (если регистры 32 разрядные например)

Цитата(Realking @ Nov 28 2017, 15:01) *
always_ff @(posedge g_clk_100MHz, negedge g_reset_n) begin
if (!g_reset_n) begin
cpu_readdata <= '0;
cpu_readdatavalid <= 1'b0;
end
else begin
cpu_readdatavalid <= cpu_read;

if (cpu_address == 0) cpu_readdata <= reg0;
else if (cpu_address == 1) cpu_readdata <= reg1;
...
end
end

Не ну с мультиплексором понятно, т.е. я ничего не выиграю. Ведь тоже самое можно сделать и с PIO. У меня регистры на разных уровнях иерархии по всему проекту разбросаны, это с каждого регистра тянуть шину к мультиплексору? При записи по проекту просто идёт шина и на неё вешается столько регистров, сколько потребуется. Так же хочется и при чтении. Т.е. нужен некий распределённый мультиплексор. Так не получится?
На ум приходит только последовательное включение мультиплексоров, но это тоже не сахар.
Realking
Цитата(_Anatoliy @ Nov 28 2017, 15:24) *
Спасибо, туплю.
2. можно так (если регистры 32 разрядные например)


Не ну с мультиплексором понятно, т.е. я ничего не выиграю. Ведь тоже самое можно сделать и с PIO. У меня регистры на разных уровнях иерархии по всему проекту разбросаны, это с каждого регистра тянуть шину к мультиплексору? При записи по проекту просто идёт шина и на неё вешается столько регистров, сколько потребуется. Так же хочется и при чтении. Т.е. нужен некий распределённый мультиплексор. Так не получится?


понятно...

тогда, если разбросаны)) сделайте с Z состоянием (синтезатор их сам должен преобразовать в мультиплексор)

с PIO просто код на С не красивый получается (а с бриджом эти регистры как память)
_Anatoliy
Цитата(Realking @ Nov 28 2017, 15:29) *
понятно...

тогда, если разбросаны)) сделайте с Z состоянием (синтезатор их сам должен преобразовать в мультиплексор)

с PIO просто код на С не красивый получается (а с бриджом эти регистры как память)

Почему?
Код
        Write2BusFpga(ADR_SET_BAND,band);

Но это дело вкуса.
Большое спасибо за консультацию. Буду пробовать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.