реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Создание компонета для SOPC Builder с несколькими регистрами ввода/вывода
Копейкин
сообщение Aug 20 2012, 11:48
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Макро IORD(base, n) применяется при адресации типа NATIVE
Если адресация DYNAMIC (рекомендованая), то макро IORD32_DIRECT(BASE, OFFSET)
см. файл project_bsp\HAL\io.h там описываются эти макросы.
Адрес пользуешь из system.h?
Сигнал чтения должен активироваться.
Смотришь через SignalTap? Советую его пользовать.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 20 2012, 12:35
Сообщение #17


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Копейкин @ Aug 20 2012, 14:48) *
Макро IORD(base, n) применяется при адресации типа NATIVE
Смотришь через SignalTap? Советую его пользовать.


SignalTap загружает проект. Хотелось бы увидеть сигналы вживую.

Поставил
Код
#define IORD_ALTERA_AVALON_RAM_1(base)  IORD_16DIRECT(base, 1);

В основном цикле просто читаю RAM
Код
ramres=IORD_ALTERA_AVALON_RAM_1(RAMTEST_0_BASE);

Цитата
Адрес пользуешь из system.h?
Сигнал чтения должен активироваться.

Да, адрес компонента (system.h)
CODE
#define RAMTEST_0_NAME "/dev/ramtest_0"
#define RAMTEST_0_TYPE "ramtest"
#define RAMTEST_0_BASE 0x00000010
#define RAMTEST_0_SPAN 8
#define RAMTEST_0_TERMINATED_PORTS ""
#define ALT_MODULE_CLASS_ramtest_0 ramtest

Если у меня на Avalon MM Slave
CODE
port (
-- Avalon Slave
clk : in std_logic := '0'; -- clock.clk
reset_n : in std_logic := '0'; -- .reset_n
avs_s0_address : in std_logic_vector(1 downto 0) := (others => '0'); -- s0.address
avs_s0_read_n : in std_logic := '0'; -- .read_n
avs_s0_readdata : out std_logic_vector(15 downto 0); -- .readdata
avs_s0_write_n : in std_logic := '0'; -- .write_n
avs_s0_writedata : in std_logic_vector(15 downto 0) := (others => '0'); -- .writedata
avs_s0_chipselect : in std_logic := '0'; -- .chipselect

то какой из портов можно наблюдать на осциляторе (если вывести его наружу) при выполнении команды IORD_ALTERA_AVALON_RAM_1(RAMTEST_0_BASE)?
Никак не пойму почему простая команда, например IORD_16DIRECT(base, 1) со стороны Nios не активирует ни один из сигналов Avalon MM Slave?

Сообщение отредактировал Acvarif - Aug 20 2012, 12:50
Go to the top of the page
 
+Quote Post
Копейкин
сообщение Aug 20 2012, 13:36
Сообщение #18


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Вы должны увидеть активацию сигналов
avs_s0_read_n (активный 0 ?) и
avs_s0_chipselect (активный 1 ?)

Уже при 50MHz тактовой частоты нужен хороший осциллограф, чтобы увидеть импульсы,
поэтому я и рекомендовал SignalTap.
--------
#define RAMTEST_0_BASE 0x00000010
Подозрительно маленький адрес. Автораспределение адресов в SOPC builder?
Можно скриншот системы, c соединениями шин?

Сообщение отредактировал Копейкин - Aug 20 2012, 13:40
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 20 2012, 14:04
Сообщение #19


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Копейкин @ Aug 20 2012, 16:36) *
Вы должны увидеть активацию сигналов
avs_s0_read_n (активный 0 ?) и
avs_s0_chipselect (активный 1 ?)

Уже при 50MHz тактовой частоты нужен хороший осциллограф, чтобы увидеть импульсы,
поэтому я и рекомендовал SignalTap.
--------
#define RAMTEST_0_BASE 0x00000010
Подозрительно маленький адрес. Автораспределение адресов в SOPC builder?
Можно скриншот системы, c соединениями шин?

Понял. Спасибо.
Активация имеется.
Хорошо, как тогда активировать-деактивировать сигналы программно в цикле? (чтобы увидеть что процесс работает)
Прикрепленное изображение

С памятью что-то пока не выходит. Попробую создать простой компонент Avalon MM Slave с одним регистром для чтения.
При компиляции проекта в Nios создается файл alt_sys_init.c в котором имеется
Код
ETH_OCM_INSTANCE( ETH_OCM_0, eth_ocm_0 );
ALTERA_AVALON_UART_INSTANCE( UART_0, uart_0 );
ALTERA_AVALON_TIMER_INSTANCE( TIMER_0, timer_0 );
//RAMTEST_INSTANCE( RAMTEST_0, ramtest_0 );
//SD_CONTROLLER_INSTANCE( SD_CONTROLLER_0, sd_controller_0 );

/*
* Initialise the devices
*
*/

void alt_sys_init( void )
{
    ALTERA_AVALON_TIMER_INIT( TIMER_0, timer_0 );
    ETH_OCM_INIT( ETH_OCM_0, eth_ocm_0 );
    ALTERA_AVALON_UART_INIT( UART_0, uart_0 );
//    RAMTEST_INIT( RAMTEST_0, ramtest_0 );
//    SD_CONTROLLER_INIT( SD_CONTROLLER_0, sd_controller_0 );
}


Строки
Код
//    RAMTEST_INIT( RAMTEST_0, ramtest_0 );
//    SD_CONTROLLER_INIT( SD_CONTROLLER_0, sd_controller_0 );

выдают ошибку. Приходся их комментить.
Откуда это берется и зачем?

Сообщение отредактировал Acvarif - Aug 20 2012, 14:12
Go to the top of the page
 
+Quote Post
Копейкин
сообщение Aug 20 2012, 16:51
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Вы имеете в виду, что сигналы avs_s0_read_n & avs_s0_chipselect всегда в активном состоянии?
Если так, то это неправильно.
Может создать простой проект без SD и Ethernet контроллеров и отладить память?

Функции RAMTEST_INIT и SD_CONTROLLER_INIT создаются разработчиком компонентов и
относятся к драйверам компонента (каталоги ..\ip\DevName\HAL\inc , ..\ip\DevName\HAL\src)
Их наличие или отсутствие задаётся в devname_sw.tcl.
Про это есть есть отдельные главы (создание компонентов и драйверов) в документации
NiosII Software Developer's Handbook \ Section2 \ SubChapter7 "Developing Device Driver for HAL".

Еще, у Вас довольно много компонентов на шине, может их следует разделить через pipeline_bridge.
Иначе падает максимальная допустимая частота шины... и возможны всякие чудеса.
У Вас TimeQuest при компиляции не говорит: "Timing requirements not met."?
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 20 2012, 17:27
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Копейкин @ Aug 20 2012, 19:51) *
Вы имеете в виду, что сигналы avs_s0_read_n & avs_s0_chipselect всегда в активном состоянии?
Если так, то это неправильно.
Может создать простой проект без SD и Ethernet контроллеров и отладить память?

Я поторопился. По поводу активации надо будет еще проверить.
CD уберу. Ethernet не мешает.
Цитата
У Вас TimeQuest при компиляции не говорит: "Timing requirements not met."?
С этим все впорядке.

Код
Функции RAMTEST_INIT и SD_CONTROLLER_INIT создаются разработчиком компонентов и
относятся к драйверам компонента (каталоги ..\ip\DevName\HAL\inc , ..\ip\DevName\HAL\src)
Их наличие или отсутствие задаётся в devname_sw.tcl.
Про это есть есть отдельные главы (создание компонентов и драйверов) в документации
NiosII Software Developer's Handbook \ Section2 \ SubChapter7 "Developing Device Driver for HAL".
Спасибо. Все понятно. Значит перед компиляцией можно закомментить даже в sd_controller_sw.tcl и др.
Типа:
Код
# Initialize the driver in alt_sys_init()
# set_sw_property auto_initialize true

Попробую упростить компонент и проект...

Сообщение отредактировал Acvarif - Aug 20 2012, 17:29
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 21 2012, 08:07
Сообщение #22


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Вроде получилось.
Для того, чтобы пронаблюдать на осцилляторе сигналы чтения avs_s0_read_n, avs_s0_chipselect
пришлось их просто затянуть, примерно так
CODE
process(clk)
begin
if (falling_edge(clk)) then
if(avs_s0_read_n = '0') then
avs_s0_read_n_ext_reg <= '0';
avs_s0_read_n_ext_fl <= '1';
end if;
if(avs_s0_read_n_ext_fl = '1') then
avs_s0_read_n_ext_cnt <= avs_s0_read_n_ext_cnt + 1;
end if;
if(avs_s0_read_n_ext_cnt = "11111111") then
avs_s0_read_n_ext_fl <= '0';
avs_s0_read_n_ext_reg <= '1';
end if;
if(avs_s0_chipselect = '1') then
avs_s0_chipselect_ext_reg <= '1';
avs_s0_chipselect_ext_fl <= '1';
end if;
if(avs_s0_chipselect_ext_fl = '1') then
avs_s0_chipselect_ext_cnt <= avs_s0_chipselect_ext_cnt + 1;
end if;
if(avs_s0_read_n_ext_cnt = "11111111") then
avs_s0_chipselect_ext_fl <= '0';
avs_s0_chipselect_ext_reg <= '0';
end if;
end if;
end process;

-- внешний контроль сигналов
avs_s0_read_n_ext <= avs_s0_read_n_ext_reg;
avs_s0_chipselect_ext <= avs_s0_chipselect_ext_reg;

При этом IORD и IORD_32DIRECT внешне (по сигналам avs_s0_read_n, avs_s0_chipselect) работают одинаково
Теперь остается прописать нормальный механизм чтения данных на Avalon MM Slave из пользовательской двухпортовой памяти .
Можно в нескольких словах, как организовать механизм чтения по прерыванию от пользовательской логики?
Go to the top of the page
 
+Quote Post
Копейкин
сообщение Aug 21 2012, 10:35
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Добавляете интерфейс Interrupt sender.
У Вас добавится прерывание, которое в SOPC билдере нужно будет подключить к процессору.
В пользовательской логике предусмотреть посылку прерывания уровнем или импульсом.
Чтение/запись как обычно Avalon MM...
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 21 2012, 11:10
Сообщение #24


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Копейкин @ Aug 21 2012, 13:35) *
Добавляете интерфейс Interrupt sender.
У Вас добавится прерывание, которое в SOPC билдере нужно будет подключить к процессору.
В пользовательской логике предусмотреть посылку прерывания уровнем или импульсом.
Чтение/запись как обычно Avalon MM...

Спасибо. Получилось
Прикрепленное изображение

Чем может грозить предупреждение?
Warning: cpu_0.data_master/ramtest_0.s0: ramtest_0.s0 does not have byteenables. Narrow (less than 32-bit) writes from cpu_0.data_master will result in spurious writes to ramtest_0.s0



Сообщение отредактировал Acvarif - Aug 21 2012, 11:13
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 22 2012, 10:13
Сообщение #25


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Почитал немного букварь "Avalon Interface Specification".
Прописал нормально механизм чтения из RAM на Avalon.
Чтение из RAM пошло.
Но пока какая-то путаница с адресами.
Если я определяю
Код
#define IORD_ALTERA_AVALON_RAM_0(base)  IORD_16DIRECT(base, 0);
#define IORD_ALTERA_AVALON_RAM_1(base)  IORD_16DIRECT(base, 1);
#define IORD_ALTERA_AVALON_RAM_2(base)  IORD_16DIRECT(base, 2);
#define IORD_ALTERA_AVALON_RAM_3(base)  IORD_16DIRECT(base, 3);

то надеюсь, что IORD_ALTERA_AVALON_RAM_0(base) прочитает данные по базовому адресу без смещения (по нулевому адресу RAM) - таки так оно и есть.
далее надеюсь, что IORD_ALTERA_AVALON_RAM_1(base) прочитает данные по адресу базовый плюс 1- а реально читаются данные опять по нулевому адресу RAM.
И только IORD_ALTERA_AVALON_RAM_2(base) читает данные по первому адресу RAM. IORD_ALTERA_AVALON_RAM_3(base) тоже читает данные по первому адресу RAM.
В чем тут хитрость?
Go to the top of the page
 
+Quote Post
Копейкин
сообщение Aug 22 2012, 13:31
Сообщение #26


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Предупреждение предупреждает (о как), что устройство не имеет сигнала выбора байта и поэтому,
при записи данных шириной меньше полного слова будут изменены соседние байты.
Почитайте про режимы адресации.
Авалон будет читать целое слово, в вашем случае шириной 32 бита.
Поэтому чтение со смещением в 2 байта, приведёт к чтению всё того же 32-битного слова.

Сообщение отредактировал Копейкин - Aug 22 2012, 13:32
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 22 2012, 14:13
Сообщение #27


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Копейкин @ Aug 22 2012, 16:31) *
Предупреждение предупреждает (о как), что устройство не имеет сигнала выбора байта и поэтому,
при записи данных шириной меньше полного слова будут изменены соседние байты.
Почитайте про режимы адресации.
Авалон будет читать целое слово, в вашем случае шириной 32 бита.
Поэтому чтение со смещением в 2 байта, приведёт к чтению всё того же 32-битного слова.

Спасибо. Понял.
Чтение заработало нормально.
Перешел к прерываниям (от внешней кнопки).
Прерывание срабатывает, но на нем и виснет (не выходит из подпрограммы прерываний)
По аналогии с микроконтроллерами полагал, что какой-то флаг прерывания должен автоматом сброситься при входе в обработчик.
Получается не не так.
Если в двух словах, то как?

Go to the top of the page
 
+Quote Post
Копейкин
сообщение Aug 22 2012, 15:24
Сообщение #28


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Нет, автоматом не сбрасывается.
Ты должен иметь свой триггер, который устанавливается железом
и сбрасывается программой (например, чтением регистра).
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Aug 23 2012, 06:30
Сообщение #29


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Копейкин @ Aug 22 2012, 18:24) *
Нет, автоматом не сбрасывается.
Ты должен иметь свой триггер, который устанавливается железом
и сбрасывается программой (например, чтением регистра).

Спасибо. Понял.
Читаю мануалы. Пытаюсь найти простейший пример (программный и аппаратный) реализации обработки прерывания от
пользовательской логики. Пока ничего путного не нашел.
Также не ясен момент (нигде пока не нашел) как устанавливается как должно срабатывать прерывание (уровень, фронт, спад)
В пользовательской логике формирую просто короткий положительный импульс. Вроде и сбрасывать в этом случае ничего не надо.
В программе вход в обработчик имеется, но выхода из него нет - виснет на обработчике.
В программе при инициализации системы регистрирую обработчик так
Код
alt_irq_register(RAMTEST_0_IRQ, (void*)RAMTEST_0_BASE, ramtest_isr);

Сам обработчик
CODE
// Обработчик прерываний RAMTEST_0_IRQ
static void ramtest_isr()
{
Start == 0;
int ramresult;
char uramresult[10] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x00};

ramresult=IORD_ALTERA_AVALON_RAM_0(RAMTEST_0_BASE);
uramresult[1] = ramresult;
uramresult[0] = ramresult >> 8;
.... и т. д.
}
Если можно в коротком примере как должно быть правильно так, чтобы обработчик по фронту от пользовательской логики выполнил свою задачу однократно и не зависал.?

Сообщение отредактировал Acvarif - Aug 23 2012, 06:31
Go to the top of the page
 
+Quote Post
Копейкин
сообщение Aug 23 2012, 09:05
Сообщение #30


Частый гость
**

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



У меня примера под рукой нет, но когда разбирался, то отложилось в памяти так:
1) Интерфейс Interrupt sender даёт нам линии irq или irq_n, которые работают по уровню, не фронту.
Выбрали, допустим irq - срабатывает на уровень "1".
2) Ставим на линию irq триггер.
3) Триггер взводится в "1" Вашим событием (кнопка, счётчик...)
4) Программа в обработчике прерывания ОБЯЗАТЕЛЬНО должна этот триггер сбросить в "0",
иначе из прерывания не выйти. Сбросить можно чтением или записью по адресу, как Вам удобно.
Вот таким образом.

Есть ещё компонент - векторизируемый контроллер прерываний - он даёт возможностей побогаче,
более предсказуемое время входа в прерывание, но требует существенных ресурсов, для реализации.
С ним не разбирался - так, обзорно...

Сообщение отредактировал Копейкин - Aug 23 2012, 09:08
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 6th July 2025 - 11:30
Рейтинг@Mail.ru


Страница сгенерированна за 0.01524 секунд с 7
ELECTRONIX ©2004-2016