Forum Discussion

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

Custom Component, Write not working

Hi,

I have just created a SOPC custom component with an Avalon-MM Slave template (clk, reset, write, read, readdata, writedata) with some HDL inside.

My problem is that in my C application, I'm able to read what I have put in readdata with IORD(base_address, 0) but nothing is written in writedata when I use IOWR(base_address, 0, data).

Am I missing something or am i doing something wrong ?

Thank you,

vvh84

6 Replies

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

    Well the answer to the question is yes you are missing something or doing something wrong. But it's not your software call. Your usage of the IOWR macro is correct. If you would like to post your <component_name>.tcl along with your firmware file(s), I can take a look.

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

    Sorry I didn't provide a lot of informations. I'm not very familiar with Nios and I was just doing some test.

    Here is the tcl file :

    #  TCL File Generated by Component Editor 9.0#  Thu Aug 27 15:19:24 CEST 2009#  DO NOT MODIFY
    #  +-----------------------------------#  | #  | Dust_Detect "Dust_Detect" v1.0#  | Vvh 2009.08.27.15:19:24#  | Dust Detector#  | #  | D:/altera/90/nios2eds/examples/vhdl/niosII_cycloneII_2c35/Detecteur_Poussiere/Dust_Detect.vhd#  | #  |    ./Dust_Detect.vhd syn, sim#  | #  +-----------------------------------
    #  +-----------------------------------#  | module Dust_Detect#  | 
    set_module_property DESCRIPTION "Dust Detector"
    set_module_property NAME Dust_Detect
    set_module_property VERSION 1.0
    set_module_property INTERNAL false
    set_module_property GROUP "User Component"
    set_module_property AUTHOR Vvh
    set_module_property DISPLAY_NAME Dust_Detect
    set_module_property LIBRARIES {ieee.std_logic_1164.all ieee.numeric_std.all std.standard.all}
    set_module_property TOP_LEVEL_HDL_FILE Dust_Detect.vhd
    set_module_property TOP_LEVEL_HDL_MODULE Dust_Detect
    set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
    set_module_property EDITABLE false#  | #  +-----------------------------------
    #  +-----------------------------------#  | files#  | 
    add_file Dust_Detect.vhd {SYNTHESIS SIMULATION}#  | #  +-----------------------------------
    #  +-----------------------------------#  | parameters#  | #  | #  +-----------------------------------
    #  +-----------------------------------#  | connection point clock#  | 
    add_interface clock clock end
    set_interface_property clock ptfSchematicName ""
    set_interface_property clock ENABLED true
    add_interface_port clock clk clk Input 1
    add_interface_port clock reset_n reset_n Input 1#  | #  +-----------------------------------
    #  +-----------------------------------#  | connection point s0#  | 
    add_interface s0 avalon end
    set_interface_property s0 addressAlignment DYNAMIC
    set_interface_property s0 bridgesToMaster ""
    set_interface_property s0 burstOnBurstBoundariesOnly false
    set_interface_property s0 holdTime 0
    set_interface_property s0 isMemoryDevice false
    set_interface_property s0 isNonVolatileStorage false
    set_interface_property s0 linewrapBursts false
    set_interface_property s0 maximumPendingReadTransactions 0
    set_interface_property s0 printableDevice false
    set_interface_property s0 readLatency 0
    set_interface_property s0 readWaitTime 1
    set_interface_property s0 setupTime 0
    set_interface_property s0 timingUnits Cycles
    set_interface_property s0 writeWaitTime 0
    set_interface_property s0 ASSOCIATED_CLOCK clock
    set_interface_property s0 ENABLED true
    add_interface_port s0 avs_s0_address address Input 8
    add_interface_port s0 avs_s0_read_n read_n Input 1
    add_interface_port s0 avs_s0_readdata readdata Output 32
    add_interface_port s0 avs_s0_write_n write_n Input 1
    add_interface_port s0 avs_s0_writedata writedata Input 32#  | #  +-----------------------------------
    
    here is my VHDL code

    
    -- Dust_Detect.vhd
    -- This file was auto-generated as a prototype implementation of a module
    -- created in component editor.  It ties off all outputs to ground and
    -- ignores all inputs.  It needs to be edited to make it do something
    -- useful.
    -- 
    -- This file will not be automatically regenerated.  You should check it in
    -- to your version control system if you want to keep it.
    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    entity Dust_Detect is
        port (
            clk              : in  std_logic                     := '0';             -- clock.clk
            reset_n          : in  std_logic                     := '0';             --      .reset_n
            avs_s0_address   : in  std_logic_vector(7 downto 0)  := (others => '0'); --    s0.address
            avs_s0_read_n    : in  std_logic                     := '0';             --      .read_n
            avs_s0_readdata  : out std_logic_vector(31 downto 0);                    --      .readdata
            avs_s0_write_n   : in  std_logic                     := '0';             --      .write_n
            avs_s0_writedata : in  std_logic_vector(31 downto 0) := (others => '0')  --      .writedata
        );
    end entity Dust_Detect;
    architecture rtl of Dust_Detect is
    type matrix_2D is array (0 to 3, 0 to 3) of unsigned (15 downto 0);
    signal cnt_dust_A : matrix_2D ;  
     constant fixA_array : matrix_2D :=(
      (x"0000000D",x"0000000E",x"0000000F",x"00000010"),
      (x"00000009",x"0000000A",x"0000000B",x"0000000C"),
      (x"00000005",x"00000006",x"00000007",x"00000008"),
      (x"00000001",x"00000002",x"00000003",x"00000004")
     );
     
    begin 
    MUX_matrix : process (clk, reset_n)                                               
    variable P_line   :    integer  range 0 to 3 ;     
    variable P_column :    integer  range 0 to 3 ;  
     begin 
        if reset_n = '0' then 
              P_line   := 0 ;      
             P_column := 0 ;
        
        elsif rising_edge (clk) then
            if avs_s0_write_n = '0' then
                case avs_s0_writedata is
                      when x"00000000" => 
                            P_line := 0; P_column := 0;
                    when x"00000001" => 
                            P_line := 0; P_column := 1;
                    when x"00000002" => 
                            P_line := 0; P_column := 2;
                    when x"00000003" => 
                            P_line := 0; P_column := 3;    
                    when x"00000010" => 
                            P_line := 1; P_column := 0;                    
                    when x"00000011" => 
                            P_line := 1; P_column := 1;    
                    when x"00000012" =>                      
                            P_line := 1; P_column := 2;
                    when x"00000013" =>                      
                            P_line := 1; P_column := 3;
                    when x"00000020" => 
                            P_line := 2; P_column := 0;                
                    when x"00000021" => 
                            P_line := 2; P_column := 1;    
                    when x"00000022" =>                     
                            P_line := 2; P_column := 2;
                    when x"00000023" =>                    
                            P_line := 2; P_column := 3;    
                    when x"00000030" => 
                            P_line := 3; P_column := 0;                               
                    when x"00000031" => 
                            P_line := 3; P_column := 1;    
                    when x"00000032" =>                     
                            P_line := 3; P_column := 2;
                    when x"00000033" =>                     
                            P_line := 3; P_column := 3;                
                    when others => NULL ;    
                  end case ;
              end if ;                        
                                  
            if     avs_s0_read_n = '0' then
                  avs_s0_readdata <=  std_logic_vector(fixA_array(P_line,P_column)) ; 
            else
                avs_s0_readdata <= "ZZZZZZZZZZZZZZZZ";              
              end if ;                
        end if ;   
        
    end process MUX_matrix;
    end architecture rtl; -- of Dust_Detect
    
    That is just a basic code to test some matrix storage. I want to send (with my application) a code which is decode as a line and column number and then put the corresponding number of the matrix in readdata.

    here is my C Code :

    
           for (i=0;i<4;i++) {
                for (j=0;j<4;j++) {
                    if ((i == 0) && (j == 0)) { n_case = 0x00000000; }
                    else if ((i == 0) && (j == 1)) { n_case = 0x00000001; }
                    (......)
                    IOWR(DUST_DETECT_S0_BASE, 0, n_case);
                    pos = sqrt(TAILLE_MATRICE)*i+j;
                    matrice = IORD(DUST_DETECT_S0_BASE,0);
                }
            }
    
    Thank you,

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

    Where is the chipselect signal in your IP ?

    yes the avalon specification available here

    http://www.altera.com/literature/manual/mnl_avalon_spec.pdf?gsa_pos=2&wt.oss_r=1&wt.oss=avalon spec

    does not include the chipselect input anymore.

    as your datawidth is 32 bit, i recommend to monitor the byteenable signals as well they tell you what part of your write date is valid.

    next thing is

    if avs_s0_read_n = '0' then

    avs_s0_readdata <= std_logic_vector(fixA_array(P_line,P_column)) ;

    so your read data is 1 clock delayed valid but i see no waitrequest but a read wait time of 1

    maybe the data you expect is avaiable after your access is finished.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I look into this further but:

    1 - You don't need a chipselect.

    2 - You don't need byteenables. If you don't include them in the interface, then all bytes are valid when a write occurs.

    3 - In your TCL script, it looks like you have the readWaitTime set to 1 which should take care of the 1 clock latency on your read. Nevertheless, there is no reason to wait for a read to change the readdata in this case.

    When you read the data, are you getting the same value every time (indicating that your P_line and P_col registers are never changed)?

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

    Yes I have the same value everytime (which is (0,0)) and avs_s0_write_n is never set to 0.

    I tried with

    
    if avs_s0_write_n = '0' then
         P_line := 1; P_column := 1;
    end if
    
    and the data was still the Matrix[0,0]. It is as if I'm not writing anything
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I recommend using byte enables and registering each byte lane using the appropriate byte enable. When you don't include byte enables you are using Avalon-MM native addressing which is deprecated and not recommended for new components.