OpenCores
URL https://opencores.org/ocsvn/forth-cpu/forth-cpu/trunk

Subversion Repositories forth-cpu

[/] [forth-cpu/] [trunk/] [core.vhd] - Diff between revs 3 and 5

Show entire file | Details | Blame | View Log

Rev 3 Rev 5
Line 5... Line 5...
--| @author     Richard James Howe.
--| @author     Richard James Howe.
--| @copyright  Copyright 2013,2017 Richard James Howe.
--| @copyright  Copyright 2013,2017 Richard James Howe.
--| @license    MIT
--| @license    MIT
--| @email      howe.r.j.89@gmail.com
--| @email      howe.r.j.89@gmail.com
--|
--|
--| @todo Make a test bench for the H2 core for executing small sections of
 
--| code, in succession, and testing the response. 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
 
 
library ieee,work;
library ieee,work;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use work.util.n_bits;
use work.util.n_bits;
 
use work.util.common_generics;
use work.h2_pkg.all;
use work.h2_pkg.all;
 
 
package core_pkg is
package core_pkg is
        type cpu_debug_interface is record
        type cpu_debug_interface is record
                pc:        address;
                pc:        address;
Line 26... Line 25...
                dout:      word;
                dout:      word;
                daddr:     address;
                daddr:     address;
        end record;
        end record;
 
 
        component core is
        component core is
        generic(number_of_interrupts: positive := 8);
        generic(g: common_generics; number_of_interrupts: positive := 8);
        port(
        port(
                -- synthesis translate_off
                -- synthesis translate_off
                debug:           out cpu_debug_interface;
                debug:           out cpu_debug_interface;
                -- synthesis translate_on
                -- synthesis translate_on
 
 
Line 44... Line 43...
                io_din:          in   word;
                io_din:          in   word;
                io_dout:         out  word:= (others => 'X');
                io_dout:         out  word:= (others => 'X');
                io_daddr:        out  word:= (others => 'X');
                io_daddr:        out  word:= (others => 'X');
 
 
                -- Interrupts
                -- Interrupts
                cpu_irq:         in std_ulogic;
 
                cpu_irc:         in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc:         in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc_mask:    in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc_mask:    in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc_mask_we: in std_ulogic);
                cpu_irc_mask_we: in std_ulogic);
        end component;
        end component;
 
 
        component interrupt_request_handler is
        component interrupt_request_handler is
        generic(
        generic(
 
                g: common_generics;
                number_of_interrupts:   positive := 8;
                number_of_interrupts:   positive := 8;
                lowest_interrupt_first: boolean  := true);
                lowest_interrupt_first: boolean  := true);
        port(
        port(
                clk:     in  std_ulogic;
                clk:     in  std_ulogic;
                rst:     in  std_ulogic;
                rst:     in  std_ulogic;
Line 70... Line 69...
                addr_o:  out std_ulogic_vector(n_bits(number_of_interrupts) - 1 downto 0));
                addr_o:  out std_ulogic_vector(n_bits(number_of_interrupts) - 1 downto 0));
        end component;
        end component;
end package;
end package;
 
 
----- CPU ----------------------------------------------------------------------
----- CPU ----------------------------------------------------------------------
 
 
library ieee,work;
library ieee,work;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use work.util.n_bits;
 
use work.core_pkg.all;
use work.core_pkg.all;
use work.h2_pkg.all;
use work.h2_pkg.all;
 
use work.util.n_bits;
 
use work.util.common_generics;
use work.util.file_format;
use work.util.file_format;
use work.util.FILE_HEX;
use work.util.file_hex;
 
use work.util.or_reduce;
 
 
entity core is
entity core is
        generic(number_of_interrupts: positive := 8);
        generic(g: common_generics; number_of_interrupts: positive := 8);
        port(
        port(
                -- synthesis translate_off
                -- synthesis translate_off
                debug:           out cpu_debug_interface;
                debug:           out cpu_debug_interface;
                -- synthesis translate_on
                -- synthesis translate_on
 
 
Line 98... Line 98...
                io_din:          in   word;
                io_din:          in   word;
                io_dout:         out  word := (others => 'X');
                io_dout:         out  word := (others => 'X');
                io_daddr:        out  word := (others => 'X');
                io_daddr:        out  word := (others => 'X');
 
 
                -- Interrupts
                -- Interrupts
                cpu_irq:         in std_ulogic;
 
                cpu_irc:         in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc:         in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc_mask:    in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc_mask:    in std_ulogic_vector(number_of_interrupts - 1 downto 0);
                cpu_irc_mask_we: in std_ulogic);
                cpu_irc_mask_we: in std_ulogic);
end;
end;
 
 
architecture structural of core is
architecture structural of core is
        constant interrupt_address_length: natural     := n_bits(number_of_interrupts);
        constant interrupt_address_length: natural     := n_bits(number_of_interrupts);
        constant file_name:                string      := "h2.hex";
        constant file_name:                string      := "h2.hex";
        constant file_type:                file_format := FILE_HEX;
        constant file_type:                file_format := file_hex;
 
 
        signal pc:    address   := (others => '0'); -- Program counter
        signal pc:    address   := (others => '0'); -- Program counter
        signal insn:  word      := (others => '0'); -- Instruction issued by program counter
        signal insn:  word      := (others => '0'); -- Instruction issued by program counter
        signal dwe:   std_ulogic := '0'; -- Write enable
        signal dwe:   std_ulogic := '0'; -- Write enable
        signal dre:   std_ulogic := '0'; -- Read enable
        signal dre:   std_ulogic := '0'; -- Read enable
        signal din:   word      := (others => '0');
        signal din:   word      := (others => '0');
        signal dout:  word      := (others => '0');
        signal dout:  word      := (others => '0');
        signal daddr: address   := (others => '0');
        signal daddr: address   := (others => '0');
 
        signal irc_edges:    std_ulogic_vector(cpu_irc'range) := (others => '0');
 
        signal irq_edges:    std_ulogic := '0';
        signal h2_irq:       std_ulogic := '0';
        signal h2_irq:       std_ulogic := '0';
        signal h2_irq_addr:  std_ulogic_vector(interrupt_address_length - 1 downto 0) := (others=>'0');
        signal h2_irq_addr:  std_ulogic_vector(interrupt_address_length - 1 downto 0) := (others=>'0');
begin
begin
        -- synthesis translate_off
        -- synthesis translate_off
        debug.pc    <= pc;
        debug.pc    <= pc;
Line 130... Line 129...
        debug.din   <= din;
        debug.din   <= din;
        debug.dout  <= dout;
        debug.dout  <= dout;
        debug.daddr <= daddr;
        debug.daddr <= daddr;
        -- synthesis translate_on
        -- synthesis translate_on
 
 
 
        -- Ensure all interrupts occur are rising edge triggered
 
        edges: work.util.rising_edge_detectors
 
        generic map(g => g, N => cpu_irc'length)
 
        port map(
 
                clk   => clk,
 
                rst   => rst,
 
                di    => cpu_irc,
 
                do    => irc_edges);
 
 
 
        irq_edges <= or_reduce(irc_edges);
 
 
        irqh_0: work.core_pkg.interrupt_request_handler
        irqh_0: work.core_pkg.interrupt_request_handler
        generic map(number_of_interrupts => number_of_interrupts)
        generic map(g => g, number_of_interrupts => number_of_interrupts)
        port map(
        port map(
                clk    => clk,
                clk    => clk,
                rst    => rst,
                rst    => rst,
 
 
                irq_i  => cpu_irq,
                irq_i  => irq_edges,
                irc_i  => cpu_irc,
                irc_i  => irc_edges,
 
 
                irq_o  => h2_irq,
                irq_o  => h2_irq,
                addr_o => h2_irq_addr,
                addr_o => h2_irq_addr,
 
 
                mask    => cpu_irc_mask,
                mask    => cpu_irc_mask,
                mask_we => cpu_irc_mask_we);
                mask_we => cpu_irc_mask_we);
 
 
        h2_0: work.h2_pkg.h2 -- The actual CPU instance (H2)
        h2_0: work.h2_pkg.h2 -- The actual CPU instance (H2)
        generic map(interrupt_address_length => interrupt_address_length)
        generic map(asynchronous_reset => g.asynchronous_reset, delay => g.delay, interrupt_address_length => interrupt_address_length)
        port map(
        port map(
                clk       =>    clk,
                clk       =>    clk,
                rst       =>    rst,
                rst       =>    rst,
 
 
                -- External interface with the 'outside world'
                -- External interface with the 'outside world'
Line 174... Line 184...
                dout      =>  dout,
                dout      =>  dout,
                daddr     =>  daddr);
                daddr     =>  daddr);
 
 
        mem_h2_0: entity work.dual_port_block_ram
        mem_h2_0: entity work.dual_port_block_ram
        generic map(
        generic map(
 
                g             => g,
                addr_length   => address'length,
                addr_length   => address'length,
                data_length   => word'length,
                data_length   => word'length,
                file_name     => file_name,
                file_name     => file_name,
                file_type     => file_type)
                file_type     => file_type)
        port map(
        port map(
Line 202... Line 213...
--| @brief Interrupt request handler, while the CPU can handle interrupts
--| @brief Interrupt request handler, while the CPU can handle interrupts
--|        it does not to a good job of it. This allows customization of
--|        it does not to a good job of it. This allows customization of
--|        priority.
--|        priority.
--|
--|
--| @author     Richard James Howe.
--| @author     Richard James Howe.
--| @copyright  Copyright 2017 Richard James Howe.
--| @copyright  Copyright 2017, 2019 Richard James Howe.
--| @license    MIT
--| @license    MIT
--| @email      howe.r.j.89@gmail.com
--| @email      howe.r.j.89@gmail.com
--|
--|
--| This is a simple interrupt handler, interrupts are decoded in priority
--| This is a simple interrupt handler, interrupts are decoded in priority
--| order which can be set by a generic. If an interrupt occurs and then
--| order which can be set by a generic. If an interrupt occurs and then
--| another interrupt of the same type occurs before it has been processed
--| another interrupt of occurs before it has been processed the second
--| the second interrupt will be lost.
--| interrupt will be lost.
--|
--|
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
 
 
library ieee,work;
library ieee,work;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
Line 221... Line 232...
use ieee.math_real.all; -- only needed for calculations relating to generics
use ieee.math_real.all; -- only needed for calculations relating to generics
use work.util.reg;
use work.util.reg;
use work.util.n_bits;
use work.util.n_bits;
use work.util.select_bit;
use work.util.select_bit;
use work.util.priority;
use work.util.priority;
 
use work.util.common_generics;
 
 
entity interrupt_request_handler is
entity interrupt_request_handler is
        generic(
        generic(
 
                g: common_generics;
                number_of_interrupts:   positive := 8;
                number_of_interrupts:   positive := 8;
                lowest_interrupt_first: boolean  := true);
                lowest_interrupt_first: boolean  := true);
        port(
        port(
                clk:     in  std_ulogic;
                clk:     in  std_ulogic;
                rst:     in  std_ulogic;
                rst:     in  std_ulogic;
Line 250... Line 263...
        signal addr:  std_ulogic_vector(addr_length - 1 downto 0) := (others => '0');
        signal addr:  std_ulogic_vector(addr_length - 1 downto 0) := (others => '0');
        signal irq:   std_ulogic := '0';
        signal irq:   std_ulogic := '0';
 
 
        signal mask_n: std_ulogic_vector(mask'range) := (others => '0');
        signal mask_n: std_ulogic_vector(mask'range) := (others => '0');
begin
begin
 
 
        irq_in: entity work.reg
        irq_in: entity work.reg
                generic map(
                generic map(g => g, N  => 1)
                        N      => 1)
 
                port map(
                port map(
                        clk    =>  clk,
                        clk    =>  clk,
                        rst    =>  rst,
                        rst    =>  rst,
                        we     =>  '1',
                        we     =>  '1',
                        di(0)  =>  irq_i,
                        di(0)  =>  irq_i,
                        do(0)  =>  irq_n);
                        do(0)  =>  irq_n);
 
 
        irc_in: entity work.reg
        irc_in: entity work.reg
                generic map(
                generic map(g => g, N  => number_of_interrupts)
                        N    => number_of_interrupts)
 
                port map(
                port map(
                        clk  =>  clk,
                        clk  =>  clk,
                        rst  =>  rst,
                        rst  =>  rst,
                        we   =>  '1',
                        we   =>  '1',
                        di   =>  irc_i,
                        di   =>  irc_i,
                        do   =>  irc_n);
                        do   =>  irc_n);
 
 
        irc_mask: entity work.reg generic map(
        irc_mask: entity work.reg generic map(g => g, N  => number_of_interrupts)
                        N    => number_of_interrupts)
 
                port map(
                port map(
                        clk  =>  clk,
                        clk  =>  clk,
                        rst  =>  rst,
                        rst  =>  rst,
                        we   =>  mask_we,
                        we   =>  mask_we,
                        di   =>  mask,
                        di   =>  mask,
Line 284... Line 293...
 
 
        process(irc_n, irq_n, mask_n)
        process(irc_n, irq_n, mask_n)
                variable addr_n: std_ulogic_vector(addr'range) := (others => '0');
                variable addr_n: std_ulogic_vector(addr'range) := (others => '0');
        begin
        begin
                addr_n := priority(irc_n, not lowest_interrupt_first);
                addr_n := priority(irc_n, not lowest_interrupt_first);
                addr <= addr_n;
                addr_o <= addr_n after g.delay;
                if select_bit(mask_n, addr_n) = '1' then
                if select_bit(mask_n, addr_n) = '1' then
                        irq <= irq_n;
                        irq_o <= irq_n after g.delay;
                else
                else
                        irq <= '0';
                        irq_o <= '0' after g.delay;
                end if;
                end if;
        end process;
        end process;
 
 
        irq_out: entity work.reg
 
                generic map(
 
                        N      => 1)
 
                port map(
 
                        clk    =>  clk,
 
                        rst    =>  rst,
 
                        we     =>  '1',
 
                        di(0)  =>  irq,
 
                        do(0)  =>  irq_o);
 
 
 
        addr_out: entity work.reg
 
                generic map(
 
                        N      => addr_length)
 
                port map(
 
                        clk    =>  clk,
 
                        rst    =>  rst,
 
                        we     =>  '1',
 
                        di     =>  addr,
 
                        do     =>  addr_o);
 
 
 
end architecture;
end architecture;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.