library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library mor1kx;
use mor1kx.all;

use work.wishbone_package.all;
use work.mor1kx_pkg.all;

entity mor1kx_vhdl is
	port(
		clk                     : in  std_logic;
		rst                     : in  std_logic;
		-- Data bus wishbone master:
		data_o                  : out wishbone_v3_master_out;
		data_i                  : in  wishbone_v3_master_in;
		-- Instruction bus wishbone master:
		inst_o                  : out wishbone_v3_master_out;
		inst_i                  : in  wishbone_v3_master_in;
		-- IRQ
		irq_i                   : in  std_logic_vector(31 downto 0);
		-- Debug
		debug_o                 : out debug_interface_o;
		debug_i                 : in  debug_interface_i;
		-- Trace Port
		traceport_exec_valid_o  : out std_logic;
		traceport_exec_pc_o     : out std_logic_vector(31 downto 0);
		traceport_exec_insn_o   : out std_logic_vector(OR1K_INSN_WIDTH - 1 downto 0);
		traceport_exec_wbdata_o : out std_logic_vector(OPTION_OPERAND_WIDTH - 1 downto 0);
		traceport_exec_wbreg_o  : out std_logic_vector(OPTION_RF_ADDR_WIDTH - 1 downto 0);
		traceport_exec_wben_o   : out std_logic
	);
end entity mor1kx_vhdl;

architecture RTL of mor1kx_vhdl is
	COMPONENT mor1kx
		GENERIC(OPTION_OPERAND_WIDTH            : INTEGER := 32; OPTION_CPU0 : STRING := "CAPPUCCINO"; FEATURE_DATACACHE : STRING := "NONE"; OPTION_DCACHE_BLOCK_WIDTH : INTEGER := 5;
			    OPTION_DCACHE_SET_WIDTH         : INTEGER := 9; OPTION_DCACHE_WAYS : INTEGER := 2; OPTION_DCACHE_LIMIT_WIDTH : INTEGER := 32; OPTION_DCACHE_SNOOP : STRING := "NONE";
			    FEATURE_DMMU                    : STRING  := "NONE"; FEATURE_DMMU_HW_TLB_RELOAD : STRING := "NONE"; OPTION_DMMU_SET_WIDTH : INTEGER := 6; OPTION_DMMU_WAYS : INTEGER := 1;
			    FEATURE_INSTRUCTIONCACHE        : STRING  := "NONE"; OPTION_ICACHE_BLOCK_WIDTH : INTEGER := 5; OPTION_ICACHE_SET_WIDTH : INTEGER := 9; OPTION_ICACHE_WAYS : INTEGER := 2;
			    OPTION_ICACHE_LIMIT_WIDTH       : INTEGER := 32; FEATURE_IMMU : STRING := "NONE"; FEATURE_IMMU_HW_TLB_RELOAD : STRING := "NONE"; OPTION_IMMU_SET_WIDTH : INTEGER := 6;
			    OPTION_IMMU_WAYS                : INTEGER := 1; FEATURE_TIMER : STRING := "ENABLED"; FEATURE_DEBUGUNIT : STRING := "NONE"; FEATURE_PERFCOUNTERS : STRING := "NONE";
			    FEATURE_MAC                     : STRING  := "NONE"; FEATURE_SYSCALL : STRING := "ENABLED"; FEATURE_TRAP : STRING := "ENABLED"; FEATURE_RANGE : STRING := "ENABLED";
			    FEATURE_PIC                     : STRING  := "ENABLED"; OPTION_PIC_TRIGGER : STRING := "LEVEL"; OPTION_PIC_NMI_WIDTH : INTEGER := 0; FEATURE_DSX : STRING := "ENABLED";
			    FEATURE_OVERFLOW                : STRING  := "ENABLED"; FEATURE_CARRY_FLAG : STRING := "ENABLED"; FEATURE_FASTCONTEXTS : STRING := "NONE"; OPTION_RF_CLEAR_ON_INIT : INTEGER := 0;
			    OPTION_RF_NUM_SHADOW_GPR        : INTEGER := 0; OPTION_RF_ADDR_WIDTH : INTEGER := 5; OPTION_RF_WORDS : INTEGER := 32;
			    -- OPTION_RESET_PC : STD_LOGIC_VECTOR;
			    FEATURE_MULTIPLIER              : STRING  := "THREESTAGE"; FEATURE_DIVIDER : STRING := "SERIAL"; FEATURE_ADDC : STRING := "ENABLED"; FEATURE_SRA : STRING := "ENABLED";
			    FEATURE_ROR                     : STRING  := "NONE"; FEATURE_EXT : STRING := "NONE"; FEATURE_CMOV : STRING := "ENABLED"; FEATURE_FFL1 : STRING := "ENABLED";
			    FEATURE_ATOMIC                  : STRING  := "ENABLED"; FEATURE_CUST1 : STRING := "NONE"; FEATURE_CUST2 : STRING := "NONE"; FEATURE_CUST3 : STRING := "NONE";
			    FEATURE_CUST4                   : STRING  := "NONE"; FEATURE_CUST5 : STRING := "NONE"; FEATURE_CUST6 : STRING := "NONE"; FEATURE_CUST7 : STRING := "NONE";
			    FEATURE_CUST8                   : STRING  := "NONE"; FEATURE_FPU : STRING := "NONE"; OPTION_SHIFTER : STRING := "BARREL"; FEATURE_STORE_BUFFER : STRING := "ENABLED";
			    OPTION_STORE_BUFFER_DEPTH_WIDTH : INTEGER := 8; FEATURE_MULTICORE : STRING := "NONE"; FEATURE_TRACEPORT_EXEC : STRING := "NONE"; BUS_IF_TYPE : STRING := "WISHBONE32";
			    IBUS_WB_TYPE                    : STRING  := "B3_READ_BURSTING"; DBUS_WB_TYPE : STRING := "CLASSIC");
		PORT(
			clk                     : IN  STD_LOGIC;
			rst                     : IN  STD_LOGIC;
			iwbm_adr_o              : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			iwbm_stb_o              : OUT STD_LOGIC;
			iwbm_cyc_o              : OUT STD_LOGIC;
			iwbm_sel_o              : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			iwbm_we_o               : OUT STD_LOGIC;
			iwbm_cti_o              : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
			iwbm_bte_o              : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
			iwbm_dat_o              : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			iwbm_err_i              : IN  STD_LOGIC;
			iwbm_ack_i              : IN  STD_LOGIC;
			iwbm_dat_i              : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
			iwbm_rty_i              : IN  STD_LOGIC;
			dwbm_adr_o              : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			dwbm_stb_o              : OUT STD_LOGIC;
			dwbm_cyc_o              : OUT STD_LOGIC;
			dwbm_sel_o              : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			dwbm_we_o               : OUT STD_LOGIC;
			dwbm_cti_o              : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
			dwbm_bte_o              : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
			dwbm_dat_o              : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			dwbm_err_i              : IN  STD_LOGIC;
			dwbm_ack_i              : IN  STD_LOGIC;
			dwbm_dat_i              : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
			dwbm_rty_i              : IN  STD_LOGIC;
			avm_d_address_o         : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			avm_d_byteenable_o      : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			avm_d_read_o            : OUT STD_LOGIC;
			avm_d_readdata_i        : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
			avm_d_burstcount_o      : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			avm_d_write_o           : OUT STD_LOGIC;
			avm_d_writedata_o       : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			avm_d_waitrequest_i     : IN  STD_LOGIC;
			avm_d_readdatavalid_i   : IN  STD_LOGIC;
			avm_i_address_o         : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			avm_i_byteenable_o      : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			avm_i_read_o            : OUT STD_LOGIC;
			avm_i_readdata_i        : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
			avm_i_burstcount_o      : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			avm_i_waitrequest_i     : IN  STD_LOGIC;
			avm_i_readdatavalid_i   : IN  STD_LOGIC;
			irq_i                   : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
			du_addr_i               : IN  STD_LOGIC_VECTOR(15 DOWNTO 0);
			du_stb_i                : IN  STD_LOGIC;
			du_dat_i                : IN  STD_LOGIC_VECTOR(OPTION_OPERAND_WIDTH - 1 DOWNTO 0);
			du_we_i                 : IN  STD_LOGIC;
			du_dat_o                : OUT STD_LOGIC_VECTOR(OPTION_OPERAND_WIDTH - 1 DOWNTO 0);
			du_ack_o                : OUT STD_LOGIC;
			du_stall_i              : IN  STD_LOGIC;
			du_stall_o              : OUT STD_LOGIC;
			traceport_exec_valid_o  : OUT STD_LOGIC;
			traceport_exec_pc_o     : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			traceport_exec_insn_o   : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
			traceport_exec_wbdata_o : OUT STD_LOGIC_VECTOR(OPTION_OPERAND_WIDTH - 1 DOWNTO 0);
			traceport_exec_wbreg_o  : OUT STD_LOGIC_VECTOR(OPTION_RF_ADDR_WIDTH - 1 DOWNTO 0);
			traceport_exec_wben_o   : OUT STD_LOGIC;
			multicore_coreid_i      : IN  STD_LOGIC_VECTOR(OPTION_OPERAND_WIDTH - 1 DOWNTO 0);
			multicore_numcores_i    : IN  STD_LOGIC_VECTOR(OPTION_OPERAND_WIDTH - 1 DOWNTO 0);
			snoop_adr_i             : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
			snoop_en_i              : IN  STD_LOGIC
		);
	END COMPONENT;

begin
	mor1kx_inst : mor1kx
		generic map(
			OPTION_OPERAND_WIDTH            => OPTION_OPERAND_WIDTH,
			OPTION_CPU0                     => OPTION_CPU0,
			FEATURE_DATACACHE               => FEATURE_DATACACHE,
			OPTION_DCACHE_BLOCK_WIDTH       => OPTION_DCACHE_BLOCK_WIDTH,
			OPTION_DCACHE_SET_WIDTH         => OPTION_DCACHE_SET_WIDTH,
			OPTION_DCACHE_WAYS              => OPTION_DCACHE_WAYS,
			OPTION_DCACHE_LIMIT_WIDTH       => OPTION_DCACHE_LIMIT_WIDTH,
			OPTION_DCACHE_SNOOP             => OPTION_DCACHE_SNOOP,
			FEATURE_DMMU                    => FEATURE_DMMU,
			FEATURE_DMMU_HW_TLB_RELOAD      => FEATURE_DMMU_HW_TLB_RELOAD,
			OPTION_DMMU_SET_WIDTH           => OPTION_DMMU_SET_WIDTH,
			OPTION_DMMU_WAYS                => OPTION_DMMU_WAYS,
			FEATURE_INSTRUCTIONCACHE        => FEATURE_INSTRUCTIONCACHE,
			OPTION_ICACHE_BLOCK_WIDTH       => OPTION_ICACHE_BLOCK_WIDTH,
			OPTION_ICACHE_SET_WIDTH         => OPTION_ICACHE_SET_WIDTH,
			OPTION_ICACHE_WAYS              => OPTION_ICACHE_WAYS,
			OPTION_ICACHE_LIMIT_WIDTH       => OPTION_ICACHE_LIMIT_WIDTH,
			FEATURE_IMMU                    => FEATURE_IMMU,
			FEATURE_IMMU_HW_TLB_RELOAD      => FEATURE_IMMU_HW_TLB_RELOAD,
			OPTION_IMMU_SET_WIDTH           => OPTION_IMMU_SET_WIDTH,
			OPTION_IMMU_WAYS                => OPTION_IMMU_WAYS,
			FEATURE_TIMER                   => FEATURE_TIMER,
			FEATURE_DEBUGUNIT               => FEATURE_DEBUGUNIT,
			FEATURE_PERFCOUNTERS            => FEATURE_PERFCOUNTERS,
			FEATURE_MAC                     => FEATURE_MAC,
			FEATURE_SYSCALL                 => FEATURE_SYSCALL,
			FEATURE_TRAP                    => FEATURE_TRAP,
			FEATURE_RANGE                   => FEATURE_RANGE,
			FEATURE_PIC                     => FEATURE_PIC,
			OPTION_PIC_TRIGGER              => OPTION_PIC_TRIGGER,
			OPTION_PIC_NMI_WIDTH            => OPTION_PIC_NMI_WIDTH,
			FEATURE_DSX                     => FEATURE_DSX,
			FEATURE_OVERFLOW                => FEATURE_OVERFLOW,
			FEATURE_CARRY_FLAG              => FEATURE_CARRY_FLAG,
			FEATURE_FASTCONTEXTS            => FEATURE_FASTCONTEXTS,
			OPTION_RF_CLEAR_ON_INIT         => OPTION_RF_CLEAR_ON_INIT,
			OPTION_RF_NUM_SHADOW_GPR        => OPTION_RF_NUM_SHADOW_GPR,
			OPTION_RF_ADDR_WIDTH            => OPTION_RF_ADDR_WIDTH,
			OPTION_RF_WORDS                 => OPTION_RF_WORDS,
			--			OPTION_RESET_PC                 => OPTION_RESET_PC,
			FEATURE_MULTIPLIER              => FEATURE_MULTIPLIER,
			FEATURE_DIVIDER                 => FEATURE_DIVIDER,
			FEATURE_ADDC                    => FEATURE_ADDC,
			FEATURE_SRA                     => FEATURE_SRA,
			FEATURE_ROR                     => FEATURE_ROR,
			FEATURE_EXT                     => FEATURE_EXT,
			FEATURE_CMOV                    => FEATURE_CMOV,
			FEATURE_FFL1                    => FEATURE_FFL1,
			FEATURE_ATOMIC                  => FEATURE_ATOMIC,
			FEATURE_CUST1                   => FEATURE_CUST1,
			FEATURE_CUST2                   => FEATURE_CUST2,
			FEATURE_CUST3                   => FEATURE_CUST3,
			FEATURE_CUST4                   => FEATURE_CUST4,
			FEATURE_CUST5                   => FEATURE_CUST5,
			FEATURE_CUST6                   => FEATURE_CUST6,
			FEATURE_CUST7                   => FEATURE_CUST7,
			FEATURE_CUST8                   => FEATURE_CUST8,
			FEATURE_FPU                     => FEATURE_FPU,
			OPTION_SHIFTER                  => OPTION_SHIFTER,
			FEATURE_STORE_BUFFER            => FEATURE_STORE_BUFFER,
			OPTION_STORE_BUFFER_DEPTH_WIDTH => OPTION_STORE_BUFFER_DEPTH_WIDTH,
			FEATURE_MULTICORE               => FEATURE_MULTICORE,
			FEATURE_TRACEPORT_EXEC          => FEATURE_TRACEPORT_EXEC,
			BUS_IF_TYPE                     => BUS_IF_TYPE,
			IBUS_WB_TYPE                    => IBUS_WB_TYPE,
			DBUS_WB_TYPE                    => DBUS_WB_TYPE
		)
		port map(
			clk                     => clk,
			rst                     => rst,
			iwbm_adr_o              => inst_o.ADR,
			iwbm_stb_o              => inst_o.STB,
			iwbm_cyc_o              => inst_o.CYC,
			iwbm_sel_o              => inst_o.SEL,
			iwbm_we_o               => inst_o.WE,
			iwbm_cti_o              => inst_o.CTI,
			iwbm_bte_o              => inst_o.BTE,
			iwbm_dat_o              => inst_o.DAT,
			iwbm_err_i              => inst_i.ERR,
			iwbm_ack_i              => inst_i.ACK,
			iwbm_dat_i              => inst_i.DAT,
			iwbm_rty_i              => inst_i.RTY,
			dwbm_adr_o              => data_o.ADR,
			dwbm_stb_o              => data_o.STB,
			dwbm_cyc_o              => data_o.CYC,
			dwbm_sel_o              => data_o.SEL,
			dwbm_we_o               => data_o.WE,
			dwbm_cti_o              => data_o.CTI,
			dwbm_bte_o              => data_o.BTE,
			dwbm_dat_o              => data_o.DAT,
			dwbm_err_i              => data_i.ERR,
			dwbm_ack_i              => data_i.ACK,
			dwbm_dat_i              => data_i.DAT,
			dwbm_rty_i              => data_i.RTY,
			--			avm_d_address_o         => avm_d_address_o,
			--			avm_d_byteenable_o      => avm_d_byteenable_o,
			--			avm_d_read_o            => avm_d_read_o,
			avm_d_readdata_i        => (others => '0'),
			--			avm_d_burstcount_o      => avm_d_burstcount_o,
			--			avm_d_write_o           => avm_d_write_o,
			--			avm_d_writedata_o       => avm_d_writedata_o,
			avm_d_waitrequest_i     => '0',
			avm_d_readdatavalid_i   => '0',
			--			avm_i_address_o         => avm_i_address_o,
			--			avm_i_byteenable_o      => avm_i_byteenable_o,
			--			avm_i_read_o            => avm_i_read_o,
			avm_i_readdata_i        => (others => '0'),
			--			avm_i_burstcount_o      => avm_i_burstcount_o,
			avm_i_waitrequest_i     => '0',
			avm_i_readdatavalid_i   => '0',
			irq_i                   => irq_i,
			du_addr_i               => debug_i.addr,
			du_stb_i                => debug_i.stb,
			du_dat_i                => debug_i.dat,
			du_we_i                 => debug_i.we,
			du_dat_o                => debug_o.dat,
			du_ack_o                => debug_o.ack,
			du_stall_i              => debug_i.stall,
			du_stall_o              => debug_o.stall,
			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,
			multicore_coreid_i      => std_logic_vector(to_unsigned(0, OPTION_OPERAND_WIDTH)),
			multicore_numcores_i    => std_logic_vector(to_unsigned(0, OPTION_OPERAND_WIDTH)),
			snoop_adr_i             => (others => '0'),
			snoop_en_i              => '0'
		);
end architecture RTL;