Jump to content

    
Sign in to follow this  
Maverick_

инициализация блочной памяти, vhdl

Recommended Posts

Например есть описание блочной памяти с инциализацией следующего вида

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;

entity bram_test is
generic (
    DATA    : integer := 32;
    ADDR    : integer := 8
);
port (
    -- Port A
    a_clk   : in  std_logic;
    a_wr    : in  std_logic;
    a_addr  : in  std_logic_vector(ADDR-1 downto 0);
    a_din   : in  std_logic_vector(DATA-1 downto 0);
    a_dout  : out std_logic_vector(DATA-1 downto 0);

    -- Port B
    b_clk   : in  std_logic;
    b_wr    : in  std_logic;
    b_addr  : in  std_logic_vector(ADDR-1 downto 0);
    b_din   : in  std_logic_vector(DATA-1 downto 0);
    b_dout  : out std_logic_vector(DATA-1 downto 0)
);
end bram_test;

architecture rtl of bram_test is
    -- Shared memory
    type mem_type is array ( (2**ADDR)-1 downto 0 ) of std_logic_vector(DATA-1 downto 0);
    
   -- FUNCTION initialize_ram  return mem_type is variable result : mem_type;
   -- BEGIN
		-- FOR i IN ((2**ADDR)-1) DOWNTO 0 LOOP
			-- result(i) := std_logic_vector( to_unsigned(natural(i), natural'(DATA)));
		-- END LOOP;
   -- RETURN result;
   -- END initialize_ram;
    
    shared variable mem : mem_type := 
(	
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
	"00000000000000000000000000000000",
   
   std_logic_vector(to_unsigned(1073741824, 32 )), --end commands, it is 30 bit = '1'
	--helper commands
	std_logic_vector(to_unsigned(16384, 32 )), -- '1'-on; '0'-off
	std_logic_vector(to_unsigned(64, 32 )), --commands
	--pause
	std_logic_vector(to_unsigned(100, 32 )), --pause_value
	std_logic_vector(to_unsigned(5, 32 )), --time_resolution
	std_logic_vector(to_unsigned(8, 32 )),   --commands

-------------------------------------------------------------------------------------

   --line
    std_logic_vector(to_unsigned(135, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(28, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(135, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(70, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(124, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(71, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(135, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(28, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(123, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(33, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(124, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(71, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(113, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(76, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(123, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(33, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(114, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(41, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(113, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(76, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(105, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(78, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(114, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(41, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(106, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(52, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(105, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(78, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(74, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(87, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(106, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(52, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(112, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(149, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(74, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(87, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(111, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(122, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(112, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(149, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(125, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(160, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(111, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(122, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(125, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(122, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(125, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(160, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(139, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(169, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(125, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(122, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(140, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(122, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(139, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(169, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(152, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(184, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(140, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(122, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(153, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(28, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(152, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(184, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
    --line
    std_logic_vector(to_unsigned(135, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(70, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(153, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(28, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands
	
	-------------------------------------------------------------------------------------	
	--change_plane XY or XZ or YZ
	std_logic_vector(to_unsigned(0, 32 )), --
	std_logic_vector(to_unsigned(32, 32 )),   --commands
	--shim_fsm_Z_axis
	std_logic_vector(to_unsigned(20, 32 )),   -- num_step
	std_logic_vector(to_unsigned(511, 32 )),   -- axis_select
	std_logic_vector(to_unsigned(128, 32 )),    --commands
	--period divider for pwm 
	std_logic_vector(to_unsigned(150, 32 )), --z
	std_logic_vector(to_unsigned(150, 32 )), --Y
	std_logic_vector(to_unsigned(150, 32 )), --X
	std_logic_vector(to_unsigned(16, 32 ))   --commands

	); -- := initialize_ram; --mem_type

	begin

-- Port A
process(a_clk)
begin
    if(a_clk'event and a_clk='1') then
        if(a_wr='1') then
            mem(conv_integer(a_addr)) := a_din;
        end if;
        a_dout <= mem(conv_integer(a_addr));
    end if;
end process;

-- Port B
process(b_clk)
begin
    if(b_clk'event and b_clk='1') then
        if(b_wr='1') then
            mem(conv_integer(b_addr)) := b_din;
        end if;
        b_dout <= mem(conv_integer(b_addr));
    end if;
end process;

end rtl;

можно ли как то задавать инициализацию остальной памяти нулями без их предварительного количественного подсчета ?

Share this post


Link to post
Share on other sites

мне надо чтобы были данные, а оставшиеся пространство памяти я заполняю нулями

в приведенном примере у меня 28 нулей

именно про них и речь

сейчас мне постоянно надо считать оставшиеся свободное пространство и заполнять нулями

я бы хотел автоматизацию типа

(others=>"00000000000000000000000000000000");

и ниже N количество данных

 

Share this post


Link to post
Share on other sites

Сразу не понял.

У вас просто странное как мне кажется заполнение... Если это программа - не легче ли её в другой файл вынести?

Если выполняются начинает с нулевого адреса - почему бы память не объявить так:

	type mem_type is array ( 0 to (2**ADDR)-1) of std_logic_vector(DATA-1 downto 0);
	

Тогда и программа логичнее будет читаться, а не снизу-вверх.

И тогда можно сделать следующую запись:

	0=>std_logic_vector(to_unsigned(16, 32 )), --commands
	1=>std_logic_vector(to_unsigned(150, 32 )), --X
	2=> ....,
	....,
	117=>std_logic_vector(to_unsigned(150, 32 )), --the end
	others => x"00000000")
	

А вообще вы бы рассказали как у вас эти магические числа рождаются.. Может их все таки в отдельном файле держать?

Ну и как минимум для читаемости можно было бы сделать функцию которая делает std_logic_vector(to_unsigned(X),DATA) и назвать её коротенько.

Share this post


Link to post
Share on other sites

В продолжение. Пофантазировать:

    std_logic_vector(to_unsigned(135, 32 )),  --aYEnd_line
    std_logic_vector(to_unsigned(70, 32 )),  --aXEnd_line
    std_logic_vector(to_unsigned(153, 32 )),   --aYStart_line
    std_logic_vector(to_unsigned(28, 32 )),   --aXStart_line
    std_logic_vector(to_unsigned(2, 32 )),    --commands

Вот это заменить на функцию DrawXYLine(XStart,YStart,XEnd,YEnd) которая параметрами возьмёт 4 integer, а вернет 5 (в том числе код команды) std_logic_vector нужного размера.
 

	std_logic_vector(to_unsigned(150, 32 )), --z
	std_logic_vector(to_unsigned(150, 32 )), --Y
	std_logic_vector(to_unsigned(150, 32 )), --X
	std_logic_vector(to_unsigned(16, 32 ))   --commands

Вот это заменить на InitXYZsize(X,Y,Z) с тремя integer в параметрах.

	std_logic_vector(to_unsigned(20, 32 )),   -- num_step
	std_logic_vector(to_unsigned(511, 32 )),   -- axis_select
	std_logic_vector(to_unsigned(128, 32 )),    --commands

SetPWMdiv(Axis,Step)
Объявить type:

 

type tmem_var is array(NATURAL RANGE<>) of std_logic_vector(DATA-1 downto 0);

Объявить функцию:
 

function fill_zeros (in_arr:tmem_var) return tmem_var
	res : tmem_var(0 to 2**ADDR-1) := (others=>(others=>'0'));
begin
	res (0 to in_arr'width-1) := in_arr;
	res (in_arr'width to 2**ADDR-1) := (others=>(others=>'0'));
	return res;
end function;

И после этого ваше заполнение памяти должно стать примерно таким:
 

shared variable mem : tmem_var(0 to 2**ADDR-1) := fill_zeros(
	InitXYZsize(150,150,150) &
	SetPWMdiv(511,20) &
	DrawXYLine(28,153,70,135) &
	DrawXYLine(184,152,28,153) &
);

Ну примерно так хотя бы.

PS. За синтаксис не ручаюсь - я ради общей идеи писал.

Share this post


Link to post
Share on other sites

Возможно так?

mem <= (data'High downto data'Low=> data, others => "00000000000000000000000000000000");

 

Дико извиняюсь за оффтоп, однако меня просто сводит с ума одна проблема. Не буду тему создавать отдельно...

12 hours ago, Maverick_ said:

FUNCTION initialize_ram return mem_type is variable result : mem_type; 
BEGIN 
  FOR i IN ((2**ADDR)-1) DOWNTO 0 LOOP 
  result(i) := std_logic_vector( to_unsigned(natural(i), natural'(DATA))); 
  END LOOP; 
  RETURN result;

 

в подобной функции вивада выдает варнинг на каждый проход цикла, ругается на то что ожидает unsigned. Все. Больше инфы не дает. Можно конечно игнорить их, но рука как то не поднимается отправить в игнор 999+ варнингов. Пробовал разные преобразования типов, не помогает.

вот код

-----
-----
-----
	constant hi_angle_width                  : integer                                        := angle_width / 2; --ширина шины адреса памяти грубых углов
	constant low_angle_width                 : integer                                        := angle_width - (angle_width / 2); --ширина шины адреса памяти точных углов
	constant real_to_integer_transform_coeff : real                                           := (2 ** real(sin_cos_width - 1)) - 1.0; --коэффициент преобразования синуса углов в целочисленное представление
	constant worst_angle_resolution          : real                                           := (2.0 * MATH_PI) / (2 ** real(hi_angle_width)); --величина (в радианах) младшего разряда грубого угла
	constant fine_angle_resolution           : real                                           := worst_angle_resolution / (2 ** real(low_angle_width)); --величина (в радианах) младшего разряда точного угла
-----
-----
-----
	type hi_angle_rom is array ((2 ** hi_angle_width) - 1 downto 0) of signed(sin_cos_width - 1 downto 0);
	type low_angle_rom is array ((2 ** low_angle_width) - 1 downto 0) of signed(sin_cos_width - 1 downto 0);

	--Инициализация памяти синусов грубых углов
	function init_hi_sin_rom return hi_angle_rom is
		variable tmp : hi_angle_rom := (others => (others => '0'));
	begin
		for addr_pos in 0 to (2 ** hi_angle_width) - 1 loop
			tmp(addr_pos) := to_signed(integer(real_to_integer_transform_coeff * sin(real(addr_pos) * worst_angle_resolution)), sin_cos_width);
		end loop;
		return tmp;
	end init_hi_sin_rom;
----
----
----

sin_cos_width к natural преобразовывал. Не помогло. Раньше вроде не было такого. Гугление решения как то не дало. Я что-то упускаю может быть...

Edited by Strob

Share this post


Link to post
Share on other sites

Ачтобы не заполнять нулями, можно память сразу инициализировать нулями, а потом заполнить данными, как выше в примере:

variable tmp : hi_angle_rom := (others => (others => '0'));

Share this post


Link to post
Share on other sites
10 hours ago, Maverick_ said:

и ниже N количество данных

Если бы не ограничение в десятичном формате входных данных, то я бы посоветовал использовать файл инициализации памяти в формате mif. Там можно в hex'е спокойно задать нужные строки и забыть о проблемах. Да и память можно будет описать как уничерсальный компонент. Единственное перевести с десятичной в шеснадчетиричную систему придётся какими-то внешними скриптами или через Эксель.

Вот формат в котором можно будет заполнять mif файл:

// memory initialization file
00	// Это нулевой адресс. Комментарий удалить
00	// Это первый адресс. Комментарий удалить
@02 a5 70 a5 2d a5 00 5a 00 de ad be ef 04 ff		// Это данные со второго адресса. Комментарий удалить
@10 05 06 07 08 09 0A 0B 0C 0D 0F AA 1b 1c 1d 1e 1f	// Это даннфе с десятого адресса. Комментарий удалить
00
00
00
00

Если задать в настройках, что нужно инициализировать все необъявленные данные в 0, тогда достаточно адрессного объявления нужных строк в файле инициализации, остальное будет автоматом заполнено нулями.

Внимание! Комментировать строки в mif файле можно только в самом начале. Где написано удалить - нужно удалить перед использованием.

UPD Ах да, в данном случае показана память байтовой ширины. Для 32 бит каждая строка должна бить в формате хххх_хххх_хххх_хххх (без подчёркиваний)

Share this post


Link to post
Share on other sites
11 hours ago, AJIEKCEu said:

А вообще вы бы рассказали как у вас эти магические числа рождаются.. Может их все таки в отдельном файле держать?

Делаю интерпретатор G code - управление шаговыми двигателями, движение по прямой, по дуге (по часой стрелке или против), винтовое движениеи так далее..

это мне надо для проверки работы

Share this post


Link to post
Share on other sites

а в VHDL нельзя разве для создания ROM вызывать функцию, в которой набирать ее значения построчно? Только в объявлении и только руками? Вроде в прошлой жизни, я делал генерируемые таблицы на VHDL, проблем не испытывал. 

Share this post


Link to post
Share on other sites
38 minutes ago, des00 said:

а в VHDL нельзя разве для создания ROM вызывать функцию, в которой набирать ее значения построчно? Только в объявлении и только руками? Вроде в прошлой жизни, я делал генерируемые таблицы на VHDL, проблем не испытывал. 

Конечно можно. Это називается инициализированная память с mif  или coe  файлами. Всё работает, только оно не воспринимает десятичные значения (ну или я не туда смотрел).

Share this post


Link to post
Share on other sites
15 minutes ago, Nick_K said:

Конечно можно. Это називается инициализированная память с mif  или coe  файлами. Всё работает, только оно не воспринимает десятичные значения (ну или я не туда смотрел).

да в топку ваши mif и coe файлы. У меня куча таблиц инициализируется на лету. Типа вот так 

localparam baseHc_t Hb = get_scaled_Hc(pIDX_GR, pIDX_LS, pIDX_ZC);

И все работает, без привязки с софту, технологическим файлам и т.д. В функции можно делать все что угодно. Примеры можно в теме про FEC посмореть. 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this