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