Wow! No TestbenchWow!

R

rickman

This is the first project I've done in Verilog in many years. With a
long history in VHDL I have a new perspective and am seeing Verilog in
a different way. I am finding some of the differences to be pretty
interesting actually.

I've already commented on the lack of the wildcard sensitivity only to
find that VHDL has recently added this. Now I am learning how Verilog
allows hierarchical path references to signals for test benches. This
is awesome!!! I would love to have had this in Verilog. It is such a
PITA to have to bring every generic or debug signal to the top of a
design just to support a test bench.

.... or did I miss something again?

Rick
 
T

Tim McBrayer

rickman said:
This is the first project I've done in Verilog in many years. With a
long history in VHDL I have a new perspective and am seeing Verilog in
a different way. I am finding some of the differences to be pretty
interesting actually.

I've already commented on the lack of the wildcard sensitivity only to
find that VHDL has recently added this. Now I am learning how Verilog
allows hierarchical path references to signals for test benches. This
is awesome!!! I would love to have had this in Verilog. It is such a
PITA to have to bring every generic or debug signal to the top of a
design just to support a test bench.

... or did I miss something again?

Yep; VHDL 2008 added External Names (P1076-2008, section 8.7), which I believe are the
moral equivalent of Verilog hierarchical references. Google's first hit on them:

http://www.doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/vhdl_200x_ease/#hierarchicalnames
 
H

HT-Lab

"rickman" wrote in message
...
I've already commented on the lack of the wildcard sensitivity only to
find that VHDL has recently added this. Now I am learning how Verilog
allows hierarchical path references to signals for test benches. This
is awesome!!! I would love to have had this in Verilog. It is such a
PITA to have to bring every generic or debug signal to the top of a
design just to support a test bench.

.... or did I miss something again?

Yes, VHDL2008 supports hierarchical references (works fine in Modelsim
10.0), before that you had SignalSpy and many other custom solutions to this
issue.

<<signal .test2008_tb.u1.muxout : std_logic_vector(2 downto 0) >> <= force
"011"; -- inject error

Hans.
www.ht-lab.com
 
P

Paul Uiterlinden

rickman said:
This is the first project I've done in Verilog in many years. With a
long history in VHDL I have a new perspective and am seeing Verilog in
a different way. I am finding some of the differences to be pretty
interesting actually.

I've already commented on the lack of the wildcard sensitivity only to
find that VHDL has recently added this. Now I am learning how Verilog
allows hierarchical path references to signals for test benches. This
is awesome!!! I would love to have had this in Verilog. It is such a
PITA to have to bring every generic or debug signal to the top of a
design just to support a test bench.

... or did I miss something again?

Yes! ;-)
Well, maybe....

For bringing up debug signals to the testbench you can use "global" signals
declared in a package. It is not synthesizable (but for debug signals that
would not be a problem). Also, the assignment to the global signal has to
take place at the location were the object to be observed is visible.

Example:

PACKAGE pkg IS
SIGNAL spy: std_logic_vector(7 DOWNTO 0);
END PACKAGE pkg;

In the architecture where you want to observe a signal:

USE work.pkg.ALL;
ARCHITECTURE arch OF design_block IS
BEGIN
...
spy <= observed_signal;
...
END ARCHITECTURE arch;

In your testbench:

USE work.pkg.ALL;
ARCHITECTURE arch OF tb IS
BEGIN
...
-- spy is visible here, due to the USE statement
IF spy = ... -- whatever
...
END ARCHITECTURE arch;


Another way to do all this is using the new VHDL-2008 feature
called "external names". Then you can peek into the DUV every which way you
want, without the need of changing DUV code.

Example (from the Ashenden/Lewis book: VHDL-2008 just the new stuff):

ASSERT <<SIGNAL .tb.duv.controller.state: std_logic_vector(0 TO 4)>>
/= "00000"
REPORT "Illegal controller state";

VHDL-2008 also includes FORCE and RELEASE assignments. This means that you
don't need simulator dependant commands anymore for forcing signals in the
DUT.

I have no idea if there already is a simulator that supports these
constructs.
 
C

comp arch

This is the first project I've done in Verilog in many years.  With a
long history in VHDL I have a new perspective and am seeing Verilog in
a different way.  I am finding some of the differences to be pretty
interesting actually.

I've already commented on the lack of the wildcard sensitivity only to
find that VHDL has recently added this.  Now I am learning how Verilog
allows hierarchical path references to signals for test benches.  This
is awesome!!!  I would love to have had this in Verilog.  It is such a
PITA to have to bring every generic or debug signal to the top of a
design just to support a test bench.

... or did I miss something again?

Rick

I've always thought that it would be nice if FPGA synthesis tools
supported the hierarchical path names too.
i.e. if you wanted to debug a core with chipscope, you could do

assign trig0[0] = my_core.some_internal_block.troublesome_node;
 
S

Sean Durkin

rickman said:
This is the first project I've done in Verilog in many years. With a
long history in VHDL I have a new perspective and am seeing Verilog in
a different way. I am finding some of the differences to be pretty
interesting actually.

I've already commented on the lack of the wildcard sensitivity only to
find that VHDL has recently added this. Now I am learning how Verilog
allows hierarchical path references to signals for test benches. This
is awesome!!! I would love to have had this in Verilog. It is such a
PITA to have to bring every generic or debug signal to the top of a
design just to support a test bench.

If you're using ModelSim, there's a library "modelsim_lib" that has a
function called "SignalSpy". With that you can access any signal in your
design from a test bench. Use it like this:

library modelsim_lib;
use modelsim_lib.util.all;

-- entity, architecture, signal declarations skipped

-----------------------------------------------------------------------------
-- spy process
-----------------------------------------------------------------------------
sig_spy : process is
begin
init_signal_spy("/DUT/submodule1/submodule2/interesting_signal",
"tb_sig", 1);
wait;
end process sig_spy;

This connects "interesting_signal" to your test bench signal "tb_sig".

This is not synthesizable and you have to consider ModelSim's built in
optimization, which might optimize away the signal you want to look at
during elaboration, but it's a start and works with older VHDL releases.
Doesn't work for GENERICs, though...

HTH,
Sean
 
P

Pontus

I've always thought that it would be nice if FPGA synthesis tools
supported the hierarchical path names too.
i.e. if you wanted to debug a core with chipscope, you could do

assign trig0[0] = my_core.some_internal_block.troublesome_node;

VHDL:
I've successfully used signals in packages (global signals) in
synthesis (synplify).
Declare a signal in a package (I used std_ulogic to try to catch
multiple drivers
at compile time, but the error(s) came at elaboration...).

So at the top entity you "use debug_pkg" and get access to the
debug_signal.
Just drive it to your output, i.e.
debug_pin <= debug_signal;

In the lower level entity, also "use debug_pkg" and send your
troublesome_node to the debug_signal:
debug_signal <= troublesome_node;

HTH -- Pont
 
J

Jonathan Bromley

Now I am learning how Verilog
allows hierarchical path references to signals for test benches. This
is awesome!!!

Not as awesome as the ability to call tasks
(procedures) in a module, from another module.
That's just the neatest thing ever, for
stimulus generation. This little example
should give you a flavour of what you can do:

`timescale 1ns/1ns

module simulatedUartTransmitter(output reg TxD);
time bitTime;
//
task setBitTime(input time newBitTime);
bitTime = newBitTime;
endtask

task sendChar(input [7:0] char);
begin
// send start bit
TxD = 0;
// send eight data bits, LSB first
repeat (8) begin
#(bitTime) TxD = char[0];
char = char >> 1;
end
// send stop bit
#(bitTime) TxD = 1;
#(bitTime);
end
endtask
//
initial TxD = 1; // line idles in "Mark" state
//
endmodule

module justTryThisOne;
// connections
wire serial_TxD;
// stimulus generator instance
simulatedUartTransmitter txGenerator(.TxD(serial_TxD));
//
// There's no DUT in this example, but you can still
// see the signal generator at work.
//
// code to generate some stimulus
initial begin
txGenerator.setBitTime(104000); // 9600Bd, roughly
#1_000_000; // idle awhile before starting
txGenerator.sendChar("h"); // ask the sig-gen...
txGenerator.sendChar("i"); // ...to send some data
txGenerator.sendChar("!"); // ...at our request
#1_000_000; // idle awhile at the end
end
endmodule

Utterly fantastic when you want to do stuff like
mimicking the behaviour of a CPU in your testbench.
Just write a module that can generate read or write
cycles on a bus, then connect an instance of it to
your DUT and get it to do accesses in the same way
you'd expect your CPU to behave.

Apologies if this is stuff you've seen already.
It's so useful that I couldn't resist sharing
the example (again).
 
P

Paul Uiterlinden

Jonathan said:
Now I am learning how Verilog
allows hierarchical path references to signals for test benches. This
is awesome!!!

Not as awesome as the ability to call tasks
(procedures) in a module, from another module.
That's just the neatest thing ever, for
stimulus generation. This little example
should give you a flavour of what you can do:

`timescale 1ns/1ns

module simulatedUartTransmitter(output reg TxD);
time bitTime;
//
task setBitTime(input time newBitTime);
bitTime = newBitTime;
endtask

task sendChar(input [7:0] char);
begin
// send start bit
TxD = 0;
// send eight data bits, LSB first
repeat (8) begin
#(bitTime) TxD = char[0];
char = char >> 1;
end
// send stop bit
#(bitTime) TxD = 1;
#(bitTime);
end
endtask
//
initial TxD = 1; // line idles in "Mark" state
//
endmodule

module justTryThisOne;
// connections
wire serial_TxD;
// stimulus generator instance
simulatedUartTransmitter txGenerator(.TxD(serial_TxD));
//
// There's no DUT in this example, but you can still
// see the signal generator at work.
//
// code to generate some stimulus
initial begin
txGenerator.setBitTime(104000); // 9600Bd, roughly
#1_000_000; // idle awhile before starting
txGenerator.sendChar("h"); // ask the sig-gen...
txGenerator.sendChar("i"); // ...to send some data
txGenerator.sendChar("!"); // ...at our request
#1_000_000; // idle awhile at the end
end
endmodule

Utterly fantastic when you want to do stuff like
mimicking the behaviour of a CPU in your testbench.
Just write a module that can generate read or write
cycles on a bus, then connect an instance of it to
your DUT and get it to do accesses in the same way
you'd expect your CPU to behave.

Apologies if this is stuff you've seen already.
It's so useful that I couldn't resist sharing
the example (again).

Thanks for sharing. I've kept this for reference, as I don't use Verilog
normally but want to keep up to date as much as possible. It is
fantastically more simple than the hoops and loops you must go through when
implementing this in VHDL. Been there, done that (or rather: doing that).
And I am saying this as a VHDL aficionado.

One question though: if the task sendChar is called concurrently from
different procedural blocks in a way that the calls are overlapping, I
think the result would be a great mess (I am saying this as a not so great
lover of how Verilog works).

Is there a simple way to deal with collisions like that? Or will the
simplicity be lost then for the most part?
 

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,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top