On my current testbench I want to simulate an operation that will occur
many times, like a write to my chip's control registers from the PCI
controller. How do I do this while keeping the code simple?
I'm using procedures but getting a "no feasible entries" error, perhaps
because I'm passing signals into the procedures, or maybe something to do
with how I'm modifying them within the procedures. Being as how I have
little experience with either procedures or testbenches, please help!!
Dan
I'm currently trying something like this:
ARCHITECTURE test_bench OF myentity IS
...--component list
...--signal list
PROCEDURE PCILB_WRITE
(chip_en : OUT STD_LOGIC;
wr_en : OUT STD_LOGIC;
a_bus : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
d_bus : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
address : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
word : IN STD_LOGIC_VECTOR(15 DOWNTO 0)) IS
BEGIN
-- assignment statements and wait statements
END PCILB_WRITE;
BEGIN
--component instantiation
--clock gen process
--reset process
...
pci : PROCESS
BEGIN
PCILB_WRITE(<signalnames>);
--repeated many times, with "read" procedures in there too
END PROCESS pci;
END test_bench;
(code is hand copied from x terminal, please ignore minor syntax errors)
Sent via Deja.com http://www.deja.com/
Before you buy.
if i recall correctly, this error occurrs when you have an object of a
different type than what the procedure expects. for example, if you try
to put a signal of type std_logic where one of std_logic_vector should
go in a procedure call.
ciao!
RoLm
> if i recall correctly, this error occurrs when you have an object of a
> different type than what the procedure expects. for example, if you try
> to put a signal of type std_logic where one of std_logic_vector should
> go in a procedure call.
How about "cannot drive signal <signalname> from this subprogram" ?
What are the root causes of that error? The signals I'm trying to drive
are all globals.
DJS
Below is an example of the problem you describe:
library ieee;
use ieee.std_logic_1164.all;
entity T is
end entity T;
architecture RTL of T is
signal S : std_logic_vector(7 downto 0);
signal M : std_logic_vector(7 downto 0);
procedure P (
signal Q : in std_logic_vector;
constant K : in std_logic_vector) is
begin -- procedure P
if Q'event then
S <= K;
else
S <= (others => '0');
end if;
end procedure P;
begin -- architecture RTL
P(M, "01010000"); -- concurrent procedure
end architecture RTL;
-- %vcom -93 -work work_lib proc.vhd
-- Model Technology ModelSim SE/EE vcom 5.4b Compiler 2000.06 Jun 8 2000
-- -- Loading package standard
-- -- Loading package std_logic_1164
-- -- Compiling entity t
-- -- Compiling architecture rtl of t
-- ###### proc.vhd(15): S <= K;
-- ERROR: proc.vhd(15): Cannot drive signal s from this subprogram.
-- ###### proc.vhd(17): S <= (others => '0');
-- ERROR: proc.vhd(17): Cannot drive signal s from this subprogram.
-- ###### proc.vhd(26): end architecture RTL;
-- ERROR: proc.vhd(26): VHDL Compiler exiting
You have this problem because of driver creation issues. Drivers are created
at elaboration. A procedure can READ signals within its scope of view (e.g.,
local to its architecture, or global in packages if packages are visible). But
a procedure declared in the declaration section of an architecture or in
packages CANNOT assign to signals because those procedures cannot create
drivers. If the procedure is declared from within the declaration section of a
PROCESS, then the drivers BELONG to the process, and at that point you can have
side-effects.
You could argue that the instantion of the procedure (e.g., P) would recognize
that the body of the procedure has an assignment to a signal, and the
compiler/elaborator could create the drivers. Howewver, that means that the
compiler needs to look into the body of subprograms. But, in VHDL, you should
be able to compile a program with the declarations of packages (no body in
procedures declared there). Thus, if you say that is "kosher", then that
creates all kinds of problems, particularly in assignments to unresolved
signals. To keep things less complex and clean side effects assignments to
signals in procedures not declared in processes is illegal. Hope that explains
things.
-----------------------------------------------------
VhdlCohen Training, Consulting, Verification
Ben Cohen vhdl...@aol.com (310) 721-4830
http://www.vhdlcohen.com/
Author of following textbooks:
VHDL Coding Styles and Methodologies, 2nd Edition,
isbn 0-7923-8474-1 Kluwer Academic Publishers, 1999
VHDL Answers to Frequently Asked Questions, 2nd Edition,
isbn 0-7923-8115-7 Kluwer Academic Publishers, 1998
------------------------------------------------------
OK... I moved my procedure to within my process, but the remaining error
is a "no feasible entries for subprogram <name>" error, thrown on the
line in which I call the procedure. The data types match, so what else
am I doing wrong?
You are talking about *TestBench* difficulties, yes?
But it seems to me that your current problem is related
with procedure itself .... I doubt if procedure itself
could be instantiated without proper process wrapping
for this porpose.
How about to concentrate into your original *TestBench*
term, and lets see from where your signals come from or
to where they are going to.
Next, how about to think in mind that if you are VHDL
compiler itself, lets see how you&vhdl will solve your
source code's requests.
This is a TestBench, so your TB have to have targets
with which, you are to communicate with.
If your target is a component, then, it is really clear
that TB will talk through your entity. And as you well
known, it is port map to be used there in such cases.
But you are now,I don't know reason why, intend to
use *procedure* instead of *component*.
Then, your procedure have to have a explicit solution
what input and output signals are to be connected with
your TB.
Is'nt this why your compiler is complaining that
*no feasible entities* with your code ?
I hope If following code could be some ref for you.
(I didn't pay any care about your original code meant for)
*******************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity TB is
constant Tick : time := 10 ns;
signal i : integer;
end entity TB;
architecture RTL of TB is
signal S : std_logic_vector(7 downto 0);
signal M : std_logic_vector(7 downto 0):=(others=>'0');
procedure P (
signal Q : in std_logic_vector(7 downto 0);
signal SX : out std_logic_vector(7 downto 0);
constant K : in std_logic_vector(7 downto 0)) is
begin -- procedure P
if Q'event then SX <= K;
else SX <= (others => '0');
end if;
end procedure P;
begin -- architecture RTL
M_GEN : process
Begin M <= M+1; wait for Tick;
end process M_GEN;
a:process(M)
begin
for i in 0 to 10 loop P(M,S,"01010000");
end loop;
end process a;
end architecture RTL;
-- confirmed with MTI/PE5.4b
*******************************************
I will be really sorry if I misunderstanding current
thread here. But,this thread seems not finalized yet,
I beard my stupid post here to conclude this.
Best regards.