Reputation: 790
I'm trying to write register file in VHDL. Firstly I'm define storing element for N bits. Secondly implement register file, with WA(write address), RA(read address), WDR/RDP (write/read data port) and other things. After that generate testbench for regfile, but in test getting "X", when taken any data by RA address. How I can fix this? Maybe something wrong in implentation of my regfile?
a) Store element for data
library ieee;
use ieee.std_logic_1164.all;
entity REGn is
generic(INITREG: std_logic_vector:="1001");
port(Din : in std_logic_vector(INITREG'range);
EN : in std_logic;
INIT: in std_logic;
CLK : in std_logic;
OE : in std_logic;
Dout: out std_logic_vector(INITREG'range));
end REGn;
architecture beh_regn of REGn is
signal reg: std_logic_vector(INITREG'range);
constant ALLZ: std_logic_vector(INITREG'range):=(others => 'Z');
begin
Main: process(Din, EN, INIT, CLK)
begin
if INIT = '1' then
reg <= INITREG;
elsif EN = '1' then
if rising_edge(CLK) then
reg <= Din;
end if;
end if;
end process;
Dout <= reg when OE='0' else ALLZ;
end beh_regn;
b) Register file
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity REGFile is
generic(INITREG: std_logic_vector:="0000";
a : integer:=2);
port(INIT: in std_logic;
WDP : in std_logic_vector(INITREG'range);
WA : in std_logic_vector(a-1 downto 0);
RA : in std_logic_vector(a-1 downto 0);
WE : in std_logic;
RDP : out std_logic_vector(INITREG'range));
end REGFile;
architecture beh_regfile of REGFile is
component REGn is
generic(INITREG: std_logic_vector:="1001");
port(Din: in std_logic_vector(INITREG'range);
EN : in std_logic;
INIT: in std_logic;
CLK : in std_logic;
OE : in std_logic;
Dout: out std_logic_vector(INITREG'range));
end component;
signal wen: std_logic_vector(2**a-1 downto 0);
signal ren: std_logic_vector(2**a-1 downto 0);
signal readd: std_logic_vector(INITREG'range);
begin
-- Write decoder
WAD: process(WA)
begin
for i in 0 to 2**a-1 loop
if i = CONV_INTEGER(WA) then
wen(i) <= '1';
else
wen(i) <= '0';
end if;
end loop;
end process;
-- Read decoder
RAD: process(RA)
begin
for i in 0 to 2**a-1 loop
if i = CONV_INTEGER(RA) then
ren(i) <= '1';
else
ren(i) <= '0';
end if;
end loop;
end process;
REGi: for i in 2**a-1 downto 0 generate
REGi: REGn generic map (INITREG)
port map (WDP, wen(i), INIT, WE, ren(i), readd);
end generate;
RDP <= readd;
end beh_regfile;
c) Testbench for register file
library ieee;
library std;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use std.textio.all;
-- Add your library and packages declaration here ...
entity regfile_tb is
-- Generic declarations of the tested unit
generic(
INITREG : STD_LOGIC_VECTOR := "0000";
a : INTEGER := 2 );
end regfile_tb;
architecture TB_ARCHITECTURE of regfile_tb is
-- Component declaration of the tested unit
component regfile
generic(
INITREG : STD_LOGIC_VECTOR := "0000";
a : INTEGER := 2 );
port(
INIT : in STD_LOGIC;
WDP : in STD_LOGIC_VECTOR(INITREG'range);
WA : in STD_LOGIC_VECTOR(a-1 downto 0);
RA : in STD_LOGIC_VECTOR(a-1 downto 0);
WE : in STD_LOGIC;
RDP : out STD_LOGIC_VECTOR(INITREG'range) );
end component;
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal INIT : STD_LOGIC;
signal WDP : STD_LOGIC_VECTOR(INITREG'range);
signal WA : STD_LOGIC_VECTOR(a-1 downto 0);
signal RA : STD_LOGIC_VECTOR(a-1 downto 0);
signal WE : STD_LOGIC;
-- Observed signals - signals mapped to the output ports of tested entity
signal RDP : STD_LOGIC_VECTOR(INITREG'range);
-- Add your code here ...
type TEST_REC is record
INIT : STD_LOGIC;
WDP : STD_LOGIC_VECTOR(INITREG'range);
WA : STD_LOGIC_VECTOR(a-1 downto 0);
RA : STD_LOGIC_VECTOR(a-1 downto 0);
WE : STD_LOGIC;
end record;
type TEST_ARRAY is array(positive range <>) of TEST_REC;
constant PATTERN : test_array:= (
-- initialize
(INIT=>'1', WDP=>"0000", WA=>"00", RA=>"00", WE=>'0'),
(INIT=>'1', WDP=>"0000", WA=>"01", RA=>"01", WE=>'0'),
(INIT=>'1', WDP=>"0000", WA=>"10", RA=>"10", WE=>'0'),
(INIT=>'1', WDP=>"0000", WA=>"11", RA=>"11", WE=>'0'),
--- test vectors
(INIT=>'0', WDP=>"1000", WA=>"00", RA=>"00", WE=>'1'),
(INIT=>'0', WDP=>"1000", WA=>"00", RA=>"00", WE=>'0')
);
begin
-- Unit Under Test port map
UUT : regfile
generic map (
INITREG => INITREG,
a => a
)
port map (
INIT => INIT,
WDP => WDP,
WA => WA,
RA => RA,
WE => WE,
RDP => RDP
);
-- Add your stimulus here ...
process
variable VECTOR: TEST_REC;
begin
for i in PATTERN'range loop
VECTOR:= PATTERN(i);
INIT <= VECTOR.INIT;
WDP <= VECTOR.WDP;
WA <= VECTOR.WA;
RA <= VECTOR.RA;
WE <= VECTOR.WE;
wait for 100 ns;
end loop;
end process;
process
variable my_line: line;
begin
wait for 5ns;
write(my_line,"WDP=");
write(my_line,WDP);
write(my_line," INIT=");
write(my_line,INIT);
write(my_line," WA=");
write(my_line,WA);
write(my_line," RA=");
write(my_line,RA);
write(my_line," RDP=");
write(my_line,RDP);
writeline(output,my_line);
wait for 96ns;
end process;
end TB_ARCHITECTURE;
configuration TESTBENCH_FOR_regfile of regfile_tb is
for TB_ARCHITECTURE
for UUT : regfile
use entity work.regfile(beh_regfile);
end for;
end for;
end TESTBENCH_FOR_regfile;
Upvotes: 0
Views: 2472
Reputation:
Your output enables aren't correct:
(image linked to full size image)
Notice three are low at the same time for all four Regn instances and they cause a conflict for the bit of Readd that's different.
In architecture beh_regn of Regn:
Dout <= reg when OE='0' else ALLZ;
With three output enables '0', a conflict between a '1' and '0' resolves to 'X' (see package std_logic_1164, the body, resolution_table).
You have the assignments to ren(i) inverted, should be:
-- Read decoder
RAD: process(RA)
begin
for i in 0 to 2**a-1 loop
if i = CONV_INTEGER(RA) then
ren(i) <= '0'; -- was '1'
else
ren(i) <= '1'; -- was '0'
end if;
end loop;
end process;
No guarantee this is all that is wrong, but answers "... in test getting "X", when taken any data by RA address. How I can fix this? Maybe something wrong in implentation of my regfile?"
(Invert the assignments to ren(i), yes there is something wrong in REGFile).
Also note despite your VHDL tool allowing it you are required to have white space between a numerical literal and a following identifier (e.g. 96ns
in your test bench). That won't change in the next revision of the standard.
Upvotes: 1