Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17254 Discussions

mapping a small table to a LUT instead of memory registers

Altera_Forum
Honored Contributor II
4,243 Views

I would like to map a table to a LUT simialr to the attached example in vhdl, but Quartus synthesis does not map the table in the attached verilog to a LUT, instead it uses memory registers. 

 

Merely synthesizing the two equivalent modules in VHDL and verilog, shows the following synthesis reports. 

 

Apparently, there is lack of initialization option in verilog compared to vhdl that is causing this mapping to registers in verilog compared to LUTs in VHDL.  

What else can I do to map the table in verilog to LUT, other than the initial block, that is not working as desired. 

 

Thanks in advance, 

Fasahat 

 

--------------------------------------- VHDL Synthesis ------------------------------- 

Analysis & Synthesis Status Successful - Fri May 14 15:46:56 2010 

Quartus II Version 9.0 Build 235 06/17/2009 SP 2 SJ Full Version 

Revision Name s_box 

Top-level Entity Name sbox 

Family Stratix II 

logic utilization n/a 

combinational aluts 40 

dedicated logic registers 8 

Total registers 8 

Total pins 18 

Total virtual pins 0 

total block memory bits 0 

DSP block 9-bit elements 0 

Total PLLs 0 

Total DLLs 0 

------------------------------ VERILOG Synthesis -------------------------------------------------- 

Analysis & Synthesis Status Successful - Fri May 14 15:48:33 2010 

Quartus II Version 9.0 Build 235 06/17/2009 SP 2 SJ Full Version 

Revision Name s_box 

Top-level Entity Name s_box_rom2 

Family Stratix II 

Logic utilization N/A 

combinational aluts 0 

dedicated logic registers 0 

Total registers 0 

Total pins 17 

Total virtual pins 0 

total block memory bits 2,048 

DSP block 9-bit elements 0 

Total PLLs 0 

Total DLLs 0
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
3,017 Views

i ran s_box_rom2.v in Quartus II 9.1sp2 targeting a CIII and the RAM was mapped to an M9K. the RAM inferring must have been improved.

0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

i see you're using SII, in this case it targets 1 M4K.

0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

from the Quartus II Handbook, version 9.0 page 454: 

 

 

--- Quote Start ---  

Example 9–63. Verilog-1995 Code: Applying a syn_ramstyle Attribute to a Variable Declaration 

reg [0:7] my_ram[0:63] /* synthesis syn_ramstyle = "logic" */; 

 

Example 9–64. Verilog-2001 Code: Applying a romstyle Attribute to a Variable Declaration 

(* romstyle = "logic" *) reg [0:7] my_rom[0:63]; 

 

Example 9–65. VHDL Code: Applying a ramstyle Attribute to a Signal Declaration 

type memory_t is array (0 to 63) of std_logic_vector (0 to 7); 

signal my_ram : memory_t; 

attribute ramstyle : string; 

attribute ramstyle of my_ram : signal is "logic"; 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

Also, from page 458 of 9.0 Quartus II Handbook : 

 

 

--- Quote Start ---  

In VHDL, you can also initialize the contents of an inferred memory by specifying a 

default value for the corresponding signal. In Verilog HDL, you can use an initial 

block to specify the memory contents. Quartus II integrated synthesis automatically 

converts the default value into a .mif file for the inferred RAM. 

--- Quote End ---  

 

 

Pretty sure both languages do the exact same thing, just for some reason it implemented them different. Most likely have the same function as well. If you want to make the vhdl implemented in memory you can make the ram_style attribute one of the following values, depending on device : 

"M512", "M4K", "M-RAM", "MLAB", "M9K", and "M144K"
0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

Dear fasahat,  

 

the Verilog and VHDL modules you provided are not identical. 

 

The VHDL module has an asynchronous 'rst' signal that causes it to output zero. This behaviour can't be implemented just with a M4K block, it would at the very least require aditional logic. 

 

The correct way to infer a synchronous ROM in VHDL would be 

 

process (clk) 

if clk'event and clk = '1' then  

byteout <= sbox_ram(conv_integer(bytein)); 

end if; 

end process; 

 

Another important aspect is the table contents: at least in the VHDL case, the 2K bit table contents can be reduced to just 48 ALUTs (and 8 registers).  

 

So, what the way Quartus implemented that is problably the most efficient way to do it.
0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

rbugalho- 

 

You are correct, they are different. Somehow failed to notice that. However, all memory blocks (M512, M4K, and MRAM) of the stratix II support asynchronous clear of the output registers. That is actually the only thing they support async clear on. So, both the vhdl and verilog code can be implemented in either ram or logic elements, just a matter of how you want to do it. 

 

From the stratix II reference: 

 

--- Quote Start ---  

When applied to output registers, the asynchronous 

clear signal clears the output registers and the effects are seen 

immediately. 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

You are right, I forgot to use reset in verilog. 

 

However, using a reset signal in verilog code and the recommended case statement (full case), does not map the memory to LUT as was the case with VHDL. 

 

Interestingly, if I remove the reset initialization of memory in VHDL code, as suggested by memory templates ( Chapter 6: Recommended HDL Coding Styles 

Inferring Memory Functions from HDL Code Example 6-23) , the synthesizer maps the table to dedicated registers and not to ALUT(s) anymore. 

 

What I am trying to get at is : 

 

If I have many small tables in adeisgn like the one in vhdl file, I see timing closure is much better (by about 30 MHz) compared to same implementation in verilog where the synthesizer infers M4K.  

 

I did not find anything in Chapter 6: Recommended HDL Coding Styles 

Inferring Memory Functions from HDL Code to infer a small memory in verilog to ALUT(s).
0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

Hi,  

You're trying both Verilog and VHDL and trying multiple coding styles. Please be carefull not to take away conclusions about Verilog vs VHDL when your code and coding style aren't actually equivalent. 

 

There are limitations to what cases can be mapped to dedicated logic blocks, such as M4K memory blocks. 

Some are fundamental limitations imposed by the dedicated logic, won't support some features.  

If you code a table whose content's can be reset, it won't ever be mapped to a M4K because M4K blocks don't support reseting it's contents. 

 

Some are just limitations of the design software. 

 

For example, IIRC, Quartus 9.0 is just "too dumb" to infer memory blocks from a "case based" coding style, either in Verilog or VHDL. You'll need 9.1 to do that. 

 

From my experience and from the examples, Quartus also won't infer memory blocks if you have a reset signal, like in the VHDL example you posted. Again, from what kbs972 wrote, this looks more like a software limitation than a hardware limitation. 

 

But if Quartus is able to infer RAM/ROM primitive from the HDL it will, in general, map it to a dedicated memory block, unless it's a very small RAM/ROM or your design is starved for resources. 

 

If you are not happy with what Quartus is doing, you can either fiddle with the synthesis settings or use attrbutes as kbs972 suggested. 

 

I find it a bit strange that you're getting better timming with ALUTs than with M4K blocks.
0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

ok, here is the stats 

 

w/reset and case statement  

verilog altera 9.0 sp2 M4k used 1 

vhdl altera 9.0 sp2 M4k used 0 alm used 40 

verilog altera 9.1 sp1 M4k used 1 

case statement (NO reset) 

verilog altera 9.0 sp2 M4k used 1 

vhdl altera 9.0 sp2 M4k used 0 alm used 40 

verilog altera 9.1 sp1 M4k used 1 

vhdl altera 9.1 sp1 M4k used 1 alm used 0 

 

So apparently, 9.1 is smarter in that vhdl is also mapped to M4K (w/reset or w/o reset) 

BUT there is a flag called 

AUTO ROM Replacement (default on) 

Allows the Compiler to find logic that can be replaced with the altsyncram or the lpm_rom megafunction. Turning on this option may change the power-up state of the design. 

 

Select OFF and it will map vhdl or verilog memory to to ALUT(s) instead. 

 

In 9.0, this flag is default on, so it mapped verilog to M4k as expected, but not the same for vhdl (now this is corrected in 9.1). 

 

Thanks for sharing, 

Fasahat
0 Kudos
Altera_Forum
Honored Contributor II
3,017 Views

Using the directive 

 

/* synthesis romstyle = "logic" */ 

 

as in example below 

 

 

define MRESET 

module s_box_rom ( 

 

input clk, 

`ifdef MRESET  

input rst, 

`endif 

input [7:0] address, 

output reg [7:0] data_out 

//);  

) /* synthesis romstyle = "logic" */; 

 

`ifdef MRESET  

always @ (posedge clk or posedge rst) 

if (rst) 

data_out <= 0; 

else 

`else 

always @ (posedge clk) 

`endif 

begin 

case (address) 

// 8'b00000000: data_out2 <= 6'b101111; 

0 : data_out <= 8'h63; 

1 : data_out <= 8'h7C; 

2 : data_out <= 8'h77; 

... 

... 

244 : data_out <= 8'hBF; 

245 : data_out <= 8'hE6; 

246 : data_out <= 8'h42; 

247 : data_out <= 8'h68; 

248 : data_out <= 8'h41; 

249 : data_out <= 8'h99; 

250 : data_out <= 8'h2D; 

251 : data_out <= 8'h0F; 

252 : data_out <= 8'hB0; 

253 : data_out <= 8'h54; 

254 : data_out <= 8'hBB; 

255 : data_out <= 8'h16; 

endcase 

end 

 

 

endmodule 

 

maps it to ALUT(s) , doing away the need for global switch settings and more control per module.
0 Kudos
Reply