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