S
stoyan.shopov
Hi everybody,
I am quite new to VHDL and I have some questions. I am trying to
build a register file consisting of 16 registers, each 32 bits wide.
The register file I need must have two outputs - two of the registers
must be driven on two output buses at any time. The register file
is updated synchronously on the rising edge of clock.
I use Xilinx ISE 6.2.
I am sorry that I put here so much code, but it is simple code
and should not take much time to read.
As a building block I use the 'reg' entity listed below.
entity reg is
Port ( din : in std_logic_vector(31 downto 0); -- data input for
register update
dout : out std_logic_vector(31 downto 0); -- data output
(tristate)
dout1 : out std_logic_vector(31 downto 0); -- identical as
dout above
wr : in std_logic; -- write strobe
wren : in std_logic; -- write enable; I shall make these clear
below
clk : in std_logic; -- clock input
oe : in std_logic; -- output enable for dout output
oe1 : in std_logic); -- output enable for daout1 output
end reg;
architecture Behavioral of reg is
signal idata: std_logic_vector(31 downto 0);
begin
update_reg: process(clk)
begin
if clk'event and clk = '1' then
if wr = '1' and wren = '1' then
idata <= din;
end if;
end if;
end process;
drive_output: process(idata, oe, oe1)
begin
-- drive first output
if oe = '1' then
dout <= idata;
else
dout <= (others => 'Z');
end if;
-- drive second output
if oe1 = '1' then
dout1 <= idata;
else
dout1 <= (others => 'Z');
end if;
end process;
end Behavioral;
----------------------------------------------------------------------------
The register is updated on the rising edge of the clock, whenever at
that
time wr AND wren are both high.
Using the reg entity, I have built a register file with the following
structure:
----------------------------------------------------------------------------
entity regarray is
Port ( din : in std_logic_vector(31 downto 0); -- data input for
register update
dout : out std_logic_vector(31 downto 0); -- data output
dout1 : out std_logic_vector(31 downto 0); -- second data
output
clk : in std_logic; -- clock input
wr : in std_logic; -- write strobe
wrsel : in std_logic_vector(3 downto 0); -- selects a
register to update
rsel : in std_logic_vector(3 downto 0); -- selects a
register for dout
rsel1 : in std_logic_vector(3 downto 0)); -- selects a
register for dout1
end regarray;
architecture Behavioral of regarray is
component reg is
Port ( din : in std_logic_vector(31 downto 0);
dout : out std_logic_vector(31 downto 0);
dout1 : out std_logic_vector(31 downto 0);
wr : in std_logic;
wren : in std_logic;
clk : in std_logic;
oe : in std_logic;
oe1 : in std_logic);
end component;
signal rseldec : std_logic_vector(15 downto 0); -- decoder for
selecting a register for dout
signal rseldec1 : std_logic_vector(15 downto 0); -- decoder for
selecting a register for dout1
signal wrseldec : std_logic_vector(15 downto 0); -- decoder for
selecting a register to update
begin
-- instantiate registers - 16 registers
reg0: reg port map(din, dout, dout1, wrseldec(0), wr, clk, rseldec(0),
rseldec1(0));
reg1: reg port map(din, dout, dout1, wrseldec(1), wr, clk, rseldec(1),
rseldec1(1));
....
reg15: reg port map(din, dout, dout1, wrseldec(15), wr, clk,
rseldec(15), rseldec1(15));
-- infer decoder for dout register select
with rsel select rseldec <=
"0000000000000001" when "0000",
"0000000000000010" when "0001",
...
"1000000000000000" when others;
-- infer decoder for dout1 register select
with rsel1 select rseldec1 <=
"0000000000000001" when "0000",
"0000000000000010" when "0001",
...
"1000000000000000" when others;
-- infer decoder for register update select
with wrsel select wrseldec <=
"0000000000000001" when "0000",
"0000000000000010" when "0001",
...
"1000000000000000" when others;
end Behavioral;
My question is: taking in account the requirements for the register
file
(two outputs, synchronous update), is my implementation correct?
I had a look at the generated schematics (I use Xilinx ISE 6.2)
and it looked fine to me - just what I had imagined - registers,
decoders,
tristate buffers. Is there a better way to code such a register file?
I tried another implementation with two multiplexers instead of
tri-state buses,
but it was taking more space on the FPGA I use (Spartan 3).
Also, I got some warning from the synthesizer that I am clueless about:
WARNING:Xst:1904 - Unit regarray : signal N5634 : Multi-source of
tristates is replaced by logic
There are 64 such warnings and they are apparently concerning the two
output
buses. I think that I am not driving the tristate buffers properly,
but this is the best I could think of. Can you help, please.
Thank you very much!
Stoyan Shopov
I am quite new to VHDL and I have some questions. I am trying to
build a register file consisting of 16 registers, each 32 bits wide.
The register file I need must have two outputs - two of the registers
must be driven on two output buses at any time. The register file
is updated synchronously on the rising edge of clock.
I use Xilinx ISE 6.2.
I am sorry that I put here so much code, but it is simple code
and should not take much time to read.
As a building block I use the 'reg' entity listed below.
entity reg is
Port ( din : in std_logic_vector(31 downto 0); -- data input for
register update
dout : out std_logic_vector(31 downto 0); -- data output
(tristate)
dout1 : out std_logic_vector(31 downto 0); -- identical as
dout above
wr : in std_logic; -- write strobe
wren : in std_logic; -- write enable; I shall make these clear
below
clk : in std_logic; -- clock input
oe : in std_logic; -- output enable for dout output
oe1 : in std_logic); -- output enable for daout1 output
end reg;
architecture Behavioral of reg is
signal idata: std_logic_vector(31 downto 0);
begin
update_reg: process(clk)
begin
if clk'event and clk = '1' then
if wr = '1' and wren = '1' then
idata <= din;
end if;
end if;
end process;
drive_output: process(idata, oe, oe1)
begin
-- drive first output
if oe = '1' then
dout <= idata;
else
dout <= (others => 'Z');
end if;
-- drive second output
if oe1 = '1' then
dout1 <= idata;
else
dout1 <= (others => 'Z');
end if;
end process;
end Behavioral;
----------------------------------------------------------------------------
The register is updated on the rising edge of the clock, whenever at
that
time wr AND wren are both high.
Using the reg entity, I have built a register file with the following
structure:
----------------------------------------------------------------------------
entity regarray is
Port ( din : in std_logic_vector(31 downto 0); -- data input for
register update
dout : out std_logic_vector(31 downto 0); -- data output
dout1 : out std_logic_vector(31 downto 0); -- second data
output
clk : in std_logic; -- clock input
wr : in std_logic; -- write strobe
wrsel : in std_logic_vector(3 downto 0); -- selects a
register to update
rsel : in std_logic_vector(3 downto 0); -- selects a
register for dout
rsel1 : in std_logic_vector(3 downto 0)); -- selects a
register for dout1
end regarray;
architecture Behavioral of regarray is
component reg is
Port ( din : in std_logic_vector(31 downto 0);
dout : out std_logic_vector(31 downto 0);
dout1 : out std_logic_vector(31 downto 0);
wr : in std_logic;
wren : in std_logic;
clk : in std_logic;
oe : in std_logic;
oe1 : in std_logic);
end component;
signal rseldec : std_logic_vector(15 downto 0); -- decoder for
selecting a register for dout
signal rseldec1 : std_logic_vector(15 downto 0); -- decoder for
selecting a register for dout1
signal wrseldec : std_logic_vector(15 downto 0); -- decoder for
selecting a register to update
begin
-- instantiate registers - 16 registers
reg0: reg port map(din, dout, dout1, wrseldec(0), wr, clk, rseldec(0),
rseldec1(0));
reg1: reg port map(din, dout, dout1, wrseldec(1), wr, clk, rseldec(1),
rseldec1(1));
....
reg15: reg port map(din, dout, dout1, wrseldec(15), wr, clk,
rseldec(15), rseldec1(15));
-- infer decoder for dout register select
with rsel select rseldec <=
"0000000000000001" when "0000",
"0000000000000010" when "0001",
...
"1000000000000000" when others;
-- infer decoder for dout1 register select
with rsel1 select rseldec1 <=
"0000000000000001" when "0000",
"0000000000000010" when "0001",
...
"1000000000000000" when others;
-- infer decoder for register update select
with wrsel select wrseldec <=
"0000000000000001" when "0000",
"0000000000000010" when "0001",
...
"1000000000000000" when others;
end Behavioral;
My question is: taking in account the requirements for the register
file
(two outputs, synchronous update), is my implementation correct?
I had a look at the generated schematics (I use Xilinx ISE 6.2)
and it looked fine to me - just what I had imagined - registers,
decoders,
tristate buffers. Is there a better way to code such a register file?
I tried another implementation with two multiplexers instead of
tri-state buses,
but it was taking more space on the FPGA I use (Spartan 3).
Also, I got some warning from the synthesizer that I am clueless about:
WARNING:Xst:1904 - Unit regarray : signal N5634 : Multi-source of
tristates is replaced by logic
There are 64 such warnings and they are apparently concerning the two
output
buses. I think that I am not driving the tristate buffers properly,
but this is the best I could think of. Can you help, please.
Thank you very much!
Stoyan Shopov