wb_arbiter: Make arbiter size parametric
[microwatt.git] / soc.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use ieee.math_real.all;
5 use std.textio.all;
6 use std.env.stop;
7
8 library work;
9 use work.common.all;
10 use work.wishbone_types.all;
11
12
13 -- 0x00000000: Main memory (1 MB)
14 -- 0xc0002000: UART0 (for host communication)
15 entity soc is
16 generic (
17 MEMORY_SIZE : positive;
18 RAM_INIT_FILE : string;
19 RESET_LOW : boolean;
20 SIM : boolean;
21 DISABLE_FLATTEN_CORE : boolean := false
22 );
23 port(
24 rst : in std_ulogic;
25 system_clk : in std_ulogic;
26
27 -- UART0 signals:
28 uart0_txd : out std_ulogic;
29 uart0_rxd : in std_ulogic;
30
31 -- Misc (to use for things like LEDs)
32 core_terminated : out std_ulogic
33 );
34 end entity soc;
35
36 architecture behaviour of soc is
37
38 -- Wishbone master signals:
39 signal wishbone_dcore_in : wishbone_slave_out;
40 signal wishbone_dcore_out : wishbone_master_out;
41 signal wishbone_icore_in : wishbone_slave_out;
42 signal wishbone_icore_out : wishbone_master_out;
43 signal wishbone_debug_in : wishbone_slave_out;
44 signal wishbone_debug_out : wishbone_master_out;
45
46 -- Arbiter array (ghdl doesnt' support assigning the array
47 -- elements in the entity instantiation)
48 constant NUM_WB_MASTERS : positive := 3;
49 signal wb_masters_out : wishbone_master_out_vector(0 to NUM_WB_MASTERS-1);
50 signal wb_masters_in : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1);
51
52 -- Wishbone master (output of arbiter):
53 signal wb_master_in : wishbone_slave_out;
54 signal wb_master_out : wishbone_master_out;
55
56 -- UART0 signals:
57 signal wb_uart0_in : wishbone_master_out;
58 signal wb_uart0_out : wishbone_slave_out;
59 signal uart_dat8 : std_ulogic_vector(7 downto 0);
60
61 -- Main memory signals:
62 signal wb_bram_in : wishbone_master_out;
63 signal wb_bram_out : wishbone_slave_out;
64 constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
65
66 -- DMI debug bus signals
67 signal dmi_addr : std_ulogic_vector(7 downto 0);
68 signal dmi_din : std_ulogic_vector(63 downto 0);
69 signal dmi_dout : std_ulogic_vector(63 downto 0);
70 signal dmi_req : std_ulogic;
71 signal dmi_wr : std_ulogic;
72 signal dmi_ack : std_ulogic;
73
74 -- Per slave DMI signals
75 signal dmi_wb_dout : std_ulogic_vector(63 downto 0);
76 signal dmi_wb_req : std_ulogic;
77 signal dmi_wb_ack : std_ulogic;
78 signal dmi_core_dout : std_ulogic_vector(63 downto 0);
79 signal dmi_core_req : std_ulogic;
80 signal dmi_core_ack : std_ulogic;
81 begin
82
83 -- Processor core
84 processor: entity work.core
85 generic map(
86 SIM => SIM,
87 DISABLE_FLATTEN => DISABLE_FLATTEN_CORE
88 )
89 port map(
90 clk => system_clk,
91 rst => rst,
92 wishbone_insn_in => wishbone_icore_in,
93 wishbone_insn_out => wishbone_icore_out,
94 wishbone_data_in => wishbone_dcore_in,
95 wishbone_data_out => wishbone_dcore_out,
96 dmi_addr => dmi_addr(3 downto 0),
97 dmi_dout => dmi_core_dout,
98 dmi_din => dmi_dout,
99 dmi_wr => dmi_wr,
100 dmi_ack => dmi_core_ack,
101 dmi_req => dmi_core_req
102 );
103
104 -- Wishbone bus master arbiter & mux
105 wb_masters_out <= (0 => wishbone_dcore_out,
106 1 => wishbone_icore_out,
107 2 => wishbone_debug_out);
108 wishbone_dcore_in <= wb_masters_in(0);
109 wishbone_icore_in <= wb_masters_in(1);
110 wishbone_debug_in <= wb_masters_in(2);
111 wishbone_arbiter_0: entity work.wishbone_arbiter
112 generic map(
113 NUM_MASTERS => NUM_WB_MASTERS
114 )
115 port map(
116 clk => system_clk, rst => rst,
117 wb_masters_in => wb_masters_out,
118 wb_masters_out => wb_masters_in,
119 wb_slave_out => wb_master_out,
120 wb_slave_in => wb_master_in
121 );
122
123 -- Wishbone slaves address decoder & mux
124 slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
125 -- Selected slave
126 type slave_type is (SLAVE_UART_0,
127 SLAVE_MEMORY,
128 SLAVE_NONE);
129 variable slave : slave_type;
130 begin
131 -- Simple address decoder.
132 slave := SLAVE_NONE;
133 if wb_master_out.adr(31 downto 24) = x"00" then
134 slave := SLAVE_MEMORY;
135 elsif wb_master_out.adr(31 downto 24) = x"c0" then
136 if wb_master_out.adr(23 downto 12) = x"002" then
137 slave := SLAVE_UART_0;
138 end if;
139 end if;
140
141 -- Wishbone muxing. Defaults:
142 wb_bram_in <= wb_master_out;
143 wb_bram_in.cyc <= '0';
144 wb_uart0_in <= wb_master_out;
145 wb_uart0_in.cyc <= '0';
146 case slave is
147 when SLAVE_MEMORY =>
148 wb_bram_in.cyc <= wb_master_out.cyc;
149 wb_master_in <= wb_bram_out;
150 when SLAVE_UART_0 =>
151 wb_uart0_in.cyc <= wb_master_out.cyc;
152 wb_master_in <= wb_uart0_out;
153 when others =>
154 wb_master_in.dat <= (others => '1');
155 wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
156 wb_master_in.stall <= '0';
157 end case;
158 end process slave_intercon;
159
160 -- Simulated memory and UART
161
162 -- UART0 wishbone slave
163 -- XXX FIXME: Need a proper wb64->wb8 adapter that
164 -- converts SELs into low address bits and muxes
165 -- data accordingly (either that or rejects large
166 -- cycles).
167 uart0: entity work.pp_soc_uart
168 generic map(
169 FIFO_DEPTH => 32
170 )
171 port map(
172 clk => system_clk,
173 reset => rst,
174 txd => uart0_txd,
175 rxd => uart0_rxd,
176 wb_adr_in => wb_uart0_in.adr(11 downto 0),
177 wb_dat_in => wb_uart0_in.dat(7 downto 0),
178 wb_dat_out => uart_dat8,
179 wb_cyc_in => wb_uart0_in.cyc,
180 wb_stb_in => wb_uart0_in.stb,
181 wb_we_in => wb_uart0_in.we,
182 wb_ack_out => wb_uart0_out.ack
183 );
184 wb_uart0_out.dat <= x"00000000000000" & uart_dat8;
185 wb_uart0_out.stall <= '0' when wb_uart0_in.cyc = '0' else not wb_uart0_out.ack;
186
187 -- BRAM Memory slave
188 bram0: entity work.wishbone_bram_wrapper
189 generic map(
190 MEMORY_SIZE => MEMORY_SIZE,
191 RAM_INIT_FILE => RAM_INIT_FILE
192 )
193 port map(
194 clk => system_clk,
195 rst => rst,
196 wishbone_in => wb_bram_in,
197 wishbone_out => wb_bram_out
198 );
199
200 -- DMI(debug bus) <-> JTAG bridge
201 dtm: entity work.dmi_dtm
202 generic map(
203 ABITS => 8,
204 DBITS => 64
205 )
206 port map(
207 sys_clk => system_clk,
208 sys_reset => rst,
209 dmi_addr => dmi_addr,
210 dmi_din => dmi_din,
211 dmi_dout => dmi_dout,
212 dmi_req => dmi_req,
213 dmi_wr => dmi_wr,
214 dmi_ack => dmi_ack
215 );
216
217 -- DMI interconnect
218 dmi_intercon: process(dmi_addr, dmi_req,
219 dmi_wb_ack, dmi_wb_dout,
220 dmi_core_ack, dmi_core_dout)
221
222 -- DMI address map (each address is a full 64-bit register)
223 --
224 -- Offset: Size: Slave:
225 -- 0 4 Wishbone
226 -- 10 16 Core
227
228 type slave_type is (SLAVE_WB,
229 SLAVE_CORE,
230 SLAVE_NONE);
231 variable slave : slave_type;
232 begin
233 -- Simple address decoder
234 slave := SLAVE_NONE;
235 if std_match(dmi_addr, "000000--") then
236 slave := SLAVE_WB;
237 elsif std_match(dmi_addr, "0001----") then
238 slave := SLAVE_CORE;
239 end if;
240
241 -- DMI muxing
242 dmi_wb_req <= '0';
243 dmi_core_req <= '0';
244 case slave is
245 when SLAVE_WB =>
246 dmi_wb_req <= dmi_req;
247 dmi_ack <= dmi_wb_ack;
248 dmi_din <= dmi_wb_dout;
249 when SLAVE_CORE =>
250 dmi_core_req <= dmi_req;
251 dmi_ack <= dmi_core_ack;
252 dmi_din <= dmi_core_dout;
253 when others =>
254 dmi_ack <= dmi_req;
255 dmi_din <= (others => '1');
256 end case;
257
258 -- SIM magic exit
259 if SIM and dmi_req = '1' and dmi_addr = "11111111" and dmi_wr = '1' then
260 stop;
261 end if;
262 end process;
263
264 -- Wishbone debug master (TODO: Add a DMI address decoder)
265 wishbone_debug: entity work.wishbone_debug_master
266 port map(clk => system_clk, rst => rst,
267 dmi_addr => dmi_addr(1 downto 0),
268 dmi_dout => dmi_wb_dout,
269 dmi_din => dmi_dout,
270 dmi_wr => dmi_wr,
271 dmi_ack => dmi_wb_ack,
272 dmi_req => dmi_wb_req,
273 wb_in => wishbone_debug_in,
274 wb_out => wishbone_debug_out);
275
276
277 end architecture behaviour;