LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Labview FPGA DRAM Address question

Solved!
Go to solution

Hello All,

 

How do I properly address the 128-bit DRAM?  I have the DRAM Bank 0 set as a 128-bit memory, implemented in my design as CLIP.  I realize that it is a 32-bit wide RAM.  I had a National Instruments AE do the initial design that I have been adding to.  He asserted that addresses needed to be incremented by four with each write.  Example: if I were writing to consecutive addresses, I would write to address: 0, 3, 7, 11, 15 etc, and I would send 128-bits to each address.  My address is computed as (pixel number in a line of video + line * (# of pixels per line) for a frame of video).  So I take my computed address and add 4.

 

However, I checked an example in example finder:  hardware IO/flexRIO/external memory/memory integrity example.  In this example, 128-bit data is being sent to the memory and the address is incremented by 1 (rather than 4) each clock cycle that data is valid.  

 

Which is it?  The help article for this function is ambiguous.  

 

 

Sets the address in external memory for reading or writing. The physical data bus for external memory is 32 bits wide (4 bytes). Each unique address value represents 4 bytes of data. Therefore, the total number of unique addresses in external memory is equal to (Memory Size in bytes)/4.  

Note  The memory interface exposed to LabVIEW FPGA is 128 bits wide. As a result, each memory write or read operation accesses four different address locations in memory. The memory controller latches this signal value only when you issue a new memory write command by asserting the Command_Write_Enable signal. 

 I am confused by the 2nd paragraph "each memory write or read operation access four different address locations in memory."  Does this mean I increment the address by 1 in order to get consecutive 128-bit "locations" (yes, I know it's 4 32-bit words in memory), or do I increment the address by 4, in order to account four 4 32-bit words per single 128-bit transfer?  

 

Thanks for your help.

 

-J

 

0 Kudos
Message 1 of 18
(7,492 Views)

Hi J-

 

Technically, you can write to the DRAM both ways.  When you write to the DRAM each address is 32 bits wide as you pointed out.  The DRAM is 128-bit, therefore you could write to registers 0, 1, 2, & 3 all at the same time (32 bits to each) and write all 128 bits at once.  You could also write only to register 0, however, you are actually writing to all 128 bits.  Registers 1, 2 & 3 would be re-written as the values they were originally.  Therefore it is most efficient to write to all of the addresses at one time.  By writing all four at once means you can fill four address with one write instead of writing four times.  I hope that you find this explanation more clear.

 

Have a great day!

 

Brandon Treece

Applications Engineer

National Instruments 

Message 2 of 18
(7,446 Views)

That doesn't answer the question.  I know that theoretically I CAN put 32-bits of data into a RAM with a 128-bit labview interface.  The question is how I address it.   Here are two scenarios that I described for addressing.  Please let me know which is correct.

 

In this situation, I am writing a 128-bit word every 20 clock cycles.  I want my memory to look like:

 

address 0: input1[127:0]

address 1: input2[127:0]

address 2: input3[127:0]

 

clock cycle 0:  data = input[127:0], address = 0, r/w = write, issue command = true.

clock cycle 1-19:  case statement disables everything (the entire write-method is gone in the false case).

clock cycle 20: data = input[127:0], address = 1, r/w = write, issue command = true.

clock cycle 21-39: case statement disables everything

clock cycle 40: data = input[127:0], address = 2, r/w = write, issue command = true.

 

Is that correct?  Or must I increment the address as follows (because labview is converting a 128-bit write to 4 32-bit writes).

 

address 0: input1[127:0]

address 3: input2[127:0]

address 7: input3[127:0]

 

clock cycle 0:  data = input[127:0], address = 0, r/w = write, issue command = true.

clock cycle 1-19:  case statement disables everything (the entire write-method is gone in the false case).

clock cycle 20: data = input[127:0], address = 3, r/w = write, issue command = true.

clock cycle 21-39: case statement disables everything

clock cycle 40: data = input[127:0], address = 7, r/w = write, issue command = true.

 

What value do i put in my design, so that I don't leave empty addresses.  If I implement my 2nd example, but the RAM must actually be addressed as in my first example, I am wasting 3/4 of my addressable space.  What must I do to sequential 128-bit writes to ensure that my data is packed, and that no addresses are unwritten?  In my sistuation, I will ALWAYS be writing to sequential addresses.  Every iteration, I will start from address zero and count up until my data logging is complete.

 

-J

 

0 Kudos
Message 3 of 18
(7,428 Views)
Solution
Accepted by topic author JJMontante

Hi J, 

 

Allow me to clarify my previous post.  There are two ways to access the DRAM memory, CLIP (as you described is what you are doing) and using the memory node.  As was pointed out before, the DRAM is 128 bits wide.  When you write to the CLIP you are writing in chunks that are the width of the databus (in this case 32 bits).  Therefore, when you write a full 128 bits to the DRAM, you are placing 32 bits in each address.  Since the address is the width of the databus, then you will write to address 0, 1, 2, & 3 with one write.  Then the next write will be to address 4, 5, 6, & 7, and then 8, 9, 10, & 11 and so on.  In this case, you need to increment your address by 4 each time you write.  Note that you start at 0, then 4, then 8, then 12 etc.  In your previous post, you were off by one digit.

 

There is also another way to write to the DRAM, and that is through the memory node, which is what is being used in the example that you are pointing out.  Here, LabVIEW takes on some of the thinking, and instead of the address being the width of the databus, they are the width of the entire chunk of 128 bits.  So when you write to the DRAM here, you only increment the address by 1 each time because they are referring to the entire chunk of memory.  To contrast this with the CLIP interface, address 0 of the memory node would correspond to addresses 0, 1, 2, & 3 in CLIP mode, and address 1 of the memory node would correspond to addresses 4, 5, 6, & 7 in CLIP mode.  If you do not write an entire 128 bits to the memory node, then the remaining addresses in the data chunk are filled with "junk" so that the addressing remains constant.  

 

As I mentioned before, it is the most efficient of write in 128 bit chucks so that you are not wasting any of the DRAM.  I hope that you find this explanation more clear.

 

Brandon Treece

Applications Engineer

National Instruments

Message 4 of 18
(7,409 Views)

Okay, I now understand your point.  Now the question comes to something interesting observed on a real system on my lab bench.  Before getting this post, my design incremented the address by 1 every cycle (as you mentioned to use on the memory method node).  However, I was using CLIP (which should be addressed by fours).

 

What I observed was that my data came back exactly as expected.  

 

I created multiple 128-bit words out of 32-bit words, in the following pattern (incrementing the last digits).

 

word 1: 1234_5678

word 2: 1234_5679

word 3: 1234_567A

word 4: 1234_567B

word 5: 1234_567C

word 6: 1234_567D

word 7: 1234_567E

word 8: 1234_567F

word 9: 1234_5680

word 10: 1234_5681

word 11: 1234_5682

word 12: 1234_5683

word 13: 1234_5684

word 14: 1234_5685

word 15: 1234_5686

word 16: 1234_5687

 

and wrote as follows: 

0x0: 1234_5678_1234_5679_1234_567A_1234_567B

0x1: 1234_567C_1234_567D_1234_567E_1234_567F

0x2: 1234_5680_1234_5681_1234_5682_1234_5683

0x3: 1234_5684_1234_5685_1234_5686_1234_5687

 

when I read back 128-bit words from DRAM, and then converted into a series of 32-bit words like my input, I successfully got back my input.  I got the same words in, in the correct order.

 

According to your explanation of clip, the lower two bits are "don't cares".  All it cares about are 0, 4, 8.  By this reckoning, I should have had all the first four addresses alias to 0x0.  Therefore, when I later begin my readback, I should get   

 

0x0:  1234_5684_1234_5685_1234_5686_1234_5687  (the last value written to that aliased address).  

 

OR

 

if those lower two address bits are NOT don't cares, and instead are directly addressing each 32-bit location, I should have gotten basically a read of 0x0 to give me 128-bits made up of the first 32-bit of each four transactions.  That would be the case if:

 

32-bit data address 0x0  gets 1234_5678 (the first 32-bits of my first 128-bit write).

32-bit data address 0x1 gets 1234_567C (the first 32-bits of my 2nd 128-bit write).

32-bit data address 0x2 gets 1234_5680 (the first 32-bits of my 3rd 128-bit write).

 

128-bit address 0x0 should return 1234_5678_1234_567C_1234_5680_1234_5684. 

 

Neither of these cases (4 addresses aliased when you don't increment by 4, or the first 32 bits of every address aliased as 3/4 of the 128-bits get overwritten with each incremented address) occurs.  There is a disconnect somewhere.  What am I missing?

0 Kudos
Message 5 of 18
(7,401 Views)

Before I continue, what version of LabVIEW are you using currently?  Also when you set up the socketed CLIP in the DRAM properties, are you using FIFO or Random Access?

 

Brandon Treece

Applications Engineer

National Instruments

Message 6 of 18
(7,373 Views)

Labview 2010, Random Access type.

0 Kudos
Message 7 of 18
(7,360 Views)

If you are using the CLIP interface, you should write your words as follows:

 

0x0: 1234_5678_1234_5679_1234_567A_1234_567B

0x4: 1234_567C_1234_567D_1234_567E_1234_567F

0x8: 1234_5680_1234_5681_1234_5682_1234_5683

0x12: 1234_5684_1234_5685_1234_5686_1234_5687

 

This means that 1234_5678 would go to address 0, 1234_5679 to address 1, and so on.

 

Could you please clarify what you mean by don't cares?  I am not sure I understand what you are referring to.  Also, if you could post a screenshot of you block diagram that could also be helpful in explaining what is going on.

 

Brandon Treece

Applications Engineer

National Instruments

Message 8 of 18
(7,303 Views)

The lower two bits of the address are 'don't cares'.  If you address by 4 (so that 128 bits are written to every fourth address), that equates to a shift-right by 2 meaning that my lower 2 bits of addressing are don't cares.

0 Kudos
Message 9 of 18
(7,197 Views)

I am not sure that I understand what you are getting at.  Nevertheless, did my last post clear things up for you, or are you still experiencing issues getting this to work properly?

 

Brandon Treece

Applications Engineer

National Instruments

0 Kudos
Message 10 of 18
(7,162 Views)