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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_regfile.vhd] - Diff between revs 60 and 62

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

Rev 60 Rev 62
Line 49... Line 49...
library neorv32;
library neorv32;
use neorv32.neorv32_package.all;
use neorv32.neorv32_package.all;
 
 
entity neorv32_cpu_regfile is
entity neorv32_cpu_regfile is
  generic (
  generic (
    CPU_EXTENSION_RISCV_E : boolean := false -- implement embedded RF extension?
    CPU_EXTENSION_RISCV_E : boolean -- implement embedded RF extension?
  );
  );
  port (
  port (
    -- global control --
    -- global control --
    clk_i  : in  std_ulogic; -- global clock, rising edge
    clk_i  : in  std_ulogic; -- global clock, rising edge
    ctrl_i : in  std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
    ctrl_i : in  std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
Line 74... Line 74...
  type   reg_file_emb_t is array (15 downto 0) of std_ulogic_vector(data_width_c-1 downto 0);
  type   reg_file_emb_t is array (15 downto 0) of std_ulogic_vector(data_width_c-1 downto 0);
  signal reg_file     : reg_file_t;
  signal reg_file     : reg_file_t;
  signal reg_file_emb : reg_file_emb_t;
  signal reg_file_emb : reg_file_emb_t;
  signal rf_wdata     : std_ulogic_vector(data_width_c-1 downto 0); -- actual write-back data
  signal rf_wdata     : std_ulogic_vector(data_width_c-1 downto 0); -- actual write-back data
  signal rd_is_r0     : std_ulogic; -- writing to r0?
  signal rd_is_r0     : std_ulogic; -- writing to r0?
  signal rf_we        : std_ulogic;
 
  signal dst_addr     : std_ulogic_vector(4 downto 0); -- destination address
  signal dst_addr     : std_ulogic_vector(4 downto 0); -- destination address
  signal opa_addr     : std_ulogic_vector(4 downto 0); -- rs1/dst address
  signal opa_addr     : std_ulogic_vector(4 downto 0); -- rs1/dst address
  signal opb_addr     : std_ulogic_vector(4 downto 0); -- rs2 address
  signal opb_addr     : std_ulogic_vector(4 downto 0); -- rs2 address
  signal rs1, rs2     : std_ulogic_vector(data_width_c-1 downto 0);
  signal rs1, rs2     : std_ulogic_vector(data_width_c-1 downto 0); -- read data
 
 
  -- comparator --
  -- comparator --
  signal cmp_opx : std_ulogic_vector(data_width_c downto 0);
  signal cmp_opx : std_ulogic_vector(data_width_c downto 0);
  signal cmp_opy : std_ulogic_vector(data_width_c downto 0);
  signal cmp_opy : std_ulogic_vector(data_width_c downto 0);
 
 
begin
begin
 
 
  -- Data Input Mux -------------------------------------------------------------------------
  -- Data Input Mux -------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  rf_wdata <= alu_i when (ctrl_i(ctrl_rf_in_mux_c) = '0') else mem_i;
  input_mux: process(rd_is_r0, ctrl_i, alu_i, mem_i)
 
  begin
 
    if (rd_is_r0 = '1') then -- write zero if accessing x0 to "emulate" it is hardwired to zero
 
      rf_wdata <= (others => '0');
 
    else
 
      if (ctrl_i(ctrl_rf_in_mux_c) = '0') then
 
        rf_wdata <= alu_i;
 
      else
 
        rf_wdata <= mem_i;
 
      end if;
 
    end if;
 
  end process input_mux;
 
 
 
  -- check if we are writing to x0 --
 
  rd_is_r0 <= (not or_reduce_f(dst_addr(4 downto 0))) when (CPU_EXTENSION_RISCV_E = false) else (not or_reduce_f(dst_addr(3 downto 0)));
 
 
 
 
  -- Register File Access -------------------------------------------------------------------
  -- Register File Access -------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  rf_access: process(clk_i)
  rf_access: process(clk_i)
  begin
  begin
    if rising_edge(clk_i) then -- sync read and write
    if rising_edge(clk_i) then -- sync read and write
      if (CPU_EXTENSION_RISCV_E = false) then -- normal register file with 32 entries
      if (CPU_EXTENSION_RISCV_E = false) then -- normal register file with 32 entries
        if (rf_we = '1') then
        if (ctrl_i(ctrl_rf_wb_en_c) = '1') then
          reg_file(to_integer(unsigned(opa_addr(4 downto 0)))) <= rf_wdata;
          reg_file(to_integer(unsigned(opa_addr(4 downto 0)))) <= rf_wdata;
        end if;
        end if;
        rs1 <= reg_file(to_integer(unsigned(opa_addr(4 downto 0))));
        rs1 <= reg_file(to_integer(unsigned(opa_addr(4 downto 0))));
        rs2 <= reg_file(to_integer(unsigned(opb_addr(4 downto 0))));
        rs2 <= reg_file(to_integer(unsigned(opb_addr(4 downto 0))));
      else -- embedded register file with 16 entries
      else -- embedded register file with 16 entries
        if (rf_we = '1') then
        if (ctrl_i(ctrl_rf_wb_en_c) = '1') then
          reg_file_emb(to_integer(unsigned(opa_addr(3 downto 0)))) <= rf_wdata;
          reg_file_emb(to_integer(unsigned(opa_addr(3 downto 0)))) <= rf_wdata;
        end if;
        end if;
        rs1 <= reg_file_emb(to_integer(unsigned(opa_addr(3 downto 0))));
        rs1 <= reg_file_emb(to_integer(unsigned(opa_addr(3 downto 0))));
        rs2 <= reg_file_emb(to_integer(unsigned(opb_addr(3 downto 0))));
        rs2 <= reg_file_emb(to_integer(unsigned(opb_addr(3 downto 0))));
      end if;
      end if;
    end if;
    end if;
  end process rf_access;
  end process rf_access;
 
 
  -- check if we are writing to x0 --
 
  rd_is_r0 <= not or_reduce_f(ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c)) when (CPU_EXTENSION_RISCV_E = false) else
 
              not or_reduce_f(ctrl_i(ctrl_rf_rd_adr3_c downto ctrl_rf_rd_adr0_c));
 
 
 
  -- valid RF write access? --
 
  rf_we <= (ctrl_i(ctrl_rf_wb_en_c) and (not rd_is_r0)) or ctrl_i(ctrl_rf_r0_we_c);
 
 
 
  -- access addresses --
  -- access addresses --
  dst_addr <= ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) when (ctrl_i(ctrl_rf_r0_we_c) = '0') else (others => '0'); -- force dst=r0?
  dst_addr <= ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c);
  opa_addr <= dst_addr when (rf_we = '1') else ctrl_i(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c); -- rd/rs1
  opa_addr <= dst_addr when (ctrl_i(ctrl_rf_wb_en_c) = '1') else ctrl_i(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c); -- rd/rs1
  opb_addr <= ctrl_i(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c); -- rs2
  opb_addr <= ctrl_i(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c); -- rs2
 
 
  -- data output --
  -- data output --
  rs1_o <= rs1;
  rs1_o <= rs1;
  rs2_o <= rs2;
  rs2_o <= rs2;

powered by: WebSVN 2.1.0

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