----------------------------------------------------------------- -- uCore 1.90 - fpga.vhd -- ----------------------------------------------------------------- -- -- Author: KLAUS SCHLEISIEK -- Last change: KS 10.12.2015 15:13:45 -- -- Do not use this file except in compliance with the License. You may -- obtain a copy of the License at http://www.microcore.org/License/ -- Software distributed under the License is distributed on an "AS IS" basis, -- WITHOUT WARRANTY OF ANY KIND, either express or implied. -- See the License for the specific language governing rights and limitations -- under the License. -- -- The Initial Developer of the Original Code is Klaus.Schleisiek AT microcore.org. -- -- Top level uCore entity with umbilical debug interface. -- This version uses a RS232 interface as umbilical. -- This file should be edited for technology specific additions like e.g. -- pad assignments. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_signed.ALL; USE work.functions.ALL; USE work.constants.ALL; ENTITY fpga IS PORT (reset_n : IN STD_LOGIC; clk_in : IN STD_LOGIC; -- system clock from global clock buffer int_n : IN STD_LOGIC; -- external interrupt input -- io data space io_ce_n : OUT STD_LOGIC; io_we_n : OUT STD_LOGIC; io_oe_n : OUT STD_LOGIC; io_addr : OUT data_addr; io_data : INOUT data_bus; -- umbilical port for debugging rxd : IN STD_LOGIC; -- incoming asynchronous data stream txd : OUT STD_LOGIC -- outgoing data stream ); END fpga; ARCHITECTURE technology OF fpga IS SIGNAL uBus : uBus_port; ALIAS clk : STD_LOGIC IS uBus.clk; ALIAS clk_en : STD_LOGIC IS uBus.clk_en; ALIAS read_en : STD_LOGIC IS uBus.read_en; ALIAS except : STD_LOGIC IS uBus.except; SIGNAL clock : STD_LOGIC; SIGNAL reset : STD_LOGIC; SIGNAL reset_i : STD_LOGIC; SIGNAL rxd_s : STD_LOGIC; COMPONENT microcore PORT (uBus : IN uBus_port; flags : INOUT flag_bus; core : OUT core_signals; ext_memory : OUT datamem_port; ext_din : IN data_bus; dma : IN datamem_port; dma_din : OUT data_bus; -- umbilical debug interface rxd : IN STD_LOGIC; txd : OUT STD_LOGIC ); END COMPONENT; SIGNAL core : core_signals; SIGNAL flags : flag_bus; SIGNAL ctrl : ctrl_bus; SIGNAL datamem : datamem_port; SIGNAL mem_din : data_bus; SIGNAL dma : datamem_port; SIGNAL dma_din : data_bus; SIGNAL io_we : STD_LOGIC; SIGNAL io_oe : STD_LOGIC; SIGNAL io_ce : STD_LOGIC; BEGIN ----------------------------------------------------------------------- -- input signal synchronization ----------------------------------------------------------------------- synch_rxd: synchronise PORT MAP(reset, clk, rxd, rxd_s); synch_interrupt: synchronise_n PORT MAP(reset, clk, int_n, flags(i_ext)); ----------------------------------------------------------------------- -- clk generation (probably a PLL will be used) ----------------------------------------------------------------------- clock <= clk_in; ----------------------------------------------------------------------- -- reset input synchronisation ----------------------------------------------------------------------- reset_sync : PROCESS (reset_n, clk) BEGIN IF reset_n = '0' AND async_reset THEN reset <= '1'; reset_i <= '1'; ELSIF rising_edge(clk) THEN IF reset_n = '0' AND NOT async_reset THEN reset <= '1'; reset_i <= '1'; ELSE reset_i <= '0'; reset <= reset_i; END IF; END IF; END PROCESS reset_sync; ----------------------------------------------------------------------- -- ctrl-register (bitwise) ----------------------------------------------------------------------- with_ctrl: IF ctrl_width /= 0 GENERATE ctrl_set_reset: PROCESS (reset, clk) BEGIN IF reset = '1' AND async_reset THEN ctrl <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN ctrl <= (OTHERS => '0'); ELSE IF uReg_write(uBus, CTRL_REG) AND clk_en = '1' AND except = '0' THEN IF uBus.dout(signbit) = '0' THEN ctrl <= ctrl OR uBus.dout(ctrl_width-1 DOWNTO 0); ELSE ctrl <= ctrl AND uBus.dout(ctrl_width-1 DOWNTO 0); END IF; END IF; END IF; END IF; END PROCESS ctrl_set_reset; flags(f_sema) <= ctrl(c_sema); END GENERATE with_ctrl; no_ctrl: IF ctrl_width = 0 GENERATE ctrl <= (OTHERS => '0'); END GENERATE no_ctrl; ----------------------------------------------------------------------- -- external data memory ----------------------------------------------------------------------- io_ce_n <= NOT io_ce; io_oe_n <= NOT io_oe; io_we_n <= NOT io_we; io_data <= datamem.dout WHEN io_we = '1' ELSE (OTHERS => 'Z'); io_ce <= datamem.enable WHEN datamem.addr(data_addr_width-1 DOWNTO dcache_addr_width) /= 0 ELSE '0'; datamem_clocks: PROCESS (reset, clk) BEGIN IF reset = '1' AND async_reset THEN io_we <= '0'; io_oe <= '0'; ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN io_we <= '0'; io_oe <= '0'; ELSIF clk_en = '1' THEN io_we <= '0'; io_oe <= '0'; ELSIF read_en = '1' AND io_ce = '1' THEN io_we <= datamem.write; io_oe <= NOT datamem.write; END IF; END IF; END PROCESS datamem_clocks; io_address_latch : PROCESS (io_ce, datamem.addr) BEGIN IF io_ce = '1' THEN io_addr <= datamem.addr(data_addr_width-1 DOWNTO 0); END IF; END PROCESS io_address_latch; ----------------------------------------------------------------------- -- microcore interface ----------------------------------------------------------------------- dma.addr <= (OTHERS => '0'); dma.dout <= (OTHERS => '0'); dma.enable <= '0'; dma.write <= '0'; uCore: microcore PORT MAP (uBus => uBus, flags => flags, core => core, ext_memory => datamem, ext_din => io_data, dma => dma, dma_din => dma_din, rxd => rxd_s, txd => txd ); -- control signals uBus.reset <= reset; uBus.clk <= clock; uBus.clk_en <= core.clk_en; uBus.read_en <= core.read_en; uBus.except <= '0'; uBus.delay <= '0'; uBus.tick <= core.tick; -- registers uBus.sources(INT_REG) <= core.int; uBus.sources(TASK_REG) <= core.task; uBus.sources(TIME_REG) <= core.time; uBus.sources(DEBUG_REG) <= core.debug; uBus.sources(FLAG_REG) <= slice('0', data_width-flag_width) & flags; uBus.sources(CTRL_REG) <= slice('0', data_width-ctrl_width) & ctrl; uBus.sources(VERSION_REG) <= to_vec(version, data_width); -- data memory and return stack uBus.enable <= datamem.enable; uBus.write <= datamem.write; uBus.addr <= datamem.addr; uBus.reg_addr <= datamem.reg_addr; uBus.dout <= datamem.dout; uBus.dma <= dma_din; END technology;