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.


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
  • \$\begingroup\$ 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? \$\endgroup\$
    – Dave Tweed
    Apr 29, 2019 at 1:16
  • \$\begingroup\$ 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 \$\endgroup\$ Apr 29, 2019 at 1:19

1 Answer 1


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 (
  input           [8:0] addra,
  output reg     [35:0] douta,
  input                 clka

  always @(posedge clka) begin
    case (addra)
    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;

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

  • \$\begingroup\$ Indeed have no clock. Why is that an issue for the synthesizer? \$\endgroup\$ Apr 29, 2019 at 1:02
  • \$\begingroup\$ 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. \$\endgroup\$
    – Dave Tweed
    Apr 29, 2019 at 1:07
  • \$\begingroup\$ 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. \$\endgroup\$ Apr 29, 2019 at 22:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.