2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
6 use unisim.vcomponents.all;
9 use work.wishbone_types.all;
13 MEMORY_SIZE : integer := 16384;
14 RAM_INIT_FILE : string := "firmware.hex";
15 RESET_LOW : boolean := true;
16 CLK_FREQUENCY : positive := 100000000;
17 USE_LITEDRAM : boolean := false;
18 NO_BRAM : boolean := false;
19 DISABLE_FLATTEN_CORE : boolean := false;
20 SCLK_STARTUPE2 : boolean := false;
21 SPI_FLASH_OFFSET : integer := 4194304;
22 SPI_FLASH_DEF_CKDV : natural := 1;
23 SPI_FLASH_DEF_QUAD : boolean := true;
24 LOG_LENGTH : natural := 512;
25 USE_LITEETH : boolean := false;
26 UART_IS_16550 : boolean := false;
27 HAS_UART1 : boolean := false
30 ext_clk : in std_ulogic;
31 ext_rst_n : in std_ulogic;
34 uart_main_tx : out std_ulogic;
35 uart_main_rx : in std_ulogic;
38 uart_pmod_tx : out std_ulogic;
39 uart_pmod_rx : in std_ulogic;
40 uart_pmod_cts_n : in std_ulogic;
41 uart_pmod_rts_n : out std_ulogic;
44 led0_b : out std_ulogic;
45 led0_g : out std_ulogic;
46 led0_r : out std_ulogic;
47 led4 : out std_ulogic;
48 led5 : out std_ulogic;
49 led6 : out std_ulogic;
50 led7 : out std_ulogic;
53 spi_flash_cs_n : out std_ulogic;
54 spi_flash_clk : out std_ulogic;
55 spi_flash_mosi : inout std_ulogic;
56 spi_flash_miso : inout std_ulogic;
57 spi_flash_wp_n : inout std_ulogic;
58 spi_flash_hold_n : inout std_ulogic;
61 eth_ref_clk : out std_ulogic;
62 eth_clocks_tx : in std_ulogic;
63 eth_clocks_rx : in std_ulogic;
64 eth_rst_n : out std_ulogic;
65 eth_mdio : inout std_ulogic;
66 eth_mdc : out std_ulogic;
67 eth_rx_dv : in std_ulogic;
68 eth_rx_er : in std_ulogic;
69 eth_rx_data : in std_ulogic_vector(3 downto 0);
70 eth_tx_en : out std_ulogic;
71 eth_tx_data : out std_ulogic_vector(3 downto 0);
72 eth_col : in std_ulogic;
73 eth_crs : in std_ulogic;
76 ddram_a : out std_ulogic_vector(13 downto 0);
77 ddram_ba : out std_ulogic_vector(2 downto 0);
78 ddram_ras_n : out std_ulogic;
79 ddram_cas_n : out std_ulogic;
80 ddram_we_n : out std_ulogic;
81 ddram_cs_n : out std_ulogic;
82 ddram_dm : out std_ulogic_vector(1 downto 0);
83 ddram_dq : inout std_ulogic_vector(15 downto 0);
84 ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
85 ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
86 ddram_clk_p : out std_ulogic;
87 ddram_clk_n : out std_ulogic;
88 ddram_cke : out std_ulogic;
89 ddram_odt : out std_ulogic;
90 ddram_reset_n : out std_ulogic
94 architecture behaviour of toplevel is
97 signal soc_rst : std_ulogic;
98 signal pll_rst : std_ulogic;
100 -- Internal clock signals:
101 signal system_clk : std_ulogic;
102 signal system_clk_locked : std_ulogic;
103 signal eth_clk_locked : std_ulogic;
105 -- External IOs from the SoC
106 signal wb_ext_io_in : wb_io_master_out;
107 signal wb_ext_io_out : wb_io_slave_out;
108 signal wb_ext_is_dram_csr : std_ulogic;
109 signal wb_ext_is_dram_init : std_ulogic;
110 signal wb_ext_is_eth : std_ulogic;
112 -- DRAM main data wishbone connection
113 signal wb_dram_in : wishbone_master_out;
114 signal wb_dram_out : wishbone_slave_out;
116 -- DRAM control wishbone connection
117 signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
119 -- LiteEth connection
120 signal ext_irq_eth : std_ulogic;
121 signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
124 signal core_alt_reset : std_ulogic;
127 signal led0_b_pwm : std_ulogic;
128 signal led0_r_pwm : std_ulogic;
129 signal led0_g_pwm : std_ulogic;
131 -- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
132 signal pwm_counter : std_ulogic_vector(8 downto 0);
135 signal spi_sck : std_ulogic;
136 signal spi_cs_n : std_ulogic;
137 signal spi_sdat_o : std_ulogic_vector(3 downto 0);
138 signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
139 signal spi_sdat_i : std_ulogic_vector(3 downto 0);
141 -- Fixup various memory sizes based on generics
142 function get_bram_size return natural is
144 if USE_LITEDRAM and NO_BRAM then
151 function get_payload_size return natural is
153 if USE_LITEDRAM and NO_BRAM then
160 constant BRAM_SIZE : natural := get_bram_size;
161 constant PAYLOAD_SIZE : natural := get_payload_size;
165 soc0: entity work.soc
167 MEMORY_SIZE => BRAM_SIZE,
168 RAM_INIT_FILE => RAM_INIT_FILE,
170 CLK_FREQ => CLK_FREQUENCY,
171 HAS_DRAM => USE_LITEDRAM,
172 DRAM_SIZE => 256 * 1024 * 1024,
173 DRAM_INIT_SIZE => PAYLOAD_SIZE,
174 DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
175 HAS_SPI_FLASH => true,
176 SPI_FLASH_DLINES => 4,
177 SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
178 SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
179 SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
180 LOG_LENGTH => LOG_LENGTH,
181 HAS_LITEETH => USE_LITEETH,
182 UART0_IS_16550 => UART_IS_16550,
183 HAS_UART1 => HAS_UART1
187 system_clk => system_clk,
191 uart0_txd => uart_main_tx,
192 uart0_rxd => uart_main_rx,
195 uart1_txd => uart_pmod_tx,
196 uart1_rxd => uart_pmod_rx,
199 spi_flash_sck => spi_sck,
200 spi_flash_cs_n => spi_cs_n,
201 spi_flash_sdat_o => spi_sdat_o,
202 spi_flash_sdat_oe => spi_sdat_oe,
203 spi_flash_sdat_i => spi_sdat_i,
205 -- External interrupts
206 ext_irq_eth => ext_irq_eth,
209 wb_dram_in => wb_dram_in,
210 wb_dram_out => wb_dram_out,
211 wb_ext_io_in => wb_ext_io_in,
212 wb_ext_io_out => wb_ext_io_out,
213 wb_ext_is_dram_csr => wb_ext_is_dram_csr,
214 wb_ext_is_dram_init => wb_ext_is_dram_init,
215 wb_ext_is_eth => wb_ext_is_eth,
216 alt_reset => core_alt_reset
219 uart_pmod_rts_n <= '0';
223 -- Note: Unlike many other boards, the SPI flash on the Arty has
224 -- an actual pin to generate the clock and doesn't require to use
225 -- the STARTUPE2 primitive.
227 spi_flash_cs_n <= spi_cs_n;
228 spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
229 spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
230 spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
231 spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
232 spi_sdat_i(0) <= spi_flash_mosi;
233 spi_sdat_i(1) <= spi_flash_miso;
234 spi_sdat_i(2) <= spi_flash_wp_n;
235 spi_sdat_i(3) <= spi_flash_hold_n;
237 spi_sclk_startupe2: if SCLK_STARTUPE2 generate
238 spi_flash_clk <= 'Z';
240 STARTUPE2_INST: STARTUPE2
254 spi_direct_sclk: if not SCLK_STARTUPE2 generate
255 spi_flash_clk <= spi_sck;
258 nodram: if not USE_LITEDRAM generate
259 signal ddram_clk_dummy : std_ulogic;
261 reset_controller: entity work.soc_reset
263 RESET_LOW => RESET_LOW
267 pll_clk => system_clk,
268 pll_locked_in => system_clk_locked and eth_clk_locked,
269 ext_rst_in => ext_rst_n,
270 pll_rst_out => pll_rst,
274 clkgen: entity work.clock_generator
276 CLK_INPUT_HZ => 100000000,
277 CLK_OUTPUT_HZ => CLK_FREQUENCY
281 pll_rst_in => pll_rst,
282 pll_clk_out => system_clk,
283 pll_locked_out => system_clk_locked
289 core_alt_reset <= '0';
291 -- Vivado barfs on those differential signals if left
292 -- unconnected. So instanciate a diff. buffer and feed
293 -- it a constant '0'.
294 dummy_dram_clk: OBUFDS
300 ddram_clk_dummy <= '0';
304 has_dram: if USE_LITEDRAM generate
305 signal dram_init_done : std_ulogic;
306 signal dram_init_error : std_ulogic;
307 signal dram_sys_rst : std_ulogic;
308 signal rst_gen_rst : std_ulogic;
311 -- Eventually dig out the frequency from the generator
312 -- but for now, assert it's 100Mhz
313 assert CLK_FREQUENCY = 100000000;
315 reset_controller: entity work.soc_reset
317 RESET_LOW => RESET_LOW,
318 PLL_RESET_BITS => 18,
323 pll_clk => system_clk,
324 pll_locked_in => eth_clk_locked,
325 ext_rst_in => ext_rst_n,
326 pll_rst_out => pll_rst,
327 rst_out => rst_gen_rst
330 -- Generate SoC reset
331 soc_rst_gen: process(system_clk)
333 if ext_rst_n = '0' then
335 elsif rising_edge(system_clk) then
336 soc_rst <= dram_sys_rst or not eth_clk_locked or not system_clk_locked;
340 dram: entity work.litedram_wrapper
344 PAYLOAD_FILE => RAM_INIT_FILE,
345 PAYLOAD_SIZE => PAYLOAD_SIZE
350 system_clk => system_clk,
351 system_reset => dram_sys_rst,
352 core_alt_reset => core_alt_reset,
353 pll_locked => system_clk_locked,
356 wb_out => wb_dram_out,
357 wb_ctrl_in => wb_ext_io_in,
358 wb_ctrl_out => wb_dram_ctrl_out,
359 wb_ctrl_is_csr => wb_ext_is_dram_csr,
360 wb_ctrl_is_init => wb_ext_is_dram_init,
362 init_done => dram_init_done,
363 init_error => dram_init_error,
366 ddram_ba => ddram_ba,
367 ddram_ras_n => ddram_ras_n,
368 ddram_cas_n => ddram_cas_n,
369 ddram_we_n => ddram_we_n,
370 ddram_cs_n => ddram_cs_n,
371 ddram_dm => ddram_dm,
372 ddram_dq => ddram_dq,
373 ddram_dqs_p => ddram_dqs_p,
374 ddram_dqs_n => ddram_dqs_n,
375 ddram_clk_p => ddram_clk_p,
376 ddram_clk_n => ddram_clk_n,
377 ddram_cke => ddram_cke,
378 ddram_odt => ddram_odt,
379 ddram_reset_n => ddram_reset_n
382 led0_b_pwm <= not dram_init_done;
383 led0_r_pwm <= dram_init_error;
384 led0_g_pwm <= dram_init_done and not dram_init_error;
388 has_liteeth : if USE_LITEETH generate
390 component liteeth_core port (
391 sys_clock : in std_ulogic;
392 sys_reset : in std_ulogic;
393 mii_eth_clocks_tx : in std_ulogic;
394 mii_eth_clocks_rx : in std_ulogic;
395 mii_eth_rst_n : out std_ulogic;
396 mii_eth_mdio : in std_ulogic;
397 mii_eth_mdc : out std_ulogic;
398 mii_eth_rx_dv : in std_ulogic;
399 mii_eth_rx_er : in std_ulogic;
400 mii_eth_rx_data : in std_ulogic_vector(3 downto 0);
401 mii_eth_tx_en : out std_ulogic;
402 mii_eth_tx_data : out std_ulogic_vector(3 downto 0);
403 mii_eth_col : in std_ulogic;
404 mii_eth_crs : in std_ulogic;
405 wishbone_adr : in std_ulogic_vector(29 downto 0);
406 wishbone_dat_w : in std_ulogic_vector(31 downto 0);
407 wishbone_dat_r : out std_ulogic_vector(31 downto 0);
408 wishbone_sel : in std_ulogic_vector(3 downto 0);
409 wishbone_cyc : in std_ulogic;
410 wishbone_stb : in std_ulogic;
411 wishbone_ack : out std_ulogic;
412 wishbone_we : in std_ulogic;
413 wishbone_cti : in std_ulogic_vector(2 downto 0);
414 wishbone_bte : in std_ulogic_vector(1 downto 0);
415 wishbone_err : out std_ulogic;
416 interrupt : out std_ulogic
420 signal wb_eth_cyc : std_ulogic;
421 signal wb_eth_adr : std_ulogic_vector(29 downto 0);
423 -- Change this to use a PLL instead of a BUFR to generate the 25Mhz
424 -- reference clock to the PHY.
425 constant USE_PLL : boolean := false;
427 eth_use_pll: if USE_PLL generate
428 signal eth_clk_25 : std_ulogic;
429 signal eth_clkfb : std_ulogic;
433 BANDWIDTH => "OPTIMIZED",
435 CLKIN1_PERIOD => 10.0,
436 CLKOUT0_DIVIDE => 64,
438 STARTUP_WAIT => "FALSE")
440 CLKOUT0 => eth_clk_25,
446 CLKFBOUT => eth_clkfb,
447 LOCKED => eth_clk_locked,
451 CLKFBIN => eth_clkfb);
460 eth_use_bufr: if not USE_PLL generate
471 eth_clk_locked <= '1';
474 liteeth : liteeth_core
476 sys_clock => system_clk,
477 sys_reset => soc_rst,
478 mii_eth_clocks_tx => eth_clocks_tx,
479 mii_eth_clocks_rx => eth_clocks_rx,
480 mii_eth_rst_n => eth_rst_n,
481 mii_eth_mdio => eth_mdio,
482 mii_eth_mdc => eth_mdc,
483 mii_eth_rx_dv => eth_rx_dv,
484 mii_eth_rx_er => eth_rx_er,
485 mii_eth_rx_data => eth_rx_data,
486 mii_eth_tx_en => eth_tx_en,
487 mii_eth_tx_data => eth_tx_data,
488 mii_eth_col => eth_col,
489 mii_eth_crs => eth_crs,
490 wishbone_adr => wb_eth_adr,
491 wishbone_dat_w => wb_ext_io_in.dat,
492 wishbone_dat_r => wb_eth_out.dat,
493 wishbone_sel => wb_ext_io_in.sel,
494 wishbone_cyc => wb_eth_cyc,
495 wishbone_stb => wb_ext_io_in.stb,
496 wishbone_ack => wb_eth_out.ack,
497 wishbone_we => wb_ext_io_in.we,
498 wishbone_cti => "000",
499 wishbone_bte => "00",
500 wishbone_err => open,
501 interrupt => ext_irq_eth
504 -- Gate cyc with "chip select" from soc
505 wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
507 -- Remove top address bits as liteeth decoder doesn't know about them
508 wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(16 downto 2);
510 -- LiteETH isn't pipelined
511 wb_eth_out.stall <= not wb_eth_out.ack;
515 no_liteeth : if not USE_LITEETH generate
516 eth_clk_locked <= '1';
520 -- Mux WB response on the IO bus
521 wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else wb_dram_ctrl_out;
523 leds_pwm : process(system_clk)
525 if rising_edge(system_clk) then
526 pwm_counter <= std_ulogic_vector(signed(pwm_counter) + 1);
527 if pwm_counter(8 downto 4) = "00000" then
528 led0_b <= led0_b_pwm;
529 led0_r <= led0_r_pwm;
530 led0_g <= led0_g_pwm;
539 led4 <= system_clk_locked;
540 led5 <= eth_clk_locked;
542 led7 <= not spi_flash_cs_n;
544 end architecture behaviour;