Worldmaster 0 7 марта Опубликовано 7 марта · Жалоба Здравствуйте. Сделал класс буфера данных под свои нужды. Просьба, кому не лень, можете указать что тут можно сделать лучше? Потому как меня не покидает чувство что где то тут косячина. Буфер у меня цикличный. Но внешнему блоку нужно знать сколько данных в нем уже есть чтобы давать команды либо на заполнение буфера либо на перенос данных в оперативу. Меня смущает цикл info_proc. Но как более правильно сделать обновление счетчиков я не придумал. entity DATA_BUFFER is generic( MAX_BUF_CNT : integer := 64; -- задает размер буфера в блоках DATA_WRITE_WIDTH : integer := 32 -- задает ширину блока ); port ( in_clk_update_i : in std_logic; -- хрень чтобы оперативно получать актуальное состояние in_clk_read_i : in std_logic; -- клок для считывания in_clk_write_i : in std_logic; -- клок для записи rst_i : in std_logic; -- ресет WriteData : in std_logic_vector(DATA_WRITE_WIDTH-1 downto 0); ReadData : out std_logic_vector(31 downto 0):=(others=>'0'); read_count : out std_logic_vector(9 downto 0):=(others=>'0'); -- счетчик показывающий доступное количество для считывания write_count : out std_logic_vector(9 downto 0):=(others=>'0') -- счетчик показывающий количество для записи ); end DATA_BUFFER; architecture logic of DATA_BUFFER is type MEMBuffer is array (0 to MAX_BUF_CNT-1) of std_logic_vector(DATA_WRITE_WIDTH-1 downto 0); signal fifo_buffer: MEMBuffer := (others=>(others=>'0')); signal read_ptr: integer := 0; signal write_ptr: integer := 0; -- упрощенная замена модулю. модуль возможен только по числу стемени двойки function rMod(value: integer; maxSize: integer) return integer is begin if value >= maxSize then return value - maxSize; else return value; end if; end function; -- функция проверки байт в кольцевом буфере function CountDataAvailableForRead(buffer_size : integer; read_ptr, write_ptr : integer) return integer is begin return rMod(write_ptr - read_ptr + buffer_size, buffer_size); end function; function CountDataAvailableForWrite(buffer_size : integer; read_ptr, write_ptr : integer) return integer is begin if read_ptr = write_ptr then return buffer_size; else return rMod(read_ptr - write_ptr + buffer_size, buffer_size); end if; end function; begin info_proc: process(rst_i, in_clk_update_i) begin if rst_i = '0' then elsif rising_edge(in_clk_update_i) then read_count <= std_logic_vector(to_unsigned(CountDataAvailableForRead(MAX_BUF_CNT, read_ptr, write_ptr),read_count'length)); write_count <= std_logic_vector(to_unsigned(CountDataAvailableForWrite(MAX_BUF_CNT, read_ptr, write_ptr),write_count'length)); end if; end process info_proc; write_proc: process(rst_i, in_clk_write_i) begin if rst_i = '0' then elsif rising_edge(in_clk_write_i) then fifo_buffer(write_ptr) <= WriteData; if write_ptr >= MAX_BUF_CNT - 1 then write_ptr <= 0; else write_ptr <= write_ptr + 1; end if; end if; end process write_proc; read_proc: process(rst_i, in_clk_read_i) begin if rst_i = '0' then elsif rising_edge(in_clk_read_i) then if DATA_WRITE_WIDTH = 32 then ReadData <= fifo_buffer(read_ptr); if read_ptr >= MAX_BUF_CNT - 1 then read_ptr <= 0; else read_ptr <= read_ptr + 1; end if; elsif DATA_WRITE_WIDTH = 16 then ReadData <= fifo_buffer(read_ptr) & fifo_buffer(read_ptr + 1); if read_ptr >= MAX_BUF_CNT - 2 then read_ptr <= 0; else read_ptr <= read_ptr + 2; end if; end if; end if; end process read_proc; end architecture; Вроде бы по частотам все проходит. Но если тут можно что то улучшить то буду благодарен за указку. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 7 марта Опубликовано 7 марта · Жалоба Не страдайте ерундой. FIFO и есть кольцевой буфер. И оно показывает, сколько в нём занято ячеек. Зная его глубину, получаете свободное место. Возьмите или IP-ядро двуклокового FIFO вашего вендора, или найдите код в интернете. На том же Гитхабе есть несколько VHDL-фреймворков, в которых есть FIFO. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Worldmaster 0 7 марта Опубликовано 7 марта · Жалоба В 07.03.2024 в 17:40, andrew_b сказал: Возьмите или IP-ядро двуклокового FIFO вашего вендора Ладно ... Уболтали. )) Похоже что у штатной корки и правда все что мне нужно. Осталось проверить ее скорострельность. Еще бы вопрос с MIPI разрулить и будет вообще все шикарно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться