I have a project that's consuming 34 of a Xilinx Coolrunner II's macrocells. I noticed I had an error and tracked it down to this:
assign rlever = RL[0] ? 3'b000 :
RL[1] ? 3'b001 :
RL[2] ? 3'b010 :
RL[3] ? 3'b011 :
RL[4] ? 3'b100 :
RL[5] ? 3'b101 :
RL[6] ? 3'b110 :
3'b111;
assign llever = LL[0] ? 3'b000 :
LL[1] ? 3'b001 :
LL[2] ? 3'b010 :
LL[3] ? 3'b011 :
LL[4] ? 3'b100 :
LL[5] ? 3'b101 :
3'b110 ;
The error is that rlever
and llever
are one bit wide, and I need them to be three bits wide. Silly me. I changed the code to be:
wire [2:0] rlever ...
wire [2:0] llever ...
so there were enough bits. However, when I rebuilt the project, this change costed me more than 30 macrocells and hundreds of product terms. Can anyone explain what I have done wrong?
(The good news is that it now simulates correctly... :-P )
EDIT -
I suppose I'm frustrated because about the time I think I start understanding Verilog and the CPLD, something happens which shows I clearly have no understanding.
assign outp[0] = inp[0] | inp[2] | inp[4] | inp[6];
assign outp[1] = inp[1] | inp[2] | inp[5] | inp[6];
assign outp[2] = inp[3] | inp[4] | inp[5] | inp[6];
The logic to implement those three lines occurs twice. That means that each of the 6 lines of Verilog consumes about 6 macrocells and 32 product terms each.
EDIT 2 - As per @ThePhoton's suggestion about the optimization switch, here is information from the summary pages produced by ISE:
Synthesizing Unit <mux1>.
Related source file is "mux1.v".
Found 3-bit 1-of-9 priority encoder for signal <code>.
Unit <mux1> synthesized.
(snip!)
# Priority Encoders : 2
3-bit 1-of-9 priority encoder : 2
So clearly the code was recognized as something special. The design is still consuming tremendous resources, however.
EDIT 3 -
I made a new schematic including only the mux that @thePhoton recommended. Synthesis produced insignificant resource usage. I also synthesized the module recommended by @Michael Karas. This also produced insignificant usage. So some sanity is prevailing.
Clearly, my use of the lever values is causing consternation. More To Come.
Final Edit
The design is no longer insane. I am not sure what happened, however. I made a lot of changes in order to implement new algorithms. One contributing factor was a 'ROM' of 111 15-bit elements. This consumed a modest number of macrocells but a lot of product terms - nearly all of those available on the xc2c64a. I look for this but had not noticed it. I believe my error was hidden by optimization. The 'levers' I'm talking about are used to select values from the ROM. I hypothesize that when I implemented the (busted) 1-bit priority encoder, ISE optimized away some of the ROM. That would be quite a trick, but it's the only explanation I can think of. This optimization reduced the resource usage markedly and lulled me into expecting a certain base-line. When I fixed the priority encoder (as per this thread,) I saw the overhead of the priority encoder and the ROM that had previously been optimized away and attributed this to the former exclusively.
After all this, I was good on macrocells but had depleted my product terms. Half of the ROM was a luxury, really, as it was just the 2's comp of the first half. I removed the negative values, replacing them elsewhere them with a simple calculation. This allowed me to trade macrocells for product terms.
For now, this thing fits into the xc2c64a; I've used 81% and 84% of my macrocells and product terms respectively. Of course, now I have to test it to ensure it does what I want...
Thanks to ThePhoton and Michael Karas for the assist. In addition to the moral support they lent to help me solve this, I've learned from the Xilinx document ThePhoton posted, and I implemented the priority encoder suggest by Michael.
|
instead of||
. \$\endgroup\$