Constants and signals in procedures

C

Chris P

I am trying to create a simulation environment in VHDL and I keep
running into this problem.

I have an register address map, which I'd like to maintain a single
copy of in a package file called "global_pkg". I define the address
values using constants, so I can use them in a case statement, which
requires static (i.e., non-signals) in the expressions.

constant ADDR_0 : std_logic_vector(15 downto 0) := X"0000";
constant ADDR_1 : std_logic_vector(15 downto 0) := X"0000";
constant ADDR_2 : std_logic_vector(15 downto 0) := X"0000";

Then I can reference these in my RTL:

case addr is
when ADDR_0 =>
reg_0 <= wrdata;
when ADDR_1 =>
reg_1 <= wrdata;

etc.

The trouble begins when I want to use procedures in my sim to access
these registers.

I have a procedure called "cpu_wr" that takes an address and data to
write:

procedure cpu_wr (
signal wr_addr : in std_logic_vector;
signal wr_data : in std_logic_vector) is
begin
-- Write the address registers
testbench.cpu_pkg.cpu_wr(
wr_addr,
wr_data);
wait for PERIOD_CLKCPU;
end procedure cpu_wr;


I'd like to call this procedure using the global address constants,
but VHDL doesn't allow a constant to be passed to a signal port on a
procedure:


cpu_wr(
work.global_pkg.ADDR_0,
wr_data);

My simulator gives me the following error:

Actual (constant "ADDR_0") for formal "wr_addr" is not a signal.

I've worked around this by maintaining two versions of the ADDR_*
paramaters; the constant version and the signal version:

constant ADDR_0 : std_logic_vector(15 downto 0) := X"0000";
signal ADDR_0_SIG : std_logic_vector(15 downto 0) := X"0000";

Is there another way to do this? It seems odd that VHDL won't allow a
constant of std_logic_vector to be passed to a signal of
std_logic_vector.

Thanks for your time.

-----------------------------------------------------------------------------
 
M

Mike Treseler

Chris said:
I've worked around this by maintaining two versions of the ADDR_*
paramaters; the constant version and the signal version:

constant ADDR_0 : std_logic_vector(15 downto 0) := X"0000";
signal ADDR_0_SIG : std_logic_vector(15 downto 0) := X"0000";

Is there another way to do this?

Yes.
I use simulation procedures more to
collect repeated blocks of code
than to parametrize.

In this case, I can make things real
simple by declaring procedures like this,

procedure write_data is
begin
expect_v := random_byte_s;
address_s <= '0';
writedata_s <= std_logic_vector(expect_v);
tic;
toggle(write_stb_s);
end procedure write_data;

in the test process scope with few parameters.
For details, see the testbench here:
http://mysite.verizon.net/miketreseler/
It seems odd that VHDL won't allow a
constant of std_logic_vector to be passed to a signal of
std_logic_vector.

It makes sense.
You can pass a signal as a constant, but not vice-versa.
How could the process alter the value of a constant?

If you really want to use signal parameters
in a library, see the 'Remote Testbench Procedure'
example on the same page.

Good luck.

-- Mike Treseler
 
K

KJ

Chris P said:
I am trying to create a simulation environment in VHDL and I keep
running into this problem.
The trouble begins when I want to use procedures in my sim to access
these registers.

I have a procedure called "cpu_wr" that takes an address and data to
write:

procedure cpu_wr (
signal wr_addr : in std_logic_vector;
signal wr_data : in std_logic_vector) is
begin
I'd like to call this procedure using the global address constants,
but VHDL doesn't allow a constant to be passed to a signal port on a
procedure:

That's because a procedure 'could' use signal attributes (like 'event as an
example if you wanted to detect a rising edge). Constants don't have such
attributes. Even if your procedure doesn't happen to use these attributes,
the fact that it could means that if you really want to pass an input signal
into a procedure then you can't pass it a constant.
I've worked around this by maintaining two versions of the ADDR_*
paramaters; the constant version and the signal version:
Is there another way to do this? It seems odd that VHDL won't allow a
constant of std_logic_vector to be passed to a signal of
std_logic_vector.

Get rid of the 'signal' changing the procedure to this...

procedure cpu_wr (
wr_addr : in std_logic_vector;
wr_data : in std_logic_vector) is
....

Kevin Jennings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top