intercon: Generate stall signals for non-pipelined slaves
[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 );
22 port(
23 rst : in std_ulogic;
24 system_clk : in std_ulogic;
25
26 -- UART0 signals:
27 uart0_txd : out std_ulogic;
28 uart0_rxd : in std_ulogic;
29
30 -- Misc (to use for things like LEDs)
31 core_terminated : out std_ulogic
32 );
33 end entity soc;
34
35 architecture behaviour of soc is
36
37 -- Wishbone master signals:
38 signal wishbone_dcore_in : wishbone_slave_out;
39 signal wishbone_dcore_out : wishbone_master_out;
40 signal wishbone_icore_in : wishbone_slave_out;
41 signal wishbone_icore_out : wishbone_master_out;
42 signal wishbone_debug_in : wishbone_slave_out;
43 signal wishbone_debug_out : wishbone_master_out;
44
45 -- Wishbone master (output of arbiter):
46 signal wb_master_in : wishbone_slave_out;
47 signal wb_master_out : wishbone_master_out;
48
49 -- UART0 signals:
50 signal wb_uart0_in : wishbone_master_out;
51 signal wb_uart0_out : wishbone_slave_out;
52 signal uart_dat8 : std_ulogic_vector(7 downto 0);
53
54 -- Main memory signals:
55 signal wb_bram_in : wishbone_master_out;
56 signal wb_bram_out : wishbone_slave_out;
57 constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
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 dmi_addr => dmi_addr(3 downto 0),
89 dmi_dout => dmi_core_dout,
90 dmi_din => dmi_dout,
91 dmi_wr => dmi_wr,
92 dmi_ack => dmi_core_ack,
93 dmi_req => dmi_core_req
94 );
95
96 -- Wishbone bus master arbiter & mux
97 wishbone_arbiter_0: entity work.wishbone_arbiter
98 port map(
99 clk => system_clk, rst => rst,
100 wb1_in => wishbone_dcore_out, wb1_out => wishbone_dcore_in,
101 wb2_in => wishbone_icore_out, wb2_out => wishbone_icore_in,
102 wb3_in => wishbone_debug_out, wb3_out => wishbone_debug_in,
103 wb_out => wb_master_out, wb_in => wb_master_in
104 );
105
106 -- Wishbone slaves address decoder & mux
107 slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
108 -- Selected slave
109 type slave_type is (SLAVE_UART_0,
110 SLAVE_MEMORY,
111 SLAVE_NONE);
112 variable slave : slave_type;
113 begin
114 -- Simple address decoder.
115 slave := SLAVE_NONE;
116 if wb_master_out.adr(31 downto 24) = x"00" then
117 slave := SLAVE_MEMORY;
118 elsif wb_master_out.adr(31 downto 24) = x"c0" then
119 if wb_master_out.adr(23 downto 12) = x"002" then
120 slave := SLAVE_UART_0;
121 end if;
122 end if;
123
124 -- Wishbone muxing. Defaults:
125 wb_bram_in <= wb_master_out;
126 wb_bram_in.cyc <= '0';
127 wb_uart0_in <= wb_master_out;
128 wb_uart0_in.cyc <= '0';
129 case slave is
130 when SLAVE_MEMORY =>
131 wb_bram_in.cyc <= wb_master_out.cyc;
132 wb_master_in <= wb_bram_out;
133 when SLAVE_UART_0 =>
134 wb_uart0_in.cyc <= wb_master_out.cyc;
135 wb_master_in <= wb_uart0_out;
136 when others =>
137 wb_master_in.dat <= (others => '1');
138 wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
139 wb_master_in.stall <= '0';
140 end case;
141 end process slave_intercon;
142
143 -- Simulated memory and UART
144
145 -- UART0 wishbone slave
146 -- XXX FIXME: Need a proper wb64->wb8 adapter that
147 -- converts SELs into low address bits and muxes
148 -- data accordingly (either that or rejects large
149 -- cycles).
150 uart0: entity work.pp_soc_uart
151 generic map(
152 FIFO_DEPTH => 32
153 )
154 port map(
155 clk => system_clk,
156 reset => rst,
157 txd => uart0_txd,
158 rxd => uart0_rxd,
159 wb_adr_in => wb_uart0_in.adr(11 downto 0),
160 wb_dat_in => wb_uart0_in.dat(7 downto 0),
161 wb_dat_out => uart_dat8,
162 wb_cyc_in => wb_uart0_in.cyc,
163 wb_stb_in => wb_uart0_in.stb,
164 wb_we_in => wb_uart0_in.we,
165 wb_ack_out => wb_uart0_out.ack
166 );
167 wb_uart0_out.dat <= x"00000000000000" & uart_dat8;
168 wb_uart0_out.stall <= '0' when wb_uart0_in.cyc = '0' else not wb_uart0_out.ack;
169
170 -- BRAM Memory slave
171 bram0: entity work.mw_soc_memory
172 generic map(
173 MEMORY_SIZE => MEMORY_SIZE,
174 RAM_INIT_FILE => RAM_INIT_FILE
175 )
176 port map(
177 clk => system_clk,
178 rst => rst,
179 wishbone_in => wb_bram_in,
180 wishbone_out => wb_bram_out
181 );
182
183 -- DMI(debug bus) <-> JTAG bridge
184 dtm: entity work.dmi_dtm
185 generic map(
186 ABITS => 8,
187 DBITS => 64
188 )
189 port map(
190 sys_clk => system_clk,
191 sys_reset => rst,
192 dmi_addr => dmi_addr,
193 dmi_din => dmi_din,
194 dmi_dout => dmi_dout,
195 dmi_req => dmi_req,
196 dmi_wr => dmi_wr,
197 dmi_ack => dmi_ack
198 );
199
200 -- DMI interconnect
201 dmi_intercon: process(dmi_addr, dmi_req,
202 dmi_wb_ack, dmi_wb_dout,
203 dmi_core_ack, dmi_core_dout)
204
205 -- DMI address map (each address is a full 64-bit register)
206 --
207 -- Offset: Size: Slave:
208 -- 0 4 Wishbone
209 -- 10 16 Core
210
211 type slave_type is (SLAVE_WB,
212 SLAVE_CORE,
213 SLAVE_NONE);
214 variable slave : slave_type;
215 begin
216 -- Simple address decoder
217 slave := SLAVE_NONE;
218 if std_match(dmi_addr, "000000--") then
219 slave := SLAVE_WB;
220 elsif std_match(dmi_addr, "0001----") then
221 slave := SLAVE_CORE;
222 end if;
223
224 -- DMI muxing
225 dmi_wb_req <= '0';
226 dmi_core_req <= '0';
227 case slave is
228 when SLAVE_WB =>
229 dmi_wb_req <= dmi_req;
230 dmi_ack <= dmi_wb_ack;
231 dmi_din <= dmi_wb_dout;
232 when SLAVE_CORE =>
233 dmi_core_req <= dmi_req;
234 dmi_ack <= dmi_core_ack;
235 dmi_din <= dmi_core_dout;
236 when others =>
237 dmi_ack <= dmi_req;
238 dmi_din <= (others => '1');
239 end case;
240
241 -- SIM magic exit
242 if SIM and dmi_req = '1' and dmi_addr = "11111111" and dmi_wr = '1' then
243 stop;
244 end if;
245 end process;
246
247 -- Wishbone debug master (TODO: Add a DMI address decoder)
248 wishbone_debug: entity work.wishbone_debug_master
249 port map(clk => system_clk, rst => rst,
250 dmi_addr => dmi_addr(1 downto 0),
251 dmi_dout => dmi_wb_dout,
252 dmi_din => dmi_dout,
253 dmi_wr => dmi_wr,
254 dmi_ack => dmi_wb_ack,
255 dmi_req => dmi_wb_req,
256 wb_in => wishbone_debug_in,
257 wb_out => wishbone_debug_out);
258
259
260 end architecture behaviour;