Forum: FPGA, VHDL & Co. Avalon MM Bus Addressing


von Tomy (Gast)


Lesenswert?

Hallo zusammen,

ich arbeite gerade an NIOS ii. In Qsys habe ich ein Custom-Peripherie, 
das die Bus-Control Signals zu Custom-Logik weiterleitet:
1
LIBRARY   IEEE;
2
  USE     IEEE.STD_LOGIC_1164.ALL;
3
  USE     IEEE.NUMERIC_STD.ALL;
4
5
ENTITY avs_bus_interface IS
6
PORT
7
(
8
  -- Avalon MM slave Signals
9
  clk, rst_n         : in std_logic := '0';
10
  avs_write_n        : in std_logic := '0';
11
  avs_read_n        : in std_logic := '0';
12
  avs_address        : in std_logic_vector(11 downto 0);
13
  avs_writedata     : in std_logic_vector(15 downto 0);
14
  avs_readdata       : out std_logic_vector(15 downto 0);
15
  
16
  -- Avalon MM Controlsignals End Conduits
17
  write_n            : out std_logic;
18
  read_n             : out std_logic := '0';
19
  address            : out std_logic_vector(11 downto 0);
20
  writedata         : out std_logic_vector(15 downto 0);
21
  readdata           : in  std_logic_vector(15 downto 0)
22
  
23
);
24
END avs_bus_interface;
25
26
architecture Behavioral of avs_bus_interface is
27
28
begin
29
30
  -- pass through...
31
  write_n      <= avs_write_n;
32
  read_n       <= avs_read_n;
33
  address      <= avs_address;
34
  writedata    <= avs_writedata;
35
  avs_readdata <= readdata;
36
  
37
end Behavioral;

In Custom-Logik gibts dann IO-Registerfile, so mein Write-Registerfile:
1
LIBRARY   IEEE;
2
  USE     IEEE.STD_LOGIC_1164.ALL;
3
  USE     IEEE.NUMERIC_STD.ALL;
4
5
ENTITY SysRegFile_write IS
6
PORT
7
(
8
  -- Inputs Avalon MM slave
9
  clk, rst_n         : in std_logic := '0';
10
  avs_write_n       : in std_logic := '0';
11
  avs_address        : in std_logic_vector(11 downto 0);
12
  avs_writedata     : in std_logic_vector(15 downto 0);
13
  
14
  -- Ouput Register File IO
15
     -- 3Level RZM- Modul
16
    RZM_Ctrl          : out std_logic_vector(15 downto 0);
17
    RZM_PwmPeak        : out std_logic_vector(15 downto 0);
18
    RZM_tDead         : out std_logic_vector(15 downto 0);
19
    RZM_Ud1Ref         : out std_logic_vector(15 downto 0);
20
    RZM_Uq1Ref         : out std_logic_vector(15 downto 0);
21
    RZM_theta1         : out std_logic_vector(15 downto 0)    
22
);
23
END sysRegFile_write;
24
25
architecture Behavioral of sysRegFile_write is
26
27
begin
28
  
29
  write_regfile_pro: process (clk, rst_n)
30
    begin
31
      if rst_n = '0' then -- asyn reset
32
        RZM_Ud1Ref   <= (others => '0');
33
        RZM_Uq1Ref   <= (others => '0');
34
        RZM_theta1   <= (others => '0');
35
      elsif rising_edge(clk) and avs_write_n = '0' then
36
        case avs_address is
37
          -- 3Level RZM- Modul
38
          when ADD_RZM_Ctrl => RZM_Ctrl    <= avs_writedata;
39
          when x"000"       => RZM_PwmPeak <= avs_writedata;
40
          when x"001"       => RZM_tDead   <= avs_writedata;
41
          when x"002"       => RZM_Ud1Ref  <= avs_writedata;
42
          when x"003"       => RZM_Uq1Ref  <= avs_writedata;
43
          when x"004"       => RZM_theta1  <= avs_writedata;
44
45
          when others => NULL;
46
        end case;
47
      end if;
48
  end process write_regfile_pro;
49
        
50
  
51
end Behavioral;

Meine Frage ist, wie, mit welchem Befehl kann man in NIOS ii EDS, C-Code 
richtig zugreifen? Mit IOWR_16DIRECT, oder IOWR?
Kann mir jemand bisschen über Avalon MM in diesem Kontext erklären?

vielen Dank im Vorraus!

lg Tomy

von hans (Gast)


Lesenswert?

ich benutze immer die macros aus der altera_avalon_pio_regs.h zum 
direkten zugriff auf einen slave

von Tomy (Gast)


Lesenswert?

danke für Deine Antwort!

wo findet man das file? und hast Du einen Zugriff auf 16-bit Wert 
(Data-Width) ? oder 32-bit?

von hans (Gast)


Lesenswert?

hey die datei wird im bsp projekt unter drivers erzeugt aber was du 
suchst

IORD_8DIRECT(base, offset)
 IORD_16DIRECT(base, offset)
 IORD_32DIRECT(base, offset)
 IOWR_8DIRECT(base, offset, data)
 IOWR_16DIRECT(base, offset, data)
 IOWR_32DIRECT(base, offset, data)

ist glaueb das hier. dort kannst du je nach bedarf schreiben/ lesen

von Tomy (Gast)


Lesenswert?

danke Hans für deine Antwort!

genau ich hab dies auch benutzt, und funktioniert....

aber die Avalon Bus- Specification hab ich in diesem Kontext nicht 
verstanden...

hast du guten tutos oder beispiel für Avalon Bus Addressing?

vielen Dank im vorraus!

und ps. schönes Wochenende!

lg tomy

von hans (Gast)


Lesenswert?

ich weiss jetzt nicht was du genau mit dem addressing meinst. die 
adressen zum schreieb lesen siehst du ja in der system.h oder in deinem 
qsys design


hans

von Tomy (Gast)


Angehängte Dateien:

Lesenswert?

hans schrieb:
> ich weiss jetzt nicht was du genau mit dem addressing meinst. die
> adressen zum schreieb lesen siehst du ja in der system.h oder in deinem
> qsys design

hallo,

ich hab hier ein SignalTap für Verstehen, was der Niosii macht, wenn ich 
mit IOWR_16DIRECT() oder IOWR mache.

Im Custom -Write Registerfile:
1
  write_regfile_pro: process (clk, rst_n)
2
    begin
3
      if rst_n = '0' then -- asyn reset
4
        Test   <= (others => '0');
5
      elsif rising_edge(clk) and avs_write_n = '0' then
6
        case avs_address is
7
          when x"003"       => Test  <= avs_writedata;
8
          when others => NULL;
9
        end case;
10
      end if;
11
  end process write_regfile_pro;

Im NiosII EDS hab versucht, auf gleiche 12-Bit Addresse 0x003 mit 0xAAAA 
zu beschreiben:

1
    #define AVS_BUS_INTERFACE_0_BASE 0x40000 // in system.h
2
3
    // Fall 1: 
4
    IOWR         (AVS_BUS_INTERFACE_0_BASE,3,0xAAAA);
5
    // Fall 2:
6
    IOWR_16DIRECT(AVS_BUS_INTERFACE_0_BASE,3,0xAAAA);
7
    // Fall 3:
8
    IOWR_16DIRECT(AVS_BUS_INTERFACE_0_BASE,(0x003<<1),0xAAAA);
9
    // Fall 4:
10
    pAVS_PIO[0x003] = 0xAAAA;

Im SignalTapII sieht man:
Fall 1:
Control-Signal: avs_write_n dauert 2- Clock Periode(gedacht aber NUR 1 
Clk-Periode!). Hier sieht so aus, er versucht 32-Bit Data auf 2 
hintereinander Addressen zu beschreiben: Address 0x006 mit Data 0xAAAA, 
Address 0x007 mit 0x0000 (warum????)
Fall 2:
Control-Signal: avs_write_n dauert 1- Clock Periode wie erwartet, aber 
wieso auf Address: 0x001 (?)
Fall 3:
avs_write_n dauert 1- Clock Periode wie erwartet, auf Address: 0x003 
->>> wie erwartet!
Fall 4:
avs_write_n dauert 1- Clock Periode wie erwartet, auf Address: 0x003 
->>> wie erwartet! Aber mit dem Trick :
1
volatile alt_16 *pAVS_PIO = (volatile alt_16*)(AVS_BUS_INTERFACE_0_BASE|0x80000000);

Kann jemand mir ins Licht bringen?

Vielen Dank im Vorraus!!!

Lg Tomy

von Sigi (Gast)


Lesenswert?

zu Fall 1:
Hast du mal in deinem <BSP>/<Application>.objdump nachgeschaut,
wie der Zugriff in Assembler gemacht wird?

von Sigi (Gast)


Lesenswert?

.., ob der Zugriff 16bittig oder 32bittig ist?

von Tomy (Gast)


Lesenswert?

Sigi schrieb:
> zu Fall 1:
> Hast du mal in deinem <BSP>/<Application>.objdump nachgeschaut,
> wie der Zugriff in Assembler gemacht wird?

Sigi schrieb:
> .., ob der Zugriff 16bittig oder 32bittig ist?


nein... gucke mir mal an....

von Tomy (Gast)


Lesenswert?

Sigi schrieb:
> .., ob der Zugriff 16bittig oder 32bittig ist?

man sieht in SignalTapII oben im Anhang, dass für Fall 1 nutzt der 
NiosII den Befehl :
1
stwio ro,0;  ->> word 32 bittig
sonst andere Fälle sieht man :
1
 sthio r0,0; halb word 16 bittig für Fall 2 und 3

für Fall 4:
1
 sth r0,0; halb word 16 bittig, nur von Fällen 2,3 unterschieden, dass im Fall 2,3 wird es nicht über Data-Cache geht (!!??)

Warum ist es im Falle 4 mit dem Trick
1
volatile alt_16 *pAVS_PIO = (volatile alt_16*)(AVS_BUS_INTERFACE_0_BASE|0x80000000);

wird es dann die richtige gewünschte Addresse (mit Assembly: sth r0,0) 
erzeugt?
lg Tomy

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.