Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

- Community Forums
- :
- Forums
- :
- Hardware Development
- :
- AI Engine, DSP IP and Tools
- :
- Re: Using RAM Blocks to manipulate data

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Highlighted

alexdetrano

Observer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

10-05-2009 02:55 PM

10,375 Views

Registered:
06-02-2009

Hello,

I'm not sure if I'm going about this in the right way, but I'll give it a shot. I have a sequence of 100 numbers (1:100) and I want to grab the first 10, then the third ten, then the fifth ten, so that my data will be (1:10)(30:40) (60:70), etc. How can I do this? I think a RAM block might come in handy here; I write the whole sequence to the RAM block, so that the first 100 memory locations would be my whole data, then use a counter of some sort to read out memory address 1:10, then address 30:40, etc. Am I thinking about this properly? I looked at the single port RAM block and the hlep file didn't really help...perhaps a dual port RAM block is necesssary? These RAM blocks are a little overwhlemeing, any help from some xilinx gurus out there would be much appreciated. Thanks!

Alexander

1 Solution

Accepted Solutions

Highlighted
Thanks for your help erochasousa, i solved my problem using a dual port ram with a diffrente rate for write and read.. And what happen if i can reverse this operation. The input now has 40 bytes and i want in the output 52 bytes??the additional 12 bytes could be any value, for example 00...With this operation the rate for the output must be the same when i have the initial 52 bytes

gotcha25

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

10-16-2009 05:49 PM

11,777 Views

Registered:
03-23-2009

14 Replies

Highlighted

walid_farid

Contributor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

10-06-2009 11:05 AM

10,361 Views

Registered:
04-14-2009

Hello,

I think you can do this using a single-port block ram initialized with the values 1:100 and then you can simply write a state machine which access the addresses you want to get the corresponding data. The state machine can be written either using the Mcode block (The state m/c is written in Matlab) or the Sysgen Black Box (The state m/c to be written in verilog or vhdl.

Regards,

Walid F.

Highlighted

gotcha25

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

10-11-2009 11:30 PM

10,334 Views

Registered:
03-23-2009

hello, i am doing something like that. I have to receive continue data and work for block. In this case i receive a block of 52 bytes and i have to eliminate the last 12 bytes. I am using 2 single port RAM but the resuts are not successful. The output data must be continuo. (Receive 52 bytes and the output have 40 bytes and next to the last byte i have the first byte of the 2nd block ).

thanks...

Highlighted

erochasousa

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

10-14-2009 07:38 AM - edited 10-14-2009 08:13 AM

10,315 Views

Registered:
10-14-2009

You can put a counter counting from 0 to 29 and glue it into a ROM storing pointers. The ROM is connected directly to the Memory address input.

The pointers can be [1:10 30:40 60:70]-1

Whenever I need to rearrange the format of a serial data input, for example after a FFT, I need to make something like "fftshift" from Matlab, I use this ROM-storing-pointers strategy.

You can use a dual-port RAM if the input data is coming continuosly all the time...

You can also use a FIFO. Just work the write signal. Keep 'we' high when the inputs 1:10 , 30:40 and 60:70 are coming. Then just read at the output. If you want continuous data like gotcha25, your read signal should have a lower rate then we signal.

For a 100-sample input data, you are outputting 30 samples. So the normalized sample rates '10' (for read signal) and '3' (for we signal).

Hope this helps

Message Edited by erochasousa on 10-14-2009 07:45 AM

Message Edited by erochasousa on 10-14-2009 08:13 AM

Highlighted
Thanks for your help erochasousa, i solved my problem using a dual port ram with a diffrente rate for write and read.. And what happen if i can reverse this operation. The input now has 40 bytes and i want in the output 52 bytes??the additional 12 bytes could be any value, for example 00...With this operation the rate for the output must be the same when i have the initial 52 bytes

gotcha25

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

10-16-2009 05:49 PM

11,778 Views

Registered:
03-23-2009

Highlighted

evgenia89

Participant

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-06-2012 04:24 AM

7,987 Views

Registered:
02-06-2012

Hello,

I am trying to do the similar things. I use FIFO and I need to read 100 samples to this and then to calculate average value. The problem is how to calculate this average, because the function mean(x) works with arrays and I don't know how to convert my input digital signal to array.

Thank you for any help!

Highlighted

vlavruhin

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-06-2012 04:36 AM

7,985 Views

Registered:
12-08-2010

Hello, Evgenia.

It's better to start new thread.

Do you want to calculate average value using blocks of the System Generator for further netlist generation? Or to find average value using standard Matlab function (mean(x))?

Best Regards,

Vitaly.

Vitaly.

Highlighted

evgenia89

Participant

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-06-2012 05:03 AM

7,982 Views

Registered:
02-06-2012

Vitaly,

I think it's better to use System Generator blocks, but the using of mean(x) is also possible because of block MCode where I can write the code.

vlavruhin

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-06-2012 05:16 AM

7,978 Views

Registered:
12-08-2010

Evgenia,

'MCode' block supports only restricted subset of Matlab language as you can see on page 224 of System Generator Reference Guide:

http://www.xilinx.com/support/sw_manuals/sysgen_ref.pdf

But there is an 'Accumulator' block which can be used to solve your problem.

Averaging is basically accumulation:

mean(X) = (X_1 + X_2 + ... + X_N) / N,

accumulated_sum(X) = X_1 + X_2 + ... + X_N.

Accumulator expects single samples at its input (not array).

Just make sure to chose proper bitwidth of accumulator in order to prevent overflow.

Best Regards,

Vitaly.

Vitaly.

Highlighted

evgenia89

Participant

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-06-2012 06:18 AM

7,974 Views

Registered:
02-06-2012

Thank you, Vitaly, it really can help in solving the problem.

But the thing is that I need to put into a memory any amount of points (let's say 1000), and then to calculate average of all these point. It should be one number but it seems that the block 'Accumulator' works for every point independently:

1st line - input signal;

2nd line - counter;

3d line - output of accumulator.

Or maybe I don't understand anything.

Highlighted

vlavruhin

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-06-2012 06:36 AM

5,481 Views

Registered:
12-08-2010

Evgenia, but what is the purpose of storing the samples in memory? If you only need to find the average value, then there is no need for additional memory buffer. Just use accumulator and get the answer.

@evgenia89 wrote:

But the thing is that I need to put into a memory any amount of points (let's say 1000), and then to calculate average of all these point. It should be one number but it seems that the block 'Accumulator' works for every point independently

Accumulator works on every clock cycle. You can add enable port (in parameters of Accumulator block).

When Enable is true, then Accumulator adds current input sample to internal register:

internal_register = internal_register + input,

output = internal_register.

When Enable is false, then Accumulator just outputs value of internal register:

output = internal_register.

When Reset is true, then Accumulator resets internal register:

internal_register = 0.

So with the help of Enable and Reset signals you can calculate the sum of input samples (and hence, the average value).

This approach will work even if you will need to find average value of long sequence (because there is no need for additional memory storage).

Best Regards,

Vitaly.

Vitaly.

Highlighted

evgenia89

Participant

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-07-2012 03:36 AM

5,472 Views

Registered:
02-06-2012

If I don't store the samles in the memory the accumulator calculates sum at every sample as shown in the figure to my previous post. Actually the output is also a bit strange - sum is from -1 to 1 in different moments.

The 'Enable' port doesn't really help - the picture is the same when I use it.

Highlighted

vlavruhin

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-07-2012 05:21 AM

5,467 Views

Registered:
12-08-2010

Hi, Evgenia.

@evgenia89 wrote:

If I don't store the samles in the memory the accumulator calculates sum at every sample as shown in the figure to my previous post.

Sure. Every block in System Generator (and in FPGA, generally) always has some output value. It's a hardware. So there is always some kind of signal at any port.

Lets consider that you have following input sequence:

*x_1, x_2, ..., x_N.*

You would like to calculate sum (or average value) of input samples.

So lets consider Accumulator block. At any clock cycle accumulator do following (if enable = true):

*internal_register = internal_register + input,*

*output = internal_register.*

At moment t=0:

*internal_register = 0,*

*acc_output = 0.*

At moment t = 1:

*input = x_1,*

*internal_register = internal_register + input = x_1,*

*acc_output = internal_register = x_1.*

At moment t = 2:

*input = x_2, *

*internal_register = internal_register + input = x_1 + x_2, *

*acc_output = internal_register = x_1 + x2.*

...

At moment t = N:

*input = x_N,*

*internal_register = internal_register + input = x_1 + x_2 + ... + x_N, *

*acc_output = internal_register = x_1 + x_2 + ... + x_N.*

evgenia89 wrote:The 'Enable' port doesn't really help - the picture is the same when I use it.

If Enable is false, then Accumulator just skips current input sample (i.e., acuumulator doesn't add it to internal register).

@evgenia89 wrote:

Actually the output is also a bit strange - sum is from -1 to 1 in different moments.

That's another story. I assume that your samples are integer or fixed-point fractional numbers. Right?

System Generator has different options to represent fixed-point numbers.

There are 'UFix_N_M' and 'Fix_N_M' formats.

N - bitwidth of number,

M - bitwidth of fractional part (i.e., position of binary point).

'Fix' means signed fractional. And 'UFix' is unsigned fractional number.

So if output of accumulator has type, for example, 'Fix_16_15', then you will get only numbers in range [-1, 1).

What is the type of your samples?

Best Regards,

Vitaly.

Vitaly.

Highlighted

evgenia89

Participant

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-19-2012 05:58 AM

5,450 Views

Registered:
02-06-2012

Hello, Vitaly,

thank you very much for your response. I changed the type of accumulator output and now it works correctly.

But my previous problem is still not solved. I believe that I need memory anyway because my task is to calculate avearge of e.g. 1024 samples, then - the next 1024 samples, and so on and in the end the average of all these stored data should be written to a file.

I am wondering if it is possible to do with System Generator or I should use memory interface generator.

Evgenia.

Highlighted

vlavruhin

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-19-2012 06:20 AM

5,447 Views

Registered:
12-08-2010

Hello, Evgenia.

Average is just scaled sum, right?

So if your task is to calculate an average value of 1024 samples, then find the sum and discard log2(1024)=10 least significant bits.

If you need to calculate average values of different frames of data, then just reset Accumulator between these frames. Simple control logic (for example, finite state machine) can do that.

So if your goal is to find average value of input samples, then you don't need additional memory storage (and memory interface generator as well).

Best Regards,

Vitaly.

Vitaly.