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

Subversion Repositories risc5x

[/] [risc5x/] [trunk/] [regs.vhd] - Rev 3

Compare with Previous | Blame | View Log

--
-- Risc5x
-- www.OpenCores.Org - November 2001
--
--
-- This library is free software; you can distribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published
-- by the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details.
--
-- A RISC CPU core.
--
-- (c) Mike Johnson 2001. All Rights Reserved.
-- mikej@opencores.org for support or any other issues.
--
-- Revision list
--
-- version 1.0 initial opencores release
--
 
use work.pkg_risc5x.all;
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_arith.all;
  use ieee.std_logic_unsigned.all;
 
entity REGS is
  port (
    WE              : in  std_logic;
    RE              : in  std_logic;
    BANK            : in  std_logic_vector(1 downto 0);
    LOCATION        : in  std_logic_vector(4 downto 0);
    DIN             : in  std_logic_vector(7 downto 0);
    DOUT            : out std_logic_vector(7 downto 0);
    RESET           : in  std_logic;
    CLK             : in  std_logic
    );
end;
--
-- USE THIS ARCHITECTURE FOR XILINX
--
use work.pkg_risc5x.all;
use work.pkg_xilinx_prims.all;
use work.pkg_prims.all;
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_arith.all;
  use ieee.std_logic_unsigned.all;
 
architecture VIRTEX of REGS is
 
  constant WIDTH : natural := 8;
  constant OP_REG : boolean := false;
 
  type slv_array is array (natural range <>) of std_logic_vector(WIDTH-1 downto 0);
  signal ram_out : slv_array(4 downto 0);
  signal wen_int : std_logic_vector(4 downto 0);
  signal sel     : std_logic_vector(2 downto 0);
 
begin -- architecture
 
  -- ram mapping
  -- bank location
  -- xx   00xxx special registers
  -- xx   01xxx common 8 to all banks
  -- 00   1xxxx 16 bank 0
  -- 01   1xxxx 16 bank 1
  -- 10   1xxxx 16 bank 2
  -- 11   1xxxx 16 bank 3
  p_wen_comb : process (BANK,LOCATION,WE)
    variable addr : std_logic_vector(3 downto 0);
  begin
    addr := (BANK & LOCATION(4 downto 3));
    wen_int <= (others => '0');
    case addr(3 downto 1) is
      when "001" => wen_int(0) <= WE; -- bank0
      when "011" => wen_int(1) <= WE; -- bank1
      when "101" => wen_int(2) <= WE; -- bank2
      when "111" => wen_int(3) <= WE; -- bank3
 
      when others => null;
    end case;
    if (LOCATION(4 downto 3) = "01") then
      wen_int(4) <= WE; -- common
    end if;
  end process;
 
  ram_bit : for i in 0 to WIDTH-1 generate
  begin
    rams : for j in 0 to 4 generate
    attribute RLOC of ram: label is "R" & integer'image((WIDTH -1)-i) & "C" & integer'image((j+1)/2) & ".S" & integer'image(1 - ((j+1) mod 2));
    begin
      ram : RAM16X1D
      port map (
        a0    => LOCATION(0),
        a1    => LOCATION(1),
        a2    => LOCATION(2),
        a3    => LOCATION(3),
        dpra0 => LOCATION(0),
        dpra1 => LOCATION(1),
        dpra2 => LOCATION(2),
        dpra3 => LOCATION(3),
        wclk  => CLK,
        we    => wen_int(j),
        d     => DIN(i),
        dpo   => ram_out(j)(i));
    end generate;
  end generate;
 
  SEL <= BANK & LOCATION(4);
 
  mux : if true generate
    attribute RLOC of mux8_1: label is "R0C3";
  begin
    mux8_1 : MUX8
      generic map (
        WIDTH         => WIDTH,
        OP_REG        => OP_REG
        )
      port map (
        DIN7          => ram_out(3),
        DIN6          => ram_out(4),
        DIN5          => ram_out(2),
        DIN4          => ram_out(4),
        DIN3          => ram_out(1),
        DIN2          => ram_out(4),
        DIN1          => ram_out(0),
        DIN0          => ram_out(4),
 
        SEL           => sel,
        ENA           => '1', -- not used
        CLK           => CLK, -- not used
 
        DOUT          => DOUT
        );
   end generate;
end VIRTEX;
 
--pragma translate_off
 
use work.pkg_risc5x.all;
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_arith.all;
  use ieee.std_logic_unsigned.all;
 
architecture RTL of REGS is
  signal final_addr : std_logic_vector(6 downto 0);
  constant WIDTH : natural := 8;
  constant OP_REG : boolean := false;
 
  -- following required for simulation model only
  constant nwords : integer := 2 ** 7;
  type ram_type is array (0 to nwords-1) of std_logic_vector(WIDTH-1 downto 0);
  signal ram_read_data : std_logic_vector(WIDTH-1 downto 0);
  --shared variable ram :ram_type := (others => (others => 'X')); -- helps debug no end!
  shared variable ram :ram_type := (others => (others => '0'));
 
begin -- architecture
  p_remap : process(BANK,LOCATION)
    variable addr : std_logic_vector(3 downto 0);
  begin
    addr := (BANK & LOCATION(4 downto 3));
    final_addr <= "0000000";
    case addr is
      when "0001" => final_addr <= "0000" & LOCATION(2 downto 0);
      when "0101" => final_addr <= "0000" & LOCATION(2 downto 0);
      when "1001" => final_addr <= "0000" & LOCATION(2 downto 0);
      when "1101" => final_addr <= "0000" & LOCATION(2 downto 0);
      -- bank #0
      when "0010" => final_addr <= "0001" & LOCATION(2 downto 0);
      when "0011" => final_addr <= "0010" & LOCATION(2 downto 0);
      -- bank #1
      when "0110" => final_addr <= "0011" & LOCATION(2 downto 0);
      when "0111" => final_addr <= "0100" & LOCATION(2 downto 0);
      -- bank #2
      when "1010" => final_addr <= "0101" & LOCATION(2 downto 0);
      when "1011" => final_addr <= "0110" & LOCATION(2 downto 0);
      -- bank #3
      when "1110" => final_addr <= "0111" & LOCATION(2 downto 0);
      when "1111" => final_addr <= "1000" & LOCATION(2 downto 0);
      when others => null;
    end case;
  end process;
 
  -- you should replace the following simulation memory model
  -- with a dpram (no clock delay on read) for synthesis if
  -- you do not wish to use the Xilinx Virtex architecture.
  -- i.e.
  --
  --U1: dpram
  --  generic map (addr_bits => 7,
  --               data_bits => 8)
  --  port map (
  --    reset   => RESET,
  --    wr_clk  => CLK,
  --    wr_en   => WE,
  --    wr_addr => final_addr,
  --    wr_data => DIN,
  --    rd_clk  => '0',
  --    rd_addr => final_addr,
  --    rd_data => DOUT
  --    );
 
  -- SIMULATION MODEL OF RAM
  p_ram_write : process
    variable ram_addr : integer := 0;
  begin
    wait until CLK'event and (CLK = '1');
    if (WE = '1') then
      ram_addr := slv_to_integer(final_addr);
      ram(ram_addr) := DIN;
    end if;
  end process;
 
  p_ram_read_comb : process(CLK,final_addr)
    variable ram_addr : integer := 0;
  begin
    ram_addr := slv_to_integer(final_addr);
    ram_read_data <= ram(ram_addr);
  end process;
 
  opreg : if OP_REG generate
    p_opreg : process
    begin
      wait until CLK'event and (CLK = '1');
      if (RE = '1') then
        DOUT <= ram_read_data;
      end if;
    end process;
  end generate;
 
  opwire : if not OP_REG generate
    DOUT <= ram_read_data;
  end generate;
 
end RTL;
 
--pragma translate_on
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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