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