Modulo division in Verilog

Hi Guys,

I have run into a problem that I was not expecting, I need to calculate the remainder after division (modulo) of a number preferebly in combinational logic or a single clock cycle, and I need it to behave in the same fashion as matlab does (as you would expect).

So i essentially need to calculate: x = mod(y, 6434);

I did this in verilog as follows

reg signed [15:0] y; wire signed [14:0] x;

assign x = y % 6434;

However this does not do what I am after. I assumed that % would perform a modulo operation however, when my input is y = -6310, x = -6310. This seems to be doing some kind of singed mod.. I would be expecting 124 as the answer as matlab produced.

Can you give me any clues as to where I am going wrong??

Regards,

Paul Solomon

Reply to
Paul Solomon
Loading thread data ...

You're not doing anything wrong. It's just that Verilog's definition of signed modulus doesn't agree with that of Matlab's. In Verilog remainder is that same sign as that of the dividend which is what some call the truncating division. Matlab apparently uses a different (albeit completely legitimate) definition. If you want the same result, you can just check the sign of the result and add 6434 if negative. HTH.

Reply to
m

Fantastic,

Thanks for that, this has fixed my prob.

Regards,

Paul Solomon

Reply to
Paul Solomon

Are you just simulating right now? I'd expect synthesizers to only support modulus for powers of 2. I would expect the need for a full divider, running upwards of 100 ns depending on your value widths.

the

as

Reply to
John_H

Hmm Interesting. I have simulated the verilog code in modelsim and it seems to work as expected. however I have also synthesized and fitted my whole design and loaded into a stratix and it does not work as expected. Do you think this could be the prob?

I assumed that modelsim and quartus should behave the same way.

I am running an 80MHz clock so 12.5ns reg - reg and there were no timing constratints broken on the timing analysis after compile

Regards.

Paul Solomon

Reply to
Paul Solomon

With 80 MHz you are absolutely not going to get a "complex" modulus to go exceedingly quick. Quartus will not produce a "real" modulus. This is probably documented in the tool for their language support.

How many bits in your input? Is the modulus fixed at 6434? Which Altera device? Given those values, some folks should be able to give you an estimate of how long it would take to produce a result. Bottom line: 12.5 ns won't happen unless the "truncated integer part" is very few bits.

would

on

seems

a
Reply to
John_H

Hi John,

I have done some further ingestigation this morning, found out a few other things, albeit frustrating things.

  1. You are right in that the modulo operation is not occuring in 12.5ns, this section of the design is in the order of 43ns.
  2. The design that simulated perfectly in Modelsim, does not actually work.

I have synthesised, fitted, and written a netlist out (to a vo file) and simulated this in modelsim and it does not work. At first I thought it was the clock going to fast, but I have slowed the clock right down (to 200ns) and it is still not making any sense.

I have also tried the same simulation in Quartus and I appear to be getting garbage out.

Do you know what I should be looking for, what kind of things could cause a discrepancy between the simulated verilog code and the simulated vo output?

both the simulators and the synthesis tool is set for verilog-2001.

btw to answer your other questions the bus width is 16bit and the mod is always 12868.

Regards,

Paul Solomon

Reply to
Paul Solomon

Coments at end:

work.

getting

a

Good news: the remainder won't be too hard to develop.

First, simulation versus synthesis: There are some things that just don't synthesize or won't synthesize well. Consider the wait operator (e.g., #12); it won't synthesize. Consider division. It can be synthesized but the results are too area-intensive and the nuances on the input/output ranges too great to come up with a solution that will apply to every application. The modulus you seek is division.

Since the 16 bits have a maximum of 65535 and the modulus is fixed at 12868 gives a maximum integer divide of 5. Three bits of integer result means you need only three stages of compare with conditional subtract. stage1 = value-(14'd12868

Reply to
John_H

Hi Paul,

You've found a case where Quartus synthesis isn't correctly implementing the Verilog standard for signed modulo operations. Currently for A mod B, Quartus is synthesizing a circuit that will always return a non-negative result. That does not match Verilog semantics when B is negative. That is why you're getting a mismatch between the ModelSim simulation (which is correctly modeling the Verilog semantics) and the design in hardware/the Quartus simulator.

Quartus was synthesizing a signed modulus implementation that matches Matlab's interpretation of signed modulus, so ironically with the original design the hardware would match Matlab. Once you changed your design so that you added B to (A MOD B) when B < 0, you actually changed the hardware so that it wouldn't match Matlab anymore.

This will be fixed in the upcoming Quartus 5.1 release.

Thanks for bringing this up, and I hope this didn't cause you too much trouble.

Regards,

Vaughn Altera [v b e t z (at) altera.com]

Reply to
Vaughn Betz

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.