[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [f-cpu] Register Bank
On Fri, Aug 03, 2001 at 03:55:18AM +0200, Yann Guidon wrote:
[...]
> while we're at it, can you try to see what is necessary to have
> "partial register write" ?
More control lines ;-P
> The current FC0 study requires the ability to write specifically
> to the following : bits 0-7, 8-15, 16-31, 32-47, 48-63 (5 subfields).
Why 32-47 and 48-63? IMHO the slices must look this way:
A: 7 downto 0 enable: '1'
B: 15 downto 8 enable: U(0) or SIMD
C: 31 downto 16 enable: U(1) or SIMD
D: 63 downto 32 enable: U(2) or SIMD
In 8-bit mode, only A is written; A+B in 16-bit mode, A+B+C in 32-bit
mode, and A...D in 64-bit mode. Note that this corresponds directly
to the encoding of the chunk size control lines in the EU interfaces
(the U08, U16 and U32 lines, or the U vector in later versions). I
knew that encoding was a pretty good choice :)
> the interface to the register set specifies 2x register
> address (6 bits each) and 5 bits for each address, counting as
> "write enable" for the subfields...
I'd rather stick to the decoded enable lines for now (let's assume that
there are three 6-to-64 decoders in the IF/ID, one for each possible
register operand -- that's probably cheaper than 5 decoders inside the
register bank). In any case, we need an additional `U' vector for
each write port (3 lines per port). The read ports can work at full
width all the time, can't they?
> Concerning the register set reset, it can probably be performed
> with some "tricks" : "hard" reset is probably not necessary.
> i think that a "smart" use of the scheduler can trigger a burst
> of register writes after a reset. what do you think ? :-)
Didn't we want to include a POST (Power-On Self Test) anyway? Since that
will have to test the registers (i.e. write into them and read back the
values), it can also initialize them. I removed the Rst line now ;)
Please have a look at the attachment.
CU
--
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);
-- write port SIMD mode lines
Write_U_0 : in std_ulogic_vector(2 downto 0);
Write_U_1 : in std_ulogic_vector(2 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
Clk : 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;
-- Note that I use this function for clarity. It infers a
-- row of multiplexers, but in the real code we probably want
-- clock gates, which demand another coding style.
function write_reg (R, D : in reg;
U : in std_ulogic_vector(2 downto 0)) return reg is
variable x : reg;
begin
x := R;
x( 7 downto 0) := D( 7 downto 0);
if to_X01(U(0)) = '1' then
x(15 downto 8) := D(15 downto 8);
end if;
if to_X01(U(1)) = '1' then
x(31 downto 16) := D(31 downto 16);
end if;
if to_X01(U(2)) = '1' then
x(63 downto 32) := D(63 downto 32);
end if;
return x;
end write_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
begin
-- an explicit wait statement is worth 1000 signals
-- in a sensitivity list :)
wait until rising_edge(Clk);
-- and now, do the work.
for i in NREGS-1 downto 0 loop
if to_X01(Write_Enable_0(i)) = '1' then
Regs(i) <= write_reg(Regs(i), Write_0, Write_U_0);
elsif to_X01(Write_Enable_1(i)) = '1' then
Regs(i) <= write_reg(Regs(i), Write_1, Write_U_1);
else
-- register remains unchanged
end if;
end loop;
end process;
end Behave_1;
-- vi: set ts=4 sw=4 equalprg="fmt -72 -p--": please