[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[f-cpu] Register Bank
To illustrate what I said before, I wrote a little register bank entity.
It's not the real thing (there is no scoreboard interface, it's not
SIMD capable, and register 0 isn't handled either) but it already has
3 read and 2 write ports that can be used simultaneously (except for
the special case that both writers try to write to the same register;
in that case, write port 0 has priority).
--
Michael "Tired" Riepe <Michael.Riepe@stud.uni-hannover.de>
"All I wanna do is have a little fun before I die"
-- regbank.vhdl -- Simple Register Bank
-- Copyright (C) 2001 Michael Riepe <michael@stud.uni-hannover.de>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- $Id$
library IEEE;
use IEEE.std_logic_1164.all;
entity Register_Bank is
generic (
WIDTH : natural := 64;
NREGS : natural := 64
);
port (
-- data inputs
Write_0 : in std_ulogic_vector(WIDTH-1 downto 0);
Write_1 : in std_ulogic_vector(WIDTH-1 downto 0);
-- write enable (decoded)
Write_Enable_0 : in std_ulogic_vector(NREGS-1 downto 0);
Write_Enable_1 : in std_ulogic_vector(NREGS-1 downto 0);
-- read enable (decoded)
Read_Enable_0 : in std_ulogic_vector(NREGS-1 downto 0);
Read_Enable_1 : in std_ulogic_vector(NREGS-1 downto 0);
Read_Enable_2 : in std_ulogic_vector(NREGS-1 downto 0);
-- clock/reset
Clk : in std_ulogic;
Rst : in std_ulogic;
--
-- data outputs
Read_0 : out std_ulogic_vector(WIDTH-1 downto 0);
Read_1 : out std_ulogic_vector(WIDTH-1 downto 0);
Read_2 : out std_ulogic_vector(WIDTH-1 downto 0)
);
end Register_Bank;
architecture Behave_1 of Register_Bank is
subtype reg is std_ulogic_vector(WIDTH-1 downto 0);
type bank is array (natural range <>) of reg;
function read_reg (Regs : bank;
Enable : std_ulogic_vector) return reg is
alias myrb : bank(Regs'length-1 downto 0) is Regs;
alias myen : std_ulogic_vector(Enable'length-1 downto 0) is Enable;
begin
assert Regs'length = Enable'length;
for i in myrb'range loop
if to_X01(myen(i)) = '1' then
return myrb(i);
end if;
end loop;
return reg'(others => 'Z'); -- port unused
end read_reg;
signal Regs : bank(NREGS-1 downto 0);
begin
-- readers (combinatorial)
Read_0 <= read_reg(Regs, Read_Enable_0);
Read_1 <= read_reg(Regs, Read_Enable_1);
Read_2 <= read_reg(Regs, Read_Enable_2);
-- writers (sequential)
process (Write_0, Write_1, Write_Enable_0, Write_Enable_1, Clk, Rst)
begin
if Rst = '1' then
Regs <= (others => (others => '0'));
elsif rising_edge(Clk) then
for i in NREGS-1 downto 0 loop
if to_X01(Write_Enable_0(i)) = '1' then
Regs(i) <= Write_0;
elsif to_X01(Write_Enable_1(i)) = '1' then
Regs(i) <= Write_1;
else
-- register remains unchanged
end if;
end loop;
end if;
end process;
end Behave_1;