399 lines
14 KiB
VHDL
399 lines
14 KiB
VHDL
-- -------------------------------------------------------------------------- --
|
|
-- top.vhd: Mor1kx Demo System
|
|
--
|
|
-- Copyright (C) 2017 Markus Koch <markus@notsyncing.net>
|
|
--
|
|
-- 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;
|