[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