FPGARelated.com
Forums

substracting a whole array of values at once

Started by CMOS ●February 11, 2007
hi,
i need a whole matrix to be substracted form another in one clock
cycle.
and i need to store all the values of these matrices in either
distributed or block RAM.
i thought this is not possible with block RAM, as these have didicated
ports that are fixed in width.
so tried to use distributed RAM with the following verilog code.


parameter nColumns = 100;
parameter nRows = 200;

parameter RAM_WIDTH = 8;

//matrix 1 data
reg [RAM_WIDTH-1:0] data_1[nColumns*nRows-1:0];


//matrix 2 data
reg [RAM_WIDTH-1:0] data_2[nColumns*nRows-1:0];

reg [7:0] ix = 0;
reg [7:0] iy = 0;

reg[10:0] diff = 0;

always @ (start) // start will trigger the calculation
begin
for(ix = 0; ix < 100; ix = ix + 1) begin
	for(iy = 0; iy < 100; iy = iy + 1) begin
		diff = diff +data_1[iy] - data_2[ix];
	end
end
end

ise webpack completed stege one systhesis of this code after around 10
minutes and did not complete the whole systhesis even after around 3
hrs.

any assistance is very much appreciated.

thank you.

CMOS wrote:

> hi, > i need a whole matrix to be substracted form another in one clock cycle. > and i need to store all the values of these matrices in either > distributed or block RAM. > i thought this is not possible with block RAM, as these have didicated > ports that are fixed in width. > so tried to use distributed RAM with the following verilog code. > > > parameter nColumns = 100; > parameter nRows = 200; > > parameter RAM_WIDTH = 8; > > //matrix 1 data > reg [RAM_WIDTH-1:0] data_1[nColumns*nRows-1:0]; > > //matrix 2 data > reg [RAM_WIDTH-1:0] data_2[nColumns*nRows-1:0]; > > reg [7:0] ix = 0; > reg [7:0] iy = 0; > > reg[10:0] diff = 0; > > always @ (start) // start will trigger the calculation begin for(ix = 0; > ix < 100; ix = ix + 1) begin > for(iy = 0; iy < 100; iy = iy + 1) begin > diff = diff +data_1[iy] - data_2[ix]; > end > end > end > > ise webpack completed stege one systhesis of this code after around 10 > minutes and did not complete the whole systhesis even after around 3 > hrs. > > any assistance is very much appreciated.
I'm answering this assuming that it is school homework. You try simulating this code first. It just might not do what you want it to do. For example, try the case of data_1 is all x7F and data_2 is all x81. Calculate the expected value of diff, and see what the simulation produces. You might want to try a smaller example. Try to get a 2 X 2 matrix correct first. You might want to look at the synthesis templates. RAMs need to be coded in fairly specific ways to be recognized. Code that is too different from the template may not produce the expected result. To produce distributed RAM: parameter RAM_WIDTH = <ram_width>; parameter RAM_ADDR_BITS = <ram_addr_bits>; reg [RAM_WIDTH-1:0] <ram_name> [(2**RAM_ADDR_BITS)-1:0]; wire [RAM_WIDTH-1:0] <output_data>; <reg_or_wire> [RAM_ADDR_BITS-1:0] <address>; <reg_or_wire> [RAM_WIDTH-1:0] <input_data>; always @(posedge <clock>) if (<write_enable>) <ram_name>[<address>] <= <input_data>; assign <output_data> = <ram_name>[<address>]; -- Phil Hays (Xilinx, always writing for myself)
On Feb 11, 9:21 pm, Phil Hays <inva...@dont.spam> wrote:
> CMOS wrote: > > hi, > > i need a whole matrix to be substracted form another in one clock cycle. > > and i need to store all the values of these matrices in either > > distributed or block RAM. > > i thought this is not possible with block RAM, as these have didicated > > ports that are fixed in width. > > so tried to use distributed RAM with the following verilog code. > > > parameter nColumns = 100; > > parameter nRows = 200; > > > parameter RAM_WIDTH = 8; > > > //matrix 1 data > > reg [RAM_WIDTH-1:0] data_1[nColumns*nRows-1:0]; > > > //matrix 2 data > > reg [RAM_WIDTH-1:0] data_2[nColumns*nRows-1:0]; > > > reg [7:0] ix = 0; > > reg [7:0] iy = 0; > > > reg[10:0] diff = 0; > > > always @ (start) // start will trigger the calculation begin for(ix = 0; > > ix < 100; ix = ix + 1) begin > > for(iy = 0; iy < 100; iy = iy + 1) begin > > diff = diff +data_1[iy] - data_2[ix]; > > end > > end > > end > > > ise webpack completed stege one systhesis of this code after around 10 > > minutes and did not complete the whole systhesis even after around 3 > > hrs. > > > any assistance is very much appreciated. > > I'm answering this assuming that it is school homework. > > You try simulating this code first. It just might not do what you want it > to do. For example, try the case of data_1 is all x7F and data_2 is all > x81. Calculate the expected value of diff, and see what the simulation > produces. > > You might want to try a smaller example. Try to get a 2 X 2 matrix correct > first. > > You might want to look at the synthesis templates. RAMs need to be coded > in fairly specific ways to be recognized. Code that is too different > from the template may not produce the expected result. To produce > distributed RAM: > > parameter RAM_WIDTH = <ram_width>; > parameter RAM_ADDR_BITS = <ram_addr_bits>; > > reg [RAM_WIDTH-1:0] <ram_name> [(2**RAM_ADDR_BITS)-1:0]; > > wire [RAM_WIDTH-1:0] <output_data>; > > <reg_or_wire> [RAM_ADDR_BITS-1:0] <address>; <reg_or_wire> > [RAM_WIDTH-1:0] <input_data>; > > always @(posedge <clock>) > if (<write_enable>) > <ram_name>[<address>] <= <input_data>; > > assign <output_data> = <ram_name>[<address>]; > > -- > Phil Hays (Xilinx, always writing for myself)
hi, thanks for the reply. actually its not a school homework. im doing a project in which i need to deduct an image from another. this has to be done several times to get the output. to reduce time for the calculation, i need to do the substraction in one clock cycle. in order to do that i need concurrent access to all pixels of both images. im not sure how this could be acheived with available block or distributed RAM. thank you.
The only way to subtract all values at once (!) is to use registers, not 
distributed memory or BlockRAM.  You will also need one subtractor for 
each pair of image pixels.

Redefine what you consider necessary.

Do you have access to all those pixels at once the clock cycle after the 
subtract?

If a new image is overwriting the first image in the clock after the 
subtract is supposed to happen, read the previous value and take the 
subtraction the same time the next value is being written.  Cycle 
through all the values you need to subtract *as you read them* rather 
than requiring the subtraction happen all at once.

You can do a bazillion subtracts of width n if you have 3n bazillion 
registers and n(+1?) bazillion LUTs.

If you HAVE to have memory, you do not HAVE to have single-cycle subtracts.

Think about the hardware.

- John_H


CMOS wrote:
> hi, > i need a whole matrix to be substracted form another in one clock > cycle. > and i need to store all the values of these matrices in either > distributed or block RAM. > i thought this is not possible with block RAM, as these have didicated > ports that are fixed in width. > so tried to use distributed RAM with the following verilog code. > > > parameter nColumns = 100; > parameter nRows = 200; > > parameter RAM_WIDTH = 8; > > //matrix 1 data > reg [RAM_WIDTH-1:0] data_1[nColumns*nRows-1:0]; > > > //matrix 2 data > reg [RAM_WIDTH-1:0] data_2[nColumns*nRows-1:0]; > > reg [7:0] ix = 0; > reg [7:0] iy = 0; > > reg[10:0] diff = 0; > > always @ (start) // start will trigger the calculation > begin > for(ix = 0; ix < 100; ix = ix + 1) begin > for(iy = 0; iy < 100; iy = iy + 1) begin > diff = diff +data_1[iy] - data_2[ix]; > end > end > end > > ise webpack completed stege one systhesis of this code after around 10 > minutes and did not complete the whole systhesis even after around 3 > hrs. > > any assistance is very much appreciated. > > thank you.
Hi CMOS,
here's the solution you want:

Assume the two input matrices to be stored in two separate RAMs (e.G. 
Blockrams). Dual Ported, if necessary.

Connect a subtractor circuit to the DataOut of these RAMs.
The Output of that circuit is identical to the output of your Result-RAM

Now the result is virtually existent. If anyone has a doubt, just make a 
readout of the Result-RAM. The result will be there. :-)

Have a nice synthesis
   Eilert


On Feb 12, 4:31 am, backhus <n...@nirgends.xyz> wrote:
> Hi CMOS, > here's the solution you want: > > Assume the two input matrices to be stored in two separate RAMs (e.G. > Blockrams). Dual Ported, if necessary. > > Connect a subtractor circuit to the DataOut of these RAMs. > The Output of that circuit is identical to the output of your Result-RAM > > Now the result is virtually existent. If anyone has a doubt, just make a > readout of the Result-RAM. The result will be there. :-) > > Have a nice synthesis > Eilert
Are you saying that the above mechanism will compute a difference of two arrays in one clock cycle? If so then, I am not following... maybe you can explain a bit more.
Why do you need the result in one clock cycle? What are you doing with
the result? Is your opeation all perallel?
Peter Alfke
On Feb 12, 7:20 am, "fpgabuilder" <fpgabuilder-gro...@yahoo.com>
wrote:
> On Feb 12, 4:31 am, backhus <n...@nirgends.xyz> wrote: > > > Hi CMOS, > > here's the solution you want: > > > Assume the two input matrices to be stored in two separate RAMs (e.G. > > Blockrams). Dual Ported, if necessary. > > > Connect a subtractor circuit to the DataOut of these RAMs. > > The Output of that circuit is identical to the output of your Result-RAM > > > Now the result is virtually existent. If anyone has a doubt, just make a > > readout of the Result-RAM. The result will be there. :-) > > > Have a nice synthesis > > Eilert > > Are you saying that the above mechanism will compute a difference of > two arrays in one clock cycle? If so then, I am not following... > maybe you can explain a bit more.
"Peter Alfke" <peter@xilinx.com> wrote in message 
news:1171298749.505302.219460@v33g2000cwv.googlegroups.com...

> Why do you need the result in one clock cycle? What are you doing with > the result? Is your opeation all perallel?
Sounds like he's trying to do MAD for motion compensation.
On Feb 12, 10:45 am, "Peter Alfke" <p...@xilinx.com> wrote:
> Why do you need the result in one clock cycle? What are you doing with > the result? Is your opeation all perallel? > Peter Alfke > On Feb 12, 7:20 am, "fpgabuilder" <fpgabuilder-gro...@yahoo.com> > wrote: > > > > > On Feb 12, 4:31 am, backhus <n...@nirgends.xyz> wrote: > > > > Hi CMOS, > > > here's the solution you want: > > > > Assume the two input matrices to be stored in two separate RAMs (e.G. > > > Blockrams). Dual Ported, if necessary. > > > > Connect a subtractor circuit to the DataOut of these RAMs. > > > The Output of that circuit is identical to the output of your Result-RAM > > > > Now the result is virtually existent. If anyone has a doubt, just make a > > > readout of the Result-RAM. The result will be there. :-) > > > > Have a nice synthesis > > > Eilert > > > Are you saying that the above mechanism will compute a difference of > > two arrays in one clock cycle? If so then, I am not following... > > maybe you can explain a bit more.- Hide quoted text - > > - Show quoted text -
On Feb 12, 11:26 am, "Pete Fraser" <pfra...@covad.net> wrote:
> "Peter Alfke" <p...@xilinx.com> wrote in message > > news:1171298749.505302.219460@v33g2000cwv.googlegroups.com... > > > Why do you need the result in one clock cycle? What are you doing with > > the result? Is your opeation all perallel? > > Sounds like he's trying to do MAD for motion compensation.
I think he meant it '1 refresh cycle' instead of '1 clock cycle'