# Verilog and XST - large LUT long to synthesize

I have a large Verilog lookup table holding 16bits values that I generate using a case..endcase statement. The synthesizer recognize it and infer a RAM block, all is working fine.

My only problem is the time required to synthesize with XST. We are talking above 10 minutes just for the LUT. How can this be improved? Should I change my design or should I look at the synthesizer options? Right now, optimization level is set to Normal.

Thanks

EDIT: Here's a snippet of code

module cos_lut_16_16 (
input[15:0] iPhase,
output reg [15:0] oCos
) ;

always @(iPhase)
case (iPhase)
0: oCos=16'h7FFF;  //0 -> 1
1: oCos=16'h7FFF;  //9.5873799242853E-5 -> 0.99999999540411
2: oCos=16'h7FFF;  //0.00019174759848571 -> 0.99999998161643
3: oCos=16'h7FFF;  //0.00028762139772856 -> 0.99999995863697
4: oCos=16'h7FFF;  //0.00038349519697141 -> 0.99999992646572
5: oCos=16'h7FFF;  //0.00047936899621426 -> 0.99999988510268
6: oCos=16'h7FFF;  //0.00057524279545712 -> 0.99999983454787
.....
65535: oCos=16'h7FFF;  //6.2830894333803 -> 0.99999999540411
endcase
endmodule

• Wow, that's a megabit of data, holding a full cycle of a cosine wave. Have you considered storing just one quadrant and then using logic to generate the other three? Apr 29, 2019 at 1:16
• I know it is overkill for what it does. I did consider, my constraint here is time and the FPGA is oversized for the application; so I went for the bazooka. This is a proof of concept, not a well engineered product Apr 29, 2019 at 1:19

This is more of a comment than an answer, but I want to include a code snippet that formats correctly, so here goes...

Show us your actual code. I have had no problem generating large LUTs (program ROMs for soft CPUs). I have an assembler for the CPU that generates hex files, and then a Perl script that turns those into simulatable/synthesizable Verilog code that looks like this:

/* tb_cpu_rom.v */

/* This is a generated file. Do not edit directly.
*/

module tb_cpu_rom (
output reg     [35:0] douta,
input                 clka
);

always @(posedge clka) begin
9'h000: douta <= 36'h000810069;
9'h001: douta <= 36'h020001234;
9'h002: douta <= 36'h820000000;
9'h003: douta <= 36'h020005678;
9'h004: douta <= 36'h024020000;
9'h005: douta <= 36'h024040100;

/* hundreds of lines snipped out */

9'h1FD: douta <= 36'h000000000;
9'h1FE: douta <= 36'h000000000;
9'h1FF: douta <= 36'h000000000;
endcase
end
endmodule


Perhaps your LUT has no clock? That could be causing a problem in synthesis.

• Indeed have no clock. Why is that an issue for the synthesizer? Apr 29, 2019 at 1:02
• I don't know that for sure. It's just a hunch based on the fact that synthesis tools in general REALLY prefer to work with synchronous logic. Try it both ways to see whether it makes a difference (even if the system is nonfunctional that way). Also, your table is 64k x 16, about 64x bigger than mine, so maybe that's why I don't run into the issue. You might be better off generating a ROM explicitly with the IP "wizard" tools, and then populating it via .mif or .coe file that you generate. Apr 29, 2019 at 1:07
• It happens that you were right on every points. First, adding a clock helped the synthesizer. Also, I was wrong when I said I had enough BRAM for the LUT. I had enough for a 15x16 LUT. As soon as I added a 16th bit, the synthesizer seemed to try to use logic element to solve the problem, hence the long wait. Honestly, I have never gone through a synthesis with16 bits, I always got bored after 15 minutes, so I didn't notice. I used a quarter wave implementation to save some ressources and it sthesized in 30 sec roughly. I notice the lack of ressource when using coregen to create a ROM core. Apr 29, 2019 at 22:46