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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_bus.vhd] - Diff between revs 15 and 16

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

Rev 15 Rev 16
Line 73... Line 73...
    ma_store_o     : out std_ulogic; -- misaligned store data address
    ma_store_o     : out std_ulogic; -- misaligned store data address
    be_load_o      : out std_ulogic; -- bus error on load data access
    be_load_o      : out std_ulogic; -- bus error on load data access
    be_store_o     : out std_ulogic; -- bus error on store data access
    be_store_o     : out std_ulogic; -- bus error on store data access
    -- physical memory protection --
    -- physical memory protection --
    pmp_addr_i     : in  pmp_addr_if_t; -- addresses
    pmp_addr_i     : in  pmp_addr_if_t; -- addresses
    pmp_maddr_o    : out pmp_addr_if_t; -- masked addresses
 
    pmp_ctrl_i     : in  pmp_ctrl_if_t; -- configs
    pmp_ctrl_i     : in  pmp_ctrl_if_t; -- configs
    priv_mode_i    : in  std_ulogic_vector(1 downto 0); -- current CPU privilege level
    priv_mode_i    : in  std_ulogic_vector(1 downto 0); -- current CPU privilege level
    -- instruction bus --
    -- instruction bus --
    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); -- bus read data
    i_bus_rdata_i  : in  std_ulogic_vector(data_width_c-1 downto 0); -- bus read data
Line 142... Line 141...
 
 
  -- physical memory protection --
  -- physical memory protection --
  type pmp_addr34_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c+1 downto 0);
  type pmp_addr34_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c+1 downto 0);
  type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0);
  type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0);
  type pmp_t is record
  type pmp_t is record
    addr_mask : pmp_addr34_t; -- 34-bit
    addr_mask     : pmp_addr34_t; -- 34-bit physical address
 
    region_base   : pmp_addr_t; -- masked region base address for comparator
 
    region_i_addr : pmp_addr_t; -- masked instruction access base address for comparator
 
    region_d_addr : pmp_addr_t; -- masked data access base address for comparator
    i_match   : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for instruction interface
    i_match   : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for instruction interface
    d_match   : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for data interface
    d_match   : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region match for data interface
    if_fault  : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for fetch operation
    if_fault  : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for fetch operation
    ld_fault  : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for load operation
    ld_fault  : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for load operation
    st_fault  : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for store operation
    st_fault  : std_ulogic_vector(PMP_NUM_REGIONS-1 downto 0); -- region access fault for store operation
Line 409... Line 411...
 
 
 
 
  -- Physical Memory Protection (PMP) -------------------------------------------------------
  -- Physical Memory Protection (PMP) -------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- compute address masks --
  -- compute address masks --
  pmp_masks: process(pmp_addr_i, pmp, pmp_ctrl_i)
  pmp_masks: process(pmp_addr_i)
  begin
  begin
    for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
    for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
      pmp.addr_mask(r) <= (others => '0'); -- default
      pmp.addr_mask(r) <= (others => '0'); -- default
      for i in PMP_GRANULARITY+2 to 33 loop
      for i in PMP_GRANULARITY+1 to 33 loop
        if (i = PMP_GRANULARITY+2) then
        if (i = PMP_GRANULARITY+1) then
          if (pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) = pmp_napot_mode_c) then
 
            pmp.addr_mask(r)(i) <= '0';
            pmp.addr_mask(r)(i) <= '0';
          else -- OFF or unsupported mode
        else -- current bit = not AND(all previous bits)
            pmp.addr_mask(r)(i) <= '1'; -- required for SW to check min granularity when entry is disabled
          pmp.addr_mask(r)(i) <= not (and_all_f(pmp_addr_i(r)(i-1 downto PMP_GRANULARITY)));
          end if;
 
        else
 
          if (pmp_ctrl_i(r)(pmp_cfg_ah_c downto pmp_cfg_al_c) = pmp_napot_mode_c) then
 
            -- current bit = not AND(all previous bits)
 
            pmp.addr_mask(r)(i) <= not and_all_f(pmp_addr_i(r)(i-1 downto PMP_GRANULARITY+2));
 
          else -- OFF or unsupported mode
 
            pmp.addr_mask(r)(i) <= '1'; -- required for SW to check min granularity when entry is disabled
 
          end if;
 
        end if;
        end if;
      end loop; -- i
      end loop; -- i
    end loop; -- r
    end loop; -- r
  end process pmp_masks;
  end process pmp_masks;
 
 
 
 
  -- masked pmpaddr output for CSR read-back --
  -- compute operands for comparator --
  pmp_masked_output: process(pmp_addr_i, pmp)
  pmp_prepare_check:
  begin
  for r in 0 to PMP_NUM_REGIONS-1 generate -- iterate over all regions
    pmp_maddr_o <= (others => (others => '0'));
    -- ignore lowest 3 bits of access addresses -> minimal region size = 8 bytes
    for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
    pmp.region_i_addr(r) <= (fetch_pc_i(31 downto 3) & "000") and pmp.addr_mask(r)(33 downto 2);
      pmp_maddr_o(r) <= pmp_addr_i(r) and pmp.addr_mask(r);
    pmp.region_d_addr(r) <= (mar(31 downto 3) & "000")        and pmp.addr_mask(r)(33 downto 2);
    end loop; -- r
    pmp.region_base(r)   <= pmp_addr_i(r)(33 downto 2)        and pmp.addr_mask(r)(33 downto 2);
  end process pmp_masked_output;
  end generate; -- r
 
 
 
 
  -- check for access address match --
  -- check for access address match --
  pmp_addr_check: process (pmp, fetch_pc_i, mar, pmp_addr_i)
  pmp_addr_check: process (pmp)
    variable i_cmp_v : std_ulogic_vector(31 downto 0);
 
    variable d_cmp_v : std_ulogic_vector(31 downto 0);
 
    variable b_cmp_v : std_ulogic_vector(31 downto 0);
 
  begin
  begin
    for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
    for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
      b_cmp_v := pmp_addr_i(r)(33 downto 2) and pmp.addr_mask(r)(33 downto 2);
 
      -- instruction interface --
      -- instruction interface --
      i_cmp_v := fetch_pc_i and pmp.addr_mask(r)(33 downto 2);
 
      if (i_cmp_v(31 downto PMP_GRANULARITY+2) = b_cmp_v(31 downto PMP_GRANULARITY+2)) then
 
        pmp.i_match(r) <= '1';
 
      else
 
        pmp.i_match(r) <= '0';
        pmp.i_match(r) <= '0';
 
      if (pmp.region_i_addr(r)(31 downto PMP_GRANULARITY+2) = pmp.region_base(r)(31 downto PMP_GRANULARITY+2)) then
 
        pmp.i_match(r) <= '1';
      end if;
      end if;
      -- data interface --
      -- data interface --
      d_cmp_v := mar and pmp.addr_mask(r)(33 downto 2);
 
      if (d_cmp_v(31 downto PMP_GRANULARITY+2) = b_cmp_v(31 downto PMP_GRANULARITY+2)) then
 
        pmp.d_match(r) <= '1';
 
      else
 
        pmp.d_match(r) <= '0';
        pmp.d_match(r) <= '0';
 
      if (pmp.region_d_addr(r)(31 downto PMP_GRANULARITY+2) = pmp.region_base(r)(31 downto PMP_GRANULARITY+2)) then
 
        pmp.d_match(r) <= '1';
      end if;
      end if;
    end loop; -- r
    end loop; -- r
  end process pmp_addr_check;
  end process pmp_addr_check;
 
 
 
 

powered by: WebSVN 2.1.0

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