Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Cyclone V SoC + DDR3
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Serb1987
Добрый день, есть борда с циклоном 5 на борту, нужно получить доступ к памяти, но на этой борде память расположена со стороны процессорного модуля (HPS), а получить доступ нужно из логики, подскажите пожалуйста как лучше поступить или откуда копать необходимую инфу?
warrior-2001
По новым чипам самая лучшае инфа - это мануал разработчика чипа.
Тут как раз находится такая инфа.
untone
Цитата(Serb1987 @ Feb 19 2014, 13:00) *
Добрый день, есть борда с циклоном 5 на борту, нужно получить доступ к памяти, но на этой борде память расположена со стороны процессорного модуля (HPS), а получить доступ нужно из логики, подскажите пожалуйста как лучше поступить или откуда копать необходимую инфу?



Из FPGA можно получить доступ к SDRAM через специальный мост FPGA2SDRAM он отпирается в Qsys в окне настройки HPS
Serb1987
Спасибо, и далее нужно писать свой кусок Авалон-ММ мастер, я правильно понимаю?
Kuzmi4
2 Serb1987
правильно,
и мне помнится там надо ещё в HPS армом снять ресет с этого порта.
Serb1987
Благодарю, у меня еще вопрос, у меня есть проект который написан на VHDL в Quartus, но мне нужно получить доступ к DDR3 на стороне HPS, как мне поступить, работать в Qsys и влепить туда проект из Quartus или наоборот? Пробовал последний вариант но не знаю как подключить ноги физической памяти к сигналам mem_*.
Kuzmi4
2 Serb1987
вырезать DDR3, а вместо него засандалить HPS.
То есть пересобрать его в Qsys а вместо DDR3 поставить HPS. Ну и не забыть что надо будет какой то простецкий код в арм залить wink.gif
А на счтё подключения ног - это вам быстрее в мануале или юзер-гиде почитать как простые примерчики собираются на вашу борду.
Serb1987
Добрый день, пока толкового ничего не нашел, поэтому прошу помощи у комьюнити, при подключении DDR3 как описано выше, запустил скрипт *pin_assignments.tcl, но после компиляции все равно есть ошибки о неподключенных пинах внешней памяти, и нет возможности ее подключить в пин планнере, как быть?
Kuzmi4
2 Serb1987
Так у вас DDR3 где - в HS или в PL?
Serb1987
DDR3 на стороне HPS, а нужно получить доступ со стороны FPGA, мосты FPGA2HPS сконфигурил, подключил memory controller в виде IP (*.qip) в проекте Квартуса, даже компилится но говорит "Critical Warning (169085): No exact pin location assignment(s) for 150 pins of 152 total pins" то есть не видит пинов ног которые нужно подклюсить к физической памяти

Kuzmi4
2 Serb1987
Если у вас DDR3 на стороне HS, значит там оно само все лапы назначит, у него жёсткая привязка по ногам для DDR и её делает сам квартус на основании информации о чипе.
Скрипт нужен только для того чтобы внутренние констрейны правильно задать, типа:
Код
...
set_instance_assignment -name PACKAGE_SKEW_COMPENSATION OFF -to memory_mem_a[0] -tag __hps_sdram_p0
...
set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to hps_system_1|hps_0|hps_io|border|hps_sdram_inst|pll0|fbout -tag __hps_sdram_p0
...
Serb1987
тоесть на критикал ворнинги можно не смотреть, мол ноги не подключены и все такое?

Вопрос вдогонку, может я вообще не правильно понял, установив IP(DDR3.qip) модуль как отдельный компонент проекта, из которого торчат ноги для физического подключения памяти и ноги для F2H моста, то ноги для памяти я вывожу как интерфейс всего проекта, а F2H ноги использую как внутренние для авалон протокола, верно?
Kuzmi4
Цитата(Serb1987 @ Jun 2 2014, 11:38) *
тоесть на критикал ворнинги можно не смотреть, мол ноги не подключены и все такое?

нет, если есть неподключенные ноги, значит надо разбираться.

касательно
Цитата(Serb1987 @ Jun 2 2014, 11:38) *
..Вопрос вдогонку...

У вас есть ваша Qsys система, в ней есть ваши PL модули и PS система, в PS системе есть компонент SDRAM. Ну и дальше..
Смотрите скриншот:
Нажмите для просмотра прикрепленного файла
Serb1987
В Qsys уже все настроено и создан IP компонент, который потом вставлен в quartus как отдельный компонент.


entity TVS is
-- generic (
-- );
Port (clk : in STD_LOGIC;

DDR3_mem_a : out std_logic_vector(14 downto 0); -- mem_a
DDR3_mem_ba : out std_logic_vector(2 downto 0); -- mem_ba
DDR3_mem_ck : out std_logic; -- mem_ck
DDR3_mem_ck_n : out std_logic; -- mem_ck_n
DDR3_mem_cke : out std_logic; -- mem_cke
DDR3_mem_cs_n : out std_logic; -- mem_cs_n
DDR3_mem_ras_n : out std_logic; -- mem_ras_n
DDR3_mem_cas_n : out std_logic; -- mem_cas_n
DDR3_mem_we_n : out std_logic; -- mem_we_n
DDR3_mem_reset_n : out std_logic; -- mem_reset_n
DDR3_mem_dq : inout std_logic_vector(31 downto 0) := (others => 'X'); -- mem_dq
DDR3_mem_dqs : inout std_logic_vector(3 downto 0) := (others => 'X'); -- mem_dqs
DDR3_mem_dqs_n : inout std_logic_vector(3 downto 0) := (others => 'X'); -- mem_dqs_n
DDR3_mem_odt : out std_logic; -- mem_odt
DDR3_mem_dm : out std_logic_vector(3 downto 0); -- mem_dm
DDR3_oct_rzqin : in std_logic := 'X' -- oct_rzqin
);
end TVS;

architecture Behavioral of TVS is

component ddr3_controller is
port (
memory_mem_a : out std_logic_vector(14 downto 0); -- mem_a
memory_mem_ba : out std_logic_vector(2 downto 0); -- mem_ba
memory_mem_ck : out std_logic; -- mem_ck
memory_mem_ck_n : out std_logic; -- mem_ck_n
memory_mem_cke : out std_logic; -- mem_cke
memory_mem_cs_n : out std_logic; -- mem_cs_n
memory_mem_ras_n : out std_logic; -- mem_ras_n
memory_mem_cas_n : out std_logic; -- mem_cas_n
memory_mem_we_n : out std_logic; -- mem_we_n
memory_mem_reset_n : out std_logic; -- mem_reset_n
memory_mem_dq : inout std_logic_vector(31 downto 0) := (others => 'X'); -- mem_dq
memory_mem_dqs : inout std_logic_vector(3 downto 0) := (others => 'X'); -- mem_dqs
memory_mem_dqs_n : inout std_logic_vector(3 downto 0) := (others => 'X'); -- mem_dqs_n
memory_mem_odt : out std_logic; -- mem_odt
memory_mem_dm : out std_logic_vector(3 downto 0); -- mem_dm
memory_oct_rzqin : in std_logic := 'X'; -- oct_rzqin
hps_0_f2h_sdram0_data_address : in std_logic_vector(29 downto 0) := (others => 'X'); -- address
hps_0_f2h_sdram0_data_burstcount : in std_logic_vector(7 downto 0) := (others => 'X'); -- burstcount
hps_0_f2h_sdram0_data_waitrequest : out std_logic; -- waitrequest
hps_0_f2h_sdram0_data_writedata : in std_logic_vector(31 downto 0) := (others => 'X'); -- writedata
hps_0_f2h_sdram0_data_byteenable : in std_logic_vector(3 downto 0) := (others => 'X'); -- byteenable
hps_0_f2h_sdram0_data_write : in std_logic := 'X'; -- write
reset_bridge_0_out_reset_reset : out std_logic; -- reset
clock_bridge_0_in_clk_clk : in std_logic := 'X' -- clk
);
end component ddr3_controller;

begin

u0 : component ddr3_controller
port map (
--clk_clk => DDR3_clk, -- clk.clk
--reset_reset_n => DDR3_reset_reset_n, -- reset.reset_n
memory_mem_a => DDR3_mem_a, -- memory.mem_a
memory_mem_ba => DDR3_mem_ba, -- .mem_ba
memory_mem_ck => DDR3_mem_ck, -- .mem_ck
memory_mem_ck_n => DDR3_mem_ck_n, -- .mem_ck_n
memory_mem_cke => DDR3_mem_cke, -- .mem_cke
memory_mem_cs_n => DDR3_mem_cs_n, -- .mem_cs_n
memory_mem_ras_n => DDR3_mem_ras_n, -- .mem_ras_n
memory_mem_cas_n => DDR3_mem_cas_n, -- .mem_cas_n
memory_mem_we_n => DDR3_mem_we_n, -- .mem_we_n
memory_mem_reset_n => DDR3_mem_reset_n, -- .mem_reset_n
memory_mem_dq => DDR3_mem_dq, -- .mem_dq
memory_mem_dqs => DDR3_mem_dqs, -- .mem_dqs
memory_mem_dqs_n => DDR3_mem_dqs_n, -- .mem_dqs_n
memory_mem_odt => DDR3_mem_odt, -- .mem_odt
memory_mem_dm => DDR3_mem_dm, -- .mem_dm
memory_oct_rzqin => DDR3_oct_rzqin -- .oct_rzqin
-- hps_0_f2h_sdram0_data_address => CONNECTED_TO_hps_0_f2h_sdram0_data_address, -- hps_0_f2h_sdram0_data.address
-- hps_0_f2h_sdram0_data_burstcount => CONNECTED_TO_hps_0_f2h_sdram0_data_burstcount, -- .burstcount
-- hps_0_f2h_sdram0_data_waitrequest => CONNECTED_TO_hps_0_f2h_sdram0_data_waitrequest, -- .waitrequest
-- hps_0_f2h_sdram0_data_writedata => CONNECTED_TO_hps_0_f2h_sdram0_data_writedata, -- .writedata
-- hps_0_f2h_sdram0_data_byteenable => CONNECTED_TO_hps_0_f2h_sdram0_data_byteenable, -- .byteenable
-- hps_0_f2h_sdram0_data_write => CONNECTED_TO_hps_0_f2h_sdram0_data_write, -- .write
-- reset_bridge_0_out_reset_reset => CONNECTED_TO_reset_bridge_0_out_reset_reset, -- reset_bridge_0_out_reset.reset
-- clock_bridge_0_in_clk_clk => CONNECTED_TO_clock_bridge_0_in_clk_clk -- clock_bridge_0_in_clk.clk
);
.....
Kuzmi4
2 Serb1987
Тогда проект в студию, надо смотреть на логи..
Serb1987
Вроде бы потихоньку решается вопрос, только приходится вручную писать файл *pin_locations.tcl и запускать его перед компиляцией проекта. "set_location_assignment PIN_G23 -to DDR3_mem_a[14]" вот самый простой пример описания нужного пина. После этого в пин планнере этот пин стал отображаться и такая строка появилась в .qsf файле.
Kuzmi4
2 Serb1987
в моём SoCkit - PS mem_a[14] находится в "H25" и эту лапу нельзя назначить для PL (Q2 v13.0sp1)
Нажмите для просмотра прикрепленного файла
Serb1987
У меня ноги прописаны по мануалу для моей борды(Helio CycloneVSoC), при чем изначально из пин планнера нельзя было назначить данные ноги, только после компиляции проекта в графе "Fitter location" им автоматически было присвоено назначение, при чем правильное, а вот графа "location" была пуста, пока я не создал и скомпилил необходимый файлик.
Нажмите для просмотра прикрепленного файла
warrior-2001
Не хочется писать много букв. Отвечу просто - скачайте проекты для любого кита альтеровского с 5 Циклоном. Там всё правильно настроено и для ddr3 со стороны процессора, и для ddr3 со стороны ПЛИС. Я на основе такого проекта все быстро подключил и в ките все заработало!

Для кита Altera этот проект называется cv_soc_devkit_ghrd. Качать можно у альтеры.
Serb1987
Подскажите пожалуйста еще один момент, я сделал так как советовал warrior-2001, добавил свои компоненты в проект, в том числе и PLL (Quartus, Mega-wizard), теперь при запуске системы PLL просто не запускается, в чем могут быть причины конфликта?
Serb1987
Еще раз обращаюсь к общественности за помощью, теперь вопрос касательно моста FPGA-to-HPS а именно шины Avalon-MM. Я пытаюсь записывать и вычитывать из памяти посредством собственного Авалон мастера(вернее 2-х, на запись и на чтение), так вот меня интересует почему waitrequest может все время висеть в 1, и не давать возможности произвести какие либо манипуляции с шиной. Заранее спасибо за помощь.
tvcam
Для обменя с памятью, я использую FPGA-to-HPS SDRAM Interfase. Два канала на чтение, один на запись. К одиному подключен стандартный DMA Avalon, на два других подключены мастера, проблемм нет, скорость очень большая. Сигнал waitrequest выставляется буквально на несколько (3-4) тактов при запуске, и после пересылки большого массива тоже на несколько тактов. Только SDRAM Interfase минимум 32 бита. У меня не получилось запустить обмен без "Burst transactions".
Serb1987
Я точно так же использую FPGA-to-HPS SDRAM Interfase, только 6 каналов (3 на запись, 3 на чтение), и не бёрстами, а поэлементно, только я не понял какое значение должно быть у burstcount если я пишу данные поэлементно шириной 32 бита?
tvcam
Я использую http://www.altera.com/support/examples/nio...-avalon-mm.html там есть возможность отключить burst, когда я отключил у меня не заработало, я не встал разбираться, а включил обратно.
Serb1987
Все сделал именно так, все проверил и тем не менее авалон упорно молчит, а waitrequest = '1' все время.
Подскажите пожалуйста где нужно снимать ресет с этого порта при помощи HPS?
Serb1987
Всем спасибо, разобрался, если что вот инфа про снятие ресетов http://www.altera.com/literature/hb/arria-...pgaportrst.html
Serb1987
Блин, проблема на проблеме, теперь с Авалоном... Подскажите будьте добры, почему может не быть сигнала readdatavalid, вернее он все время в 0 и данные с шины не поступают? Waitrequest работает относительно моего read. Пытался изначально читать поэлементтно, потом пробовал бёрстами - не работает.
Код
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity avalon_read is
    generic (hor_res : natural:= 360;
                ver_res : natural:= 288
                );
    port (clk                                     : in std_logic;
            reset                                 : in std_logic;
            fifo_write                            : out std_logic;
            fifo_full                            : in std_logic;
            -- read master
            avm_read_master_read             : out std_logic;
            avm_read_master_address         : out std_logic_vector (29 downto 0);
            avm_read_master_readdata         : in std_logic_vector (31 downto 0);
            avm_read_master_waitrequest     : in std_logic;
            avm_read_readdatavalid         : in std_logic;
            data_out                                : out std_logic_vector (31 downto 0);
            burstcount                            : out std_logic_vector (7 downto 0)
            );
end avalon_read;

architecture Behavioral of avalon_read is

signal pix_cnt        : natural := 0;
signal str_cnt        : natural := 0;
signal quad_cnt    : natural := 0;
signal addr_0        : natural := 0;
signal addr_1        : natural := 0;
signal addr_2        : natural := 0;
signal addr_3        : natural := 0;

signal avm_read    : std_logic := '0';
signal wr_fifo        : std_logic := '0';

-- state machine states
type read_states_T is (idle, running, stopping);----
signal read_state : read_states_T;

-- extra read master signals
signal read_address : natural;         -- the current read address

begin

-------------------------------------------------------------------------------
-- THE READ MASTER STATE MACHINE
-------------------------------------------------------------------------------

read_FSM: process (clk, reset, read_state, avm_read_master_waitrequest)
begin
    if reset = '0' then
        read_state <= idle;
    elsif rising_edge (clk) then----------------------
        case read_state is
            when idle =>
            if fifo_full = '0' and avm_read_readdatavalid = '0' then
                read_state <= running;
                avm_read_master_address <= std_logic_vector(to_unsigned(read_address, 30));
                burstcount <= "00000010";
            else
                read_state <= idle;
            end if;
            when running =>
                if avm_read_master_waitrequest = '0' then
                    read_state <= stopping;

                else
                    read_state <= running;
                end if;
            when stopping =>
--                if avm_read_readdatavalid = '1' then
                    read_state <= idle;
                    if quad_cnt = 3 then
                            quad_cnt <= 0;
                            if pix_cnt = hor_res-1 then
                                pix_cnt <= 0;
                                if str_cnt = ver_res-1 then
                                    str_cnt <= 0;
                                else
                                    str_cnt <= str_cnt+1;
                                end if;
                            else
                                pix_cnt <= pix_cnt +1;
                            end if;
                        else
                            quad_cnt <= quad_cnt+1;
                        end if;
--                else
--                    read_state <= stopping;
--                end if;
        end case;
    end if;
end process;



process(clk, reset, fifo_full, read_state, quad_cnt, avm_read_master_waitrequest)
begin
if reset = '0' then
        fifo_write <= '0';
elsif falling_edge(clk) then
    if (quad_cnt = 3 and read_state = running and fifo_full = '0' and avm_read_master_waitrequest = '0')  then ---- avm_read_readdatavalid = '1'
        fifo_write <= '1';
    else
        fifo_write <= '0';
    end if;
end if;
end process;

addr_0 <= (pix_cnt*2 + str_cnt*2*(hor_res*2))*4;--+ 500000000
addr_1 <= (pix_cnt*2+1 + str_cnt*2*(hor_res*2))*4;
addr_2 <= (pix_cnt*2 + (str_cnt*2+1)*(hor_res*2))*4;
addr_3 <= (pix_cnt*2+1 + (str_cnt*2+1)*(hor_res*2))*4;

read_address <= addr_0 when quad_cnt = 0 else
                     addr_1 when quad_cnt = 1 else
                     addr_2 when quad_cnt = 2 else
                     addr_3 when quad_cnt = 3;

data_out(31 downto 24) <= avm_read_master_readdata(15 downto 8) when quad_cnt = 0;---UL
data_out(23 downto 16) <= avm_read_master_readdata(15 downto 8) when quad_cnt = 1;---UR
data_out(15 downto 8) <= avm_read_master_readdata(15 downto 8) when quad_cnt = 2;----LL
data_out(7 downto 0) <= avm_read_master_readdata(15 downto 8) when quad_cnt = 3;-----LR
        
avm_read_master_read <= '1' when read_state = running and fifo_full = '0' else '0';

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