Forum: FPGA, VHDL & Co. Einfaches Register mit AXI Interface


von Student (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe mal eine Frage, was spricht dagegen dass man selbst AXI4 Lite 
Interface implementiert, statt vorgefrtiger IP-Core (mit IPIF Interface) 
von Xilinx zu nehmen?

Ich habe mal kurz einfaches Register implementiert und in ISIM 
Simuliert. Sieht maeine meinung nach gut aus. Oder was meint ihr?

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
  
6
------------------------------------------------------------------------------
7
-- Entity section
8
------------------------------------------------------------------------------
9
-- Definition of Generics:
10
--   C_S_AXI_DATA_WIDTH           -- AXI4LITE slave: Data width
11
--   C_S_AXI_ADDR_WIDTH           -- AXI4LITE slave: Address Width
12
--   C_BASEADDR                   -- AXI4LITE slave: base address
13
--   C_HIGHADDR                   -- AXI4LITE slave: high address
14
--
15
-- Definition of Ports:
16
--   S_AXI_ACLK                   -- AXI4LITE slave: Clock 
17
--   S_AXI_ARESETN                -- AXI4LITE slave: Reset
18
--   S_AXI_AWADDR                 -- AXI4LITE slave: Write address
19
--   S_AXI_AWVALID                -- AXI4LITE slave: Write address valid
20
--   S_AXI_WDATA                  -- AXI4LITE slave: Write data
21
--   S_AXI_WSTRB                  -- AXI4LITE slave: Write strobe
22
--   S_AXI_WVALID                 -- AXI4LITE slave: Write data valid
23
--   S_AXI_BREADY                 -- AXI4LITE slave: Response ready
24
--   S_AXI_ARADDR                 -- AXI4LITE slave: Read address
25
--   S_AXI_ARVALID                -- AXI4LITE slave: Read address valid
26
--   S_AXI_RREADY                 -- AXI4LITE slave: Read data ready
27
--   S_AXI_ARREADY                -- AXI4LITE slave: read addres ready
28
--   S_AXI_RDATA                  -- AXI4LITE slave: Read data
29
--   S_AXI_RRESP                  -- AXI4LITE slave: Read data response
30
--   S_AXI_RVALID                 -- AXI4LITE slave: Read data valid
31
--   S_AXI_WREADY                 -- AXI4LITE slave: Write data ready
32
--   S_AXI_BRESP                  -- AXI4LITE slave: Response
33
--   S_AXI_BVALID                 -- AXI4LITE slave: Resonse valid
34
--   S_AXI_AWREADY                -- AXI4LITE slave: Wrte address ready
35
------------------------------------------------------------------------------
36
 
37
entity simple_ipcore_axilite is
38
  generic(
39
    -- Bus protocol parameters
40
    C_S_AXI_DATA_WIDTH             : integer              := 32;
41
    C_S_AXI_ADDR_WIDTH             : integer              := 32;
42
    C_BASEADDR                     : std_logic_vector     := X"FFFFFFFF";
43
    C_HIGHADDR                     : std_logic_vector     := X"00000000"
44
  );
45
  port(
46
    --USER ports
47
    calc_time                       : out std_logic;
48
    -------------------------
49
    -- AXI4lite interface
50
    -------------------------
51
    --- Global signals
52
    S_AXI_ACLK                     : in  std_logic;
53
    S_AXI_ARESETN                  : in  std_logic;
54
    --- Write address channel
55
    S_AXI_AWADDR                   : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
56
    S_AXI_AWVALID                  : in  std_logic;
57
    S_AXI_AWREADY                  : out std_logic;
58
    --- Write data channel
59
    S_AXI_WDATA                    : in  std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
60
    S_AXI_WVALID                   : in  std_logic;
61
    S_AXI_WREADY                   : out std_logic;
62
    S_AXI_WSTRB                    : in  std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
63
    --- Write response channel
64
    S_AXI_BVALID                   : out std_logic;
65
    S_AXI_BREADY                   : in  std_logic;
66
    S_AXI_BRESP                    : out std_logic_vector(1 downto 0);
67
    --- Read address channel
68
    S_AXI_ARADDR                   : in  std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
69
    S_AXI_ARVALID                  : in  std_logic;
70
    S_AXI_ARREADY                  : out std_logic; 
71
    --- Read data channel
72
    S_AXI_RDATA                    : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
73
    S_AXI_RVALID                   : out std_logic;
74
    S_AXI_RREADY                   : in  std_logic;
75
    S_AXI_RRESP                    : out std_logic_vector(1 downto 0)
76
  );
77
 
78
end entity simple_ipcore_axilite;
79
 
80
------------------------------------------------------------------------------
81
-- Architecture section
82
------------------------------------------------------------------------------
83
 
84
architecture IMP of simple_ipcore_axilite is
85
  type axi_states is (addr_wait, read_state, write_state, response_state);
86
  signal state : axi_states;
87
 
88
  signal address : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
89
  signal value : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
90
  signal reset : std_logic;
91
 
92
  signal S_AXI_BVALID_i : std_logic;
93
 
94
  -- selection signals
95
96
  -- core interface signeals
97
  signal write_enable : std_logic;
98
  
99
begin
100
  -- unused signals
101
  S_AXI_BRESP <= "00";
102
  S_AXI_RRESP <= "00";
103
 
104
  -- axi-lite slave state machine
105
  axi_slave_states : process (S_AXI_ACLK)
106
  begin
107
    if rising_edge(S_AXI_ACLK) then
108
      if S_AXI_ARESETN='0' then -- slave reset state
109
        S_AXI_RVALID <= '0';
110
        S_AXI_BVALID_i <= '0';
111
        S_AXI_ARREADY <= '0';
112
        S_AXI_WREADY <= '0';
113
        S_AXI_AWREADY <= '0';
114
        state <= addr_wait;
115
        address <= (others=>'0');
116
        write_enable <= '0';
117
      else
118
        case state is
119
          when addr_wait => 
120
          -- wait for a read or write address and latch it in
121
            if S_AXI_ARVALID = '1' then -- read
122
              state <= read_state;
123
              address <= S_AXI_ARADDR;
124
              S_AXI_ARREADY <= '1';
125
            elsif (S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then -- write
126
              state <= write_state;
127
              address <= S_AXI_AWADDR;
128
            else
129
              state <= addr_wait;
130
            end if;
131
 
132
          when read_state =>
133
          -- place correct data on bus and generate valid pulse
134
            S_AXI_ARREADY <= '0';
135
            S_AXI_RVALID <= '1';
136
            state <= response_state;
137
 
138
        S_AXI_RDATA <= value;
139
          
140
       when write_state =>
141
          -- generate a write pulse
142
            S_AXI_AWREADY <= '1';
143
            write_enable <= '1';
144
            S_AXI_WREADY <= '1';
145
            state <= response_state;
146
        
147
        value <= S_AXI_WDATA;
148
 
149
          when response_state =>
150
            write_enable <= '0';
151
            S_AXI_AWREADY <= '0';
152
            S_AXI_WREADY <= '0';
153
            S_AXI_BVALID_i <= '1';
154
          -- wait for response from master
155
            if (S_AXI_RREADY = '1') or (S_AXI_BVALID_i = '1' and S_AXI_BREADY = '1') then
156
              S_AXI_RVALID <= '0';
157
              S_AXI_BVALID_i <= '0';
158
              state <= addr_wait;
159
            else
160
              state <= response_state;
161
            end if;
162
 
163
        end case;
164
      end if;
165
    end if;
166
  end process;
167
  S_AXI_BVALID <= S_AXI_BVALID_i;  
168
 
169
170
end IMP;

Die Simulation dazu:
1
 
2
3
--------------------------------------------------------------------------------
4
-- Company: 
5
-- Engineer:
6
--
7
-- Create Date:   17:03:36 01/07/2014
8
-- Design Name:   
9
-- Module Name:   C:/Users/user71/Desktop/Xilinx_projects/AXI_Test/tb_simple_ipcore_axilite.vhd
10
-- Project Name:  AXI_Test
11
-- Target Device:  
12
-- Tool versions:  
13
-- Description:   
14
-- 
15
-- VHDL Test Bench Created by ISE for module: simple_ipcore_axilite
16
-- 
17
-- Dependencies:
18
-- 
19
-- Revision:
20
-- Revision 0.01 - File Created
21
-- Additional Comments:
22
--
23
-- Notes: 
24
-- This testbench has been automatically generated using types std_logic and
25
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
26
-- that these types always be used for the top-level I/O of a design in order
27
-- to guarantee that the testbench will bind correctly to the post-implementation 
28
-- simulation model.
29
--------------------------------------------------------------------------------
30
LIBRARY ieee;
31
USE ieee.std_logic_1164.ALL;
32
 
33
-- Uncomment the following library declaration if using
34
-- arithmetic functions with Signed or Unsigned values
35
--USE ieee.numeric_std.ALL;
36
 
37
ENTITY tb_simple_ipcore_axilite IS
38
END tb_simple_ipcore_axilite;
39
 
40
ARCHITECTURE behavior OF tb_simple_ipcore_axilite IS 
41
 
42
    -- Component Declaration for the Unit Under Test (UUT)
43
 
44
    COMPONENT simple_ipcore_axilite
45
    PORT(
46
         calc_time : OUT  std_logic;
47
         S_AXI_ACLK : IN  std_logic;
48
         S_AXI_ARESETN : IN  std_logic;
49
         S_AXI_AWADDR : IN  std_logic_vector(31 downto 0);
50
         S_AXI_AWVALID : IN  std_logic;
51
         S_AXI_AWREADY : OUT  std_logic;
52
         S_AXI_WDATA : IN  std_logic_vector(31 downto 0);
53
         S_AXI_WVALID : IN  std_logic;
54
         S_AXI_WREADY : OUT  std_logic;
55
         S_AXI_WSTRB : IN  std_logic_vector(3 downto 0);
56
         S_AXI_BVALID : OUT  std_logic;
57
         S_AXI_BREADY : IN  std_logic;
58
         S_AXI_BRESP : OUT  std_logic_vector(1 downto 0);
59
         S_AXI_ARADDR : IN  std_logic_vector(31 downto 0);
60
         S_AXI_ARVALID : IN  std_logic;
61
         S_AXI_ARREADY : OUT  std_logic;
62
         S_AXI_RDATA : OUT  std_logic_vector(31 downto 0);
63
         S_AXI_RVALID : OUT  std_logic;
64
         S_AXI_RREADY : IN  std_logic;
65
         S_AXI_RRESP : OUT  std_logic_vector(1 downto 0)
66
        );
67
    END COMPONENT;
68
    
69
70
   --Inputs
71
   signal S_AXI_ACLK : std_logic := '0';
72
   signal S_AXI_ARESETN : std_logic := '0';
73
   signal S_AXI_AWADDR : std_logic_vector(31 downto 0) := (others => '0');
74
   signal S_AXI_AWVALID : std_logic := '0';
75
   signal S_AXI_WDATA : std_logic_vector(31 downto 0) := (others => '0');
76
   signal S_AXI_WVALID : std_logic := '0';
77
   signal S_AXI_WSTRB : std_logic_vector(3 downto 0) := (others => '0');
78
   signal S_AXI_BREADY : std_logic := '0';
79
   signal S_AXI_ARADDR : std_logic_vector(31 downto 0) := (others => '0');
80
   signal S_AXI_ARVALID : std_logic := '0';
81
   signal S_AXI_RREADY : std_logic := '0';
82
83
   --Outputs
84
   signal calc_time : std_logic;
85
   signal S_AXI_AWREADY : std_logic;
86
   signal S_AXI_WREADY : std_logic;
87
   signal S_AXI_BVALID : std_logic;
88
   signal S_AXI_BRESP : std_logic_vector(1 downto 0);
89
   signal S_AXI_ARREADY : std_logic;
90
   signal S_AXI_RDATA : std_logic_vector(31 downto 0);
91
   signal S_AXI_RVALID : std_logic;
92
   signal S_AXI_RRESP : std_logic_vector(1 downto 0);
93
94
   -- Clock period definitions
95
   constant S_AXI_ACLK_period : time := 10 ns;
96
 
97
BEGIN
98
 
99
  -- Instantiate the Unit Under Test (UUT)
100
   uut: simple_ipcore_axilite PORT MAP (
101
          calc_time => calc_time,
102
          S_AXI_ACLK => S_AXI_ACLK,
103
          S_AXI_ARESETN => S_AXI_ARESETN,
104
          S_AXI_AWADDR => S_AXI_AWADDR,
105
          S_AXI_AWVALID => S_AXI_AWVALID,
106
          S_AXI_AWREADY => S_AXI_AWREADY,
107
          S_AXI_WDATA => S_AXI_WDATA,
108
          S_AXI_WVALID => S_AXI_WVALID,
109
          S_AXI_WREADY => S_AXI_WREADY,
110
          S_AXI_WSTRB => S_AXI_WSTRB,
111
          S_AXI_BVALID => S_AXI_BVALID,
112
          S_AXI_BREADY => S_AXI_BREADY,
113
          S_AXI_BRESP => S_AXI_BRESP,
114
          S_AXI_ARADDR => S_AXI_ARADDR,
115
          S_AXI_ARVALID => S_AXI_ARVALID,
116
          S_AXI_ARREADY => S_AXI_ARREADY,
117
          S_AXI_RDATA => S_AXI_RDATA,
118
          S_AXI_RVALID => S_AXI_RVALID,
119
          S_AXI_RREADY => S_AXI_RREADY,
120
          S_AXI_RRESP => S_AXI_RRESP
121
        );
122
123
   -- Clock process definitions
124
   S_AXI_ACLK_process :process
125
   begin
126
    S_AXI_ACLK <= '0';
127
    wait for S_AXI_ACLK_period/2;
128
    S_AXI_ACLK <= '1';
129
    wait for S_AXI_ACLK_period/2;
130
   end process;
131
 
132
133
   -- Stimulus process
134
   stim_proc: process
135
   begin    
136
      -- hold reset state for 50 ns.
137
      wait for 20 ns;  
138
139
      -- insert stimulus here
140
141
    -- Write operation 
142
    S_AXI_ARESETN <= '1';
143
    
144
    wait for 10 ns;
145
    wait until rising_edge(S_AXI_ACLK);
146
    
147
    S_AXI_AWADDR <= x"FEEEEEEF";
148
    S_AXI_AWVALID <= '1';
149
    S_AXI_WDATA <= x"0000000F";
150
    S_AXI_WVALID <= '1';
151
    S_AXI_WSTRB <= x"F";
152
    S_AXI_BREADY <= '1';
153
    
154
    wait for 10 ns;  
155
    wait until falling_edge(S_AXI_WREADY);
156
    
157
    S_AXI_AWADDR <= x"00000000";
158
    S_AXI_AWVALID <= '0'; 
159
    S_AXI_WDATA <= x"00000000";
160
    S_AXI_WVALID <= '0';
161
    S_AXI_WSTRB <= x"0";
162
163
    wait until falling_edge(S_AXI_BVALID);
164
    S_AXI_BREADY <= '0';
165
    
166
    -- Read operation 
167
    
168
    wait for 50 ns;
169
    wait until rising_edge(S_AXI_ACLK);
170
    
171
    S_AXI_ARADDR <= x"FEEEEEEF";
172
    S_AXI_ARVALID <= '1';
173
    S_AXI_RREADY <= '1';
174
    
175
    wait for 10 ns;  
176
    wait until falling_edge(S_AXI_ARREADY);
177
    
178
    S_AXI_ARADDR <= x"00000000";
179
    S_AXI_ARVALID <= '0';
180
    
181
    wait until falling_edge(S_AXI_RVALID);
182
    S_AXI_RREADY <= '0';
183
    
184
      wait;
185
   end process;
186
187
END;

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Student schrieb:
> Hallo,
>
> Ich habe mal eine Frage, was spricht dagegen dass man selbst AXI4 Lite
> Interface implementiert, statt vorgefrtiger IP-Core (mit IPIF Interface)
> von Xilinx zu nehmen?

nichts. AXI4 ist ein häufiger Standard von Xilinx. Lässt sich alles 
einfach zusammenschmeißen. Die Cores lassen sich so entkoppeln.


> Ich habe mal kurz einfaches Register implementiert und in ISIM
> Simuliert. Sieht maeine Meinung nach gut aus. Oder was meint ihr?
>

Vom Screenshot erstmal nicht schlecht. Was mir bei deinem Code 
aufgefallen ist; Du hast alles in einen Prozess gepackt. Solcher Code 
ist schlecht wartbar und ISE tut sich mit dem Fitten schwer. Es wird 
auch Unterumständen unerwartete Effekte geben. Da sind solche langen 
Prozesse schwierig bei der Fehlersuche.
Bei dir würde es sich anbieten einen Prozess für lesen und einen 
weiteren für schreiben.

Du kannst mal in die Mais CPU schauen, das sind z.B. die Dateien
reg_bank.vhd
spb_memory.vhd
wo du verstehst kannst wie ich es meine.

Weiter so, du bist auf dem richtigen Weg in der Lernkurve.

von Duke Scarring (Gast)


Lesenswert?

Student schrieb:
> Ich habe mal eine Frage, was spricht dagegen dass man selbst AXI4 Lite
> Interface implementiert, statt vorgefrtiger IP-Core (mit IPIF Interface)
> von Xilinx zu nehmen?
Nichts.
Vielen Dank für Deinen Vorstoß.
Die IP-Cores kann man nehmen, wenn sie für die gestellte Aufgabe genau 
passen. Sobald man eine Sonderlocke braucht, wird der Aufwand einen 
feritgen IP-Core hinzubiegen schnell so groß, das man es auch gleich 
selber machen kann.

> Ich habe mal kurz einfaches Register implementiert und in ISIM
> Simuliert. Sieht maeine meinung nach gut aus. Oder was meint ihr?
Ja, die Simulation sieht auf den ersten Blick gut aus.

Ich würde die drei Interfaces in records packen. Die Signalnamen sind 
wegen der minimalen Unterschiede fehlerträchtig zu lesen:
1
     S_AXI_AWADDR
2
     S_AXI_AWVALID
3
     S_AXI_AWREADY
4
     S_AXI_WDATA
5
     S_AXI_WVALID
6
     S_AXI_WREADY
7
     S_AXI_WSTRB
8
     S_AXI_BVALID
9
     S_AXI_BREADY
10
     S_AXI_BRESP
11
     S_AXI_ARADDR
12
     S_AXI_ARVALID
13
     S_AXI_ARREADY
14
     S_AXI_RDATA
15
     S_AXI_RVALID
16
     S_AXI_RREADY
17
     S_AXI_RRESP

Student schrieb:
> use ieee.std_logic_arith.all;
> use ieee.std_logic_unsigned.all;
Bitte nimm diese Bibliotheken raus:
1. Hier wird nichts gerechnet, Du brauchst Sie gar nicht.
2. Beitrag "Re: IEEE.STD_LOGIC_ARITH.ALL obsolete"

Und dann noch ein kleiner Schönheitsfehler:
Mit calc_time wird nichts angestellt...

Duke

von Atze vom Bau (Gast)


Lesenswert?

René D. schrieb:
> Du hast alles in einen Prozess gepackt. Solcher Code
> ist schlecht wartbar und ISE tut sich mit dem Fitten schwer.

...hast Du dazu weiterführende Informationen von Xilinx, wie groß ein 
Prozess sein soll/darf?

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Atze vom Bau schrieb:

> ...hast Du dazu weiterführende Informationen von Xilinx, wie groß ein
> Prozess sein soll/darf?

Da gibt es sicher keine Beschränkung. Der Fitter wird es schon packen.
Ich habe auch so angefangen VHDL zu schreiben. Doch man merkt, das die 
Kennzahlen, wie erreichbare Frequenz nach oben oder auch verwendete LUT 
nach unten gehen.

von Student (Gast)


Lesenswert?

Vielen Dank für eure Antworten!

Die Frage ist insofern entstanden da es im Internet nicht mal ein 
Beispiel darüber gibt, wie man in solchen Fällen vorgehen soll und 
Xilinx nur vorgefertigter IPCore empfiehlt.

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

Student schrieb:
> Vielen Dank für eure Antworten!
>
> Die Frage ist insofern entstanden da es im Internet nicht mal ein
> Beispiel darüber gibt, wie man in solchen Fällen vorgehen soll und
> Xilinx nur vorgefertigter IPCore empfiehlt.

Melde dich mal hier an. Das ist besser, wenn du in späteren Threads 
wieder auftauchst. Halte uns hier auf dem Laufenden. Ich habe auch von 
deinem Beispiel das AXI timing gelernt.

Ich habe ähnliche Probleme gehabt. AXI kam nachdem ich meinen Einstieg 
in die FPGA welt gefunden habe. Es ist immer etwas Zauber über einfache 
Sachen.

Für meine eigenen Sachen habe ich mir einen eigenen Bus spezifiziert. 
Ich habe Ihn SPB simple Pipeline Bus genannt.

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.