Add Tercel PHY reset synchronization
[microwatt.git] / fpga / top-acorn-cle-215.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library unisim;
6 use unisim.vcomponents.all;
7
8 library work;
9 use work.wishbone_types.all;
10
11 entity toplevel is
12 generic (
13 MEMORY_SIZE : integer := 16384;
14 RAM_INIT_FILE : string := "firmware.hex";
15 CLK_FREQUENCY : positive := 100000000;
16 USE_LITEDRAM : boolean := false;
17 NO_BRAM : boolean := false;
18 DISABLE_FLATTEN_CORE : boolean := false;
19 SPI_FLASH_OFFSET : integer := 10485760;
20 SPI_FLASH_DEF_CKDV : natural := 1;
21 SPI_FLASH_DEF_QUAD : boolean := true;
22 LOG_LENGTH : natural := 2048;
23 UART_IS_16550 : boolean := true
24 );
25 port(
26 clk200_p : in std_ulogic;
27 clk200_n : in std_ulogic;
28
29 -- P2 signals used as UART
30 uart_rx : in std_ulogic;
31 uart_tx : out std_ulogic;
32
33 -- LEDs
34 led0 : out std_logic;
35 led1 : out std_logic;
36 led2 : out std_logic;
37 led3 : out std_logic;
38
39 -- SPI
40 spi_flash_cs_n : out std_ulogic;
41 spi_flash_mosi : inout std_ulogic;
42 spi_flash_miso : inout std_ulogic;
43 spi_flash_wp_n : inout std_ulogic;
44 spi_flash_hold_n : inout std_ulogic;
45
46 -- DRAM wires
47 ddram_a : out std_logic_vector(15 downto 0);
48 ddram_ba : out std_logic_vector(2 downto 0);
49 ddram_ras_n : out std_logic;
50 ddram_cas_n : out std_logic;
51 ddram_we_n : out std_logic;
52 ddram_dm : out std_logic_vector(1 downto 0);
53 ddram_dq : inout std_logic_vector(15 downto 0);
54 ddram_dqs_p : inout std_logic_vector(1 downto 0);
55 ddram_dqs_n : inout std_logic_vector(1 downto 0);
56 ddram_clk_p : out std_logic;
57 ddram_clk_n : out std_logic;
58 ddram_cke : out std_logic;
59 ddram_odt : out std_logic;
60 ddram_reset_n : out std_logic
61 );
62 end entity toplevel;
63
64 architecture behaviour of toplevel is
65
66 -- Internal clock
67 signal ext_clk : std_ulogic;
68
69 -- Reset signals:
70 signal soc_rst : std_ulogic;
71 signal pll_rst : std_ulogic;
72
73 -- Internal clock signals:
74 signal system_clk : std_ulogic;
75 signal system_clk_locked : std_ulogic;
76
77 -- DRAM main data wishbone connection
78 signal wb_dram_in : wishbone_master_out;
79 signal wb_dram_out : wishbone_slave_out;
80
81 -- DRAM control wishbone connection
82 signal wb_ext_io_in : wb_io_master_out;
83 signal wb_ext_io_out : wb_io_slave_out;
84 signal wb_ext_is_dram_csr : std_ulogic;
85 signal wb_ext_is_dram_init : std_ulogic;
86
87 -- Control/status
88 signal core_alt_reset : std_ulogic;
89
90 -- SPI flash
91 signal spi_sck : std_ulogic;
92 signal spi_cs_n : std_ulogic;
93 signal spi_sdat_o : std_ulogic_vector(3 downto 0);
94 signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
95 signal spi_sdat_i : std_ulogic_vector(3 downto 0);
96
97 -- Fixup various memory sizes based on generics
98 function get_bram_size return natural is
99 begin
100 if USE_LITEDRAM and NO_BRAM then
101 return 0;
102 else
103 return MEMORY_SIZE;
104 end if;
105 end function;
106
107 function get_payload_size return natural is
108 begin
109 if USE_LITEDRAM and NO_BRAM then
110 return MEMORY_SIZE;
111 else
112 return 0;
113 end if;
114 end function;
115
116 constant BRAM_SIZE : natural := get_bram_size;
117 constant PAYLOAD_SIZE : natural := get_payload_size;
118 begin
119
120 -- Main SoC
121 soc0: entity work.soc
122 generic map(
123 MEMORY_SIZE => BRAM_SIZE,
124 RAM_INIT_FILE => RAM_INIT_FILE,
125 SIM => false,
126 CLK_FREQ => CLK_FREQUENCY,
127 HAS_DRAM => USE_LITEDRAM,
128 DRAM_SIZE => 1024 * 1024 * 1024,
129 DRAM_INIT_SIZE => PAYLOAD_SIZE,
130 DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
131 HAS_SPI_FLASH => true,
132 SPI_FLASH_DLINES => 4,
133 SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
134 SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
135 SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
136 LOG_LENGTH => LOG_LENGTH,
137 UART0_IS_16550 => UART_IS_16550
138 )
139 port map (
140 -- System signals
141 system_clk => system_clk,
142 rst => soc_rst,
143
144 -- UART signals
145 uart0_txd => uart_tx,
146 uart0_rxd => uart_rx,
147
148 -- SPI signals
149 spi_flash_sck => spi_sck,
150 spi_flash_cs_n => spi_cs_n,
151 spi_flash_sdat_o => spi_sdat_o,
152 spi_flash_sdat_oe => spi_sdat_oe,
153 spi_flash_sdat_i => spi_sdat_i,
154
155 -- DRAM wishbone
156 wb_dram_in => wb_dram_in,
157 wb_dram_out => wb_dram_out,
158 wb_ext_io_in => wb_ext_io_in,
159 wb_ext_io_out => wb_ext_io_out,
160 wb_ext_is_dram_csr => wb_ext_is_dram_csr,
161 wb_ext_is_dram_init => wb_ext_is_dram_init,
162 alt_reset => core_alt_reset
163 );
164
165 -- SPI Flash. The SPI clk needs to be fed through the STARTUPE2
166 -- primitive of the FPGA as it's not a normal pin
167 --
168 spi_flash_cs_n <= spi_cs_n;
169 spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
170 spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
171 spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
172 spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
173 spi_sdat_i(0) <= spi_flash_mosi;
174 spi_sdat_i(1) <= spi_flash_miso;
175 spi_sdat_i(2) <= spi_flash_wp_n;
176 spi_sdat_i(3) <= spi_flash_hold_n;
177
178 STARTUPE2_INST: STARTUPE2
179 port map (
180 CLK => '0',
181 GSR => '0',
182 GTS => '0',
183 KEYCLEARB => '0',
184 PACK => '0',
185 USRCCLKO => spi_sck,
186 USRCCLKTS => '0',
187 USRDONEO => '1',
188 USRDONETS => '0'
189 );
190
191 clk200: IBUFDS
192 port map (
193 i => clk200_p,
194 ib => clk200_n,
195 o => ext_clk
196 );
197
198 nodram: if not USE_LITEDRAM generate
199 signal ddram_clk_dummy : std_ulogic;
200 begin
201 reset_controller: entity work.soc_reset
202 generic map(
203 RESET_LOW => false
204 )
205 port map(
206 ext_clk => ext_clk,
207 pll_clk => system_clk,
208 pll_locked_in => system_clk_locked,
209 ext_rst_in => '0',
210 pll_rst_out => pll_rst,
211 rst_out => soc_rst
212 );
213
214 clkgen: entity work.clock_generator
215 generic map(
216 CLK_INPUT_HZ => 200000000,
217 CLK_OUTPUT_HZ => CLK_FREQUENCY
218 )
219 port map(
220 ext_clk => ext_clk,
221 pll_rst_in => pll_rst,
222 pll_clk_out => system_clk,
223 pll_locked_out => system_clk_locked
224 );
225
226 led0 <= soc_rst;
227 led1 <= pll_rst;
228 led2 <= not system_clk_locked;
229 led3 <= '0';
230 core_alt_reset <= '0';
231
232 -- Vivado barfs on those differential signals if left
233 -- unconnected. So instanciate a diff. buffer and feed
234 -- it a constant '0'.
235 dummy_dram_clk: OBUFDS
236 port map (
237 O => ddram_clk_p,
238 OB => ddram_clk_n,
239 I => ddram_clk_dummy
240 );
241 ddram_clk_dummy <= '0';
242
243 end generate;
244
245 has_dram: if USE_LITEDRAM generate
246 signal dram_init_done : std_ulogic;
247 signal dram_init_error : std_ulogic;
248 signal dram_sys_rst : std_ulogic;
249 begin
250
251 -- Eventually dig out the frequency from the generator
252 -- but for now, assert it's 100Mhz
253 assert CLK_FREQUENCY = 100000000;
254
255 reset_controller: entity work.soc_reset
256 generic map(
257 RESET_LOW => false,
258 PLL_RESET_BITS => 18,
259 SOC_RESET_BITS => 1
260 )
261 port map(
262 ext_clk => ext_clk,
263 pll_clk => system_clk,
264 pll_locked_in => '1',
265 ext_rst_in => '0',
266 pll_rst_out => pll_rst,
267 rst_out => open
268 );
269
270 dram: entity work.litedram_wrapper
271 generic map(
272 DRAM_ABITS => 26,
273 DRAM_ALINES => 16,
274 DRAM_DLINES => 16,
275 DRAM_CKLINES => 1,
276 DRAM_PORT_WIDTH => 128,
277 PAYLOAD_FILE => RAM_INIT_FILE,
278 PAYLOAD_SIZE => PAYLOAD_SIZE
279 )
280 port map(
281 clk_in => ext_clk,
282 rst => pll_rst,
283 system_clk => system_clk,
284 system_reset => soc_rst,
285 core_alt_reset => core_alt_reset,
286 pll_locked => system_clk_locked,
287
288 wb_in => wb_dram_in,
289 wb_out => wb_dram_out,
290 wb_ctrl_in => wb_ext_io_in,
291 wb_ctrl_out => wb_ext_io_out,
292 wb_ctrl_is_csr => wb_ext_is_dram_csr,
293 wb_ctrl_is_init => wb_ext_is_dram_init,
294
295 init_done => dram_init_done,
296 init_error => dram_init_error,
297
298 ddram_a => ddram_a,
299 ddram_ba => ddram_ba,
300 ddram_ras_n => ddram_ras_n,
301 ddram_cas_n => ddram_cas_n,
302 ddram_we_n => ddram_we_n,
303 ddram_cs_n => open,
304 ddram_dm => ddram_dm,
305 ddram_dq => ddram_dq,
306 ddram_dqs_p => ddram_dqs_p,
307 ddram_dqs_n => ddram_dqs_n,
308 ddram_clk_p => ddram_clk_p,
309 ddram_clk_n => ddram_clk_n,
310 ddram_cke => ddram_cke,
311 ddram_odt => ddram_odt,
312 ddram_reset_n => ddram_reset_n
313 );
314
315 led0 <= soc_rst;
316 led1 <= pll_rst;
317 led2 <= not dram_init_done or dram_init_error;
318 led3 <= not dram_init_error; -- Make it blink ?
319 end generate;
320 end architecture behaviour;