Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Best testbench style for microprocessor bus simulation

Reply
Thread Tools

Best testbench style for microprocessor bus simulation

 
 
Doug Miller
Guest
Posts: n/a
 
      01-28-2004
I'm looking for suggestions for improving the brevity and clarity of my
testbenches when I'm simulating software initialization and interrupt
handling over a microprocessor bus. Currently, I use a pair of processes
such as the following:

bus_simplifier: process(addr,din,op)
begin
if (op = write) then
reg_write <= '1';
reg_read <= '0';
reg_en <= '1';
reg_addr <= addr;
reg_data <= din;
elsif (op = read) then
-- etc....
elsif (op = nop) then
-- etc....
end if;
end process;

up_stim: process
variable up_stim_initflag : std_logic := '0';
begin
if (up_stim_initflag = '0') then
-- Startup conditions
op <= nop;
int_vector <= (others => 'U');
wait until reset='1';
wait until reset='0';

-- Read from register
wait until up_clk='1'
wait for 0.1 ns;
addr <= "X"FC000000";
op <= read;
wait for UP_CLK_PERIOD;
op <= nop;
wait for UP_CLK_PERIOD;

-- Read and write lots more registers...

up_stim_initflag :='1'; -- Set flag so initialization code only
executes once

end if; -- end of initialization

-- Start of interrupt processing

wait until interrupt = '1';

-- Read and write lots of registers to imitate software interrupt
processing

end process;

Can anyone suggest a better way to encapsulate and compact this in a better
way? Ideally, I'd like to reduce the 7 lines below the "--Read from
register" line to a single line, while still making the address, data and
operation type easily readable, so that when I need to initialize lots of
registers, I can write it efficiently.

Thanks,
Doug Miller


 
Reply With Quote
 
 
 
 
Jim Lewis
Guest
Posts: n/a
 
      01-29-2004
Doug,
What it sounds like you want is a transaction based
testbench. Using procedures is a good start:

-- Baud Rate = 115200. ExtClk = 20 MHz. Divisor = 11
CpuWrite(CpuRec, UART_DIVISOR_HIGH, X"0000");
CpuWrite(CpuRec, UART_DIVISOR_LOW, X"000A");

-- Configure for Even Parity, One Stop Bit, and 8 Data Bits
CpuWrite(CpuRec, UART_CFG1, X"00" & "00" &
PARITY_EVEN & STOP_BITS_1 & DATA_BITS_;
-- Disable all interrupts (default)
CpuWrite(CpuRec, UART_RX_INT_MASK, X"0000");
CpuWrite(CpuRec, UART_TX_INT_MASK, X"0000");

-- Make it Active and Select EXT CLK
CpuWrite(CpuRec, UART_CFG2, X"00C0");

wait for 5 * tperiod_Clk ;
-- Clear Interrupt Status
CpuRead (CpuRec, UART_RX_INT_STAT, DataO);
CpuRead (CpuRec, UART_TX_INT_STAT, DataO);

. . .

Want to know more? I am giving a half day tutorial on
transaction based testbenches at both DesignCon (February)
and DVCon (March). Details are at:

DesignCon: http://www.designcon.com/conference/tf2.html
DVCon: http://www.dvcon.org/tutorial6.html


Need a more detailed class with labs? SynthWorks is
offering its 3 Day, VHDL Testbenches and Verification
class at public locations. The code shown above is
from the lab files in the class. The next class date
is Feb 25-27 in Dallas, Tx.
Description: http://www.synthworks.com/vhdl_testb...rification.htm
Public Classes: http://www.synthworks.com/public_vhdl_courses.htm


Best Regards,
Jim Lewis
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~
Jim Lewis
Director of Training (E-Mail Removed)
SynthWorks Design Inc. http://www.SynthWorks.com
800-505-8435 (800-505-VHDL) / 503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~



Doug Miller wrote:

> I'm looking for suggestions for improving the brevity and clarity of my
> testbenches when I'm simulating software initialization and interrupt
> handling over a microprocessor bus. Currently, I use a pair of processes
> such as the following:
>
> bus_simplifier: process(addr,din,op)
> begin
> if (op = write) then
> reg_write <= '1';
> reg_read <= '0';
> reg_en <= '1';
> reg_addr <= addr;
> reg_data <= din;
> elsif (op = read) then
> -- etc....
> elsif (op = nop) then
> -- etc....
> end if;
> end process;
>
> up_stim: process
> variable up_stim_initflag : std_logic := '0';
> begin
> if (up_stim_initflag = '0') then
> -- Startup conditions
> op <= nop;
> int_vector <= (others => 'U');
> wait until reset='1';
> wait until reset='0';
>
> -- Read from register
> wait until up_clk='1'
> wait for 0.1 ns;
> addr <= "X"FC000000";
> op <= read;
> wait for UP_CLK_PERIOD;
> op <= nop;
> wait for UP_CLK_PERIOD;
>
> -- Read and write lots more registers...
>
> up_stim_initflag :='1'; -- Set flag so initialization code only
> executes once
>
> end if; -- end of initialization
>
> -- Start of interrupt processing
>
> wait until interrupt = '1';
>
> -- Read and write lots of registers to imitate software interrupt
> processing
>
> end process;
>
> Can anyone suggest a better way to encapsulate and compact this in a better
> way? Ideally, I'd like to reduce the 7 lines below the "--Read from
> register" line to a single line, while still making the address, data and
> operation type easily readable, so that when I need to initialize lots of
> registers, I can write it efficiently.
>
> Thanks,
> Doug Miller
>
>


 
Reply With Quote
 
 
 
 
Jonathan Bromley
Guest
Posts: n/a
 
      01-29-2004
"Jim Lewis" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...

> What it sounds like you want is a transaction based
> testbench. Using procedures is a good start:
>
> -- Baud Rate = 115200. ExtClk = 20 MHz. Divisor = 11
> CpuWrite(CpuRec, UART_DIVISOR_HIGH, X"0000");
> CpuWrite(CpuRec, UART_DIVISOR_LOW, X"000A");

[...]

Is it just me, or does anyone else find this pretty clumsy?

Just to recap, the problem is...
1.We want these procedures to go in a package, for the sake
of reusability.
2.Procedures in a package can't access signals in an architecture
directly, of course, because those signals aren't visible
(don't exist!) when the procedure is analyzed.
3.So whenever we invoke the procedure, we need to provide as
actual parameters not only the stuff that's unique for this
call to the procedure (UART_DIVISOR_HIGH, X"0000") but also
stuff describing the signals that the procedure will activate
(CpuRec).
4.Respectable and reliable authors (Bergeron, Lewis, Cohen, even
our training materials) then advise packaging all these signals
in a record, so it's easier to change the details and less hassle
to invoke the procedure.

So far, so traditional. But I still find it offensive to have to
name the connections every time I invoke the procedure. Am I alone?

I like to add one additional layer of encapsulation, adding a
"wrapper" procedure in the stimulus-generator process...

-- architecture contains the CPU-interface record CpuRec,
signal CpuRec: CpuRec_Type;
-- and this process that does the work...
CPU_stimulus_generator: process

-- Wrapper procedure:
procedure CpuWrite(in REG: Reg_Adrs_Type; in DATA: Data_Type) is
begin
CpuWrite(CpuRec, REG, DATA);
end;

-- and more procedures for CpuRead, etc, etc

begin
...
CpuWrite(UART_DIVISOR_HIGH, X"0000");
CpuWrite(UART_DIVISOR_LOW, X"000A");
...
end process;

The wrapper procedures simply take general-purpose package
procedures like CpuWrite(rec, adrs, data) and specialise them
with the signals that will be used by that specific process.
There's no loss of portability, and IMHO a great gain in clarity
of the mainstream stimulus generator code. Even in complicated
cases, the wrapper procedures are simple and short.

Criticism welcome!
--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: http://www.velocityreviews.com/forums/(E-Mail Removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.



 
Reply With Quote
 
Jim Lewis
Guest
Posts: n/a
 
      01-29-2004
VHDL-200X DTA topic hits about the middle of this thread.

Jim Lewis <(E-Mail Removed)> wrote:
>>What it sounds like you want is a transaction based
>>testbench. Using procedures is a good start:
>>
>> -- Baud Rate = 115200. ExtClk = 20 MHz. Divisor = 11
>> CpuWrite(CpuRec, UART_DIVISOR_HIGH, X"0000");
>> CpuWrite(CpuRec, UART_DIVISOR_LOW, X"000A");


Jonathan Bromley wrote:
>
> [...]
>
> Is it just me, or does anyone else find this pretty clumsy?
>


.... Snip ...

>
> I like to add one additional layer of encapsulation, adding a
> "wrapper" procedure in the stimulus-generator process...
>
> -- architecture contains the CPU-interface record CpuRec,
> signal CpuRec: CpuRec_Type;
> -- and this process that does the work...
> CPU_stimulus_generator: process
>
> -- Wrapper procedure:
> procedure CpuWrite(in REG: Reg_Adrs_Type; in DATA: Data_Type) is
> begin
> CpuWrite(CpuRec, REG, DATA);
> end;
>
> -- and more procedures for CpuRead, etc, etc
>
> begin
> ...
> CpuWrite(UART_DIVISOR_HIGH, X"0000");
> CpuWrite(UART_DIVISOR_LOW, X"000A");
> ...
> end process;
>
> The wrapper procedures simply take general-purpose package
> procedures like CpuWrite(rec, adrs, data) and specialise them
> with the signals that will be used by that specific process.
> There's no loss of portability, and IMHO a great gain in clarity
> of the mainstream stimulus generator code. Even in complicated
> cases, the wrapper procedures are simple and short.
>
> Criticism welcome!


First, I feel your pain. However, since we have
worked the procedures down to only having one extra
signal, the record, I don't feel it that much. To
remove this one signal name, you propose to add the
clutter of the translation procedures and potential
simulation inefficiency of the additional layer of
procedure calls.

Engineering wise, there is probably a balance point.
Your suggestion probably works great if there are only
a few procedures and if no additional procedures will be
added.

I think I would always be willing to type the extra
name. If I was really that concerned about it, I would
make the record name C.

The language is up for revision, so rather than argue
about the merits of the wrapper approach, I would
prefer to brain-storm on language changes that would
help this situation.

The VHDL-200X Data Types and Abstractions (DTA) group
(headed by Peter Ashenden) is looking at adding generics
to packages (including type generics). One of the
things that comes with this is instantiatable
packages. So I have been wondering, if I instantiate
a package in a process declaration region, can the
package see signals in the process environment and
can procedures in the instantiated package see signals
by side-effect? This most would solve the same problem.
Currently it is planned that this feature will be based
on the SUAVE proposal (but perhaps with some syntax
changes). For links to the SUAVE work, go to:
http://www.eda.org/vhdl-200x/vhdl-20...proposals.html


Another problem I have with using a single record is that
the record must be inout (both the transaction source and
the BFMs drive elements of the record). This limits the
record to use of types with a resolution function - and in
my case I take the easy way out by using the std_logic
family. Currently there is a fast track proposal to address
this issue by making it possible to specify modes of record
elements individually. For more information see:
http://www.eda.org/vhdl-200x/vhdl-20...rface_mode.txt

Comments welcome.

More information on the VHDL-200X is at:
http://www.eda.org/vhdl-200x

Anyone can participate as an observer. If you are an IEEE member
and a DASC member you can be a voting member and vote on issues.
However, do note people do listen and are concerned about the
issues of observers. Speaking as the team leader of the
modeling and productivity group and co-team leader of
fast track, I would welcome people with language skills like
Jonathan and Mike to contribute to working group proposal
writing.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~
Jim Lewis
Director of Training (E-Mail Removed)
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~

 
Reply With Quote
 
Jonathan Bromley
Guest
Posts: n/a
 
      01-30-2004
"Jim Lewis" <(E-Mail Removed)> wrote in
message news:(E-Mail Removed)...

> VHDL-200X DTA topic hits about the middle of this thread.


I'll try to get back to following VHDL-200X. I've let it
lapse recently, with other issues taking higher priority -
SystemV*****g, for example

[...]

> > The wrapper procedures simply take general-purpose package
> > procedures like CpuWrite(rec, adrs, data) and specialise them
> > with the signals that will be used by that specific process.
> > There's no loss of portability, and IMHO a great gain in clarity
> > of the mainstream stimulus generator code. Even in complicated
> > cases, the wrapper procedures are simple and short.
> >
> > Criticism welcome!

>
> First, I feel your pain. However, since we have
> worked the procedures down to only having one extra
> signal, the record, I don't feel it that much.


I think I hear what you're saying, but I don't find it
very convincing. [On a second reading of what I've
written below, it sounds a bit combative. It's not meant
to be, and please accept my apologies if it seems so.
A deadline looms, and I don't have time to polish the
phrasing of a newsgroup post!]

> To remove this one signal name, you propose to add...


VHDL is and will probably remain fairly verbose. I have
no problem with that, and never have had. The argument
that says (in parody) productivity=gates/keystrokes is
a bad joke. No, my motivation is definitely NOT to save
keystrokes. It's an encapsulation/hiding issue. Within
the stimulus generator process, I want calls to the BFM
procedures to be parameterised ONLY ON THE THINGS THAT
ARE DIFFERENT PER-CALL: the connected signal is not,
and should be rolled into the procedure.

Remember partial function application in Pop-II (and
LISP, I think, and some functional languages)?

> clutter of the translation procedures


A fair criticism, but I stand by my position that the
specialisation wrappers are invariably simple and small.

> and potential
> simulation inefficiency of the additional layer of
> procedure calls.


BFM procedures are likely to be non-trivial. The
overhead of one more function call and its associated
parameter-passing should be negligible in comparison
with the execution time and memory footprint of the
procedure. Anyhow, any half-decent compiler should
be able to inline calls of that kind that simply pass
on parameters from one procedure to another, especially
as the wrapper procedure is sure to be local to the
process that uses it.

> Engineering wise, there is probably a balance point.
> Your suggestion probably works great if there are only
> a few procedures and if no additional procedures will be
> added.


I agree that it gives rise to a maintenance issue when
new BFM procedures are added to the package.

> I think I would always be willing to type the extra
> name. If I was really that concerned about it, I would
> make the record name C.


AARGH!

> The language is up for revision, so rather than argue
> about the merits of the wrapper approach, I would
> prefer to brain-storm on language changes that would
> help this situation.


My wrapper trick is just a fudge to get a reasonable
compromise between the style I want, the features
available in VHDL, and the pressing need for re-use.
I don't want to promote it as a solution for the future.

The right solution to this problem IMHO is procedural
entry points into entities (as proposed in OOVHDL, I think).
This would give you the wonderful ability from Verilog
of being able to write a BFM module, with procedures to
invoke its functionality but also with ports to connect
(permanently) to the signals it will drive/receive.
The procedure would then be called by an OO-style
"instancename.BFMprocedure(params)" method call.
What's more, VHDL could easily make a good, robust job
of the mutual exclusion problem, which is always a
major issue when you allow this kind of cross-module
access; we could borrow the tasks/entries/rendezvous
mechanism from Ada - it matches this problem beautifully.

> The VHDL-200X Data Types and Abstractions (DTA) group
> (headed by Peter Ashenden) is looking at adding generics
> to packages (including type generics). One of the
> things that comes with this is instantiatable
> packages. So I have been wondering, if I instantiate
> a package in a process declaration region, can the
> package see signals in the process environment and
> can procedures in the instantiated package see signals
> by side-effect? This most would solve the same problem.
> Currently it is planned that this feature will be based
> on the SUAVE proposal (but perhaps with some syntax
> changes). For links to the SUAVE work, go to:
> http://www.eda.org/vhdl-200x/vhdl-20...proposals.html


Thanks for the link. Again, I'll try to get up to speed with
it in the next few weeks, as time permits.

> Another problem I have with using a single record is that
> the record must be inout (both the transaction source and
> the BFMs drive elements of the record). This limits the
> record to use of types with a resolution function - and in
> my case I take the easy way out by using the std_logic
> family. Currently there is a fast track proposal to address
> this issue by making it possible to specify modes of record
> elements individually.


This issue is another reason why I tend to prefer NOT using
records, so that signal-class "port" parameters can be given
their proper directions - then the "wrapper" trick looks
even more useful.

> For more information see:

http://www.eda.org/vhdl-200x/vhdl-20...site_interface
_mode.txt
> Comments welcome.


Not until I've had a chance to look very much more carefully!

Thanks for your comments and all the references.
--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (E-Mail Removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Style Request for Testbench with Bus Interfaces M. Norton VHDL 1 04-01-2011 03:24 PM
Style Request for Testbench with Bus Interfaces M. Norton VHDL 9 03-30-2011 10:10 PM
testbench for a microprocessor Mr.X VHDL 5 04-09-2008 03:55 PM
Address Bus and External Data Bus Confusion LoXodonte A+ Certification 1 04-18-2006 09:09 PM
Re: Best testbench style for microprocessor bus simulation Mike Treseler VHDL 1 01-29-2004 10:48 PM



Advertisments