FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6359 Discussions

Custom Component, Write not working

Altera_Forum
Honored Contributor II
1,235 Views

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
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
377 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
377 Views

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

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

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

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

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.

0 Kudos
Reply