Перейти к содержанию
    

ZED

Свой
  • Постов

    261
  • Зарегистрирован

  • Посещение

Весь контент ZED


  1. Я, честно говоря, не особо понимаю как время-импульсное кодироваие может быть применено в радиолокации, ведь по времени между излученным и отраженным импульсом оределяется расстояние до цели. А если это время меняется хоть по определенному закону непонятно на какую дальность рассчитывать (нацеливаться). Поэтому и используют равное расстояние между импульсами, да и импульсы одинаковой длины. Единственное где могло бы найти применение время-импульсное кодирование, - это в радиолокации с активным ответом.
  2. Вот решил написать свой вариант FIFO-буфера, правда я его в кристалле не тестировал. Прошу покритиковать. library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity FIFO is generic (Addr_Size : natural := 3; -- Разрядность адреса (глубина FIFO) Data_Size : natural := 32); -- Разрядность данных port (RST : in std_logic; -- Сброс CLK_WR : in std_logic; -- Тактовый сигнал для записи WE : in std_logic; -- Разрешение записи (Write Enable) Data_WR : in std_logic_vector(Data_Size - 1 downto 0); -- Данные, записываемые в буфер CLK_RD : in std_logic; -- Тактовый сигнал для чтения RE : in std_logic; -- Разрешение чтения (Read Enable) Data_RD : out std_logic_vector(Data_Size - 1 downto 0); -- Данные, читаемые из буфера Full : out std_logic; -- Флаг того, что буфер полон Empty : out std_logic); -- Флаг того, что буфер пуст end entity FIFO; architecture RTL of FIFO is type FIFO_RAM_Type is array (0 to 2**Addr_Size - 1) of std_logic_vector(Data_Size - 1 downto 0); signal FIFO_RAM : FIFO_RAM_Type; --================================================================================ ================================================-- -- Функция преобразования из двоичного кода в код Грея: -- --================================================================================ ================================================-- function Bin_to_Gray (D: unsigned) return unsigned is variable Q : unsigned(D'range); begin Q := ('0' & D(D'high downto 1)) xor D; return Q; end function Bin_to_Gray; --================================================================================ ================================================-- --================================================================================ ================================================-- -- Функция преобразования кода Грея в двоичный код: -- --================================================================================ ================================================-- function Gray_to_Bin (D: in unsigned) return unsigned is variable Q: unsigned(D'high downto D'low); begin Q(D'high) := D(D'high); for i in D'high - 1 downto D'low loop Q(i) := D(i) xor Q(i + 1); end loop; return Q; end function; --================================================================================ ================================================-- signal Addr_Write_Gray : unsigned(Addr_Size downto 0); -- Адрес записи данных в буфер в коде Грея signal Addr_Write_Gray_Next : unsigned(Addr_Size downto 0); -- Следующий адрес записи данных в буфер в коде Грея signal Addr_Read_Gray : unsigned(Addr_Size downto 0); -- Адрес чтения данных из буфера в коде Грея signal Addr_Write_Bin : unsigned(Addr_Size downto 0); -- Адрес записи данных в буфер в двоичном коде signal Addr_Write_Bin_Next : unsigned(Addr_Size downto 0); -- Следующий адрес записи данных в буфер в двоичном коде signal Addr_Read_Bin : unsigned(Addr_Size downto 0); -- Адрес чтения данных из буфера в двоичном коде signal WE_Allow : std_logic; -- Разрешение записи данных в FIFO-буфер signal RE_Allow : std_logic; -- Разрешение чтения данных из FIFO-буфера signal Full_Match : std_logic; -- Сравнение адресов записи и чтения для флага того, что буфер полон signal Empty_Match : std_logic; -- Сравнение адресов записи и чтения для флага того, что буфер пуст begin -- Адрес записи данных в буфер в двоичном коде: -- process(RST, CLK_WR) begin if (RST = '1') then Addr_Write_Bin <= (others => '0'); elsif (Rising_Edge(CLK_WR)) then if(WE_Allow = '1') then Addr_Write_Bin <= Addr_Write_Bin + 1; end if; end if; end process; -- Следующий адрес записи данных в буфер в двоичном коде: -- process(RST, CLK_WR) begin if (RST = '1') then Addr_Write_Bin_Next <= TO_UNSIGNED(1, Addr_Size + 1); elsif (Rising_Edge(CLK_WR)) then if(WE_Allow = '1') then Addr_Write_Bin_Next <= Addr_Write_Bin_Next + 1; end if; end if; end process; -- Адрес записи данных в FIFO-буфер в коде Грея: -- Addr_Write_Gray <= Bin_to_Gray(Addr_Write_Bin); -- Следующий адрес записи данных в буфер в коде Грея: -- Addr_Write_Gray_Next <= Bin_to_Gray(Addr_Write_Bin_Next); -- Адрес чтения данных из буфера в двоичном коде: -- process(RST, CLK_RD) begin if (RST = '1') then Addr_Read_Bin <= (others => '0'); elsif (Rising_Edge(CLK_RD)) then if(RE_Allow = '1') then Addr_Read_Bin <= Addr_Read_Bin + 1; end if; end if; end process; -- Адрес чтения данных из FIFO-буфера: -- Addr_Read_Gray <= Bin_to_Gray(Addr_Read_Bin); -- Запись данных в FIFO-буфер: -- process begin wait until (rising_edge(CLK_WR)); if(WE_Allow = '1') then FIFO_RAM(TO_INTEGER(Addr_Write_Gray(Addr_Size - 1 downto 0))) <= Data_WR; end if; end process; -- Чтение данных из FIFO-буфера: -- process begin wait until (rising_edge(CLK_RD)); if(RE_Allow = '1') then Data_RD <= FIFO_RAM(TO_INTEGER(Addr_Read_Gray(Addr_Size - 1 downto 0))); end if; end process; -- Разрешение записи данных в FIFO-буфер: -- WE_Allow <= '1' when (WE = '1' and Full_Match = '0') else '0'; -- Разрешение чтения данных из FIFO-буфера: -- RE_Allow <= '1' when (RE = '1' and Empty_Match = '0') else '0'; -- Сравнение адресов записи и чтения для флага того, что буфер полон: -- Full_Match <= '1' when (Addr_Write_Bin(Addr_Size - 1 downto 0) = Addr_Read_Bin(Addr_Size - 1 downto 0) and Addr_Write_Bin(Addr_Size) /= Addr_Read_Bin(Addr_Size) and (RE = '0' or (RE = '1' and WE = '1'))) else '0'; -- Флаг того, что буфер полон: -- Full <= '1' when (Full_Match = '1' or (Addr_Write_Bin_Next(Addr_Size - 1 downto 0) = Addr_Read_Bin(Addr_Size - 1 downto 0) and Addr_Write_Bin_Next(Addr_Size) /= Addr_Read_Bin(Addr_Size) and (RE = '0' and WE = '1'))) else '0'; -- Сравнение адресов записи и чтения для флага того, что буфер пуст: -- Empty_Match <= '1' when (Addr_Write_Bin = Addr_Read_Bin and (WE = '0' or (RE = '1' and WE = '1'))) else '0'; -- Флаг того, что буфер пуст: -- Empty <= Empty_Match; end architecture RTL; FIFO.rar
  3. Все правильно. Вы читаете именно те книжки.
  4. Poluektovich спасибо за ссылки!!! Приятно, что даже на русском, я даже и не надеялся. Буду читать, осваивать, позже мыслях по этому поводу. отпишусь о свои CaPpuCcino, Вам спасибо за дельный ответ, все по пунктам.
  5. yes, спасибо Вам за развернутый ответ. С языком C++ не дружен к сожалению. А вот взять, например систему на кристалле (SoC). Вот есть некий процессор, шинный интерфейс и ПЛИС. Для такой задачи лучше видимо подойдет SystemC, нежели SystemVerilog, или тут они примерно равны? Вот хочу еще разобраться с TLM. Насколько его сложно освоить и с чего лучше начать, чтобы понять концепцию (видимо с понятия класса)? Как писать (например те же шинные интерфейсы) на этом уровне, что нужно учитывать (вопрос философии)? Ну я имел ввиду транзакционную модель, чтобы использовать ее для отладки остальной части проекта, или так не делают? Есть ли какие-нибудь готовые проекты или примеры с описанием применения TLM от простого к сложному?
  6. Введение я написал, дабы не раздуть новое обсуждение на тему для чего он нужен и кто поддерживает/не поддерживает синтез, ну и т.д. Поиском по форуму естественно пользовался: появилось больше вопросов, чем ответов. Эти вопросы я и задаю. Пытаюсь проникнуться философией этого языка. В основном интересует TLM.
  7. Самым главным достоинством языка SystemC является то, что можно подняться на системный уровень и спускаться до уровня RTL в рамках одного языка. Т.е. моделирование комплексной системы (системы на кристалле) можно производить оставаясь в едином языковом пространстве. Еще одним преимуществом является высокая скорость моделирования. Сначала создается высокоуровневая поведенческая модель системы. Все сложные элементы (такие как шины, процессоры, DDR-памяти, интерфейсы и т.д.) строятся на базе транзакционных моделей (TLM). Проверяется правильность функционирования системы в целом. В полученной модели выделяются блоки, отвечающие за аппаратную часть (HardWare), и блоки, отвечающие за программную часть (SoftWare). Далее программисты и аппаратчики работаю параллельно: программисты пишут программы на C (C++), а аппаратчики спускаются на уровень регистровых передач (RTL). Таким, образом обе группы (HardWare и SoftWare) изначально работают с одной моделью, а в процессе разработки TLM-блоки заменяются уже своими физическими (или программными) эквивалентами. Не совсем понятно как взаимодействуют блоки на разных уровнях - TLM и RTL. Пример: память DDR и контроллер к ней написан на уровне TLM, а блок, использующий ее написан на RTL-уровне. Настораживает, что в интернете так и не нашел TLM-моделей стандартных элементов (к примеру той же DDR-памяти или шины). Есть ли у кого-нибудь опыт разработки целой системы с использованием SystemC? На сколько там все прозрачно? Оправдывает ли себя вообще такой подход? Какие есть возможности визуализации и документирования создаваемого проекта? Можно ли в проект на SystemC делать VHDL-вставки RTL-уровня?
  8. А ну да, коэффициенты у нас лежат в диапазоне от -1024 до 1024. FFT_Coefficients.rar
  9. А вот так не подойдет: entity FIFO_Reg is generic(Width : integer); Port ( Data_In : in STD_LOGIC_VECTOR (Width-1 downto 0); WRITE : in STD_LOGIC; FULL : out STD_LOGIC; CLK : in STD_LOGIC; CE : in STD_LOGIC; RST : in STD_LOGIC; Dato_Out : out STD_LOGIC_VECTOR (Width-1 downto 0); READ : in STD_LOGIC; EMPTY : out STD_LOGIC:='1'); end FIFO_Reg; architecture RTL of FIFO_Reg is signal Empty_State, Empty_State_Next : std_logic:='1'; signal Data_Out_Buf, Data_Out_Next : std_logic_vector(Width-1 downto 0); begin EMPTY <= Empty_State; DO <= Data_Out_Buf; -- Sync Process -- process(CLK,nRESET) begin if RST='1' then Empty_State <= '1'; elsif rising_edge(CLK) then if CE='1' then Empty_State <= Empty_State_Next; Data_Out_Buf <= Data_Out_Next; end if; end if; end process; -- End of Sync Process -- -- Comb Process -- process(Empty_State, nWRITE, Data_In, READ, Data_Out_Buf) begin -----Default Values----- Empty_State_Next <= Empty_State; FULL <= '1'; Data_Out_Next <= Data_Out_Buf; -----Case section----- case (Empty_State) is when '1' => if WRITE='0' then FULL <= '0'; Data_Out_Next <= (others => 'X'); else Empty_State_Next <= '0'; FULL <= '0'; Data_Out_Next <= Data_In; end if; when '0' => if READ='1' then if WRITE='1' then FULL <= '0'; Data_Out_Next <= Data_In; else Empty_State_Next <= '1'; FULL <= '0'; Data_Out_Next <= (others => 'X'); end if; end if; when others=>NULL; end case; end process; end RTL; И можно последовательно подключить сколько угодно таких буферов.
  10. С помощью Matlab'овских скриптов. Посредством функции Matlab frintf, нужные значения записываются в файл.
  11. Как вы это определили? Matlab в командном окне выводит какое-нибудь сообщение?
  12. Зачем? Изменяй m-файл! Я же тебе даже примерно написал, что нужно изменять всообщении. И нажимай Run. Далее пихай VHDL-файл в свой проект, предварительно протестив.
  13. Ну во-первых это файлы с расширением *.m, значит они Matlab'овские. Т.е. открываеть его нужно в Matlab, а не Simulink. Далее нажимаете запуск (Run) и на диске C у вас появится файл с названием filter.vhd. Нет с помощью Matlab'а я получаю коэффициенты фильтра с заданными характеристиками и перевожу их в дополнительный код. Также мой Matlab'овский файл содержит "скелет" VHDL-кода, написанного мной, куда просто подставляются коэффициенты. Далее этот код записывается в файл C:\filter.vhd. Когда откроете файл Вы все поймете, там достаточно комментариев. Если что-то не понятно, спрашивайте. Успехов! P.S. Также вы можете менять параметры фильтра: полосу пропускания, частоту дискретизации, неравномеерность в полосе пропускания и т.д. Затем Вы снова нажимаете Run и получаете новый файл filter.vhd уже с новыми параметрами (коэффициентами).
  14. Вот коэффициенты ROM_x.mif плюс файл Matlab для их генерации. Надеюсь ничего не напутал. FFT_Coefficients.rar
  15. А счего начать? Я даже не совсем представляю как все это должно выглядеть.
  16. Ну я вообщето взял готовый проект getting-started-project-at91sam9260-ek и просто вставил туда свой код. А можно пример?
  17. define symbol __ICFEDIT_size_irqstack__ = 0x60; Только ругается он на CSTACK.
  18. В sdram.icf задано: define symbol __ICFEDIT_size_cstack__ = 0x1000; P.S. Забыл указать, что прошиваю и отлаживаюсь с помощью J-Link for ARM от IAR System.
  19. Именно он, когда дохожу до вышеуказанной строчки. Так функция и не содержит никаких параметров: void Init_CLK(void).
  20. Теперь возникли проблемы с PLL. Хотел протестировать работу MMU, для этого написал код дрыгания ножкой. В этом коде есть функция инициализации PLL: // Частота медленного RC-генератора SLCK 32.768 кГц. Период 1/32768 = 30.51 мкс // Максимальное время запуска основоного генератора: 75 мкс // Время запуска основного генератора:8 * OSCOUNT(=16) * 30.51 мкс = 3.9 мс // Запуск основного генератора: AT91C_BASE_PMC->PMC_MOR = (AT91C_CKGR_OSCOUNT & (0x40 << 8)) | AT91C_CKGR_MOSCEN; // Ждать пока пройдет время запуска: while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); // Переключение блока задающей частоты на основную тактовую частоту AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_MAIN_CLK; // Настройка PLL на частоту 192 МГц: AT91C_BASE_PMC->PMC_PLLAR = ( AT91C_CKGR_SRCA // 29 бит = 1 | (0x2 << 14) // OUTA = 2 | (0xBF << 8) // PLLACOUNT = 191 | (AT91C_CKGR_MULA & (0x7C << 16)) // MULA = 124 | (AT91C_CKGR_DIVA & 12)); // DIVA = 12 // Ждать пока пройдет время запуска: while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA)); // Выбор задающей частоты и тактовой частоты процессора: // Предделитель тактовой частоты PRES = 1, Предделитель задающей частоты MDIV = 2. AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_1; // Ждать пока пройдет время запуска: while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); // В качестве основной частоты использовать частоту PLL: AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK; // Ждать пока пройдет время запуска: while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); Проблема в том, что на строчке: AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK; IAR выдает следующее: Полазил по форуму, там написано, что все дело в REMAP. Пробовал делать REMAP вручную: AT91C_BASE_MATRIX->MATRIX_MRCR = AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D; Все тоже самое. Помогите разобраться. Кстати еще вопрос, с какой примерно частотой у меня должна будет дрыгаться ножка при включенном MMU и Кэшах?
  21. Спасибо Вам большое за советы и помощь!
  22. Может это Вам поможет, но в Quartus'е она не будет работать, т.к. она не синтезируема. Должно быть что-то вроде этого: library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.std_logic_textio.all; use std.textio.all; entity ROM is port(CLK: in std_logic; CE: in std_logic; ADDR: in std_logic_vector(addr_size - 1 downto 0); Q: out std_logic_vector(2*data_size - 1 downto 0)); end entity ROM; architecture RTL_ROM of ROM is type ROM_TYPE is array(0 to 2**addr_size - 1) of std_logic_vector(2*data_size - 1 downto 0); -- Функция инициализации памяти из файла: -- function INIT_ROM(constant filename: string) return ROM_TYPE is -- Входным параметром является строковая переменная названия файла file initfile: text open read_mode is filename; -- Открытие файла filename для чтения variable fline: line; variable ROM: ROM_TYPE := (others => (others => 'U')); -- Память begin for i in ROM_Type'range loop readline(initfile, fline); hread(fline, ROM(i)); end loop; return ROM; end function INIT_ROM; -- Файл шестнадцатиричный, для двоичного файла использовать read вместо hread-- signal ROM_BANK: ROM_TYPE:= INIT_ROM(init_file); -- Инициализация памяти begin process begin wait until (rising_edge(CLK)); if (CE = '1') then Q <= ROM_BANK(TO_INTEGER(UNSIGNED(ADDR))); end if; end process; end RTL_RAM; Если вы хотите в квартусе проининциализировать ROM, то просто берите компонент и подключайте mif-файл (пример для RAM, для ROM он схожий): Объявление компонента: component lpm_ram_dp generic(intended_device_family: string; lpm_indata: string; lpm_outdata: string; lpm_file: string; lpm_rdaddress_control: string; lpm_type: string; lpm_width: NATURAL; lpm_widthad: NATURAL; lpm_wraddress_control: string; rden_used: string; use_eab: string); port(rdclken: in std_logic; rdclock: in std_logic; wren: in std_logic; wrclken: in std_logic; wrclock: in std_logic; q: out std_logic_vector (lpm_width - 1 downto 0); data: in std_logic_vector (lpm_width - 1 downto 0); rdaddress: in std_logic_vector (lpm_widthad - 1 downto 0); wraddress: in std_logic_vector (lpm_widthad - 1 downto 0)); end component; Подключение компонента: RAM_1: lpm_ram_dp generic map(intended_device_family => "APEX20KE", lpm_indata => "REGISTERED", lpm_outdata => "REGISTERED", lpm_file => "Data.mif", lpm_rdaddress_control => "REGISTERED", lpm_type => "LPM_RAM_DP", lpm_width => data_size, lpm_widthad => addr_size, lpm_wraddress_control => "REGISTERED", rden_used => "FALSE", use_eab => "ON") port map(rdclken => RCE, rdclock => CLK, wren => WE, wrclken => WCE, wrclock => CLK, data => D, rdaddress => ADDR_RD, wraddress => ADDR_WR, q => Q); mif-файл (пример): WIDTH=64; DEPTH=32; ADDRESS_RADIX=UNS; DATA_RADIX=BIN; CONTENT BEGIN -------------------- RAM -------------------- 0 : 0000000000000000000000000000000000000000000000000111111111111111; 1 : 0000000000000000001100010101100100000000000000000111011000011010; 2 : 0000000000000000010110110001000100000000000000000101100111110010; 3 : 0000000000000000011101101011010000000000000000000010111111100010; 4 : 0000000000000000011111111111110011111111111111111111111001101011; 5 : 0000000000000000011101010111101111111111111111111100110100110010; 6 : 0000000000000000010110001101000011111111111111111010001111010100; 7 : 0000000000000000001011100110100111111111111111111000100010110110; 8 : 1111111111111111111111001101011011111111111111111000000000001010; 9 : 1111111111111111110010111011111111111111111111111000101100100111; 10 : 1111111111111111101000101011110011111111111111111010100001010101; 11 : 1111111111111111100010000010010111111111111111111101001100010001; 12 : 1111111111111111100000000001011100000000000000000000010011000000; 13 : 1111111111111111100010111100111100000000000000000011010110110010; 14 : 1111111111111111101010010111111000000000000000000101111001010111; 15 : 1111111111111111110101001000110100000000000000000111100001100110; 16 : 0000000000000000000001100101010000000000000000000111111111010111; 17 : 0000000000000000001101110010000100000000000000000111001110000100; 18 : 0000000000000000010111110110011100000000000000000101010101010101; 19 : 0000000000000000011110001110110100000000000000000010100111110100; 20 : 0000000000000000011111111100000011111111111111111111100000010111; 21 : 0000000000000000011100101101001111111111111111111100011101110010; 22 : 0000000000000000010101000010010111111111111111111001111110001100; 23 : 0000000000000000001010000111010111111111111111111000011010010000; 24 : 1111111111111111111101101000001011111111111111111000000001011010; 25 : 1111111111111111110001100000100011111111111111111000110111100001; 26 : 1111111111111111100111101000010011111111111111111010110100001101; 27 : 1111111111111111100001100001001011111111111111111101100100001100; 28 : 1111111111111111100000000111101100000000000000000000101100010001; 29 : 1111111111111111100011101001101100000000000000000011101101100000; 30 : 1111111111111111101011100100001100000000000000000110001010000000; 31 : 1111111111111111110110101000111100000000000000000111101001100110; END; А так пользуйтесь советом gin'а P.S. mif-файл лучше всего генерить в Matlab'e
  23. Блин код забыл прикрепить: unsigned int AT91F_ARM_ReadControl() { register unsigned int ctl; ctl = __MRC(15, 0, 1, 0, 0); return ctl; } void AT91F_ARM_WriteControl(unsigned int ctl) { __MCR(15, 0, ctl, 1, 0, 0); } void AT91F_ARM_WriteTTB(unsigned int ttb) { __MCR(15, 0, ttb, 2, 0, 0); } void AT91F_ARM_WriteDomain(unsigned int domain) { __MCR(15, 0, domain, 3, 0, 0); } //----------------------------------------------------------------------------- // Размер страницы = 4 Kб (0x1000) // Раскладка по памяти: // 0000 0000 - Boot Memory // 0010 0000 - ROM, не используется (32 Кб) // 0020 0000 - SRAM0 (4 Кб) // 0030 0000 - SRAM1 (4 Кб) // 0050 0000 - UHP (16 Кб) // 2000 0000 - SDRAM (32 Mб) // 4000 0000 - NAND DATA // 4020 0000 - NAND ADDR // 4040 0000 - NAND CMD // FFF0 0000 - Периферия //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Описания секций: // [1..0] = "01"; // 2 - B - Bufferable; // 3 - C - Cacheable; // 4 - '1'; // [8..5] - Domain = "1111"; // 9 = '0'; // [11..10] - AP; // [19..12] = "00000000" // [31..20] - Базовый адрес секции // Биты AP // 01 - Нет доступа (No Access) // 10 - Только чтение (Read-only) // 11 - Чтение/Запись (Read/write) // Биты C и B: // 0 0 - Не Кэшируемая, Не Буферизируемая // 0 1 - Не Кэшируемая, Буферизируемая // 1 0 - Write-Trough-кеш // 1 1 - Write-Back-кеш //----------------------------------------------------------------------------- #define TLB_ADDR 0x2F000000 // Базовый адрес расположения TLB в памяти #define TLB_NCNB 0xDF2 // Noncachable, Nonbufferable 11 0 1111 1 00 10 #define TLB_WT 0xDFA // Write-through 11 0 1111 1 10 10 #define TLB_WB 0xDFE // Write-back 11 0 1111 1 11 10 // Инициализация MMU: void AT91F_InitMMU(void) { // TLB располагается в SDRAM unsigned int *TLB = (unsigned int *) (TLB_ADDR); unsigned int i, ctl; // Инициализация TTB: AT91F_ARM_WriteTTB(TLB_ADDR); // Записать начальный адрес расположения TTB (CP15 c2) AT91F_ARM_WriteDomain(0xFFFFFFFF); // Domain Access Control Register (CP15 c3) // Очистка TLB: for (i = 0; i < 4096; ++i) TLB[i] = 0; // После Reamp по адресу 0x00000000 расположена SRAM0: TLB[0x000] = 0x00000000 | TLB_WB; // После Reamp по адресу 0x00100000 расположена ROM: TLB[0x001] = 0x00100000 | TLB_NCNB; // SRAM1: TLB[0x003] = 0x00300000 | TLB_WB; // UHP: TLB[0x005] = 0x00500000 | TLB_WB; // Код основной программы, расположенный в SDRAM (32 Мб): for (i = 0x200; i < 0x200 + 31; i++){ TLB[i] = (i << 20) | TLB_WB; } // Переферия: TLB[0xFFF] = 0xFFF00000 | TLB_NCNB //Разрешить MMU ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 0); AT91F_ARM_WriteControl(ctl); //Разрешить I-Cache ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 12); AT91F_ARM_WriteControl(ctl); //Разрешить D-Cache ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 2); AT91F_ARM_WriteControl(ctl); } Т.е. эта строчка лишьняя: // После Reamp по адресу 0x00000000 расположена SRAM0: TLB[0x000] = 0x00000000 | TLB_WB; Вот видимо у меня такой случай. Я все это делаю, чтобы запустить EMAC на вышеупомянутом контроллере. И вот в теме, которую я открыл, чтобы с ним разобраться EMAC AT91SAM9260. Так вот в этой теме мне сказали, цитирую: Вот поэтому я так все дотошно и спрашиваю, хочу разобраться. Просто еще несколько месяцев назад я вообще не знал что такое ARM процессоры, IAR, J-Link и т.д. Не говоря уже о кэшах, MMU и всего подобного.
  24. Да проблем с этим нет. Вы не могли бы мне объяснить назначения доменов и соответственно битов AP? Вот привожу, что у меня получилось: Небольшие уточнения, правильно ли я понимаю: TLB располагаем в конце SDRAM, основную программу вначале (я для кэшируемой области памяти выделил первые 32 Мб), инициализируем ее как Write-Back, переферию делаем некэшируемой. Все, TLB готов! Если я хочу задать переменную в некэшируемой области памяти, то беру адрес, для которого TLB = 0, ну например 0x2350 0000. Тогда объявляем указатель: unsigned int *variable = (unsigned int *) (0x2350 0000); variable = 1234; // присваевыем, как пример, число переменной P.S. SII, спасибо Вам за ссылку!
×
×
  • Создать...