Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,376 Views

FPGA memory initialization and management

Hi, 

my design is using a cyclone IV on-chip memory. I have two questions (for the moment): 

- when configuring the memory with qsys, I don't really understand the data-width choice. If it's 32-bit-wide, does it mean a +1 increment in the address will be a 32-bit increment for the data? If I read something at address a, will *a be a 32-bit word? 

- the initialization could be made by a file. What should I use to edit this file? For example I have an 8-bit words memory, I've tried a hexadecimal editor but when reading it (by a software executed on a Nios2 cpu) it's not what I expect. 

 

Thank you for the explanations you can give me.
0 Kudos
16 Replies
Altera_Forum
Honored Contributor I
109 Views

The address changes depending on where you are in the design. 

 

1. On an altsyncram component, with 32-bit data width, incrementing the address +1 increments the data by a 32-bit word. 

 

2. Qsys slave addressing is word-based. So, on a Qsys Avalon-MM slave interface, with 32-bit data width, incrementing the address +1 increments the data by a 32-bit word. 

 

3. Qsys master addressing is byte-based. So, for a master accessing an Avalon-MM slave interface, with 32-bit data width, incrementing the master address +4 increments the data by a 32-bit word. 

 

The Altera hex editor works fine. I typically create a couple of words in an example file using the hex editor, save it as Intel hex format, and the look at that file relative to the Intel hex standard. For 32-bit words, I'm pretty sure the Intel hex format will be one 32-bit value per line in the file. I then write code (C, MATLAB, or Tcl) to create the hex file. 

 

Cheers, 

Dave
Altera_Forum
Honored Contributor I
109 Views

OK. 

 

I don't use an Avalon-MM but a dual-port RAM in Qsys. One is connected to the cpu, the other is exported so the FPGA design can write on it. I don't know why, but the results don't seem good. 

 

For the editor, I don't find it in any Quartus II menu. Where is it?
Altera_Forum
Honored Contributor I
109 Views

 

--- Quote Start ---  

 

I don't use an Avalon-MM but a dual-port RAM in Qsys. One is connected to the cpu, the other is exported so the FPGA design can write on it. I don't know why, but the results don't seem good. 

 

--- Quote End ---  

 

Read the code and see what it does with the altsyncram address port. 

 

 

--- Quote Start ---  

 

For the editor, I don't find it in any Quartus II menu. Where is it? 

--- Quote End ---  

 

File->New, Memory Files, Hexadecimal (Intel-Format) File. 

 

Cheers, 

Dave
Altera_Forum
Honored Contributor I
109 Views

 

--- Quote Start ---  

Read the code and see what it does with the altsyncram address port. 

--- Quote End ---  

 

Qsys tells it's an altera_avalon_onchip_memory2, I don't know if it's the same as altsyncram... 

The address is controlled by a VHDL line: addr <= std_logic_vector(to_unsigned(tstep, addr'length)); 

Tell me if I shouldn't do that. 

 

 

 

--- Quote Start ---  

 

File->New, Memory Files, Hexadecimal (Intel-Format) File. 

 

--- Quote End ---  

 

Thanks for that. Is the Memory Initialization File better?
Altera_Forum
Honored Contributor I
109 Views

I really don't understand what's happening in my design. I give you details: 

The hardware part (a Quartus II project downloaded on the Cyclone IV of a de0-nano board) is instantiating a qsys project with a Nios II cpu and a dual-port memory. The cpu can read the memory that can be written by the hardware part. For the moment I don't write anything, the memory (8-bit words) is initialized by a .hex file created as a memory initialization file by Quartus II as showed by this picture: 

https://www.alteraforum.com/forum/attachment.php?attachmentid=9298  

A software is running on the cpu. I give the code: 

#include <stdio.h> # include "system.h" int main() { int *pmem; int i=0; printf("Start!\n"); for (i=0; i<15; i++) { pmem=(int *)(0x80000000|(ONCHIP_MEMORY2_0_BASE+i)); printf("%u\n", *pmem); } return 0; } 

 

and the result is: 

 

--- Quote Start ---  

Start! 

67305985 

67305985 

67305985 

67305985 

134678021 

134678021 

134678021 

134678021 

2826 

2826 

2826 

2826 

 

--- Quote End ---  

 

 

I don't understand this. If you can explain what is done, please tell me. 

Thanks.
Altera_Forum
Honored Contributor I
109 Views

 

--- Quote Start ---  

Qsys tells it's an altera_avalon_onchip_memory2, I don't know if it's the same as altsyncram... 

--- Quote End ---  

 

Looking at the Qsys GUI is not the same as reading the code. Generate your Qsys system, and then look at the synthesis code. There will be either a component instance called altera_avalon_onchip_memory2 or there will be a file with that name. It will use an altsyncram :) 

 

 

--- Quote Start ---  

The address is controlled by a VHDL line: addr <= std_logic_vector(to_unsigned(tstep, addr'length)); 

Tell me if I shouldn't do that. 

 

--- Quote End ---  

 

If the RAM is in Qsys, then you don't get to control it, unless of course you have added a dual-ported RAM to your Qsys system and exported one side of the RAM to the top-level. Either way, this is not enough code to tell what you are doing. Basically it looks like you're converting an integer tstep to a std_logic_vector, but you have not shown how you update tstep. 

 

 

--- Quote Start ---  

 

Thanks for that. Is the Memory Initialization File better? 

--- Quote End ---  

 

Better than what? You asked how you can initialize it from file. 

 

You can use RAM/ROM initialization files when you want the RAM to contain "something" at power-on, eg., a processor bootloader program. Whether you need an initialization file or not depends on what you are trying to do. 

 

Cheers, 

Dave
Altera_Forum
Honored Contributor I
109 Views

Assuming you have your base address correct, try the following code; 

 

# include <stdio.h> # include "system.h" int main() { int *pmem; int i=0; printf("Start!\n"); pmem=(int *)(0x80000000|(ONCHIP_MEMORY2_0_BASE)); for (i=0; i<15; i++) { printf("%u\n", *pmem++); } return 0; }  

 

The statement *pmem++ operates as follows; *pmem points to the 32-bit int, so your print statement prints out the value of the integer, and then the ++ increments the pointer by the size of the pointer, i.e., 32-bits. Your original code added i to a# define, so that would have only moved the pointer by a single byte. 

 

Cheers, 

Dave
Altera_Forum
Honored Contributor I
109 Views

OK it IS an altsyncram. 

 

The tstep signal is generated like that: 

process(clk, tckup) begin if rising_edge(clk) then if (tckup='1') then wen <= '1'; if tstep<25000 then tstep <= tstep+1; end if; else wen <= '0'; end if; end if; end process; 

 

 

--- Quote Start ---  

Better than what? You asked how you can initialize it from file. 

--- Quote End ---  

 

Better than a .hex file?
Altera_Forum
Honored Contributor I
109 Views

 

--- Quote Start ---  

 

The tstep signal is generated like that: 

process(clk, tckup) begin if rising_edge(clk) then if (tckup='1') then wen <= '1'; if tstep<25000 then tstep <= tstep+1; end if; else wen <= '0'; end if; end if; end process; 

 

--- Quote End ---  

 

This code has some minor coding issues; (1) you do not need tckup in the sensivity list, (2) generally you should not code using integers. Its better to be explicit to synthesis tools so there is no room for ambiguity. In your case you could define tstep as an integer over a limited range. or use an unsigned of an appropriate bit-length.  

 

 

--- Quote Start ---  

 

Better than a .hex file? 

--- Quote End ---  

 

.hex files are an industry standard, .mif files are Altera-specific. I personally prefer to stick with standard formats where possible. However, both .hex and .mif initialize RAM, so either is fine. 

 

Cheers, 

Dave
Altera_Forum
Honored Contributor I
109 Views

I think I've corrected everything (pmem++, sensivity list and integer range) and now the result is: 

 

--- Quote Start ---  

Start! 

67305985 

134678021 

2826 

--- Quote End ---  

 

I still don't understand...
Altera_Forum
Honored Contributor I
109 Views

 

--- Quote Start ---  

 

I still don't understand...  

 

--- Quote End ---  

 

That's ok. Use this as an opportunity to learn. You have several options. 

 

1. Use the Eclipse IDE and the debugger to manually write and read memory locations 

 

2. Add a JTAG-to-Avalon-MM bridge to your Qsys system and read and write memory using that 

 

3. Create a simulation of your system and look at the memory read/write accesses 

 

Try any or all three! 

 

Cheers, 

Dave
Altera_Forum
Honored Contributor I
109 Views

I love to learn new things! 

 

1. I do use the Eclipse ISE but I don't know how to use a debugger. Is there a tutorial or a document I could read to learn that? 

 

2. I don't use an Avalon-MM bridge in Qsys. I've read papers about that but it seemed complicated and I preferred the self-made method to use a dual-port memory to access it both with software and with hardware. 

 

3. I know Modelsim but I don't know how to do that. 

 

If one of the 3 options seems better for you, please tell me and surely I'll need your help to go further...
Altera_Forum
Honored Contributor I
109 Views

I had a problem messing int and char types. Things seem to work as expected. 

I let you know when I need more help. Thank you.
Altera_Forum
Honored Contributor I
109 Views

 

--- Quote Start ---  

I love to learn new things! 

 

--- Quote End ---  

 

Great! With FPGAs, there are plenty of opportunities. 

 

 

--- Quote Start ---  

 

1. I do use the Eclipse ISE but I don't know how to use a debugger. Is there a tutorial or a document I could read to learn that? 

 

--- Quote End ---  

 

Altera has a "My First NIOS II Tutorial" that provides a walk-through of their Eclipse setup. 

 

 

--- Quote Start ---  

 

2. I don't use an Avalon-MM bridge in Qsys. I've read papers about that but it seemed complicated and I preferred the self-made method to use a dual-port memory to access it both with software and with hardware. 

 

--- Quote End ---  

 

You can use self-made hardware, but its much more efficient if you create those self-made components as Qsys components and then wire them together in the Qsys GUI as this saves you having to create arbitration logic. Here some tutorials on using the JTAG interface to access custom logic; 

 

http://www.alterawiki.com/wiki/using_the_usb-blaster_as_an_sopc/qsys_avalon-mm_master_tutorial 

http://www.ovro.caltech.edu/~dwh/correlator/pdf/altera_jtag_to_avalon_analysis.pdf 

http://www.ovro.caltech.edu/~dwh/correlator/pdf/vjtag.pdf 

 

 

--- Quote Start ---  

 

3. I know Modelsim but I don't know how to do that. 

 

--- Quote End ---  

 

You need to learn this too. The best way to debug hardware issues is to trace the problem using SignalTap II and then reproduce that problem in simulation, and then debug in the simulator. 

 

 

--- Quote Start ---  

 

If one of the 3 options seems better for you, please tell me and surely I'll need your help to go further... 

--- Quote End ---  

 

You need to learn them all :) 

 

Cheers, 

Dave
Altera_Forum
Honored Contributor I
109 Views

Now I try to read the memory to control what happened but I don't know if it's my hardware part that's not not doing as I want or the software one. So I'd like to look at the memory. 

Maybe the In-System Memory Content Editor could help me reading the memory but I don't know how to use it. 

Can you help me?
Altera_Forum
Honored Contributor I
109 Views

 

--- Quote Start ---  

Now I try to read the memory to control what happened but I don't know if it's my hardware part that's not not doing as I want or the software one. So I'd like to look at the memory. 

Maybe the In-System Memory Content Editor could help me reading the memory but I don't know how to use it. 

Can you help me? 

--- Quote End ---  

 

I've never used the In-System Memory editor, I prefer using the JTAG-to-Avalon-MM bridge. Go through the tutorial I linked to above, and it shows how to use it. 

 

Using the JTAG bridge, you can read/write memory, and then using NIOS you can read/write too. Using SignalTap II to trace the RAM I/O you can watch the accesses from either master. 

 

Cheers, 

Dave
Reply