- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am trying to do a small concept where in I have created a project on DE2-115 board. In the same project, I have also implemented niosII processor and written a simple program to toggle the LED. In my final application that i intend to built, partly will be implemented in verilog and remaining will be implemented in .c file. Hence there may arise a need to access (read/write) the variable through verilog file which is declared in niosII application .c file and vice-versa. I wanted to know Is this possible and if yes how can i go about doing that. I intend to use it in final implementation and not just for debugging. thanks. JagdishLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In HDL (i.e Verilog) you must create the variable as a register in a Memory Mapped slave.
In Nios c code you define a pointer to the base address of the MM slave so you can access it as a regular variable. Remember to add 0x80000000 to the pointer address for uncached access: this prevents Nios to get the variable from cache rather than actual data possibly modified from HDL side.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Creating a reg variable is fine, I did this
reg [31:0] SharedVar; But Can you kindly tell me how to define a pointer to the base address of the MM slave and, add 0x80000000 to the pointer address for uncached access.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I created a variable in HDL by using "reg [15:0] SharedVar;"
But can you please tell me how to define a pointer to the base address of the MM slave and how to add 0x80000000 to the pointer address for uncached access thanks- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First of all you must wrap SharedVar into an Avalon slave
Then create the sopc/qsys MM slave component Add it to your sopc system (here's you define the base address to be used in C code) and rebuild Here you find a complete template provided by Altera: http://www.altera.com/support/examples/nios2/exm-avalon-memory-slave.html- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I went through the template details and i have a question. Do i need to do to all this access the shared variables. Can you kindly suggest me any other method by which i can access the same memory location of onchip memory or SDRAM using HDL and C code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The template implements far more than you need. For example it defines 16 registers (= shared variables) whereas you only need one; moreover it manages different data access modes, variable data width and many other features.
If you don't bother keeping all this stuff in your code, you can integrate it straight in your code. Otherwise cut away the non essential bells and whistles.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
my apologies for replying this late.
before trying the template wanted to get some clarity. Is the above template applicable even while using On-chip memory? OR Is it that on-chip memory can be handled in much simpler way and directly using hdl and niosII? One more question where are the variables stored that are declared in hdl. (integer, reg). can't this variable's memory location be accessed using niosII. thanks -Jagdish- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Is the above template applicable even while using On-chip memory? OR Is it that on-chip memory can be handled in much simpler way and directly using hdl and niosII? --- Quote End --- The above template DOES apply to onchip memory. --- Quote Start --- One more question where are the variables stored that are declared in hdl. (integer, reg). can't this variable's memory location be accessed using niosII. --- Quote End --- That's exactly the purpose of the MM slave. It maps the hdl registers to Nios address space
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, I have one doubt over here,
Implementing MM slave will allow me to share maximum 16 regs of HDL. What if i want to fill 10Mbytes of SDRAM location in HDL and later on use it in NiosII application? Will the MM slave still be the answer to this. I doubt this because in MM slave i found only 16 regs were available. In my application, I want to fill the video data (Around 10Mbytes) in SDRAM using HDL and later on retrieve the Data from SDRAM in niosII application for sending it to external world. -Jagdish- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's only a template and 16 regs are defined as typical example.
You could even have defined a single register or, on the other hand, extend the address range to whatever you need. In a generic case where you have: reg [31:0] ram[DEPTH-1:0]; You access from Avalon MM slde something like this:
always @(posedge clk) begin
if(slave_write)
ram <= slave_writedata;
else if (slave_read)
slave_readdata <= ram;
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok... then to access SDRAM's 10Mbytes location i will try using one reg out of 16 and declare as
reg[16:0] ram[(100000000 - 1) : 0]; kindly confirm my assumption slave write, slave read are the flags that i need to declare and use as per my logic slave_address is the variable to hold the address on which i want to carry out read and write activity. slave_readdata is the variable i will declare to retrieve the data from SDRAM the statement "ram[slave_address] <= slave_writedata;" will write the data in address location present in "slave_address". In nios II C appln, i will use the pointer to this address and retrieve the data. Am i right? -Jagdish- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry. I didn't notice you want to store your data into sdram. I wrongly assumed onchip ram was your target! :-(
Then you need a different architecture: Nios connects directly to the sdram in the standard way and you need another Avalon master on the same bus, in order to write data coming from custom hdl. Usually this task is accomplished by dma which will take care to transfer data from your source. An alternate method is exposing bus signals out of sopc system and access memory directly from your hdl side. But in this case you must be careful to correctly arbitrate the bus in order to avoid contention and stalling Nios accesses.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok... No issues
Anyways i will continue the activity of memory mapped slave with onchip memory and atleast make sure that i can access same onchip memory address locations via HDL and NiosII. if you can kindly confirm my assumptions of earlier post. and please have a look at my implementations below. the HDL code is getting compiled, but niosIi code is giving error. Kindly help.. HDL part module DE2_115_GOLDEN_TOP( .... // signals to connect to an Avalon-MM slave interface slave_address, slave_read, slave_write, slave_readdata, slave_writedata, slave_byteenable, // signals to connect to custom user logic (up to 16 input and output pairs) user_dataout_0, user_datain_0, // optional signals so that your external logic knows what location is being accessed user_chipselect, user_byteenable, user_write, user_read ); //======================================================= // PARAMETER declarations //======================================================= parameter DATA_WIDTH = 16; // word size of each input and output register parameter ENABLE_SYNC_SIGNALS = 0; // only used by the component .tcl file, 1 to expose user_chipselect/write/read, 0 to stub them parameter MODE_0 = 2; // 0 = Output, 1 = Input, 2 = Ouput and Input, 3 = Output with loopback, 4 = Disabled ---------------------------------------------------------- // slave interface input [3:0] slave_address; input slave_read; input slave_write; output reg [DATA_WIDTH-1:0] slave_readdata; input [DATA_WIDTH-1:0] slave_writedata; input [(DATA_WIDTH/8)-1:0] slave_byteenable; // user interface output wire [DATA_WIDTH-1:0] user_dataout_0; input [DATA_WIDTH-1:0] user_datain_0; output wire [15:0] user_chipselect; output wire [(DATA_WIDTH/8)-1:0] user_byteenable; output wire user_write; output wire user_read; *** reg [data_width-1:0] ram[10]; assign user_write = slave_write; // outputs are registed so need a delayed copy of the write signal assign user_read = slave_read; // using Qsys i had integrated niosII, PIO lEd, on chip memory and Avalon MM slave niosII_Qsys inst_niosII_Qsys ( .clk_clk (CLOCK_50), // clk.clk .redled_external_connection_export (LEDG), // redled_external_connection.export .amm_slave_ui_dataout_0 (slave_writedata), // amm_slave_ui.dataout_0 .amm_slave_ui_datain_0 (slave_readdata) // .datain_0 ); // finally ----------------------------------------------------------------------------- always @(posedge CLOCK_50) begin swreg = SW; if(swreg[0] == 1) begin flag = 1; regledr[0] = 1; end else begin flag = 0; regledr[0] = 0; end // write to memory only once when sw is turned ON if(flag == 1) begin flag = 2; // onchip memory address range starts at 0x20000, // i have directly written data 5 to the first array index. i don't know at which onchip address the ram variable starts. ram[0] <= 5; /*if(slave_write) ram[slave_address] <= slave_writedata; else if (slave_read) slave_readdata <= ram[slave_address]; */ end end NiosII code //Auto generated code# define ONCHIP_MEMORY2_BASE 0x20000 // ONCHIP_MEMORY2_BASE starts address main .c file variable = IORD((ONCHIP_MEMORY2_BASE+20), 0); In nios II when i try to read onchip memory address location (ONCHIP_MEMORY2_BASE + 20) using the above statement it gives me memory error as "address 0xaddf7c of niosII_SW.elf section `.bss' is not within region `onchip_memory2' ""address 0xaddf7c of niosII_SW.elf section `.onchip_memory2' is not within region `onchip_memory2'"- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In your component HDL definition you declared a 4-bit addess range:
...
// slave interface
input slave_address;
...
That means you can't access data a offset 20. Slave maps into Nios memory from ONCHIP_MEMORY2_BASE to ONCHIP_MEMORY2_BASE+15. You should see this slave address range in Qsys, too. Anyway the correct syntax is variable = IORD(ONCHIP_MEMORY2_BASE, 20); Please also note that Nios use byte addressing, so you possibly need to discard the 2 LSB of address when accessing 32bit data. I can't understand the linker error about .bss section: I'm concerned it is related to the IORD call. I'd rather think you made sort of mess with linker settings after you added the new onchip memory device. Do you map any memory section into it? How is 'variable' defined?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am really confused.. Unable to handle a simple thing, please help me out. Kindly refer the document attached that shows my QSYS implementation. It shows system contents, memory address map and also the slave address issue which i am facing.
I modified the slave template file (.tcl)to have only one register. i also tried to increase the bits for slave address, but observed that reg count has reduced to 1 as i expected but even after changing the address field number[3..0], it doesn't get reflected in qsys. it still remains the same. In HDL i increased the range as "input [15:0] slave_address;". I declared the variable "SharedRam" in HDL as reg [DATA_WIDTH-1:0] SharedRam[10]; I am unable to figure out at what address the "SharedRam" variable is stored in onchip memory. In which file, will i come to know its address. In HDL i am trying to store value 5 at 0th location of SharedRam variable by using SharedVar[0] <= 5; I hope this fine. In NiosII I have declared one 4 byte variable : unsigned int uiVar[10] = {0}; and then attempting to read the onchip memory : uiVar[0] = IORD(ONCHIP_MEMORY2_BASE, 20); (ONCHIP_MEMORY2_BASE is 0x20000) I verified the contents of uiVar[0], and found it is not equal to 5 which i am expecting. The address of this variable as per niosii_objdump file 000201f8 g O .bss 00000028 uiVar Kindly help me write to known address in HDL and then use niosII to read the data from the same location. if the address is known, it is of help. Similarly later on i will try other way round such that, i will write to a memory location in NiosII and read the same memory location from HDL. thanks -Jagdish- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sure, I see you are really confused.
And so am I, since I can't understand what's you point. I guess SharedVar is defined and assigned inside st_0 MM slave device, but you are trying to read its value from onchip_memory2 !!! Then, that's the main problem; the correct base address to be used in IORD is 0x41040. Anyway there are other major flaws and I think you need to learn the basics of Nios system before you can go further with this design.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page