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; |