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

Можно ли тут что нибудь оптимизировать?

Здравствуйте.

Вот сделал модуль для работы с оперативой.

Он нормально работает но может быть кто то подскажет как тут можно что нибудь оптимизировать чтобы максимально поднять скорость работы?

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use IEEE.numeric_std.all;  



entity SDRAM_SERIALIZER is 
 
port ( 
    rst_n : in std_logic;  

	isdram_clk : in std_logic; 
	isdrc_clk : in std_logic; 
 
    RAM_InitComplete: out std_logic;

	cam1_data_ready: in std_logic;
	cam1_write_clk: in std_logic;
	cam1_WriteData: in std_logic_vector(15 downto 0);
	
	cam2_data_ready: in std_logic;
	cam2_write_clk: in std_logic; 
	cam2_WriteData: in std_logic_vector(15 downto 0);
		  
	Buf_Read_Request: in std_logic;						-- флаг сообщает что необходимо начать считывание данных из оперативы
	Buf_Read_Valid: out std_logic;						-- флаг валидности данных
	Buf_ReadData: out std_logic_vector(31 downto 0);	 -- данные для передачи в выходной буфер
	FIFO_AlmostFull: in std_logic; -- показывает что приемный буфер почти пуст чтобы модуль оперативы начал заполнение
	FIFO_AlmostEmpty: in std_logic; -- почти пустой буфер имеет приоритет при отправке
	
	max_frame_size: in std_logic_vector(16 downto 0); -- максимальное количество для считывания и записи с нуля из оперативы. Запись и считывание происходит циклично
	reset_read_ptr: in std_logic; -- сигнал для сброса указателя считывания	
	
	Busy: out std_logic;
	all_data_read_complete: out std_logic;
	
    IO_sdram_dq: inout std_logic_vector(31 downto 0);
    O_sdram_clk: out std_logic;
    O_sdram_cke: out std_logic;
    O_sdram_cs_n: out std_logic;
    O_sdram_cas_n: out std_logic;
    O_sdram_ras_n: out std_logic;
    O_sdram_wen_n: out std_logic;
    O_sdram_dqm: out std_logic_vector(3 downto 0);
    O_sdram_addr: out std_logic_vector(10 downto 0);
    O_sdram_ba: out std_logic_vector(1 downto 0)
); 
end SDRAM_SERIALIZER;

 
architecture logic of SDRAM_SERIALIZER is  
constant WRITE: std_logic := '0';
constant READ: std_logic := '1'; 
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
     

--signal Ack: std_logic; -- подтверждение операции
signal IsDataReady: std_logic;	-- флаг готовности данных
signal IsReady: std_logic;	-- флаг готовности модуля
signal ReadData: std_logic_vector(31 downto 0):= (others => 'Z'); -- данные для чтения
signal WriteData: std_logic_vector(31 downto 0); 	-- данные для записи 
  
-- для модуля работы с сдрам 
signal RAM_transmit_en : std_logic:='0';	-- флаг начала передачи
signal RAM_RW: std_logic:='0';	-- чтение или запись
signal RAM_Data_count: std_logic_vector(7 downto 0) := (others => 'Z');	-- количество данных для чтения или записи
signal RAM_Bank_addr: std_logic_vector(1 downto 0) := (others => 'Z'); 	
signal RAM_Row_addr: std_logic_vector(10 downto 0) := (others => 'Z'); 	
signal RAM_Col_addr: std_logic_vector(7 downto 0) := (others => 'Z'); 	 
signal RAM_IsDataReady: std_logic:='0';	-- флаг готовности данных
signal RAM_IsReady: std_logic;	-- флаг готовности модуля
signal RAM_ReadData: std_logic_vector(31 downto 0);	-- данные для чтения
signal RAM_WriteData: std_logic_vector(31 downto 0);	-- данные для записи 
signal RAM_Ack: std_logic:='0'; 
signal RAM_EXCHANGE_COMPLETE: std_logic:= '0'; -- флаг показывает что транзакция взаимодействия с оперативой завершена 
 
 
signal all_data_read_complete_s: std_logic := '0'; 
 
 -- пропишем просто сигналы для запроса а не массив
signal RAM_ROW_ADDR_req: std_logic_vector(10 downto 0) := (others => '0'); 	 
signal RAM_COL_ADDR_BIT_req: std_logic_vector(7 downto 0) := (others => '0'); 
signal RAM_RW_BIT_req: std_logic:='0';  
signal RAM_32BIT_WORD_COUNT_BIT_req: std_logic_vector(7 downto 0) := (others => 'Z');   
signal ram_start_processing: std_logic:='0'; -- при исполнении пакета фиксируем old_state 
 
signal fifo_rst_i: std_logic:='0';  

signal cam1_rst_i: std_logic:='0'; 		
signal cam1_ReadData : std_logic_vector(31 downto 0):=(others=>'0'); 		
signal cam1_read_count : std_logic_vector(9 downto 0):=(others=>'0');
signal cam1_write_count : std_logic_vector(10 downto 0):=(others=>'0');
signal cam1_almost_empty : std_logic:='0'; 		 
signal cam1_almost_empty_160 : std_logic:='0'; 

signal cam2_rst_i: std_logic:='0';
signal cam2_in_clk_read_i: std_logic:='0';
signal cam2_in_clk_write_i: std_logic:='0';  		
signal cam2_ReadData : std_logic_vector(31 downto 0):=(others=>'0'); 		
signal cam2_read_count : std_logic_vector(9 downto 0):=(others=>'0');
signal cam2_write_count : std_logic_vector(10 downto 0):=(others=>'0'); 
signal cam2_almost_empty : std_logic:='0'; 		
	  
signal RAM_READ_PTR: integer := 0;
signal RAM_WRITE_PTR: integer := 0;
signal MAX_FRAME_LEN: integer := 78400; -- максимальный размер кадра в памяти 560*560 в блоках по 32
    
signal cam1_read_en : std_logic := '0';   
signal cam2_read_en : std_logic := '0';  
 
signal cam_index: std_logic:= '0'; 

type BUF_CTRL_PROC_LOC_FSM_STATE is (RESET, IDLE, START,START_READ, START_WRITE,  PROCESSING);
signal BUF_CTRL_PROC_loc_state: BUF_CTRL_PROC_LOC_FSM_STATE := RESET;  

type SDRAM_PROC_LOC_FSM_STATE is (Init, Idle, pre_proc, Processing);
signal SDRAM_PROC_loc_state: SDRAM_PROC_LOC_FSM_STATE := idle; 
signal SDRAM_IO_word_cntr: integer := 0; 

signal reset_write_ptr: std_logic := '0';
signal forceRead: std_logic:='0';
signal bus_clear: std_logic:='0';
signal SDRAMInitDone: std_logic := '0';
signal Total_data_count: integer := 0;
signal do_work: std_logic := '0'; 
signal lock_read: std_logic := '0';
   
signal cam1buf_empty: std_logic := '0';
signal cam1buf_full: std_logic := '0';
signal cam2buf_empty: std_logic := '0';
signal cam2buf_full: std_logic := '0';
   
signal can_read : std_logic := '0';
signal can_write : std_logic := '0';
   
component cam_hs
	port (
		Data: in std_logic_vector(15 downto 0);
		Reset: in std_logic;
		WrClk: in std_logic;
		RdClk: in std_logic;
		WrEn: in std_logic;
		RdEn: in std_logic;
		Wnum: out std_logic_vector(10 downto 0);
		Rnum: out std_logic_vector(9 downto 0);
		Almost_Empty: out std_logic;
		Q: out std_logic_vector(31 downto 0);
		Empty: out std_logic;
		Full: out std_logic
	);
end component;
  

component SDRAM_MODULE
	port (
		rst_n : in std_logic:= '0';   
		sdram_clk : in std_logic:= '0';   
		sdrc_clk : in std_logic:= '0';    

		IO_sdram_dq: inout std_logic_vector(31 downto 0):=(others=>'0');
		O_sdram_clk: out std_logic:= '0';  
		O_sdram_cke: out std_logic:= '0';  
		O_sdram_cs_n: out std_logic:= '0';  
		O_sdram_cas_n: out std_logic:= '0';  
		O_sdram_ras_n: out std_logic:= '0';  
		O_sdram_wen_n: out std_logic:= '0';  
		O_sdram_dqm: out std_logic_vector(3 downto 0):=(others=>'0');
		O_sdram_addr: out std_logic_vector(10 downto 0):=(others=>'0');
		O_sdram_ba: out std_logic_vector(1 downto 0):=(others=>'0');
  
		transmit_en : in std_logic:= '0';	-- флаг начала передачи
		RW: in std_logic:= '0';	-- чтение или запись
		Data_count: in std_logic_vector(7 downto 0):=(others=>'0');	-- количество данных для чтения или записи
		Bank_addr: in std_logic_vector(1 downto 0) :=(others=>'0');
		Row_addr: in std_logic_vector(10 downto 0):=(others=>'0');
		Col_addr: in std_logic_vector(7 downto 0) :=(others=>'0');	 
		IsDataReady: out std_logic:= '0';	-- флаг готовности данных
		IsReady: out std_logic:= '0';	-- флаг готовности модуля
		InitDone: out std_logic:= '0';  
		ReadData: out std_logic_vector(31 downto 0):=(others=>'0');	-- данные для чтения
		WriteData: in std_logic_vector(31 downto 0):=(others=>'0');	-- данные для записи 
		Ack: out std_logic:= '0'
	);
end component;
 
component CDC is
   port (
    I_clk_dest : in std_logic;   		
	signal_in : in std_logic;   
	signal_out : out std_logic 	
   );
end component;
 
begin  
--------------------------------------------------------------------------------------------
 
cam1buf: cam_hs
	port map (
		Data => cam1_WriteData,
		Reset => cam1_rst_i,
		WrClk => cam1_write_clk,
		RdClk => isdrc_clk,
		WrEn => cam1_data_ready,
		RdEn => cam1_read_en,
		Wnum => cam1_write_count,
		Rnum => cam1_read_count, 
		Almost_Empty => cam1_almost_empty,
		Q => cam1_ReadData,
		Empty => cam1buf_empty,
		Full => cam1buf_full
	);
	
	
--------------------------------------------------------------------------------------------

cam2buf: cam_hs
	port map (
		Data => cam2_WriteData,
		Reset => cam2_rst_i,
		WrClk => cam2_write_clk,
		RdClk => isdrc_clk,
		WrEn => cam2_data_ready,
		RdEn => cam2_read_en,
		Wnum => cam2_write_count,
		Rnum => cam2_read_count, 
		Almost_Empty => cam2_almost_empty,
		Q => cam2_ReadData,
		Empty => cam2buf_empty,
		Full => cam2buf_full
	);
	
 --------------------------------------------------------------------------------------------
MySDRAM: SDRAM_MODULE
	port map (
		rst_n => rst_n, 
		sdram_clk => isdram_clk,
		sdrc_clk => isdrc_clk, 

		IO_sdram_dq => IO_sdram_dq,
		O_sdram_clk => O_sdram_clk,
		O_sdram_cke => O_sdram_cke,
		O_sdram_cs_n => O_sdram_cs_n,
		O_sdram_cas_n => O_sdram_cas_n,
		O_sdram_ras_n => O_sdram_ras_n,
		O_sdram_wen_n => O_sdram_wen_n,
		O_sdram_dqm => O_sdram_dqm,
		O_sdram_addr => O_sdram_addr,
		O_sdram_ba => O_sdram_ba,
 
		transmit_en =>	RAM_transmit_en,
		RW 			=>	RAM_RW, 
		Data_count	 => RAM_Data_count,
		Bank_addr	 => RAM_Bank_addr,
		Row_addr	 => RAM_Row_addr,
		Col_addr	 => RAM_Col_addr,
		IsDataReady	 => RAM_IsDataReady,
		IsReady		 => RAM_IsReady,
		ReadData	 => RAM_ReadData,
		WriteData	 => RAM_WriteData,
        InitDone => SDRAMInitDone,
		Ack => RAM_Ack
);


 cam1_almost_empty_cdc: CDC  
   port map(
      I_clk_dest => isdrc_clk,
      signal_in  => cam1_almost_empty,
      signal_out => cam1_almost_empty_160
   ); 

--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
RAM_InitComplete <= SDRAMInitDone; 
Busy <= '0' when BUF_CTRL_PROC_loc_state = IDLE else '1';
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------- 

cam1_rst_i <= not rst_n;  
cam2_rst_i <= not rst_n;  
fifo_rst_i <= not rst_n;  
all_data_read_complete <= all_data_read_complete_s;
 
Buf_ReadData <= RAM_ReadData; 
Buf_Read_Valid <= '1' when RAM_IsDataReady = '1' and RAM_RW_BIT_req = READ else '0'; 
   
  
cmp_proc: process(rst_n, isdrc_clk,ram_ack,MAX_FRAME_LEN,RAM_READ_PTR)
variable new_val: integer;
begin   
if rst_n = '0' then
	all_data_read_complete_s <= '0'; 
elsif rising_edge(isdrc_clk) then	 
	if ram_ack = '1' then -- обновляем только когда модуль закончил чтение
		new_val := to_integer(unsigned(max_frame_size));  
		
		if new_val /= MAX_FRAME_LEN then 		
			reset_write_ptr <= '1';
		else 
			reset_write_ptr <= '0';
		end if;
		
		if RAM_READ_PTR >= MAX_FRAME_LEN then 
			all_data_read_complete_s <= '1';  
		else 
			all_data_read_complete_s <= '0';
		end if;
		
		MAX_FRAME_LEN <= new_val;  
	end if;
end if;
end process cmp_proc;
 

-- процесс длясчетчика указателей в оперативе для чтения или записи данных
SDRAM_IO: process(rst_n, isdrc_clk,reset_read_ptr,reset_write_ptr, do_work, RAM_IsDataReady,SDRAM_IO_word_cntr, RAM_RW_BIT_req, cam_index, RAM_WRITE_PTR, RAM_READ_PTR, MAX_FRAME_LEN, Total_data_count)
variable allow_work: std_logic := '0';
begin  
if rst_n = '0' then
	RAM_WRITE_PTR <= 0;
	RAM_READ_PTR <= 0; 
elsif rising_edge(isdrc_clk) then
    if reset_read_ptr = '1' then
        RAM_READ_PTR <= 0; 
    end if;  
	
	if reset_write_ptr = '1' then 
		RAM_WRITE_PTR <= 0;
	end if;
	 
	lock_read <= '0';	
	if do_work = '1' then 
		if SDRAM_IO_word_cntr <= Total_data_count - 1   then
			allow_work := '1';			
		else 
			allow_work := '0';
		end if; 
		
		if SDRAM_IO_word_cntr < Total_data_count - 1   then
			lock_read <= '0';			
		else 
			lock_read <= '1';
		end if; 
		
		if allow_work = '1' then 
			if RAM_IsDataReady = '1' then   			 		
				if RAM_RW_BIT_req = WRITE then	
					if RAM_WRITE_PTR >= MAX_FRAME_LEN - 1 then
						RAM_WRITE_PTR <= 0;
					else 
						RAM_WRITE_PTR <= RAM_WRITE_PTR + 1;
					end if;																
				else   
					if RAM_READ_PTR <= MAX_FRAME_LEN - 1 then                        
						RAM_READ_PTR <= RAM_READ_PTR + 1;
					end if;
				end if;  
				SDRAM_IO_word_cntr <= SDRAM_IO_word_cntr + 1; 			 
			end if;    
		end if;
	else 
		SDRAM_IO_word_cntr <= 0; 
	end if; 
end if;
end process SDRAM_IO;

-- определяен какую камеру подключать в момент. пока работа только с одной камерой
process(RAM_IsDataReady, RAM_RW_BIT_req, cam_index, cam1_ReadData, cam2_ReadData)  
begin  
	RAM_WriteData <= (others => '0'); 
	if RAM_IsDataReady = '1' and RAM_RW_BIT_req = WRITE then 
		if cam_index = '0' then 
			RAM_WriteData <= cam1_ReadData;
			cam1_read_en <= '1';
			cam2_read_en <= '0';
		else 
			cam2_read_en <= '1';
			cam1_read_en <= '0';
			RAM_WriteData <= cam2_ReadData;
		end if; 
	else 
		cam1_read_en <= '0';
		cam2_read_en <= '0';
	end if;  
end process;

-- обработчик чтения или записи данных SDRAM
SDRAM_PROC:process (rst_n, isdrc_clk, SDRAM_PROC_loc_state, RAM_IsReady, ram_start_processing, ram_ack)
begin 
if rst_n = '0' then 
	SDRAM_PROC_loc_state <= idle;
	RAM_Bank_addr 	<= (others=>'0');
	RAM_Row_addr 	<= (others=>'0');
	RAM_Col_addr 	<= (others=>'0');
	RAM_Data_count 	<= (others=>'0');
elsif rising_edge(isdrc_clk) then	 
	RAM_Bank_addr 	<= (others=>'0');
	
	case SDRAM_PROC_loc_state is 
		when idle=>
			if ram_start_processing = '1' then
				SDRAM_PROC_loc_state <= init; 	
				RAM_EXCHANGE_COMPLETE <= '0'; 
			else
				RAM_EXCHANGE_COMPLETE <= '1';
				RAM_transmit_en <= '0';  
				RAM_Row_addr 	<= (others=>'0');
				RAM_Col_addr 	<= (others=>'0');
				RAM_Data_count 	<= (others=>'0');
			end if; 
		when init =>
			-- инициирование параметров транзакции
			if RAM_IsReady = '1' then   
				RAM_Row_addr <= RAM_ROW_ADDR_req; 
				RAM_Col_addr <= RAM_COL_ADDR_BIT_req; 
				RAM_Data_count <= RAM_32BIT_WORD_COUNT_BIT_req;  -- задаем значение для контроллера, отправляется + 1
				Total_data_count <= to_integer(unsigned(RAM_32BIT_WORD_COUNT_BIT_req)) + 1;  
				RAM_RW <= RAM_RW_BIT_req;				  			
				RAM_transmit_en <= '1';
				SDRAM_PROC_loc_state <= pre_proc; 
			end if; 
		when pre_proc => 	
			do_work <= '1';
			SDRAM_PROC_loc_state <= processing; 
		when processing=> 
			if ram_ack = '1' then  
				SDRAM_PROC_loc_state <= idle; 
				do_work <= '0';
				RAM_transmit_en <= '0';
			end if; 			
	end case;	 
end if;
end process SDRAM_PROC;

bus_clear <= '1' when Buf_Read_Request = '1' and all_data_read_complete_s = '0' else '0';	-- объединяет сигналы в одно чтобы использовать дальше 		
forceRead <= '1' when bus_clear = '1' and FIFO_AlmostEmpty = '1'  else '0';	 -- если буфер почти пустой то читаем более агресивно игнорируя размер в буфере камеры. Размер буфера выбран больше.
can_read <= '1' when bus_clear = '1' and FIFO_AlmostFull = '0'  else '0';		-- показывает что можно начать считывать
can_write <= '1' when cam1_almost_empty_160 = '0' and forceRead = '0' else '0'; -- можно начать запись
			
			
BUF_CTRL_PROC:process (rst_n, isdrc_clk, RAM_EXCHANGE_COMPLETE, can_write, ram_ack, BUF_CTRL_PROC_loc_state, can_read)
variable rptr: std_logic_vector(18 downto 0):= (others => '0');
variable wptr: std_logic_vector(18 downto 0):= (others => '0');
variable  count: integer := 0; 
variable  ellapsed_count: integer := 0;  
begin
if rst_n = '0' then
    BUF_CTRL_PROC_loc_state <= RESET; 
elsif rising_edge(isdrc_clk) then 
	case BUF_CTRL_PROC_loc_state is 
		when RESET => 
            BUF_CTRL_PROC_loc_state <= IDLE; 
			ram_start_processing <= '0';
			
			RAM_RW_BIT_req <= '0';  
			RAM_ROW_ADDR_req <= (others=>'0');
			RAM_COL_ADDR_BIT_req <= (others=>'0');
			RAM_32BIT_WORD_COUNT_BIT_req <= (others=>'0'); 
		when IDLE => 
			-- если есть возможность то начинаем выполнять запись или чтение
			if RAM_EXCHANGE_COMPLETE = '1' then  
				if can_write = '1' then   
					BUF_CTRL_PROC_loc_state <= START_WRITE;  
				elsif can_read = '1' then
					BUF_CTRL_PROC_loc_state <= START_READ; 
				end if;  
			end if;
		when START_READ =>
			-- начинаем процесс чтения из оперативы в выходной буфер			
			rptr:= std_logic_vector(to_unsigned(RAM_READ_PTR, 19));  
			BUF_CTRL_PROC_loc_state <= START; 
			RAM_RW_BIT_req <= READ; -- читаем =1, пишем 0		 
			RAM_ROW_ADDR_req <= rptr(18 downto 8);	
			RAM_COL_ADDR_BIT_req <= rptr(7 downto 0);	

			ellapsed_count := MAX_FRAME_LEN - RAM_READ_PTR;
			-- контроль остатков для чтения если запрашивается не кратное количество
			if ellapsed_count >= 256 then                        
				count := 255;
			else 
				count := ellapsed_count - 1;
			end if; 
			
			RAM_32BIT_WORD_COUNT_BIT_req <=  std_logic_vector(to_unsigned(count, RAM_32BIT_WORD_COUNT_BIT_req'length));	-- 256 за раз всю строку 
		when START_WRITE =>
			 
			-- начинаем процесс записи в оперативу 
			wptr:= std_logic_vector(to_unsigned(RAM_WRITE_PTR, 19));  
			-- половина буфера заполнена, надо скинуть в память
			BUF_CTRL_PROC_loc_state <= START; 
			RAM_RW_BIT_req <= WRITE; -- читаем =1, пишем 0	 
			RAM_ROW_ADDR_req <= wptr(18 downto 8);	
			RAM_COL_ADDR_BIT_req <= wptr(7 downto 0);	 	

			ellapsed_count := MAX_FRAME_LEN - RAM_WRITE_PTR;
			-- контроль остатков для чтения если запрашивается не кратное количество
			if ellapsed_count >= 128 then                        
				count := 127;
			else 
				count := ellapsed_count-1;
			end if;  
			RAM_32BIT_WORD_COUNT_BIT_req <= std_logic_vector(to_unsigned(count, RAM_32BIT_WORD_COUNT_BIT_req'length));	 
		when START =>  
			-- ждем пока модуль закончит транзакцию
			ram_start_processing <= '1'; 
			if ram_ack = '0' then
				BUF_CTRL_PROC_loc_state <= PROCESSING; 
			end if;
		when PROCESSING =>
			-- ждем пока головной процесс отключит чтобы не читалось повторно
			ram_start_processing <= '0';
			if ram_ack = '1' then
				BUF_CTRL_PROC_loc_state <= RESET;
			end if;
	end case;
end if;

end process BUF_CTRL_PROC;

end architecture;

 

Сейчас у меня максимально дает вот такие параметры:

image.thumb.png.1f3a007445c266dfa657d72fbb9bdc95.png

 

Но почему то кажется что можно еще лучше.

Буду признателен за объективную критику. 

Спасибо.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...