Worldmaster 0 27 марта Опубликовано 27 марта · Жалоба Здравствуйте. Продолжаю неравный бой за каждый мегагерц. )) Есть у меня процессы для организации взаимодействия с SDRAM через контроллер. -- обработчик чтения или записи данных SDRAM SDRAM_PROCESSOR:process (rst_n, sdrc_clk, RAM_IsReady, ram_old_state, ram_new_state ) variable loc_state: LOC_FSM_STATE := idle ; begin if rst_n = '0' then io_state <= idle; loc_state := idle; elsif falling_edge(sdrc_clk) then if ram_old_state /= ram_new_state then loc_state := init; ram_old_state <= ram_new_state; RAM_EXCHANGE_COMPLETE <= '0'; end if; case loc_state is when idle=> RAM_EXCHANGE_COMPLETE <= '1'; RAM_transmit_en <= '0'; RAM_Bank_addr <= (others=>'0'); RAM_Row_addr <= (others=>'0'); RAM_Col_addr <= (others=>'0'); RAM_Data_count <= (others=>'0'); when init => if RAM_IsReady = '1' then RAM_Bank_addr <= RAM_BANK_ADDR_BIT_req ; RAM_Row_addr <= RAM_ROW_ADDR_req; RAM_Col_addr <= RAM_COL_ADDR_BIT_req; RAM_Data_count <= RAM_32BIT_WORD_COUNT_BIT_req; ------------------------------------------------------------------------------------ модуль может за раз записать не более 255 блоков данных по 32 байта. также перед записью нужно активировать каждую новую строку для записи тут код для проверки количества данных которые нужно записать и обрезка их по максимуму в строке. Все константы кратны 2 чтобы работали mod if RAM_RW_BIT_req = WRITE then RAM_RW <= WRITE; -- WRITE : std_logic := '0'; if ((RAM_WRITE_PTR mod MAX_ROW_COLS)+ to_integer(unsigned(RAM_32BIT_WORD_COUNT_BIT_req))) > MAX_ROW_COLS then RAM_Data_count <= std_logic_vector(to_unsigned(MAX_ROW_COLS - (RAM_WRITE_PTR mod MAX_ROW_COLS), RAM_Data_count'length)); end if; else RAM_RW <= READ; -- READ : std_logic := '1'; if ((RAM_READ_PTR mod MAX_ROW_COLS)+ to_integer(unsigned(RAM_32BIT_WORD_COUNT_BIT_req))) > MAX_ROW_COLS then RAM_Data_count <= std_logic_vector(to_unsigned(MAX_ROW_COLS - (RAM_READ_PTR mod MAX_ROW_COLS), RAM_Data_count'length)); end if; end if; ------------------------------------------------------------------------------------ RAM_transmit_en <= '1'; io_state <= do_work; loc_state := processing; del_rst <= '0'; del_cnt <= std_logic_vector(to_unsigned(4, del_cnt'length)); end if; when processing=> del_rst <= '1'; if ram_ack = '1' then RAM_WriteData <= (others => 'Z'); RAM_Data_count <= (others => '0'); loc_state := idle; io_state <= idle; RAM_transmit_en <= '0'; end if; end case; end if; end process SDRAM_PROCESSOR; И второй процесс который формирует команду для записи BUFFER_CONTROLLER_PROC:process (rst_n, sdrc_clk, RAM_EXCHANGE_COMPLETE, cam1_write_count, cam_frame_reading) type LOC_FSM_STATE is (RESET, IDLE, START, PROCESSING); variable loc_state: LOC_FSM_STATE := RESET; begin if rst_n = '0' then loc_state := RESET; RAM_32BIT_WORD_COUNT_BIT_req <= (others =>'0'); RAM_BANK_ADDR_BIT_req <= (others => '0'); -- банк RAM_ROW_ADDR_req <= (others =>'0'); elsif rising_edge(sdrc_clk) then case loc_state is when RESET => RAM_32BIT_WORD_COUNT_BIT_req <= (others =>'0'); RAM_BANK_ADDR_BIT_req <= (others => '0'); -- банк RAM_ROW_ADDR_req <= (others =>'0'); loc_state := IDLE; when IDLE => RAM_BUF_ID_req <= cam_index; -- индекс камеры if RAM_EXCHANGE_COMPLETE = '1' then -- проверка наличия данных в буфере камеры -- как только обработали половину массима инициируем запись или чтение RAM для освобождения половины буфера. -- чтение или запись должна быть выполнена пока идет обработка другой половины буфера if cam1_write_count >= CAM_DROP_THR then -- половина буфера заполнена, надо скинуть в память loc_state := START; RAM_RW_BIT_req <= WRITE; -- читаем =1, пишем 0 ----------------------------------------------------------------------------- RAM_ROW_ADDR_req <= std_logic_vector(to_unsigned(RAM_WRITE_PTR / RAM_ROW_SIZE, RAM_ROW_ADDR_req'length)); RAM_COL_ADDR_BIT_req <= std_logic_vector(to_unsigned(RAM_WRITE_PTR mod RAM_ROW_SIZE, RAM_COL_ADDR_BIT_req'length)); RAM_32BIT_WORD_COUNT_BIT_req <= cam1_read_count; --(("000" & cam1_write_count(7 downto 1)) + 10); -- делим пополам и добавляем 10 ----------------------------------------------------------------------------- elsif cam_frame_reading = '1' then -- проверка наличия данных в буфере ФИФО if fifo_write_count >= FIFO_DROP_CNT then -- половина буфера заполнена, надо скинуть в память loc_state := START; RAM_RW_BIT_req <= READ; -- читаем =1, пишем 0 ----------------------------------------------------------------------------- а вот тут надо нарезать строку и столбец по известному указателю. тоже деление на кратное 2 число. RAM_ROW_ADDR_req <= std_logic_vector(to_unsigned(RAM_READ_PTR / RAM_ROW_SIZE, RAM_ROW_ADDR_req'length)); RAM_COL_ADDR_BIT_req <= std_logic_vector(to_unsigned(RAM_READ_PTR mod RAM_ROW_SIZE, RAM_COL_ADDR_BIT_req'length)); RAM_32BIT_WORD_COUNT_BIT_req <= fifo_read_count(7 downto 0); ----------------------------------------------------------------------------- end if; end if; end if; when START => ram_new_state <= not ram_new_state; loc_state := PROCESSING; when PROCESSING => if ram_ack = '1' then loc_state := RESET; end if; end case; end if; end process BUFFER_CONTROLLER_PROC; Так вот собсно вопрос. Можно ли это как то оптимизировать чтобы устранить моды и деление?? В надежде что это повысит скорость. осталось набрать всего 60 мегагерц до порога. )) Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 29 27 марта Опубликовано 27 марта · Жалоба MAX_ROW_COLS,RAM_ROW_SIZE чему равно? Степень двойки? Если да то их можно заменить на сдвиги или операцию с маской должно быть быстрее если это компилятор не делает сам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Worldmaster 0 27 марта Опубликовано 27 марта · Жалоба В 27.03.2024 в 13:18, MegaVolt сказал: чему равно? Степень двойки? Да. Все константы степень двойки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MegaVolt 29 27 марта Опубликовано 27 марта · Жалоба 49 минут назад, Worldmaster сказал: Да. Все константы степень двойки. Ну значит целочисленное деление на 2^N это сдвиг на N вправо. Целочисленное взятие по модулю 2^N это откидывание всего что старше Nого бита. В железе делается мгновенно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Worldmaster 0 2 апреля Опубликовано 2 апреля (изменено) · Жалоба В 27.03.2024 в 14:18, MegaVolt сказал: 2^N это сдвиг на N вправо. А на vhdl есть синтезируемый блок сдвига или нужно городить что то свое? или делать что то типа: "00000000" & REG(15 downto 8) Изменено 2 апреля пользователем Worldmaster Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 2 апреля Опубликовано 2 апреля · Жалоба 7 minutes ago, Worldmaster said: А на vhdl есть синтезируемый блок сдвига или нужно городить что то свое? library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity shift_example is Port ( input_number : in STD_LOGIC_VECTOR (7 downto 0); shift_amount : in INTEGER; result_left : out STD_LOGIC_VECTOR (7 downto 0); result_right : out STD_LOGIC_VECTOR (7 downto 0)); end shift_example; architecture Behavioral of shift_example is begin -- Сдвиг влево для умножения result_left <= input_number sll shift_amount; -- Сдвиг вправо для деления result_right <= input_number srl shift_amount; end Behavioral; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Worldmaster 0 2 апреля Опубликовано 2 апреля · Жалоба В 02.04.2024 в 12:57, Maverick_ сказал: -- Сдвиг влево для умножения result_left <= input_number sll shift_amount; -- Сдвиг вправо для деления result_right <= input_number srl shift_amount; Эти операторы нормально синтезируются? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 2 апреля Опубликовано 2 апреля · Жалоба 1 hour ago, Worldmaster said: Эти операторы нормально синтезируются? Да Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gibson1980 0 2 апреля Опубликовано 2 апреля · Жалоба Странно, а у меня ругается на операторы Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Worldmaster 0 2 апреля Опубликовано 2 апреля · Жалоба В 02.04.2024 в 18:08, gibson1980 сказал: Странно, а у меня ругается на операторы Вот и у меня тоже, но не стал писать. Я сделал по другому: RAM_ROW_ADDR_req <= RAM_READ_PTR(18 downto 8); тут отбрасываю младшую часть это деление RAM_COL_ADDR_BIT_req <= RAM_READ_PTR(7 downto 0); тут отбрасываю старшую часть а это mod Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladec 10 3 апреля Опубликовано 3 апреля · Жалоба 16 часов назад, gibson1980 сказал: Странно, а у меня ругается на операторы Может какую то из библиотек не подключили use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться