Merge pull request #173 from Jbalkind/core-vcs-syntax
[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 -- Memory map:
14 --
15 -- 0x00000000: Block RAM (MEMORY_SIZE) or DRAM depending on syscon
16 -- 0x40000000: DRAM (when present)
17 -- 0xc0000000: SYSCON
18 -- 0xc0002000: UART0
19 -- 0xc0004000: XICS ICP
20 -- 0xc0100000: LiteDRAM control (CSRs)
21 -- 0xf0000000: Block RAM (aliased & repeated)
22 -- 0xffff0000: DRAM init code (if any)
23
24 entity soc is
25 generic (
26 MEMORY_SIZE : positive;
27 RAM_INIT_FILE : string;
28 RESET_LOW : boolean;
29 CLK_FREQ : positive;
30 SIM : boolean;
31 DISABLE_FLATTEN_CORE : boolean := false;
32 HAS_DRAM : boolean := false;
33 DRAM_SIZE : integer := 0
34 );
35 port(
36 rst : in std_ulogic;
37 system_clk : in std_ulogic;
38
39 -- DRAM controller signals
40 wb_dram_in : out wishbone_master_out;
41 wb_dram_out : in wishbone_slave_out;
42 wb_dram_ctrl : out std_ulogic;
43 wb_dram_init : out std_ulogic;
44
45 -- UART0 signals:
46 uart0_txd : out std_ulogic;
47 uart0_rxd : in std_ulogic;
48
49 -- DRAM controller signals
50 alt_reset : in std_ulogic
51 );
52 end entity soc;
53
54 architecture behaviour of soc is
55
56 -- Wishbone master signals:
57 signal wishbone_dcore_in : wishbone_slave_out;
58 signal wishbone_dcore_out : wishbone_master_out;
59 signal wishbone_icore_in : wishbone_slave_out;
60 signal wishbone_icore_out : wishbone_master_out;
61 signal wishbone_debug_in : wishbone_slave_out;
62 signal wishbone_debug_out : wishbone_master_out;
63
64 -- Arbiter array (ghdl doesnt' support assigning the array
65 -- elements in the entity instantiation)
66 constant NUM_WB_MASTERS : positive := 3;
67 signal wb_masters_out : wishbone_master_out_vector(0 to NUM_WB_MASTERS-1);
68 signal wb_masters_in : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1);
69
70 -- Wishbone master (output of arbiter):
71 signal wb_master_in : wishbone_slave_out;
72 signal wb_master_out : wishbone_master_out;
73
74 -- Syscon signals
75 signal dram_at_0 : std_ulogic;
76 signal do_core_reset : std_ulogic;
77 signal wb_syscon_in : wishbone_master_out;
78 signal wb_syscon_out : wishbone_slave_out;
79
80 -- UART0 signals:
81 signal wb_uart0_in : wishbone_master_out;
82 signal wb_uart0_out : wishbone_slave_out;
83 signal uart_dat8 : std_ulogic_vector(7 downto 0);
84
85 -- XICS0 signals:
86 signal wb_xics0_in : wishbone_master_out;
87 signal wb_xics0_out : wishbone_slave_out;
88 signal int_level_in : std_ulogic_vector(15 downto 0);
89
90 signal xics_to_execute1 : XicsToExecute1Type;
91
92 -- Main memory signals:
93 signal wb_bram_in : wishbone_master_out;
94 signal wb_bram_out : wishbone_slave_out;
95 constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
96
97 -- DMI debug bus signals
98 signal dmi_addr : std_ulogic_vector(7 downto 0);
99 signal dmi_din : std_ulogic_vector(63 downto 0);
100 signal dmi_dout : std_ulogic_vector(63 downto 0);
101 signal dmi_req : std_ulogic;
102 signal dmi_wr : std_ulogic;
103 signal dmi_ack : std_ulogic;
104
105 -- Per slave DMI signals
106 signal dmi_wb_dout : std_ulogic_vector(63 downto 0);
107 signal dmi_wb_req : std_ulogic;
108 signal dmi_wb_ack : std_ulogic;
109 signal dmi_core_dout : std_ulogic_vector(63 downto 0);
110 signal dmi_core_req : std_ulogic;
111 signal dmi_core_ack : std_ulogic;
112
113 -- Delayed/latched resets and alt_reset
114 signal rst_core : std_ulogic := '1';
115 signal rst_uart : std_ulogic := '1';
116 signal rst_xics : std_ulogic := '1';
117 signal rst_bram : std_ulogic := '1';
118 signal rst_dtm : std_ulogic := '1';
119 signal rst_wbar : std_ulogic := '1';
120 signal rst_wbdb : std_ulogic := '1';
121 signal alt_reset_d : std_ulogic;
122
123 begin
124
125 resets: process(system_clk)
126 begin
127 if rising_edge(system_clk) then
128 rst_core <= rst or do_core_reset;
129 rst_uart <= rst;
130 rst_xics <= rst;
131 rst_bram <= rst;
132 rst_dtm <= rst;
133 rst_wbar <= rst;
134 rst_wbdb <= rst;
135 alt_reset_d <= alt_reset;
136 end if;
137 end process;
138
139 -- Processor core
140 processor: entity work.core
141 generic map(
142 SIM => SIM,
143 DISABLE_FLATTEN => DISABLE_FLATTEN_CORE,
144 ALT_RESET_ADDRESS => (15 downto 0 => '0', others => '1')
145 )
146 port map(
147 clk => system_clk,
148 rst => rst_core,
149 alt_reset => alt_reset_d,
150 wishbone_insn_in => wishbone_icore_in,
151 wishbone_insn_out => wishbone_icore_out,
152 wishbone_data_in => wishbone_dcore_in,
153 wishbone_data_out => wishbone_dcore_out,
154 dmi_addr => dmi_addr(3 downto 0),
155 dmi_dout => dmi_core_dout,
156 dmi_din => dmi_dout,
157 dmi_wr => dmi_wr,
158 dmi_ack => dmi_core_ack,
159 dmi_req => dmi_core_req,
160 xics_in => xics_to_execute1
161 );
162
163 -- Wishbone bus master arbiter & mux
164 wb_masters_out <= (0 => wishbone_dcore_out,
165 1 => wishbone_icore_out,
166 2 => wishbone_debug_out);
167 wishbone_dcore_in <= wb_masters_in(0);
168 wishbone_icore_in <= wb_masters_in(1);
169 wishbone_debug_in <= wb_masters_in(2);
170 wishbone_arbiter_0: entity work.wishbone_arbiter
171 generic map(
172 NUM_MASTERS => NUM_WB_MASTERS
173 )
174 port map(
175 clk => system_clk,
176 rst => rst_wbar,
177 wb_masters_in => wb_masters_out,
178 wb_masters_out => wb_masters_in,
179 wb_slave_out => wb_master_out,
180 wb_slave_in => wb_master_in
181 );
182
183 -- Wishbone slaves address decoder & mux
184 slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out, wb_dram_out, wb_syscon_out)
185 -- Selected slave
186 type slave_type is (SLAVE_SYSCON,
187 SLAVE_UART,
188 SLAVE_BRAM,
189 SLAVE_DRAM,
190 SLAVE_DRAM_INIT,
191 SLAVE_DRAM_CTRL,
192 SLAVE_ICP_0,
193 SLAVE_NONE);
194 variable slave : slave_type;
195 begin
196 -- Simple address decoder.
197 slave := SLAVE_NONE;
198 -- Simple address decoder. Ignore top bits to save silicon for now
199 slave := SLAVE_NONE;
200 if std_match(wb_master_out.adr, x"0-------") then
201 slave := SLAVE_DRAM when HAS_DRAM and dram_at_0 = '1' else
202 SLAVE_BRAM;
203 elsif std_match(wb_master_out.adr, x"FFFF----") then
204 slave := SLAVE_DRAM_INIT;
205 elsif std_match(wb_master_out.adr, x"F-------") then
206 slave := SLAVE_BRAM;
207 elsif std_match(wb_master_out.adr, x"4-------") and HAS_DRAM then
208 slave := SLAVE_DRAM;
209 elsif std_match(wb_master_out.adr, x"C0000---") then
210 slave := SLAVE_SYSCON;
211 elsif std_match(wb_master_out.adr, x"C0002---") then
212 slave := SLAVE_UART;
213 elsif std_match(wb_master_out.adr, x"C01-----") then
214 slave := SLAVE_DRAM_CTRL;
215 elsif std_match(wb_master_out.adr, x"C0004---") then
216 slave := SLAVE_ICP_0;
217 end if;
218
219 -- Wishbone muxing. Defaults:
220 wb_bram_in <= wb_master_out;
221 wb_bram_in.cyc <= '0';
222 wb_uart0_in <= wb_master_out;
223 wb_uart0_in.cyc <= '0';
224
225 -- Only give xics 8 bits of wb addr
226 wb_xics0_in <= wb_master_out;
227 wb_xics0_in.adr <= (others => '0');
228 wb_xics0_in.adr(7 downto 0) <= wb_master_out.adr(7 downto 0);
229 wb_xics0_in.cyc <= '0';
230
231 wb_dram_in <= wb_master_out;
232 wb_dram_in.cyc <= '0';
233 wb_dram_ctrl <= '0';
234 wb_dram_init <= '0';
235 wb_syscon_in <= wb_master_out;
236 wb_syscon_in.cyc <= '0';
237 case slave is
238 when SLAVE_BRAM =>
239 wb_bram_in.cyc <= wb_master_out.cyc;
240 wb_master_in <= wb_bram_out;
241 when SLAVE_DRAM =>
242 wb_dram_in.cyc <= wb_master_out.cyc;
243 wb_master_in <= wb_dram_out;
244 when SLAVE_DRAM_INIT =>
245 wb_dram_in.cyc <= wb_master_out.cyc;
246 wb_master_in <= wb_dram_out;
247 wb_dram_init <= '1';
248 when SLAVE_DRAM_CTRL =>
249 wb_dram_in.cyc <= wb_master_out.cyc;
250 wb_master_in <= wb_dram_out;
251 wb_dram_ctrl <= '1';
252 when SLAVE_SYSCON =>
253 wb_syscon_in.cyc <= wb_master_out.cyc;
254 wb_master_in <= wb_syscon_out;
255 when SLAVE_UART =>
256 wb_uart0_in.cyc <= wb_master_out.cyc;
257 wb_master_in <= wb_uart0_out;
258 when SLAVE_ICP_0 =>
259 wb_xics0_in.cyc <= wb_master_out.cyc;
260 wb_master_in <= wb_xics0_out;
261 when others =>
262 wb_master_in.dat <= (others => '1');
263 wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
264 wb_master_in.stall <= '0';
265 end case;
266 end process slave_intercon;
267
268 -- Syscon slave
269 syscon0: entity work.syscon
270 generic map(
271 HAS_UART => true,
272 HAS_DRAM => HAS_DRAM,
273 BRAM_SIZE => MEMORY_SIZE,
274 DRAM_SIZE => DRAM_SIZE,
275 CLK_FREQ => CLK_FREQ
276 )
277 port map(
278 clk => system_clk,
279 rst => rst,
280 wishbone_in => wb_syscon_in,
281 wishbone_out => wb_syscon_out,
282 dram_at_0 => dram_at_0,
283 core_reset => do_core_reset,
284 soc_reset => open -- XXX TODO
285 );
286
287 -- Simulated memory and UART
288
289 -- UART0 wishbone slave
290 -- XXX FIXME: Need a proper wb64->wb8 adapter that
291 -- converts SELs into low address bits and muxes
292 -- data accordingly (either that or rejects large
293 -- cycles).
294 uart0: entity work.pp_soc_uart
295 generic map(
296 FIFO_DEPTH => 32
297 )
298 port map(
299 clk => system_clk,
300 reset => rst_uart,
301 txd => uart0_txd,
302 rxd => uart0_rxd,
303 irq => int_level_in(0),
304 wb_adr_in => wb_uart0_in.adr(11 downto 0),
305 wb_dat_in => wb_uart0_in.dat(7 downto 0),
306 wb_dat_out => uart_dat8,
307 wb_cyc_in => wb_uart0_in.cyc,
308 wb_stb_in => wb_uart0_in.stb,
309 wb_we_in => wb_uart0_in.we,
310 wb_ack_out => wb_uart0_out.ack
311 );
312 wb_uart0_out.dat <= x"00000000000000" & uart_dat8;
313 wb_uart0_out.stall <= '0' when wb_uart0_in.cyc = '0' else not wb_uart0_out.ack;
314
315 xics0: entity work.xics
316 generic map(
317 LEVEL_NUM => 16
318 )
319 port map(
320 clk => system_clk,
321 rst => rst_xics,
322 wb_in => wb_xics0_in,
323 wb_out => wb_xics0_out,
324 int_level_in => int_level_in,
325 e_out => xics_to_execute1
326 );
327
328 -- BRAM Memory slave
329 bram0: entity work.wishbone_bram_wrapper
330 generic map(
331 MEMORY_SIZE => MEMORY_SIZE,
332 RAM_INIT_FILE => RAM_INIT_FILE
333 )
334 port map(
335 clk => system_clk,
336 rst => rst_bram,
337 wishbone_in => wb_bram_in,
338 wishbone_out => wb_bram_out
339 );
340
341 -- DMI(debug bus) <-> JTAG bridge
342 dtm: entity work.dmi_dtm
343 generic map(
344 ABITS => 8,
345 DBITS => 64
346 )
347 port map(
348 sys_clk => system_clk,
349 sys_reset => rst_dtm,
350 dmi_addr => dmi_addr,
351 dmi_din => dmi_din,
352 dmi_dout => dmi_dout,
353 dmi_req => dmi_req,
354 dmi_wr => dmi_wr,
355 dmi_ack => dmi_ack
356 );
357
358 -- DMI interconnect
359 dmi_intercon: process(dmi_addr, dmi_req,
360 dmi_wb_ack, dmi_wb_dout,
361 dmi_core_ack, dmi_core_dout)
362
363 -- DMI address map (each address is a full 64-bit register)
364 --
365 -- Offset: Size: Slave:
366 -- 0 4 Wishbone
367 -- 10 16 Core
368
369 type slave_type is (SLAVE_WB,
370 SLAVE_CORE,
371 SLAVE_NONE);
372 variable slave : slave_type;
373 begin
374 -- Simple address decoder
375 slave := SLAVE_NONE;
376 if std_match(dmi_addr, "000000--") then
377 slave := SLAVE_WB;
378 elsif std_match(dmi_addr, "0001----") then
379 slave := SLAVE_CORE;
380 end if;
381
382 -- DMI muxing
383 dmi_wb_req <= '0';
384 dmi_core_req <= '0';
385 case slave is
386 when SLAVE_WB =>
387 dmi_wb_req <= dmi_req;
388 dmi_ack <= dmi_wb_ack;
389 dmi_din <= dmi_wb_dout;
390 when SLAVE_CORE =>
391 dmi_core_req <= dmi_req;
392 dmi_ack <= dmi_core_ack;
393 dmi_din <= dmi_core_dout;
394 when others =>
395 dmi_ack <= dmi_req;
396 dmi_din <= (others => '1');
397 end case;
398
399 -- SIM magic exit
400 if SIM and dmi_req = '1' and dmi_addr = "11111111" and dmi_wr = '1' then
401 stop;
402 end if;
403 end process;
404
405 -- Wishbone debug master (TODO: Add a DMI address decoder)
406 wishbone_debug: entity work.wishbone_debug_master
407 port map(clk => system_clk,
408 rst => rst_wbdb,
409 dmi_addr => dmi_addr(1 downto 0),
410 dmi_dout => dmi_wb_dout,
411 dmi_din => dmi_dout,
412 dmi_wr => dmi_wr,
413 dmi_ack => dmi_wb_ack,
414 dmi_req => dmi_wb_req,
415 wb_in => wishbone_debug_in,
416 wb_out => wishbone_debug_out);
417
418
419 end architecture behaviour;