Electronic – Why does changing an ‘add’ to a logical or devour 7 CPLD macrocells

programmable-logicverilogxilinx

I have a design that's synthesizing to about 50 macrocells.

I have this section of code:

module levers2(
     input [2:0] LL,
     input [2:0] RL,
    output reg [10:0] DIVISOR,
    output reg FAULT
    );

reg [10:0] grid[0:63];
wire [5:0] tmp = (LL<<3)+RL;
(snip)

tmp is for all intents, an address line. I have two 3-bit input lines and I'm combining them to make a 6-bit address line. So I shift LL by three bits and add RL. When I synthesize, I get a 47 macrocell result.

However, if I change the operator to a logical or:

wire [5:0] tmp = (LL<<3) | RL;

The design synthesizes to 54 macrocells. That's 7 macrocells lost for what?!

I would think a bitwise or would be efficient and easy, much easier than an add which has the extra baggage of the carry.

Can anyone shed some light on what's going on?

EDIT —

I determined it was using more macrocells by using ISE's reporting mechanism.
I also tried a few different things (but not the concatenation operator mentioned below) and everything added 7 macrocells except for the 'add'. I was happy that the behavior was consistent.

As a side note, I added a single 3-input OR to my top-level schematic and fed it three signals (fault outputs) from different modules. This added 9 macrocells. You can bet I found a new way when I saw that, heh.

Best Answer

If all you want to do is combine two smaller arrays into a larger array of signals then it's best to use the concatenation operator:

wire [5:0] tmp = {LL, RL};

With the above, wire[5:3] will be connected to LL, and wire[2:0] will be connected to RL

You can use it in any order like:

wire[5:0] tmp = {RL, LL];

Or even:

wire[5:0] tmp = {LL[0], RL, LL[2:1];

(you can see how this can be used to shift/rotate signals)

Still, I'm not sure why changing to the OR should use another 7 macrocells, it's possibly (probably) because the synthesis tool is inferring an adder with the + operator and the CPLD has an adder cell that it can use, as opposed to making the adder from a few gates.

How did you determine this? Did you check the technology schematic to see what's being created?
To help discover exactly what's happening, seeing the rest of your modules code would be helpful (also I can try it in ISE here)

EDIT - out of curiosity I wrote a small test module using the relevant bit of the above code. I tried synthesising (with default settings) for a Spartan-3A and the XC264A CPLD, with the + or the|. Both terms produced identical results for the Spartan and the CPLD, both in the technology viewer and the place and route macrocell usage report.
With this information, it looks like it must be something to do with the rest of the design and possibly the synthesis tool settings (optimisation, etc). The snippet above should just concatenate the two smaller signals into one larger one, so no logic should be necessary.