Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Запись по базовому адресу пользовательской логики
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Acvarif
Имеется пользовательская логика с базовым адресом 0x00000010 подключенная к шине Avalon в SOPC
с портами
Код
    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_write_n       : in  std_logic                     := '0';             --      .write_n
        avs_s0_writedata     : in  std_logic_vector(15 downto 0) := (others => '0'); --      .writedata
        avs_s0_byteenable    : in  std_logic_vector(1 downto 0)     := (others => '0');
        avs_s0_readdata      : out std_logic_vector(15 downto 0);                    --      .readdata
        ins_irq0_irq             : out std_logic;    

        -- Avalon Source
        aso_out0_ready                     : in  std_logic                     := '0'; --      .ready
        aso_out0_data                      : out std_logic_vector(15 downto 0);        --  out0.data
        aso_out0_valid                     : out std_logic;                            --      .valid
......................................................и т. д.
В пользовательской логике имеется такая конструкция (VHDL)
Код
    process(clk)
    begin
    if (falling_edge(clk)) then
        if(avs_s0_address = "00" and avs_s0_write_n = '0') then
            if(avs_s0_writedata = "0000000000000001") then
                s_aso_out0_ready <= '1';
            elsif (avs_s0_writedata = "0000000000000000") then    
                s_aso_out0_ready <= '0';
            end if;    
        end if;    
    end if;        
    end process;

В программе Nios запись для установки s_aso_out0_ready в 1 делаю так
Код
#define IOWR_ALTERA_AVALON_PUSK(base)   IOWR_32DIRECT(base, 0, 0x0001);
#define IOWR_ALTERA_AVALON_STOP(base)   IOWR_32DIRECT(base, 0, 0x0000);

          IOWR_ALTERA_AVALON_PUSK(0x00000010);
          Delay(0x0002);
          IOWR_ALTERA_AVALON_STOP(0x00000010);
          Delay(0x000f);

Все работает.
Но как теперь сделать то же только по адресу avs_s0_address = "01" ?
Не врубаюсь, что теперь нужно менять в IOWR_ALTERA_AVALON_PUSK(base) IOWR_32DIRECT(base, 0, 0x0001);
смещение или базовый адрес...или еще как-то
Копейкин
Используется режим адресации DYNAMIC.
Вы пишите 32-битное слово, которое занимает диапазон адресов BASE+0 - BASE+3.
Адресация побайтная. Поэтому если вы желаете записать байт BASE+1, то нужно
использовать сигнал byteenable[1].
Если нужно смещение + одно 32-битное слово, то нужно записать:
IOWR_32DIRECT( base, 4, value );
alexPec
А он при компиляции не написал у вас (в синтезаторе, варнинг) про адреса подобное:

Warning: Output pins are stuck at VCC or GND
Warning (13410): Pin "HC_ETH_RESET_N" is stuck at VCC
Warning (13410): Pin "flash_ssram_a[1]" is stuck at GND
Warning (13410): Pin "flash_ssram_a[0]" is stuck at GND

Когда с 32 разрядами работаешь, бывает такое. может адреса стоит подцепить к более старшим (кстати а сейчас они куда подцеплены на шине, к а0,а1?)
А если все нормально, то адрес выставляете в base+свое значение адреса*4. Короче, лучше выровнять слова по 32-битной (4-х байтной) границе и не морочиться с BE
Acvarif
Цитата(Копейкин @ Dec 4 2012, 18:18) *
Используется режим адресации DYNAMIC.
Вы пишите 32-битное слово, которое занимает диапазон адресов BASE+0 - BASE+3.
Адресация побайтная. Поэтому если вы желаете записать байт BASE+1, то нужно
использовать сигнал byteenable[1].
Если нужно смещение + одно 32-битное слово, то нужно записать:
IOWR_32DIRECT( base, 4, value );

Не совсем понял
avs_s0_writedata : in std_logic_vector(15 downto 0)
слово у меня 16 битное
Тоесть в моей пользовательской лолгике (с базовым адресом 0x00000010) имеются 4 (четыре avs_s0_address : in std_logic_vector(1 downto 0)) 16 битных регистра.
В нулевой регистр все пишется непосредственно по базовому адресу. А как записать данные в первый...третий регистры? Как это будет выглядеть в коде Nios?
Цитата
Когда с 32 разрядами работаешь, бывает такое. может адреса стоит подцепить к более старшим (кстати а сейчас они куда подцеплены на шине, к а0,а1?)
А если все нормально, то адрес выставляете в base+свое значение адреса*4. Короче, лучше выровнять слова по 32-битной (4-х байтной) границе и не морочиться с BE

Пользовательский модуль подцеплен к s0.
Копейкин
Выглядеть будет так:
IOWR_16DIRECT( base, reg * 2, val);
где номер регистра reg = 0, 1, 2, 3...n
reg - 16-битный регистр.
Так как адресация процессора всё равно байтовая.
В железе младший адрес адресной шины будет выбран
автоматически, согласно разрядности шины данных.
Поэтому в железе смещение будет на 1.
reg0 - 0x00
reg1 - 0x01
reg2 - 0x02 ...
Acvarif
Цитата(Копейкин @ Dec 5 2012, 19:47) *
Выглядеть будет так:
IOWR_16DIRECT( base, reg * 2, val);
где номер регистра reg = 0, 1, 2, 3...n
reg - 16-битный регистр.
Так как адресация процессора всё равно байтовая.
В железе младший адрес адресной шины будет выбран
автоматически, согласно разрядности шины данных.
Поэтому в железе смещение будет на 1.
reg0 - 0x00
reg1 - 0x01
reg2 - 0x02 ...

Спасибо. Работает. Тоесть чтобы записать данные в пользовательский регистр 01 нужно выполнить IOWR_16DIRECT( base, 2, val);
не совсем понятны рассуждения.
Команда IOWR_16DIRECT( base, reg * 2, val); пишет данные val в 16 битный регистр по базовому адресу base со смещением относительно базового адреса на reg * 2
Тоесть если бы в пользовательской логике был регистр 8 разрядный то смещение нужно было-бы делать reg * 4 и команда должна быть IOWR_8DIRECT( base, 4, val);
. Это верно? Или все же reg + 4, а в предыдущем случае reg + 2?
Копейкин
Нужно просто уложить в голове, что у процессора адресация всегда побайтная.
А вот шина Avalon-MM использует в качестве самого младшего адреса для слейва:
8 бит - A[0]
16 бит - A[1]
32 бит - A[2]
Я привел пример для записи в 16-битный слейв, где смещение reg * 2,
так как A[0] не используется, а самый младший используемый адрес A[1].
Для 8-битного слейва (reg * 1) т.е. IOWR_8DIRECT( base, reg, val ).
Для 32-битного, соответственно (reg *4) т.е. IOWR_32DIRECT( base, reg*4, val).
Собственно макросы IOWR_ это ассемблерные команды STBIO, STHIO, STWIO (store byte/halfword/word in IO space)
Так яснее?
Acvarif
Цитата(Копейкин @ Dec 7 2012, 11:30) *
Нужно просто уложить в голове, что у процессора адресация всегда побайтная.
А вот шина Avalon-MM использует в качестве самого младшего адреса для слейва:
8 бит - A[0]
16 бит - A[1]
32 бит - A[2]
Я привел пример для записи в 16-битный слейв, где смещение reg * 2,
так как A[0] не используется, а самый младший используемый адрес A[1].
Для 8-битного слейва (reg * 1) т.е. IOWR_8DIRECT( base, reg, val ).
Для 32-битного, соответственно (reg *4) т.е. IOWR_32DIRECT( base, reg*4, val).
Собственно макросы IOWR_ это ассемблерные команды STBIO, STHIO, STWIO (store byte/halfword/word in IO space)
Так яснее?

Спасибо. Понятно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.