2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
6 use work.wishbone_types.all;
10 MEMORY_SIZE : integer := 16384;
11 RAM_INIT_FILE : string := "firmware.hex";
12 RESET_LOW : boolean := true;
13 CLK_INPUT : positive := 125000000;
14 CLK_FREQUENCY : positive := 48000000;
15 HAS_FPU : boolean := true;
16 HAS_BTC : boolean := false;
17 USE_LITEDRAM : boolean := true;
18 NO_BRAM : boolean := true;
19 SCLK_STARTUPE2 : boolean := false;
20 SPI_FLASH_OFFSET : integer := 4194304;
21 SPI_FLASH_DEF_CKDV : natural := 1;
22 SPI_FLASH_DEF_QUAD : boolean := true;
23 LOG_LENGTH : natural := 0;
24 USE_LITEETH : boolean := true;
25 UART_IS_16550 : boolean := true;
26 HAS_UART1 : boolean := false;
27 ICACHE_NUM_LINES : natural := 64
30 ext_clk : in std_ulogic;
31 ext_rst_n : in std_ulogic;
34 uart0_txd : out std_ulogic;
35 uart0_rxd : in std_ulogic;
38 spi_flash_cs_n : out std_ulogic;
39 spi_flash_mosi : inout std_ulogic;
40 spi_flash_miso : inout std_ulogic;
41 spi_flash_wp_n : inout std_ulogic;
42 spi_flash_hold_n : inout std_ulogic;
45 eth_clocks_tx : out std_ulogic;
46 eth_clocks_rx : in std_ulogic;
47 eth_mdio : inout std_ulogic;
48 eth_mdc : out std_ulogic;
49 eth_rx_ctl : in std_ulogic;
50 eth_rx_data : in std_ulogic_vector(3 downto 0);
51 eth_tx_ctl : out std_ulogic;
52 eth_tx_data : out std_ulogic_vector(3 downto 0);
55 ddram_a : out std_ulogic_vector(13 downto 0);
56 ddram_ba : out std_ulogic_vector(2 downto 0);
57 ddram_ras_n : out std_ulogic;
58 ddram_cas_n : out std_ulogic;
59 ddram_we_n : out std_ulogic;
60 ddram_cs_n : out std_ulogic;
61 ddram_dm : out std_ulogic_vector(3 downto 0);
62 ddram_dq : inout std_ulogic_vector(31 downto 0);
63 ddram_dqs_p : inout std_ulogic_vector(3 downto 0);
64 ddram_clk_p : out std_ulogic_vector(1 downto 0);
65 -- only the positive differential pin is instantiated
66 --ddram_dqs_n : inout std_ulogic_vector(3 downto 0);
67 --ddram_clk_n : out std_ulogic_vector(1 downto 0);
68 ddram_cke : out std_ulogic;
69 ddram_odt : out std_ulogic;
70 ddram_reset_n : out std_ulogic
74 architecture behaviour of toplevel is
77 signal soc_rst : std_ulogic;
78 signal pll_rst : std_ulogic;
80 -- Internal clock signals:
81 signal system_clk : std_ulogic;
82 signal system_clk_locked : std_ulogic;
84 -- External IOs from the SoC
85 signal wb_ext_io_in : wb_io_master_out;
86 signal wb_ext_io_out : wb_io_slave_out;
87 signal wb_ext_is_dram_csr : std_ulogic;
88 signal wb_ext_is_dram_init : std_ulogic;
89 signal wb_ext_is_eth : std_ulogic;
91 -- DRAM main data wishbone connection
92 signal wb_dram_in : wishbone_master_out;
93 signal wb_dram_out : wishbone_slave_out;
95 -- DRAM control wishbone connection
96 signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
99 signal ext_irq_eth : std_ulogic;
100 signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
103 signal core_alt_reset : std_ulogic;
106 signal spi_sck : std_ulogic;
107 signal spi_cs_n : std_ulogic;
108 signal spi_sdat_o : std_ulogic_vector(3 downto 0);
109 signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
110 signal spi_sdat_i : std_ulogic_vector(3 downto 0);
112 -- Fixup various memory sizes based on generics
113 function get_bram_size return natural is
115 if USE_LITEDRAM and NO_BRAM then
122 function get_payload_size return natural is
124 if USE_LITEDRAM and NO_BRAM then
131 constant BRAM_SIZE : natural := get_bram_size;
132 constant PAYLOAD_SIZE : natural := get_payload_size;
136 USRMCLKI : IN STD_ULOGIC;
137 USRMCLKTS : IN STD_ULOGIC
140 attribute syn_noprune: boolean ;
141 attribute syn_noprune of USRMCLK: component is true;
146 soc0: entity work.soc
148 MEMORY_SIZE => BRAM_SIZE,
149 RAM_INIT_FILE => RAM_INIT_FILE,
151 CLK_FREQ => CLK_FREQUENCY,
154 HAS_DRAM => USE_LITEDRAM,
155 DRAM_SIZE => 256 * 1024 * 1024,
156 DRAM_INIT_SIZE => PAYLOAD_SIZE,
157 HAS_SPI_FLASH => true,
158 SPI_FLASH_DLINES => 4,
159 SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
160 SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
161 SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
162 LOG_LENGTH => LOG_LENGTH,
163 UART0_IS_16550 => UART_IS_16550,
164 HAS_UART1 => HAS_UART1,
165 ICACHE_NUM_LINES => ICACHE_NUM_LINES
169 system_clk => system_clk,
173 uart0_txd => uart0_txd,
174 uart0_rxd => uart0_rxd,
177 spi_flash_sck => spi_sck,
178 spi_flash_cs_n => spi_cs_n,
179 spi_flash_sdat_o => spi_sdat_o,
180 spi_flash_sdat_oe => spi_sdat_oe,
181 spi_flash_sdat_i => spi_sdat_i,
184 wb_dram_in => wb_dram_in,
185 wb_dram_out => wb_dram_out,
187 -- External interrupts
188 ext_irq_eth => ext_irq_eth,
191 wb_ext_io_in => wb_ext_io_in,
192 wb_ext_io_out => wb_ext_io_out,
193 wb_ext_is_dram_csr => wb_ext_is_dram_csr,
194 wb_ext_is_dram_init => wb_ext_is_dram_init,
195 wb_ext_is_eth => wb_ext_is_eth,
197 alt_reset => core_alt_reset
202 spi_flash_cs_n <= spi_cs_n;
203 spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
204 spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
205 spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
206 spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
207 spi_sdat_i(0) <= spi_flash_mosi;
208 spi_sdat_i(1) <= spi_flash_miso;
209 spi_sdat_i(2) <= spi_flash_wp_n;
210 spi_sdat_i(3) <= spi_flash_hold_n;
212 uclk: USRMCLK port map (
217 nodram: if not USE_LITEDRAM generate
218 signal ddram_clk_dummy : std_ulogic;
220 reset_controller: entity work.soc_reset
222 RESET_LOW => RESET_LOW
226 pll_clk => system_clk,
227 pll_locked_in => system_clk_locked,
228 ext_rst_in => ext_rst_n,
229 pll_rst_out => pll_rst,
233 clkgen: entity work.clock_generator
235 CLK_INPUT_HZ => CLK_INPUT,
236 CLK_OUTPUT_HZ => CLK_FREQUENCY
240 pll_rst_in => pll_rst,
241 pll_clk_out => system_clk,
242 pll_locked_out => system_clk_locked
245 core_alt_reset <= '0';
249 has_dram: if USE_LITEDRAM generate
250 signal dram_init_done : std_ulogic;
251 signal dram_init_error : std_ulogic;
252 signal dram_sys_rst : std_ulogic;
253 signal rst_gen_rst : std_ulogic;
256 -- Eventually dig out the frequency from
257 -- litesdram generate.py sys_clk_freq
258 -- but for now, assert it's 48Mhz for Arctic Tern
259 assert CLK_FREQUENCY = 48000000;
261 reset_controller: entity work.soc_reset
263 RESET_LOW => RESET_LOW,
264 PLL_RESET_BITS => 18,
269 pll_clk => system_clk,
270 pll_locked_in => system_clk_locked,
271 ext_rst_in => ext_rst_n,
272 pll_rst_out => pll_rst,
273 rst_out => rst_gen_rst
276 -- Generate SoC reset
277 soc_rst_gen: process(system_clk)
279 if ext_rst_n = '0' then
281 elsif rising_edge(system_clk) then
282 soc_rst <= dram_sys_rst or not system_clk_locked;
286 dram: entity work.litedram_wrapper
292 DRAM_PORT_WIDTH => 128,
293 NUM_LINES => 8, -- reduce from default of 64 to make smaller/timing
294 PAYLOAD_FILE => RAM_INIT_FILE,
295 PAYLOAD_SIZE => PAYLOAD_SIZE
300 system_clk => system_clk,
301 system_reset => dram_sys_rst,
302 core_alt_reset => core_alt_reset,
303 pll_locked => system_clk_locked,
306 wb_out => wb_dram_out,
307 wb_ctrl_in => wb_ext_io_in,
308 wb_ctrl_out => wb_dram_ctrl_out,
309 wb_ctrl_is_csr => wb_ext_is_dram_csr,
310 wb_ctrl_is_init => wb_ext_is_dram_init,
312 init_done => dram_init_done,
313 init_error => dram_init_error,
316 ddram_ba => ddram_ba,
317 ddram_ras_n => ddram_ras_n,
318 ddram_cas_n => ddram_cas_n,
319 ddram_we_n => ddram_we_n,
320 ddram_cs_n => ddram_cs_n,
321 ddram_dm => ddram_dm,
322 ddram_dq => ddram_dq,
323 ddram_dqs_p => ddram_dqs_p,
324 ddram_clk_p => ddram_clk_p,
325 -- only the positive differential pin is instantiated
326 --ddram_dqs_n => ddram_dqs_n,
327 --ddram_clk_n => ddram_clk_n,
328 ddram_cke => ddram_cke,
329 ddram_odt => ddram_odt,
331 ddram_reset_n => ddram_reset_n
336 has_liteeth : if USE_LITEETH generate
338 component liteeth_core port (
339 sys_clock : in std_ulogic;
340 sys_reset : in std_ulogic;
341 rgmii_eth_clocks_tx : out std_ulogic;
342 rgmii_eth_clocks_rx : in std_ulogic;
343 rgmii_eth_mdio : inout std_ulogic;
344 rgmii_eth_mdc : out std_ulogic;
345 rgmii_eth_rx_ctl : in std_ulogic;
346 rgmii_eth_rx_data : in std_ulogic_vector(3 downto 0);
347 rgmii_eth_tx_ctl : out std_ulogic;
348 rgmii_eth_tx_data : out std_ulogic_vector(3 downto 0);
349 wishbone_adr : in std_ulogic_vector(29 downto 0);
350 wishbone_dat_w : in std_ulogic_vector(31 downto 0);
351 wishbone_dat_r : out std_ulogic_vector(31 downto 0);
352 wishbone_sel : in std_ulogic_vector(3 downto 0);
353 wishbone_cyc : in std_ulogic;
354 wishbone_stb : in std_ulogic;
355 wishbone_ack : out std_ulogic;
356 wishbone_we : in std_ulogic;
357 wishbone_cti : in std_ulogic_vector(2 downto 0);
358 wishbone_bte : in std_ulogic_vector(1 downto 0);
359 wishbone_err : out std_ulogic;
360 interrupt : out std_ulogic
364 signal wb_eth_cyc : std_ulogic;
365 signal wb_eth_adr : std_ulogic_vector(29 downto 0);
368 liteeth : liteeth_core
370 sys_clock => system_clk,
371 sys_reset => soc_rst,
372 rgmii_eth_clocks_tx => eth_clocks_tx,
373 rgmii_eth_clocks_rx => eth_clocks_rx,
374 rgmii_eth_mdio => eth_mdio,
375 rgmii_eth_mdc => eth_mdc,
376 rgmii_eth_rx_ctl => eth_rx_ctl,
377 rgmii_eth_rx_data => eth_rx_data,
378 rgmii_eth_tx_ctl => eth_tx_ctl,
379 rgmii_eth_tx_data => eth_tx_data,
380 wishbone_adr => wb_eth_adr,
381 wishbone_dat_w => wb_ext_io_in.dat,
382 wishbone_dat_r => wb_eth_out.dat,
383 wishbone_sel => wb_ext_io_in.sel,
384 wishbone_cyc => wb_eth_cyc,
385 wishbone_stb => wb_ext_io_in.stb,
386 wishbone_ack => wb_eth_out.ack,
387 wishbone_we => wb_ext_io_in.we,
388 wishbone_cti => "000",
389 wishbone_bte => "00",
390 wishbone_err => open,
391 interrupt => ext_irq_eth
394 -- Gate cyc with "chip select" from soc
395 wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
397 -- Remove top address bits as liteeth decoder doesn't know about them
398 wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(14 downto 0);
400 -- LiteETH isn't pipelined
401 wb_eth_out.stall <= not wb_eth_out.ack;
405 no_liteeth : if not USE_LITEETH generate
409 -- Mux WB response on the IO bus
410 wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
413 end architecture behaviour;