OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu.vhd] - Diff between revs 45 and 47

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 45 Rev 47
Line 71... Line 71...
    FAST_SHIFT_EN                : boolean := false; -- use barrel shifter for shift operations
    FAST_SHIFT_EN                : boolean := false; -- use barrel shifter for shift operations
    -- Physical Memory Protection (PMP) --
    -- Physical Memory Protection (PMP) --
    PMP_NUM_REGIONS              : natural := 0; -- number of regions (0..64)
    PMP_NUM_REGIONS              : natural := 0; -- number of regions (0..64)
    PMP_MIN_GRANULARITY          : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
    PMP_MIN_GRANULARITY          : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
    -- Hardware Performance Monitors (HPM) --
    -- Hardware Performance Monitors (HPM) --
    HPM_NUM_CNTS                 : natural := 0      -- number of inmplemnted HPM counters (0..29)
    HPM_NUM_CNTS                 : natural := 0      -- number of implemented HPM counters (0..29)
  );
  );
  port (
  port (
    -- global control --
    -- global control --
    clk_i          : in  std_ulogic := '0'; -- global clock, rising edge
    clk_i          : in  std_ulogic := '0'; -- global clock, rising edge
    rstn_i         : in  std_ulogic := '0'; -- global reset, low-active, async
    rstn_i         : in  std_ulogic := '0'; -- global reset, low-active, async
 
    sleep_o        : out std_ulogic; -- cpu is in sleep mode when set
    -- instruction bus interface --
    -- instruction bus interface --
    i_bus_addr_o   : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
    i_bus_addr_o   : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
    i_bus_rdata_i  : in  std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
    i_bus_rdata_i  : in  std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
    i_bus_wdata_o  : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
    i_bus_wdata_o  : out std_ulogic_vector(data_width_c-1 downto 0); -- bus write data
    i_bus_ben_o    : out std_ulogic_vector(03 downto 0); -- byte enable
    i_bus_ben_o    : out std_ulogic_vector(03 downto 0); -- byte enable
Line 110... Line 111...
    -- interrupts (risc-v compliant) --
    -- interrupts (risc-v compliant) --
    msw_irq_i      : in  std_ulogic := '0'; -- machine software interrupt
    msw_irq_i      : in  std_ulogic := '0'; -- machine software interrupt
    mext_irq_i     : in  std_ulogic := '0'; -- machine external interrupt
    mext_irq_i     : in  std_ulogic := '0'; -- machine external interrupt
    mtime_irq_i    : in  std_ulogic := '0'; -- machine timer interrupt
    mtime_irq_i    : in  std_ulogic := '0'; -- machine timer interrupt
    -- fast interrupts (custom) --
    -- fast interrupts (custom) --
    firq_i         : in  std_ulogic_vector(3 downto 0) := (others => '0')
    firq_i         : in  std_ulogic_vector(7 downto 0) := (others => '0');
 
    firq_ack_o     : out std_ulogic_vector(7 downto 0)
  );
  );
end neorv32_cpu;
end neorv32_cpu;
 
 
architecture neorv32_cpu_rtl of neorv32_cpu is
architecture neorv32_cpu_rtl of neorv32_cpu is
 
 
  -- local signals --
  -- local signals --
  signal ctrl       : std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
  signal ctrl       : std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
  signal alu_cmp    : std_ulogic_vector(1 downto 0); -- alu comparator result
  signal comparator : std_ulogic_vector(1 downto 0); -- comparator result
  signal imm        : std_ulogic_vector(data_width_c-1 downto 0); -- immediate
  signal imm        : std_ulogic_vector(data_width_c-1 downto 0); -- immediate
  signal instr      : std_ulogic_vector(data_width_c-1 downto 0); -- new instruction
  signal instr      : std_ulogic_vector(data_width_c-1 downto 0); -- new instruction
  signal rs1, rs2   : std_ulogic_vector(data_width_c-1 downto 0); -- source registers
  signal rs1, rs2   : std_ulogic_vector(data_width_c-1 downto 0); -- source registers
  signal alu_res    : std_ulogic_vector(data_width_c-1 downto 0); -- alu result
  signal alu_res    : std_ulogic_vector(data_width_c-1 downto 0); -- alu result
  signal alu_add    : std_ulogic_vector(data_width_c-1 downto 0); -- alu address result
  signal alu_add    : std_ulogic_vector(data_width_c-1 downto 0); -- alu address result
Line 148... Line 150...
 
 
  -- pmp interface --
  -- pmp interface --
  signal pmp_addr  : pmp_addr_if_t;
  signal pmp_addr  : pmp_addr_if_t;
  signal pmp_ctrl  : pmp_ctrl_if_t;
  signal pmp_ctrl  : pmp_ctrl_if_t;
 
 
 
  -- atomic memory access - success? --
 
  signal atomic_sc_res: std_ulogic;
 
 
begin
begin
 
 
  -- Sanity Checks --------------------------------------------------------------------------
  -- Sanity Checks --------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- CSR system --
  -- CSR system --
Line 206... Line 211...
    CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
    CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
    -- Physical memory protection (PMP) --
    -- Physical memory protection (PMP) --
    PMP_NUM_REGIONS              => PMP_NUM_REGIONS,              -- number of regions (0..64)
    PMP_NUM_REGIONS              => PMP_NUM_REGIONS,              -- number of regions (0..64)
    PMP_MIN_GRANULARITY          => PMP_MIN_GRANULARITY,          -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
    PMP_MIN_GRANULARITY          => PMP_MIN_GRANULARITY,          -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
    -- Hardware Performance Monitors (HPM) --
    -- Hardware Performance Monitors (HPM) --
    HPM_NUM_CNTS                 => HPM_NUM_CNTS                  -- number of inmplemnted HPM counters (0..29)
    HPM_NUM_CNTS                 => HPM_NUM_CNTS                  -- number of implemented HPM counters (0..29)
  )
  )
  port map (
  port map (
    -- global control --
    -- global control --
    clk_i         => clk_i,       -- global clock, rising edge
    clk_i         => clk_i,       -- global clock, rising edge
    rstn_i        => rstn_i,      -- global reset, low-active, async
    rstn_i        => rstn_i,      -- global reset, low-active, async
Line 219... Line 224...
    alu_wait_i    => alu_wait,    -- wait for ALU
    alu_wait_i    => alu_wait,    -- wait for ALU
    bus_i_wait_i  => bus_i_wait,  -- wait for bus
    bus_i_wait_i  => bus_i_wait,  -- wait for bus
    bus_d_wait_i  => bus_d_wait,  -- wait for bus
    bus_d_wait_i  => bus_d_wait,  -- wait for bus
    -- data input --
    -- data input --
    instr_i       => instr,       -- instruction
    instr_i       => instr,       -- instruction
    cmp_i         => alu_cmp,     -- comparator status
    cmp_i         => comparator,  -- comparator status
    alu_add_i     => alu_add,     -- ALU address result
    alu_add_i     => alu_add,     -- ALU address result
    rs1_i         => rs1,         -- rf source 1
    rs1_i         => rs1,         -- rf source 1
    -- data output --
    -- data output --
    imm_o         => imm,         -- immediate
    imm_o         => imm,         -- immediate
    fetch_pc_o    => fetch_pc,    -- PC for instruction fetch
    fetch_pc_o    => fetch_pc,    -- PC for instruction fetch
Line 232... Line 237...
    -- interrupts (risc-v compliant) --
    -- interrupts (risc-v compliant) --
    msw_irq_i     => msw_irq_i,   -- machine software interrupt
    msw_irq_i     => msw_irq_i,   -- machine software interrupt
    mext_irq_i    => mext_irq_i,  -- machine external interrupt
    mext_irq_i    => mext_irq_i,  -- machine external interrupt
    mtime_irq_i   => mtime_irq_i, -- machine timer interrupt
    mtime_irq_i   => mtime_irq_i, -- machine timer interrupt
    -- fast interrupts (custom) --
    -- fast interrupts (custom) --
    firq_i        => firq_i,
    firq_i        => firq_i,      -- fast interrupt trigger
 
    firq_ack_o    => firq_ack_o,  -- fast interrupt acknowledge mask
    -- system time input from MTIME --
    -- system time input from MTIME --
    time_i        => time_i,      -- current system time
    time_i        => time_i,      -- current system time
    -- physical memory protection --
    -- physical memory protection --
    pmp_addr_o    => pmp_addr,    -- addresses
    pmp_addr_o    => pmp_addr,    -- addresses
    pmp_ctrl_o    => pmp_ctrl,    -- configs
    pmp_ctrl_o    => pmp_ctrl,    -- configs
Line 248... Line 254...
    be_instr_i    => be_instr,    -- bus error on instruction access
    be_instr_i    => be_instr,    -- bus error on instruction access
    be_load_i     => be_load,     -- bus error on load data access
    be_load_i     => be_load,     -- bus error on load data access
    be_store_i    => be_store     -- bus error on store data access
    be_store_i    => be_store     -- bus error on store data access
  );
  );
 
 
 
  -- CPU is sleeping? --
 
  sleep_o <= ctrl(ctrl_sleep_c); -- set when CPU is sleeping (after WFI)
 
 
 
 
  -- Register File --------------------------------------------------------------------------
  -- Register File --------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  neorv32_cpu_regfile_inst: neorv32_cpu_regfile
  neorv32_cpu_regfile_inst: neorv32_cpu_regfile
  generic map (
  generic map (
Line 265... Line 274...
    mem_i  => rdata,              -- memory read data
    mem_i  => rdata,              -- memory read data
    alu_i  => alu_res,            -- ALU result
    alu_i  => alu_res,            -- ALU result
    csr_i  => csr_rdata,          -- CSR read data
    csr_i  => csr_rdata,          -- CSR read data
    -- data output --
    -- data output --
    rs1_o  => rs1,                -- operand 1
    rs1_o  => rs1,                -- operand 1
    rs2_o  => rs2                 -- operand 2
    rs2_o  => rs2,                -- operand 2
 
    cmp_o  => comparator          -- comparator status
  );
  );
 
 
 
 
  -- ALU ------------------------------------------------------------------------------------
  -- ALU ------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
Line 287... Line 297...
    rs1_i       => rs1,           -- rf source 1
    rs1_i       => rs1,           -- rf source 1
    rs2_i       => rs2,           -- rf source 2
    rs2_i       => rs2,           -- rf source 2
    pc2_i       => curr_pc,       -- delayed PC
    pc2_i       => curr_pc,       -- delayed PC
    imm_i       => imm,           -- immediate
    imm_i       => imm,           -- immediate
    -- data output --
    -- data output --
    cmp_o       => alu_cmp,       -- comparator status
 
    res_o       => alu_res,       -- ALU result
    res_o       => alu_res,       -- ALU result
    add_o       => alu_add,       -- address computation result
    add_o       => alu_add,       -- address computation result
    -- co-processor interface --
    -- co-processor interface --
    cp0_start_o => cp0_start,     -- trigger co-processor 0
    cp0_start_o => cp0_start,     -- trigger co-processor 0
    cp0_data_i  => cp0_data,      -- co-processor 0 result
    cp0_data_i  => cp0_data,      -- co-processor 0 result
Line 308... Line 317...
    -- status --
    -- status --
    wait_o      => alu_wait       -- busy due to iterative processing units
    wait_o      => alu_wait       -- busy due to iterative processing units
  );
  );
 
 
 
 
  -- Co-Processor 0: MULDIV Unit ------------------------------------------------------------
  -- Co-Processor 0: Integer Multiplication/Division ('M' Extension) ------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  neorv32_cpu_cp_muldiv_inst_true:
  neorv32_cpu_cp_muldiv_inst_true:
  if (CPU_EXTENSION_RISCV_M = true) generate
  if (CPU_EXTENSION_RISCV_M = true) generate
    neorv32_cpu_cp_muldiv_inst: neorv32_cpu_cp_muldiv
    neorv32_cpu_cp_muldiv_inst: neorv32_cpu_cp_muldiv
    generic map (
    generic map (
Line 338... Line 347...
    cp0_data  <= (others => '0');
    cp0_data  <= (others => '0');
    cp0_valid <= cp0_start; -- to make sure CPU does not get stalled if there is an accidental access
    cp0_valid <= cp0_start; -- to make sure CPU does not get stalled if there is an accidental access
  end generate;
  end generate;
 
 
 
 
  -- Co-Processor 1: Atomic Memory Access, SC - store-conditional ('M' extension) -----------
  -- Co-Processor 1: Atomic Memory Access ('A' Extension) -----------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  atomic_op_cp: process(cp1_start, ctrl)
  -- "pseudo" co-processor for atomic operations
  begin
 
    -- "fake" co-processor for atomic operations
 
    -- used to get the result of a store-conditional operation into the data path
    -- used to get the result of a store-conditional operation into the data path
    if (CPU_EXTENSION_RISCV_A = true) then
  atomic_op_cp: process(clk_i)
 
  begin
 
    if rising_edge(clk_i) then
      if (cp1_start = '1') then
      if (cp1_start = '1') then
        cp1_data    <= (others => '0');
        atomic_sc_res <= not ctrl(ctrl_bus_lock_c);
        cp1_data(0) <= not ctrl(ctrl_bus_lock_c);
 
        cp1_valid   <= '1';
 
      else
      else
        cp1_data  <= (others => '0');
        atomic_sc_res <= '0';
        cp1_valid <= '0';
 
      end if;
      end if;
    else
 
      cp1_data  <= (others => '0');
 
      cp1_valid <= cp1_start; -- to make sure CPU does not get stalled if there is an accidental access
 
    end if;
    end if;
  end process atomic_op_cp;
  end process atomic_op_cp;
 
 
 
  -- CP result --
 
  cp1_data(data_width_c-1 downto 1) <= (others => '0');
 
  cp1_data(0) <= atomic_sc_res when (CPU_EXTENSION_RISCV_A = true) else '0';
 
  cp1_valid   <= cp1_start; -- always assigned even if A is disabled to make sure CPU does not get stalled if there is an accidental access
 
 
 
 
  -- Co-Processor 2: Not implemented (yet) --------------------------------------------------
  -- Co-Processor 2: Bit Manipulation ('B' Extension) ---------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  neorv32_cpu_cp_bitmanip_inst_true:
  neorv32_cpu_cp_bitmanip_inst_true:
  if (CPU_EXTENSION_RISCV_B = true) generate
  if (CPU_EXTENSION_RISCV_B = true) generate
    neorv32_cpu_cp_bitmanip_inst: neorv32_cpu_cp_bitmanip
    neorv32_cpu_cp_bitmanip_inst: neorv32_cpu_cp_bitmanip
    port map (
    port map (
Line 372... Line 380...
      clk_i   => clk_i,           -- global clock, rising edge
      clk_i   => clk_i,           -- global clock, rising edge
      rstn_i  => rstn_i,          -- global reset, low-active, async
      rstn_i  => rstn_i,          -- global reset, low-active, async
      ctrl_i  => ctrl,            -- main control bus
      ctrl_i  => ctrl,            -- main control bus
      start_i => cp2_start,       -- trigger operation
      start_i => cp2_start,       -- trigger operation
      -- data input --
      -- data input --
      cmp_i   => alu_cmp,         -- comparator status
      cmp_i   => comparator,      -- comparator status
      rs1_i   => rs1,             -- rf source 1
      rs1_i   => rs1,             -- rf source 1
      rs2_i   => rs2,             -- rf source 2
      rs2_i   => rs2,             -- rf source 2
      -- result and status --
      -- result and status --
      res_o   => cp2_data,        -- operation result
      res_o   => cp2_data,        -- operation result
      valid_o => cp2_valid        -- data output valid
      valid_o => cp2_valid        -- data output valid
Line 388... Line 396...
    cp2_data  <= (others => '0');
    cp2_data  <= (others => '0');
    cp2_valid <= cp2_start; -- to make sure CPU does not get stalled if there is an accidental access
    cp2_valid <= cp2_start; -- to make sure CPU does not get stalled if there is an accidental access
  end generate;
  end generate;
 
 
 
 
  -- Co-Processor 3: Not implemented (yet) --------------------------------------------------
  -- Co-Processor 3: Not implemented --------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- control: ctrl cp3_start
 
  -- inputs:  rs1 rs2 alu_cmp
 
  cp3_data  <= (others => '0');
  cp3_data  <= (others => '0');
  cp3_valid <= cp3_start; -- to make sure CPU does not get stalled if there is an accidental access
  cp3_valid <= cp3_start; -- to make sure CPU does not get stalled if there is an accidental access
 
 
 
 
  -- Bus Interface Unit ---------------------------------------------------------------------
  -- Bus Interface Unit ---------------------------------------------------------------------

powered by: WebSVN 2.1.0

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