Forum Discussion
Altera_Forum
Honored Contributor
11 years agoHello Everybody,
thanks for keeping track of my problem! My solution at the moment looks like this:
-----------------------------------------------------------------------------
-- Dual Ported RAM Declaration + attributes
-----------------------------------------------------------------------------
SHARED VARIABLE ram : ram_t := initramfromfile(g_mem_ini_file);
SIGNAL s_data_read_a : word_t;
SIGNAL s_data_read_b : word_t;
ATTRIBUTE ramstyle : STRING;
ATTRIBUTE ramstyle OF ram : VARIABLE IS "M10K, no_rw_check";
ATTRIBUTE ram_init_file : STRING;
ATTRIBUTE ram_init_file OF ram : VARIABLE IS g_mem_ini_file;
-----------------------------------------------------------------------------
BEGIN -- rtl
s_int_address_a <= conv_integer(address_a);
s_int_address_b <= conv_integer(address_b);
-- Reorganize the read data from the RAM to match the output
unpack : FOR i IN 0 TO 3 GENERATE
data_read_a(8*i + 7 DOWNTO 8*i) <= s_data_read_a(i);
data_read_b(8*i + 7 DOWNTO 8*i) <= s_data_read_b(i);
END GENERATE unpack;
PROCESS(clk_a)
BEGIN
IF(clk_a'EVENT AND clk_a = '1') THEN
IF(enable_a = '1') THEN
IF(write_byte_enable_a(0) = '1') THEN
ram(s_int_address_a)(0) := data_write_a(7 DOWNTO 0);
END IF;
IF write_byte_enable_a(1) = '1' THEN
ram(s_int_address_a)(1) := data_write_a(15 DOWNTO 8);
END IF;
IF write_byte_enable_a(2) = '1' THEN
ram(s_int_address_a)(2) := data_write_a(24 DOWNTO 16);
END IF;
IF write_byte_enable_a(3) = '1' THEN
ram(s_int_address_a)(3) := data_write_a(31 DOWNTO 25);
END IF;
END IF;
s_data_read_a <= ram(s_int_address_a);
END IF;
END PROCESS;
PROCESS(clk_b)
BEGIN
IF(clk_b'EVENT AND clk_b = '1') THEN
IF(enable_b = '1') THEN
IF(write_byte_enable_b(0) = '1') THEN
ram(s_int_address_b)(0) := data_write_b(7 DOWNTO 0);
END IF;
IF write_byte_enable_b(1) = '1' THEN
ram(s_int_address_b)(1) := data_write_b(15 DOWNTO 8);
END IF;
IF write_byte_enable_b(2) = '1' THEN
ram(s_int_address_b)(2) := data_write_b(23 DOWNTO 16);
END IF;
IF write_byte_enable_b(3) = '1' THEN
ram(s_int_address_b)(3) := data_write_b(31 DOWNTO 24);
END IF;
END IF;
s_data_read_b <= ram(s_int_address_b);
END IF;
END PROCESS;
END altera;
And it looks like it is working! I synthesized this code and saw in the reports that actually the M10K was generated. Probably the problem was that I tried to generate a 2D array which was address X 32 bit. Once I used the array with address X 3 X 8 bit, it worked fine. I don't understand why the synthesis tool doesn't understand this, but at least that problem is solved ;) BTW: Why can't I use there a loop expression to avoid writing it four times? I mean like this (which should be exactly the same like above):
PROCESS(clk_a)
BEGIN
IF(clk_a'EVENT AND clk_a = '1') THEN
IF(enable_a = '1') THEN
FOR i IN 0 TO 3 LOOP
IF(write_byte_enable_a(i) = '1') THEN
ram(s_int_address_a)(i) := data_write_a(8*i+7 DOWNTO 8*i);
END IF;
END LOOP;
END IF;
s_data_read_a <= ram(s_int_address_a);
END IF;
END PROCESS;
With this Loop, Quartus gives me the same error messeges like posted in my initial post. Anyway, I just still have some trouble with the RAM init function which I wrote. For testing purposes I striped it down to this:
IMPURE FUNCTION initramfromfile (ramfilename : STRING) RETURN ram_t IS
FILE ini_file : TEXT OPEN READ_MODE IS ramfilename;
VARIABLE fileline : LINE;
VARIABLE ram_dp : ram_t := (OTHERS => (OTHERS => (OTHERS => '0')));
VARIABLE data_slv : STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE char : CHARACTER;
BEGIN
FOR i IN ram_t'RANGE LOOP
IF (NOT endfile(ini_file)) THEN
FOR j IN 3 DOWNTO 0 LOOP
ram_dp(i)(j) := (OTHERS => '1');
END LOOP; -- j
ELSE
FOR j IN 3 DOWNTO 0 LOOP
ram_dp(i)(j) := (OTHERS => '1');
END LOOP;
END IF;
END LOOP;
-- check if declared memory size is sufficient
ASSERT (endfile(ini_file))
REPORT "Memory is too small!"
SEVERITY FAILURE;
RETURN ram_dp;
END function;
Ok, you probably wonder what this code is supposed to initialize, but I didn't post the commented code (since I'm just about to debug). From my understanding this code should produce a *.mif file which contains '1' on any position. But when I have a look at the generated *.mif file, it turnes out they are all '0' (from the initialzation). It seems like the problem is the
IF (NOT endfile(ini_file)) THEN
END IF;
statement. If I comment this statement, I see the *.mif file turnes all '1'. How comes the tool doesn't even enter the else-path? Thanks for all your help!