-- -------------------------------------------------------------------------- -- -- top.vhd: Mor1kx Demo System -- -- Copyright (C) 2017 Markus Koch -- -- This Source Code Form is subject to the terms of the Mozilla Public -- License, v. 2.0. If a copy of the MPL was not distributed with this -- file, You can obtain one at http://mozilla.org/MPL/2.0/. -- -------------------------------------------------------------------------- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library ddr3; library ip; use ip.wishbone_package.all; use ip.mor1kx_pkg.all; entity top is port( clk_hw : in std_logic; rst_hw : in std_logic; -- GPIO GPIOA : inout std_logic_vector(wishbone_data_width - 1 downto 0); -- JINN jinn_uart_rx : in std_logic; jinn_uart_tx : out std_logic; -- UART uart_rx : in std_logic; uart_tx : out std_logic; -- DDR3 RAM mem_a : out std_logic_vector(12 downto 0); -- memory.mem_a mem_ba : out std_logic_vector(2 downto 0); -- .mem_ba mem_ck : out std_logic_vector(0 downto 0); -- .mem_ck mem_ck_n : out std_logic_vector(0 downto 0); -- .mem_ck_n mem_cke : out std_logic_vector(0 downto 0); -- .mem_cke mem_cs_n : out std_logic_vector(0 downto 0); -- .mem_cs_n mem_dm : out std_logic_vector(1 downto 0); -- .mem_dm mem_ras_n : out std_logic_vector(0 downto 0); -- .mem_ras_n mem_cas_n : out std_logic_vector(0 downto 0); -- .mem_cas_n mem_we_n : out std_logic_vector(0 downto 0); -- .mem_we_n mem_reset_n : out std_logic; -- .mem_reset_n mem_dq : inout std_logic_vector(15 downto 0) := (others => '0'); -- .mem_dq mem_dqs : inout std_logic_vector(1 downto 0) := (others => '0'); -- .mem_dqs mem_dqs_n : inout std_logic_vector(1 downto 0) := (others => '0'); -- .mem_dqs_n mem_odt : out std_logic_vector(0 downto 0); -- .mem_odt oct_rzqin : in std_logic; -- oct.rzqin -- SPI Flash Hardware Signals flash_si : out std_logic; -- spi serial in flash_so : in std_logic; -- spi serial out flash_sck : out std_logic; -- spi clock flash_reset_n : out std_logic; -- spi hard reset flash_cs_n : out std_logic; -- spi chip select flash_wp_n : out std_logic -- spi write protect ); end entity top; architecture RTL of top is constant debug_baud : natural := 460800; constant F_CPU : natural := 50000000; -- WB config constant masters : natural := 3; constant slaves : natural := 4; --constant INTERCON_ID_SRAM : natural := 0; constant INTERCON_ID_DDR3 : natural := 0; constant INTERCON_ID_FLASH : natural := 1; constant INTERCON_ID_GPIO : natural := 2; constant INTERCON_ID_UART : natural := 3; -- constant INTERCON_ID_NS16550 : natural := 4; constant in_simulation : boolean := false --pragma synthesis_off or true --pragma synthesis_on ; constant in_synthesis : boolean := not in_simulation; signal clk : std_logic; signal rst : std_logic; signal interrupt : std_logic_vector(32 - 1 downto 0); signal intercon_slave_i : wishbone_v3_slave_in_vector(slaves - 1 downto 0); signal intercon_slave_o : wishbone_v3_slave_out_vector(slaves - 1 downto 0); signal intercon_master_i : wishbone_v3_master_in_vector(masters - 1 downto 0); signal intercon_master_o : wishbone_v3_master_out_vector(masters - 1 downto 0); signal pll_locked : std_logic; signal rst_ddr3_n : std_logic; signal debug_o : debug_interface_o; signal debug_i : debug_interface_i; signal traceport_exec_valid_o : std_logic; signal traceport_exec_pc_o : std_logic_vector(31 downto 0); signal traceport_exec_insn_o : std_logic_vector(OR1K_INSN_WIDTH - 1 downto 0); signal traceport_exec_wbdata_o : std_logic_vector(OPTION_OPERAND_WIDTH - 1 downto 0); signal traceport_exec_wbreg_o : std_logic_vector(OPTION_RF_ADDR_WIDTH - 1 downto 0); signal traceport_exec_wben_o : std_logic; signal mor1kx_rst : std_logic; signal jinn_data_i : std_logic_vector(7 downto 0); signal jinn_data_available : std_logic; signal jinn_data_o : std_logic_vector(7 downto 0); signal jinn_data_valid_o : std_logic; signal jinn_uart_busy_i : std_logic; signal avl_ready_0 : std_logic; signal avl_burstbegin_0 : std_logic; signal avl_addr_0 : std_logic_vector(24 downto 0); signal avl_rdata_valid_0 : std_logic; signal avl_rdata_0 : std_logic_vector(31 downto 0); signal avl_wdata_0 : std_logic_vector(31 downto 0); signal avl_be_0 : std_logic_vector(3 downto 0); signal avl_read_req_0 : std_logic; signal avl_write_req_0 : std_logic; signal avl_size_0 : std_logic_vector(2 downto 0); signal local_init_done : std_logic; -- status.local_init_done signal local_cal_success : std_logic; -- .local_cal_success signal local_cal_fail : std_logic; -- .local_cal_fail signal avl_reqEn : std_logic; signal writeAck : std_logic; signal readAck : std_logic; begin debug_i.addr <= (others => '0'); debug_i.dat <= (others => '0'); debug_i.stb <= '1'; debug_i.we <= '0'; -- System controller resetSync : process(clk, rst_hw) is begin if rst_hw = '0' then -- low active rst <= '1'; rst_ddr3_n <= '0'; elsif rising_edge(clk) then if pll_locked = '1' then rst_ddr3_n <= '1'; -- Start DDR3 Controller if (local_init_done = '1' and local_cal_success = '1') or in_simulation then rst <= '0'; -- Start system! end if; end if; end if; end process resetSync; -- Clock management clk <= clk_hw; pll_locked <= '1'; -- SRAM -- sram_wb_inst : entity work.sram_wb -- port map( -- clk => clk, -- rst => rst, -- wb_in => intercon_slave_i(INTERCON_ID_SRAM), -- wb_out => intercon_slave_o(INTERCON_ID_SRAM) -- ); -- CPU (boots to 0x000 instead of 0x100) interrupt <= (others => '0'); mor1kx_vhdl_inst : entity ip.mor1kx_vhdl port map( clk => clk, rst => mor1kx_rst or GPIOA(10), data_o => intercon_master_o(1), data_i => intercon_master_i(1), inst_o => intercon_master_o(0), inst_i => intercon_master_i(0), irq_i => interrupt, debug_o => debug_o, debug_i => debug_i, traceport_exec_valid_o => traceport_exec_valid_o, traceport_exec_pc_o => traceport_exec_pc_o, traceport_exec_insn_o => traceport_exec_insn_o, traceport_exec_wbdata_o => traceport_exec_wbdata_o, traceport_exec_wbreg_o => traceport_exec_wbreg_o, traceport_exec_wben_o => traceport_exec_wben_o ); -- Debug interface jinn_inst : entity work.jinn port map( clk_i => clk, rst_i => rst, master_i => intercon_master_i(2), master_o => intercon_master_o(2), cpu_stall => debug_i.stall, cpu_reset => mor1kx_rst, data_i => jinn_data_i, data_available => jinn_data_available, data_o => jinn_data_o, data_valid_o => jinn_data_valid_o, output_busy_i => jinn_uart_busy_i ); uart_rx_inst : entity work.uart_rx port map( clk => clk, rst => rst, data => jinn_data_i, byte_ready => jinn_data_available, error => open, ckDiv => std_logic_vector(to_unsigned(F_CPU / debug_baud - 1, 16)), parityEnable => '0', parityOdd => '0', twoStopBits => '0', rx => jinn_uart_rx ); uart_tx_inst : entity work.uart_tx port map( clk => clk, rst => rst, data => jinn_data_o, byte_ready => jinn_data_valid_o, busy => jinn_uart_busy_i, ckDiv => std_logic_vector(to_unsigned(F_CPU / debug_baud - 1, 16)), parityEnable => '0', parityOdd => '0', twoStopBits => '0', tx => jinn_uart_tx ); -- DDR3 RAM ddr3_inst : entity ddr3.ddr3 port map( pll_ref_clk => clk, global_reset_n => rst_hw, soft_reset_n => '1', afi_clk => open, afi_half_clk => open, afi_reset_n => open, afi_reset_export_n => open, mem_a => mem_a, mem_ba => mem_ba, mem_ck => mem_ck, mem_ck_n => mem_ck_n, mem_cke => mem_cke, mem_cs_n => mem_cs_n, mem_dm => mem_dm, mem_ras_n => mem_ras_n, mem_cas_n => mem_cas_n, mem_we_n => mem_we_n, mem_reset_n => mem_reset_n, mem_dq => mem_dq, mem_dqs => mem_dqs, mem_dqs_n => mem_dqs_n, mem_odt => mem_odt, avl_ready_0 => avl_ready_0, avl_burstbegin_0 => avl_burstbegin_0, avl_addr_0 => avl_addr_0, avl_rdata_valid_0 => avl_rdata_valid_0, avl_rdata_0 => avl_rdata_0, avl_wdata_0 => avl_wdata_0, avl_be_0 => avl_be_0, avl_read_req_0 => avl_read_req_0, avl_write_req_0 => avl_write_req_0, avl_size_0 => avl_size_0, mp_cmd_clk_0_clk => clk, mp_cmd_reset_n_0_reset_n => rst_hw, mp_rfifo_clk_0_clk => clk, mp_rfifo_reset_n_0_reset_n => rst_hw, mp_wfifo_clk_0_clk => clk, mp_wfifo_reset_n_0_reset_n => rst_hw, local_init_done => local_init_done, local_cal_success => local_cal_success, local_cal_fail => local_cal_fail, oct_rzqin => oct_rzqin, pll_mem_clk => open, pll_write_clk => open, pll_locked => open, pll_write_clk_pre_phy_clk => open, pll_addr_cmd_clk => open, pll_avl_clk => open, pll_config_clk => open, pll_mem_phy_clk => open, afi_phy_clk => open, pll_avl_phy_clk => open, csr_clk => clk, csr_reset_n => rst_hw ); avl_addr_0 <= intercon_slave_i(INTERCON_ID_DDR3).ADR(26 downto 2); -- & "00"; avl_be_0 <= intercon_slave_i(INTERCON_ID_DDR3).SEL; avl_burstbegin_0 <= '0'; avl_wdata_0 <= intercon_slave_i(INTERCON_ID_DDR3).DAT; avl_read_req_0 <= (intercon_slave_i(INTERCON_ID_DDR3).STB and (not intercon_slave_i(INTERCON_ID_DDR3).WE)) and avl_reqEn; avl_write_req_0 <= (intercon_slave_i(INTERCON_ID_DDR3).STB and intercon_slave_i(INTERCON_ID_DDR3).WE) and avl_reqEn; avl_size_0 <= "001"; --intercon_slave_o(INTERCON_ID_DDR3).DAT <= avl_rdata_0; -- DDR3 first words include boot rom code ddr3_mem_data : with intercon_slave_i(INTERCON_ID_DDR3).ADR select intercon_slave_o(INTERCON_ID_DDR3).DAT <= x"18604000" when x"00000000", --x"18600200" when x"00000000", x"a8630100" when x"00000004", x"44001800" when x"00000008", x"15000000" when x"0000000c", avl_rdata_0 when others; -- nop intercon_slave_o(INTERCON_ID_DDR3).ERR <= '0'; intercon_slave_o(INTERCON_ID_DDR3).RTY <= '0'; intercon_slave_o(INTERCON_ID_DDR3).ACK <= (readAck or writeAck) and intercon_slave_i(INTERCON_ID_DDR3).STB; readAck <= avl_rdata_valid_0; --(avl_rdata_valid_0 and not intercon_slave_i(INTERCON_ID_SRAM).WE); writeAck <= (intercon_slave_i(INTERCON_ID_DDR3).WE and avl_ready_0); wb2avl : process(clk, rst) is begin if rst = '1' then avl_reqEn <= '1'; elsif rising_edge(clk) then if intercon_slave_i(INTERCON_ID_DDR3).STB = '1' and not intercon_slave_o(INTERCON_ID_DDR3).ACK = '1' then avl_reqEn <= '0'; else avl_reqEn <= '1'; end if; end if; end process wb2avl; -- Non Volatile Memory flashrom_wb_inst : entity work.flashrom_wb port map( dbg_allow_write => not GPIOA(11), clk => clk, rst => rst, clr => '0', wb_in => intercon_slave_i(INTERCON_ID_FLASH), wb_out => intercon_slave_o(INTERCON_ID_FLASH), spi_si => flash_si, spi_so => flash_so, spi_sck => flash_sck, spi_reset_n => flash_reset_n, spi_cs_n => flash_cs_n, spi_wp_n => flash_wp_n ); -- GPIO gpio_inst : entity work.gpio port map( clk => clk, rst => rst, clr => '0', wb_in => intercon_slave_i(INTERCON_ID_GPIO), wb_out => intercon_slave_o(INTERCON_ID_GPIO), gpio => GPIOA ); -- UART uart_wb_inst : entity work.uart_wb generic map( portcount => 1 ) port map( clk => clk, rst => rst, slave_i => intercon_slave_i(INTERCON_ID_UART), slave_o => intercon_slave_o(INTERCON_ID_UART), irq_o => open, -- TODO rx(0) => uart_rx, tx(0) => uart_tx ); -- Intercon crossbar_inst : entity ip.crossbar generic map( masters => masters, slaves => slaves, async => true ) port map( clk => clk, rst => rst, slave_i => intercon_master_o, slave_o => intercon_master_i, master_i => intercon_slave_o, master_o => intercon_slave_i, address => ( INTERCON_ID_DDR3 => x"00000000", INTERCON_ID_FLASH => x"40000000", INTERCON_ID_GPIO => x"C0000000", INTERCON_ID_UART => x"C0000100" ), mask => ( INTERCON_ID_DDR3 => x"f0000000", INTERCON_ID_FLASH => x"ffc00000", INTERCON_ID_GPIO => x"fffffff0", INTERCON_ID_UART => x"ffffffc0" ) ); end architecture RTL;