Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Expressing Pipeline Delays in Verilog

I have been searching for an answer to this problem for awhile now, but have yet to find any information online that would help me. I hope this is the appropriate forum to ask a Verilog question. I'm using an Altera device, and it involves Quartus, so it's not completely irrelevant.

Suppose I need to calculate: "x + y / z". The width of the variables is a parameter called WIDTH. Obviously, y / z could be very expensive, so I build a pipelined divider module. The length of the pipeline is dependent on the WIDTH.

Now, the result of y / z comes out of the pipelined divider. Since it's pipelined, it is delayed, so I need to load x into a FIFO with the same length as the divider pipeline. Problem! The length of the divider pipeline is calculated in the divider. The parent module has no access to the parameters of the children (at least in QII). So the following would not work:

**** I omit a lot of code and structure here. Just trying to get the point across ****


module MY_FUNC(clk, x, y, z, result);
parameter WIDTH = 1; // default.
divider#  (.WIDTH(WIDTH)) div_blk (clk, y, z, divide_result);
FIFO#  (.WIDTH(WIDTH), .LENGTH(div_blk.PIPELINE_LENGTH)) fifo_blk (clk, x, delay_x);
always ...
result <= delay_x + divide_result
endmodule
module divider(...);
parameter WIDTH = 1; //default
parameter PIPELINE_LENGTH = WIDTH >> 1;
endmodule

The above code is what I first tried, but the synthesizer won't let me do div_blk.PIPELINE_LENGTH. I've tried a bunch of other ideas, but none of them solve the problem.

Is there a way to do this?

And yes, I know QII has a divider megafunction. This is just an example. My project has pipelines everywhere and it has gotten very difficult keeping track of their lengths.

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    The length of the divider pipeline is calculated in the divider.

    --- Quote End ---

    It's not exactly clear what you mean here. I'm not aware of modules, that "decide" about pipeline delay at will. Normally the delay is set as a parameter by the user when instantiating the module. If the module's pipeline delay has to be choosen based on other parameters e.g. word length, they are known at the interface.

    I understand, that you're asking for something like a module "output parameter", that reports the actual pipeline delay. I think it's not provided by Verilog or VHDL.

    There may be a workaround, by using an output signal for this information. It turns into a constant value during compilation. If it's fed to a variable delay construct, the compiler possibly can utilize it to set the pipeline delay at compile time rather than actually implementing a variable delay.

    But my preferred solution would be to gather all respective module parameters in a project global define file (Verilog) respectively a parameter package (VHDL).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I am not clear why the pipe length is not fixed to maximum worst case

    Also consider converting division to multiplication. This requires a LUT and is convenient for small widths.

    To convert x/z to multiplication:

    pre-multiply z to suitable power of 2 then divide by truncation to get equivalent result:

    e.g.:

    1 * 1024/1 = 1024

    2* 1024/2 = 1024

    ....

    insert 1024, 1024/2 ... in LUT then

    multiply LUT values by x and truncate off 10 bits.