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