1
\$\begingroup\$

As the title says, I'd like to know if the behavior of a zero division in ieee.numeric_std is somehow defined. If one does

signal a, b : unsigned (width1_g-1 downto 0);
signal c    : unsigned (width2_g-1 downto 0);

div_proc : process (clk_i)
begin
    if rising_edge(clk_i) then
        c <= a / b;
    end if;
end process;

for example, what will be the outcome of c?

\$\endgroup\$
1
  • \$\begingroup\$ To know the outcome - what will be latched to c - you must look into the circuit synthesized for the division operation. Of course register c must get some value, but it will not be correct. Depending on implementation it may also be metastable. \$\endgroup\$
    – Anonymous
    Commented Nov 23, 2018 at 10:31

2 Answers 2

1
\$\begingroup\$

In your example a and b are not initialized, but I assume you want a division with b := 0 somewhere, this answer is for FPGAs only:

From the numeric_std.vhd package:

-- NOTE: If second argument is zero for "/" operator, a severity level -- of ERROR is issued.

 -- Id: A.21   function "/" (L,R: UNSIGNED ) return UNSIGNED;

So in simulation this should crash. If it doesn't crash, you should find a better simulator.

In synthesis:

  • Vivado only supports division by powers of 2 in older versions and will try to infer a Divider LogiCORE unit for others, which doesn't support division by a constant 0 (so that's a synthesis error) and allows for optional error detection when trying to divide by a variable that might be 0. I haven't tried what happens if you turn this inference off in current editions, but I'd suspect it again only accepts powers of 2.

  • Current Quartus products try to infer a DSP divisor with extremely similar limitations as the Xilinx Divider. No idea what happens when you try to synthesize it in pure LUTs. I know division can be infered for non-binary powers and it's horrible.

Don't try to divide by zero.

\$\endgroup\$
2
  • \$\begingroup\$ The reason I'm asking is: I'm developing on a Zynq, and one module involves a division by a unsigned, which is passed from the CPU to the FPGA logic through a register. So am I right in assuming it would be good practice to add logic to catch up the division-by-0 case because otherwise the behavoir would be undefined? \$\endgroup\$
    – Andy Ef
    Commented Nov 23, 2018 at 13:35
  • \$\begingroup\$ @AndyEf It will be very much defined, it just won't be good. \$\endgroup\$
    – DonFusili
    Commented Nov 23, 2018 at 13:55
1
\$\begingroup\$

In simulation:

  • The VHDL IEEE Std 1076.2-1996 standard defines division by zero as an error condition. So this should immediately terminate the simulation.
  • The Verilog IEEE Std 1364-2005 standard, on the other hand, says that division by zero should return xxx and not trigger anything spectacular (see chapter 5.1.5 Arithmetic operators in the standard).

Of course on real hardware, anything could happen, because neither of these outcomes are implementable (there is no builtin mechanism in the chip to stop running - or should "stop the simulation" translate to "blow the chip up"?, and xxx values would require tristate logic which is not there). So the decision is up to the synthesis tool you're using (and the decision could be "it's undefined"). Maybe it is specified in the documentation of the specific tool you're using.

But in reality, you certainly won't manage to properly synthesize such a construct without bloating your design anyway (and some synthesis tools aren't even able to produce a general-purpose divider block that can take any value for the divisor: they will be restricted to power of two). So just don't do that in a real hardware design.

\$\endgroup\$

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.