Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How can I initialize variable in VHDL?

2,452 views
Skip to first unread message

Derek May

unread,
Jul 14, 1995, 3:00:00 AM7/14/95
to
I am writing a VHDL model of a DRAM, and I want to be able to initialize the
memory array. I currently have a process that writes to and reads from
memory (I have shown a simplified version of the process below). The variable
"memory" is an array of vectors and I want to be able to initialize this
variable with data supplied in an input file.

TYPE dram_array IS array( 0 to 1048576) OF std_logic_vector(15 downto 0);

read_write : PROCESS (mode)
VARIABLE memory : dram_array;
VARIABLE index : integer := 0;
VARIABLE input_reg : std_logic_vector(15 downto 0);
VARIABLE output_reg : std_logic_vector(15 downto 0);

index := to_unsigned(address);
IF mode = read THEN
output_reg(15 downto 0) <= memory(index)(15 downto 0);
ELSIF mode = write THEN
memory(index)(15 downto 0) := input_reg(15 downto 0);
END IF;
END PROCESS read_write;


Note: I have very little VHDL programming experience, so please bear with me
if my terminology is incorrect.

I currently have a test bench program that is separate from my main functional
VHDL program. My test bench program reads a test vector file and supplies the
input signals (address, data, enables, etc) to my main functional program. I
would like to be able to read an initialization file with the test bench
program and somehow initialize the memory variable.

I know that global variables are not allowed in VHDL, so I would like to know
if anyone has any suggestions on how I might accomplish this task.

Thanks in advance,
Derek

Bsgriffin

unread,
Jul 16, 1995, 3:00:00 AM7/16/95
to
In article <3u6l62$p...@tilde.csc.ti.com>, dm...@hp.memh.ti.com (Derek May)
writes:

>Subject: How can I initialize variable in VHDL?
>From: dm...@hp.memh.ti.com (Derek May)
>Date: 14 Jul 1995 20:48:02 GMT

First let me point out that your memory will consume approx 16M (16
milliion) bytes of memory. This
is likely to cause performance problems in just about every VHDL
simulator. Unless you really need
to store 'X's and 'Z's in each memory location, you might consider using
an array of integers to store
the memory contents. This will reduce the memory requirements of the
simulator by a factor of four.
It also simplifies initializing the memory from a file.

To initialize the memory write a procedure that will open a file and read
a memory address and value
on each line and place it in the memory. Something like this:

procedure load( mem : inout dram_array; fn : in string ) is
variable l : line;
file fp : text is in fn;
variable addr : integer;
variable data : integer;
begin

while not endfile(fp) loop
readline(l, fp);
read(addr, l);
read(data, l);
mem(addr) := data;
end loop;

end procedure;

The file contents would then look something like this:

0 10
1 65443
2 3373
3 1245
100 8989

etc.

This is a very simple approach. More sophisticated methods are possible.

As for using an integer memory, the read_write process would only need a
couple of small changes.
You need to add a type conversion when reading or writing the memory.
I'll leave the bodies of these
functions as an exercise to the user. Here is where they go:

TYPE dram_array IS array( 0 to 1_048_576) OF integer;

function toInteger ( sv : std_logic_vector ) return integer;
function toSLV ( i : integer ) return std_logic_vector;

read_write : PROCESS (mode)
VARIABLE init : boolean := FALSE;


VARIABLE memory : dram_array;
VARIABLE index : integer := 0;
VARIABLE input_reg : std_logic_vector(15 downto 0);
VARIABLE output_reg : std_logic_vector(15 downto 0);

begin
IF init THEN


index := to_unsigned(address);
IF mode = read THEN

output_reg(15 downto 0) <= toSLV( memory(index) );


ELSIF mode = write THEN

memory(index) := toInteger( input_reg );
END IF;
ELSE
load( memory, "memdata.dat" );
init := TRUE;
END IF;
END PR

VhdlCohen

unread,
Jul 17, 1995, 3:00:00 AM7/17/95
to
dm...@hp.memh.ti.com (Derek May) wrote:
>>I am writing a VHDL model of a DRAM, and I want to be able to initialize
the
>>memory array. ...

>>I would like to be able to read an initialization file with the test
bench
>> program and somehow initialize the memory variable.

Enclosed is a memory model extracted from the testbench chapter (p. 254)
of my book "VHDL Coding Styles and Methodologies", Kluwer Academics.
It is close to your model, and demonstrates how a memory can be
initialized from a file. The model includes a package for the type
conversion (character to Std_Logic).
Of course, this presents one solution of the many possible solutions .
--------------------------------------------------------------------------
-----
-- Title : Memory Component
-- Description : Model a memory which is initialized by a file.

-- Memory Operation: Memory is initialized at startup from
-- file "memdata.txt.
--
-- READ <- write at this edge
--
-- RdWrF --------+ +------
-- +______+
--
-- CeF ---+ +---+ +------
-- +--+ +-------+
--------------------------------------------------------------------------
-----
-- Revisions :
-- Date Author Revision Comments
-- Sun Dec 11 12:24:46 1994 cohen Rev A Creation
--------------------------------------------------------------------------
-----
library IEEE;
use IEEE.Std_Logic_1164.all;

package Mem_Pkg is
constant DataWidth_c : natural; -- Data width
constant AddrWidth_c : natural; -- Address width
constant MaxDepth_c : natural;

function CharToStd(Char_v : character) return Std_Logic;
end Mem_Pkg;

package body Mem_Pkg is
constant DataWidth_c : natural := 8; -- deferred constant
constant AddrWidth_c : natural := 16; -- Address width
constant MaxDepth_c : natural := 2 ** AddrWidth_c; -- 64K

function CharToStd(Char_v : character) return Std_Logic is
begin
case Char_v is
when '1' => return '1';
when '0' => return '0';
when others =>
return '0';
assert false
report "Input Character is NOT a 1 or 0"
severity warning;
end case; -- Char_v
end CharToStd;

end Mem_Pkg;

library IEEE; -- used because Std_Logic
use IEEE.Std_Logic_1164.all; -- signals are resolved

library ATEP_Lib;
use ATEP_Lib.Mem_Pkg.all;
use ATEP_Lib.Mem_Pkg;

entity Memory_Nty is
generic (FileName_g : String(1 to 12):= "memdata_.txt");
port(
MemAddr : in natural;
MemData : inout Std_Logic_Vector(Mem_Pkg.DataWidth_c - 1 downto
0);
RdWrF : in Std_Logic;
CeF : in Std_Logic); -- Chip Select
end Memory_Nty;


architecture Memory_a of Memory_Nty is

begin -- Memory_a

Memory_Lbl : process(MemAddr, MemData, RdWrF, CeF)
use Std.TextIO.all; -- localize TextIO to this process
use Std.TextIO;

subtype Data_Typ is
Std_Logic_Vector(Mem_Pkg.DataWidth_c - 1 downto 0);
subtype MemSize_Typ is integer range 0 to Mem_Pkg.MaxDepth_c - 1;
type Mem_Typ is array(MemSize_Typ) of Data_Typ;

variable Memory_v : Mem_Typ;
variable Initialization_v : boolean := true;
file MemData_f : TextIO.text is in FileName_g;

procedure MemoryData -- Preload memory from a file, VHDL'87
(variable FileName_v : in TextIO.text;
variable Memory_v : inout Mem_Typ) is

variable InLine_v : TextIO.line;
variable MemAddress_v : MemSize_Typ := 0; -- 0 to 64k
variable Word_v : Data_Typ;
variable WordIndex_v : natural;
begin
File_Lbl : while not TextIO.Endfile(MemData_f) loop
-- Read 1 line from the input file
TextIO.ReadLine(MemData_f, InLine_v);

-- Test if InLine_v is an empty line,
next File_Lbl when InLine_v'length = 0; -- null line
if InLine_v'length < DataWidth_c then -- error
assert false
report "Data width in file is less than defined width"
severity warning;
next File_Lbl;
-- detect lines of 80 characters with spaces
elsif InLine_v(DataWidth_c) = ' ' then -- error
assert false
report "Data width in file is less than defined width"
severity warning;
next File_Lbl;
end if;
-- Read a data word
WordIndex_v := InLine_v'left;
-- Convert characters to Std_Logic and fill a data word
LoadWord_Lbl : for W_i in Mem_Pkg.DataWidth_c - 1 downto 0 loop
Word_v(W_i) := Mem_Pkg.CharToStd(InLine_v(WordIndex_v));
WordIndex_v := WordIndex_v + 1;
end loop LoadWord_Lbl;
-- Store word in memory and increment address index
Memory_v(MemAddress_v) := Word_v;
MemAddress_v := MemAddress_v + 1;
end loop File_Lbl;
end MemoryData;


begin -- process Memory_Lbl
-- Load memory if in initialization
if Initialization_v then
MemoryData(FileName_v => MemData_f,
Memory_v => Memory_v);
Initialization_v := false;
end if;

-- Normal operation
if CeF = '0' then -- memory transaction
if RdWrF'event and
RdWrF'last_value = '0'and -- positive transition
RdWrF = '1' then -- of RdWrF
Memory_v(MemAddr) := MemData; -- WRITE OPERATION
elsif RdWrF = '1' then -- memory read
MemData <= Memory_v(MemAddr);
end if;
else
MemData <= (others => 'Z');
end if;
end process Memory_Lbl;

end Memory_a;

-- Example of data in "memdata.txt"
10000000
1111000
01001101 -- Only 1st 8 characters are read
10101001
11111
00000000
10000000
11110000
01001101
-- If line is less than 8 characters (in this case), then its an error.

0 new messages