Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12589 Discussions

Share variables between verilog file and niosII application file(.c file)

Altera_Forum
Honored Contributor II
1,642 Views

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. 

 

Jagdish
0 Kudos
16 Replies
Altera_Forum
Honored Contributor II
964 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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'"
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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?
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
964 Views

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.
0 Kudos
Reply