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 := true
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
345 DRAM_PORT_WIDTH => 128,
346 PAYLOAD_FILE => RAM_INIT_FILE,
347 PAYLOAD_SIZE => PAYLOAD_SIZE
352 system_clk => system_clk,
353 system_reset => dram_sys_rst,
354 core_alt_reset => core_alt_reset,
355 pll_locked => system_clk_locked,
358 wb_out => wb_dram_out,
359 wb_ctrl_in => wb_ext_io_in,
360 wb_ctrl_out => wb_dram_ctrl_out,
361 wb_ctrl_is_csr => wb_ext_is_dram_csr,
362 wb_ctrl_is_init => wb_ext_is_dram_init,
364 init_done => dram_init_done,
365 init_error => dram_init_error,
368 ddram_ba => ddram_ba,
369 ddram_ras_n => ddram_ras_n,
370 ddram_cas_n => ddram_cas_n,
371 ddram_we_n => ddram_we_n,
372 ddram_cs_n => ddram_cs_n,
373 ddram_dm => ddram_dm,
374 ddram_dq => ddram_dq,
375 ddram_dqs_p => ddram_dqs_p,
376 ddram_dqs_n => ddram_dqs_n,
377 ddram_clk_p => ddram_clk_p,
378 ddram_clk_n => ddram_clk_n,
379 ddram_cke => ddram_cke,
380 ddram_odt => ddram_odt,
381 ddram_reset_n => ddram_reset_n
384 led0_b_pwm <= not dram_init_done;
385 led0_r_pwm <= dram_init_error;
386 led0_g_pwm <= dram_init_done and not dram_init_error;
390 has_liteeth : if USE_LITEETH generate
392 component liteeth_core port (
393 sys_clock : in std_ulogic;
394 sys_reset : in std_ulogic;
395 mii_eth_clocks_tx : in std_ulogic;
396 mii_eth_clocks_rx : in std_ulogic;
397 mii_eth_rst_n : out std_ulogic;
398 mii_eth_mdio : in std_ulogic;
399 mii_eth_mdc : out std_ulogic;
400 mii_eth_rx_dv : in std_ulogic;
401 mii_eth_rx_er : in std_ulogic;
402 mii_eth_rx_data : in std_ulogic_vector(3 downto 0);
403 mii_eth_tx_en : out std_ulogic;
404 mii_eth_tx_data : out std_ulogic_vector(3 downto 0);
405 mii_eth_col : in std_ulogic;
406 mii_eth_crs : in std_ulogic;
407 wishbone_adr : in std_ulogic_vector(29 downto 0);
408 wishbone_dat_w : in std_ulogic_vector(31 downto 0);
409 wishbone_dat_r : out std_ulogic_vector(31 downto 0);
410 wishbone_sel : in std_ulogic_vector(3 downto 0);
411 wishbone_cyc : in std_ulogic;
412 wishbone_stb : in std_ulogic;
413 wishbone_ack : out std_ulogic;
414 wishbone_we : in std_ulogic;
415 wishbone_cti : in std_ulogic_vector(2 downto 0);
416 wishbone_bte : in std_ulogic_vector(1 downto 0);
417 wishbone_err : out std_ulogic;
418 interrupt : out std_ulogic
422 signal wb_eth_cyc : std_ulogic;
423 signal wb_eth_adr : std_ulogic_vector(29 downto 0);
425 -- Change this to use a PLL instead of a BUFR to generate the 25Mhz
426 -- reference clock to the PHY.
427 constant USE_PLL : boolean := false;
429 eth_use_pll: if USE_PLL generate
430 signal eth_clk_25 : std_ulogic;
431 signal eth_clkfb : std_ulogic;
435 BANDWIDTH => "OPTIMIZED",
437 CLKIN1_PERIOD => 10.0,
438 CLKOUT0_DIVIDE => 64,
440 STARTUP_WAIT => "FALSE")
442 CLKOUT0 => eth_clk_25,
448 CLKFBOUT => eth_clkfb,
449 LOCKED => eth_clk_locked,
453 CLKFBIN => eth_clkfb);
462 eth_use_bufr: if not USE_PLL generate
473 eth_clk_locked <= '1';
476 liteeth : liteeth_core
478 sys_clock => system_clk,
479 sys_reset => soc_rst,
480 mii_eth_clocks_tx => eth_clocks_tx,
481 mii_eth_clocks_rx => eth_clocks_rx,
482 mii_eth_rst_n => eth_rst_n,
483 mii_eth_mdio => eth_mdio,
484 mii_eth_mdc => eth_mdc,
485 mii_eth_rx_dv => eth_rx_dv,
486 mii_eth_rx_er => eth_rx_er,
487 mii_eth_rx_data => eth_rx_data,
488 mii_eth_tx_en => eth_tx_en,
489 mii_eth_tx_data => eth_tx_data,
490 mii_eth_col => eth_col,
491 mii_eth_crs => eth_crs,
492 wishbone_adr => wb_eth_adr,
493 wishbone_dat_w => wb_ext_io_in.dat,
494 wishbone_dat_r => wb_eth_out.dat,
495 wishbone_sel => wb_ext_io_in.sel,
496 wishbone_cyc => wb_eth_cyc,
497 wishbone_stb => wb_ext_io_in.stb,
498 wishbone_ack => wb_eth_out.ack,
499 wishbone_we => wb_ext_io_in.we,
500 wishbone_cti => "000",
501 wishbone_bte => "00",
502 wishbone_err => open,
503 interrupt => ext_irq_eth
506 -- Gate cyc with "chip select" from soc
507 wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
509 -- Remove top address bits as liteeth decoder doesn't know about them
510 wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(16 downto 2);
512 -- LiteETH isn't pipelined
513 wb_eth_out.stall <= not wb_eth_out.ack;
517 no_liteeth : if not USE_LITEETH generate
518 eth_clk_locked <= '1';
522 -- Mux WB response on the IO bus
523 wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else wb_dram_ctrl_out;
525 leds_pwm : process(system_clk)
527 if rising_edge(system_clk) then
528 pwm_counter <= std_ulogic_vector(signed(pwm_counter) + 1);
529 if pwm_counter(8 downto 4) = "00000" then
530 led0_b <= led0_b_pwm;
531 led0_r <= led0_r_pwm;
532 led0_g <= led0_g_pwm;
541 led4 <= system_clk_locked;
542 led5 <= eth_clk_locked;
544 led7 <= not spi_flash_cs_n;
546 end architecture behaviour;