Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

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

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

16 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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'"
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.