Problem with register file

F

Fi3rizi0

Guest
Hi all,
I try to realize a register file, with register "0" can be only reads
and is full of "0".
When I simulate with multisim, the register 0 is"Undefined" always.
Where I mistake?

thanks


this is the code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity reg_file is

generic (
n_registri : integer :=5; -- Number of register is
2**N_registri
n_bit : integer :=32); -- Register dimension

port (
wen : in std_logic; -- write enable
adx_d : in std_logic_vector(n_registri-1 downto 0); --Register
Address for writing
d : in std_logic_vector(n_bit-1 downto 0); --Data to
writing
clk : in std_logic;
rst_n : in std_logic; --Reset
adx_a : in std_logic_vector(n_registri-1 downto 0); --Register
Address for reading A
a : out std_logic_vector(n_bit-1 downto 0);
adx_b : in std_logic_vector(n_registri-1 downto 0); --Register
Address for reading B
b : out std_logic_vector(n_bit-1 downto 0));

end reg_file;

architecture behavioral of reg_file is

type matrice is array (0 to (2**n_registri)-1) of
std_logic_vector(n_bit-1 downto 0);

constant zero : std_logic_vector(n_bit-1 downto 0) := (others =>
'0');
signal registri : matrice;

begin -- behavioral

-- Register 0 can only be reads;
registri(0) <= conv_std_logic_vector(0,n_bit);

-- purpose: Scrittura D
-- type : sequential
-- inputs : clk, rst_n
-- outputs:
writing: process (clk, rst_n)
begin -- process scrittura
if rst_n = '0' then -- asynchronous reset (active
low)
for i in 1 to (2**n_registri)-1 loop
registri(i) <= (others => '0');
end loop; -- i
elsif clk'event and clk = '1' then -- rising clock edge
if (wen = '1') and (adx_d /=
conv_std_logic_vector(0,n_registri)) then
registri(conv_integer(adx_d)) <= d;
end if;
end if;
end process scrittura;

-- purpose: Lettura porta A
-- type : combinational
-- inputs : adx_a
-- outputs:
lettura_a: process (adx_a,registri)
begin -- process lettura_a

a <= registri(conv_integer(adx_a));

end process lettura_a;

-- purpose: Lettura porta B
-- type : combinational
-- inputs : adx_b
-- outputs:
lettura_b: process (adx_b,registri)
begin -- process lettura_b

b <= registri(conv_integer(adx_b));

end process lettura_b;

end behavioral;
 
On Fri, 16 May 2008 08:13:56 -0700 (PDT), Fi3rizi0 <Fi3rizi0@gmail.com>
wrote:

Hi all,
I try to realize a register file, with register "0" can be only reads
and is full of "0".
When I simulate with multisim, the register 0 is"Undefined" always.
Where I mistake?

thanks


this is the code:
library ieee;
use ieee.std_logic_1164.all;
Here (below) is the first mistake; though it's not causing this problem
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
Use the standard library which gives you signed and unsigned types.

adx_d etc should preferably be unsigned, which will reduce type
conversions, or integer, to eliminate them.

adx_a : in unsigned(n_registri-1 downto 0);

registri(0) <= conv_std_logic_vector(0,n_bit);
and

if (wen = '1') and (adx_d /=
conv_std_logic_vector(0,n_registri)) then
registri(conv_integer(adx_d)) <= d;
HERE is the real problem
end if;
Think hardware... you can create a regular array of storage ("registri")
here, which this process writes to all of, and another process writes to
the first word of, with an entirely separate write bus? What would such
a memory look like? It needs a memory block where the address bus
addresses every location EXCEPT one... There is no such thing. You would
have to implement it using two separate memories!

The reason you are getting 'U' on registri(0) is that this process
drives ALL of registri, but leaves registri(0) uninitialised. And
shorting it to a separate '0' signal is resolved as ... uninitialised.
(Read about resolved types).

The simulator is simply warning you that this is dangerous design
practice for hardware.

The simplest solution would be to (a) initialise registri(0) to '0'
along with all the other registers at reset, and DELETE the separate
registri(0) <= () outside the process. Then your CPU will not function
correctly before reset. Your write logic, protecting registri(0), looks
OK to me, so it SHOULD work afterwards.

Alternatively, if you do not trust the write process to protect
registri(0), (why not?) then put the conditional test in the READ
processes, to select registri(n) or (others=> '0')

a <= (others => '0) when adx_a = 0 else registri(to_integer(adx_a));

Now you can simplify the write process. It can write to the memory
location registri(0) because that is never read.

- Brian
 

Welcome to EDABoard.com

Sponsor

Back
Top