FPGARelated.com
Forums

Inferring an accumulator using Verilog on Xilinx Spartan 2e

Started by Y K October 10, 2003
I need to infer an 8 bit accumulator (acc8) using Verilog on the
Xilinx Webpack.
The Library guide seems to contain syntax errors.
I could not get the tool to infer a loadable accumulator, no matter
how I play around with the implementation. I get an adder using 10
slices, instead of 5 slices I should get when an accumulator is
inferred.
Does anybody know the solution?
You have to be a little careful because  the carry logic in the slice
follows the LUT, so in order to get in one level of logic you need to
visualize the load preceeding the add.  To do that, one input of the
adder has an and gate so that it is forced to zero when load is active,
the other input is a mux to select your load value or the addend (could
be the same, depending on your design).  Note in that case that there
is logic in front of both add inputs.  That same logic needs to preceed
the carry mux DI input, which does have an AND gate available (the mult
and).  In order to use that, your load signal has to be active low.
Some synthesis tools will infer the right structure as long as it is
realizable in the hardware, while others need you to be more explicit.


Y K wrote:

> I need to infer an 8 bit accumulator (acc8) using Verilog on the > Xilinx Webpack. > The Library guide seems to contain syntax errors. > I could not get the tool to infer a loadable accumulator, no matter > how I play around with the implementation. I get an adder using 10 > slices, instead of 5 slices I should get when an accumulator is > inferred. > Does anybody know the solution?
-- --Ray Andraka, P.E. President, the Andraka Consulting Group, Inc. 401/884-7930 Fax 401/884-7950 email ray@andraka.com http://www.andraka.com "They that give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin, 1759
This pointed me at a workaround:
The problem is indeed around the load input. The following code shows 
three versions: The Xilinx "Verilog" version (self explanatory), the 
same written in Verilog, and one where reset and load are or'ed 
together. Only the third one works.
I prefer a pure Verilog solution for future portability reasons. The 
code is going to a product line that may live for 20 years, and I don't 
want to rewrite it everytime I have to design a board using a new FPGA 
family.
The workaround is good enough for me, but perhaps Xilinx can fix the 
documentation and XST code too?

Thank you
Yishai Kagan
yk_four_zeroes_one@hotmail.com
(convert to digits to get the correct e-mail).

Here it is:
module accumulator8(input C,R,L,D,CE,ADD, input [7:0] B, output reg 
[7:0] Q);
/* The following does not work for obvious reasons.
// Verilog Inference Code copied from the Libraries Guide Page 163
always @ (posedge C)
begin
    if (R)
       Q <= 0;
    else if (L)
       Q <= D;
    else if (CE)
       end
    if (ADD)
       Q <= Q + B;
    else
       Q <= Q - B;
end
*/
// The following does not infer an accumulator for less obvious reasons:
/*
always @ (posedge C)
begin
    if (R)
       Q <= 0;
    else if (~L)
       Q <= D;
    else if (CE)
    begin
       if (ADD)
          Q <= Q + B;
       else
          Q <= Q - B;
    end
end
*/
// The problem is in L, as you claim.
// The following code does infer an accumulator,
// at the expense of losing the distinct reset:
wire RorL = R || L;
always @ (posedge C or posedge RorL)
begin
    if (RorL)
       Q <= D;
    else if (CE)
    begin
       if (ADD)
          Q <= Q + B;
       else
          Q <= Q - B;
    end
end


endmodule


Ray Andraka wrote:
> You have to be a little careful because the carry logic in the slice > follows the LUT, so in order to get in one level of logic you need to > visualize the load preceeding the add. To do that, one input of the > adder has an and gate so that it is forced to zero when load is active, > the other input is a mux to select your load value or the addend (could > be the same, depending on your design). Note in that case that there > is logic in front of both add inputs. That same logic needs to preceed > the carry mux DI input, which does have an AND gate available (the mult > and). In order to use that, your load signal has to be active low. > Some synthesis tools will infer the right structure as long as it is > realizable in the hardware, while others need you to be more explicit. > > > Y K wrote: > > >>I need to infer an 8 bit accumulator (acc8) using Verilog on the >>Xilinx Webpack. >>The Library guide seems to contain syntax errors. >>I could not get the tool to infer a loadable accumulator, no matter >>how I play around with the implementation. I get an adder using 10 >>slices, instead of 5 slices I should get when an accumulator is >>inferred. >>Does anybody know the solution? > > > -- > --Ray Andraka, P.E. > President, the Andraka Consulting Group, Inc. > 401/884-7930 Fax 401/884-7950 > email ray@andraka.com > http://www.andraka.com > > "They that give up essential liberty to obtain a little > temporary safety deserve neither liberty nor safety." > -Benjamin Franklin, 1759 > >
This pointed me at a workaround:
The problem is indeed around the load input. The following code shows
three versions: The Xilinx "Verilog" version (self explanatory), the
same written in Verilog, and one where reset and load are or'ed
together. Only the third one works.
I prefer a pure Verilog solution for future portability reasons. The
code is going to a product line that may live for 20 years, and I don't
want to rewrite it everytime I have to design a board using a new FPGA
family.
The workaround is good enough for me, but perhaps Xilinx can fix the
documentation and XST code too?

Thank you
Yishai Kagan
yk_four_zeroes_one@hotmail.com
(convert to digits to get the correct e-mail).

Here it is:
module accumulator8(input C,R,L,D,CE,ADD, input [7:0] B, output reg
[7:0] Q);
/* The following does not work for obvious reasons.
// Verilog Inference Code copied from the Libraries Guide Page 163
always @ (posedge C)
begin
    if (R)
       Q <= 0;
    else if (L)
       Q <= D;
    else if (CE)
       end
    if (ADD)
       Q <= Q + B;
    else
       Q <= Q - B;
end
*/
// The following does not infer an accumulator for less obvious reasons:
/*
always @ (posedge C)
begin
    if (R)
       Q <= 0;
    else if (~L)
       Q <= D;
    else if (CE)
    begin
       if (ADD)
          Q <= Q + B;
       else
          Q <= Q - B;
    end
end
*/
// The problem is in L, as you claim.
// The following code does infer an accumulator,
// at the expense of losing the distinct reset:
wire RorL = R || L;
always @ (posedge C or posedge RorL)
begin
    if (RorL)
       Q <= D;
    else if (CE)
    begin
       if (ADD)
          Q <= Q + B;
       else
          Q <= Q - B;
    end
end


endmodule


Ray Andraka wrote:
> You have to be a little careful because the carry logic in the slice > follows the LUT, so in order to get in one level of logic you need to > visualize the load preceeding the add. To do that, one input of the > adder has an and gate so that it is forced to zero when load is active, > the other input is a mux to select your load value or the addend (could > be the same, depending on your design). Note in that case that there > is logic in front of both add inputs. That same logic needs to preceed > the carry mux DI input, which does have an AND gate available (the mult > and). In order to use that, your load signal has to be active low. > Some synthesis tools will infer the right structure as long as it is > realizable in the hardware, while others need you to be more explicit. > > > Y K wrote: > > >>I need to infer an 8 bit accumulator (acc8) using Verilog on the >>Xilinx Webpack. >>The Library guide seems to contain syntax errors. >>I could not get the tool to infer a loadable accumulator, no matter >>how I play around with the implementation. I get an adder using 10 >>slices, instead of 5 slices I should get when an accumulator is >>inferred. >>Does anybody know the solution? > > > -- > --Ray Andraka, P.E. > President, the Andraka Consulting Group, Inc. > 401/884-7930 Fax 401/884-7950 > email ray@andraka.com > http://www.andraka.com > > "They that give up essential liberty to obtain a little > temporary safety deserve neither liberty nor safety." > -Benjamin Franklin, 1759 > >
This pointed me at a workaround:
The problem is indeed around the load input. The following code shows
three versions: The Xilinx "Verilog" version (self explanatory), the
same written in Verilog, and one where reset and load are or'ed
together. Only the third one works.
I prefer a pure Verilog solution for future portability reasons. The
code is going to a product line that may live for 20 years, and I don't
want to rewrite it everytime I have to design a board using a new FPGA
family.
The workaround is good enough for me, but perhaps Xilinx can fix the
documentation and XST code too?

Thank you
Yishai Kagan
yk_four_zeroes_one@hotmail.com
(convert to digits to get the correct e-mail).

Here it is:
module accumulator8(input C,R,L,D,CE,ADD, input [7:0] B, output reg
[7:0] Q);
/* The following does not work for obvious reasons.
// Verilog Inference Code copied from the Libraries Guide Page 163
always @ (posedge C)
begin
    if (R)
       Q <= 0;
    else if (L)
       Q <= D;
    else if (CE)
       end
    if (ADD)
       Q <= Q + B;
    else
       Q <= Q - B;
end
*/
// The following does not infer an accumulator for less obvious reasons:
/*
always @ (posedge C)
begin
    if (R)
       Q <= 0;
    else if (~L)
       Q <= D;
    else if (CE)
    begin
       if (ADD)
          Q <= Q + B;
       else
          Q <= Q - B;
    end
end
*/
// The problem is in L, as you claim.
// The following code does infer an accumulator,
// at the expense of losing the distinct reset:
wire RorL = R || L;
always @ (posedge C or posedge RorL)
begin
    if (RorL)
       Q <= D;
    else if (CE)
    begin
       if (ADD)
          Q <= Q + B;
       else
          Q <= Q - B;
    end
end


endmodule


Ray Andraka wrote:
> You have to be a little careful because the carry logic in the slice > follows the LUT, so in order to get in one level of logic you need to > visualize the load preceeding the add. To do that, one input of the > adder has an and gate so that it is forced to zero when load is active, > the other input is a mux to select your load value or the addend (could > be the same, depending on your design). Note in that case that there > is logic in front of both add inputs. That same logic needs to preceed > the carry mux DI input, which does have an AND gate available (the mult > and). In order to use that, your load signal has to be active low. > Some synthesis tools will infer the right structure as long as it is > realizable in the hardware, while others need you to be more explicit. > > > Y K wrote: > > >>I need to infer an 8 bit accumulator (acc8) using Verilog on the >>Xilinx Webpack. >>The Library guide seems to contain syntax errors. >>I could not get the tool to infer a loadable accumulator, no matter >>how I play around with the implementation. I get an adder using 10 >>slices, instead of 5 slices I should get when an accumulator is >>inferred. >>Does anybody know the solution? > > > -- > --Ray Andraka, P.E. > President, the Andraka Consulting Group, Inc. > 401/884-7930 Fax 401/884-7950 > email ray@andraka.com > http://www.andraka.com > > "They that give up essential liberty to obtain a little > temporary safety deserve neither liberty nor safety." > -Benjamin Franklin, 1759 > >