Title: Specman Notes
1Specman Notes
2Specman Elite
- From Verisity (http//www.verisity.com)
- Presents a high-level language for writing test
environments - Test Benches
- Coverage
- Constraint based test generation and checking
3Configuration
- On pitteda3 or pitteda4
- Verisity user Environment variables (no
newlines) - setenv SPECMAN_HOME
- CAD_DIR/verisity/specman_3.3.3/sn_rel3.3.3
- setenv PATH SPECMAN_HOME/SPECMAN_HOME/bin/s
n_arch.shSPECMAN_HOME/binPATH - setenv SPECMAN_DIR SPECMAN_HOME/SPECMAN_HOME/
bin/sn_arch.sh - setenv VERISITYLD_LICENSE_FILE
- 5286_at_pitteda1.ee.pitt.edu
4Files
- Copy the tutorial tar file
- Copy the emacs specman-mode file
- If you use emacs
- If you like language editors
- Untar the tutorial directories into your own
account ( ./src and ./gold )
5Running
- (make sure X and DISPLAY are right)
- specview
6e language
- Looks like verilog to me
- Has support for data types
- With statistical values
- With constraints (hard and soft)
- Stimulus
- Checking
- Events
7On Line Help
- Verisity has all their help on line
- e language ref
- Command ref for Specman Elite
- Usage etc.
- Tutorial is on OUR web page (large pdf)
- Do not print it, just do it.
- Its not great
8File Format
- A code segment is enclosed with a begin-code
marker lt' and an end-code marker 'gt. - Both the begin-code and the end-code markers must
be placed at the beginning of a line (left most),
with no other text on that same line (no code and
no comments). - The following three lines of code form a code
segment - lt'
- import cpu_test_env
- 'gt
- Several code segments can appear in one file.
Each code segment consists of one or more
statements.
9Comments
- e files begin as a comment which ends when the
first begin-code marker lt' is encountered. - Comments within code segments can be marked with
double dashes (--) or double slashes (//) - a 5 -- This is an inline comment
- b 7 // This is also an inline comment
- The end-code 'gt and the begin-code lt' markers can
be used in the middle of code sections, to write
several consecutive lines of comment
10Pre Defined Constants
- Constant Description
- TRUE For Boolean variables and expressions.
- FALSE For Boolean variables and expressions.
- NULL For structs, specifies a NULL pointer.
For character strings, specifies an empty
string. - UNDEF UNDEF indicates NONE where an index is
expected. - MAX_INT Represents the largest 32-bit int (231
-1) - MIN_INT Represents the smallest 32-bit int
(-231). - MAX_UINT Represents the largest 32-bit uint
(232-1).
11Keywords
- all of
- all_values
- and
- as a
- as_a
- assert
- assume
- async
- attribute
- before
- bit
- bits
- bool
- break
- byte
- bytes
- c export
- case
- change
- check that
- compute
- computed
- consume
- continue
- cover
- cross
- cvl call
- cvl callback
- cvl method
- cycle
- default
- define
- delay
- detach
- do
- down to
- dut_error
- each
- edges
- else
- emit
- event
- exec
- expect
- extend
- fail
- fall
- file
- first of
- for
- force
- from
- gen
- global
- hdl pathname
- if
- ifdef
- ifndef
- in
- index
12Keywords
- int
- is a
- is also
- is c routine
- is empty
- is first
- is inline
- is instance
- is not a
- is not empty
- is only
- is undefined
- item
- keep
- keeping
-
- key
- like
- line
- list of
- matching
- me
- nand
- new
- nor
- not
- not in
- now
- nxor
- on
- only
- or
- others
- pass
- prev
- print
- range
- ranges
- release
- repeat
- return
- reverse
- rise
- routine
- select
- session
- soft
- start
- state machine
- step
- struct
- string
- sync
- sys
- that
- then
- time
- to
- transition
- true
- try
13Keywords
- type
- uint
- unit
- until
- using
- var
- verilog code
- verilog function
- verilog import
- verilog simulator
- verilog task
- verilog time
- verilog timescale
- verilog trace
- verilog variable
- vhdl code
- vhdl driver
- vhdl function
- vhdl procedure
- vhdl driver
- vhdl simulator
- vhdl time
- when
- while
- with
- within
14Syntactic Elements
- Statements
- Statements are top-level constructs and are
valid within the begin-code lt' and end-code 'gt
markers. Statements end with a semicolon - Struct members
- Struct members are second-level constructs and
are valid only within a struct definition. - Actions
- Actions are third-level constructs and are valid
only when associated with a struct member, such
as a method or an event. - Expressions
- Expressions are lower-level constructs that can
be used only within another e construct. - The syntax hierarchy roughly corresponds
to the level of indentation shown below - statements
- struct members
- actions
- expressions
15Statements
- Statements are top-level constructs and are valid
within thebegin-code lt' and end-code 'gt markers. - Key Statement Types
- Struct defines a new data structure
- Type defines an enumerated/subtype
- Extend extends a previously defined struct or
type - Define extends language with new commands,
actions, expressions - More import, verilog-x, vhdl-x
- Order is not critical but imports must be first
(after macro defines)
16Struct Struct Members
- Struct members are second-level constructs and
are valid only within a struct definition. - struct struct-type struct-descriptor like
base-struct-type struct-descriptor - member struct-member ...
- Example
- type packet_kind atm, eth
- struct packet
- len int
- keep len lt 256
- kind packet_kind
17Struct Members
- field declaration
- Defines a data entity that is a member of the
enclosing struct and has an explicit data type. - method declaration
- Defines an operational procedure that can
manipulate the fields of the enclosing struct and
access run-time values in the DUT. - subtype declaration
- Defines an instance of the parent struct in which
specific struct members have particular values or
behavior. (e.g., when) - constraint declaration
- Influences the distribution of values generated
for data entities and the order in which values
are generated. (e.g., keep) - coverage declaration
- Defines functional test goals and collects data
on how well the testing is meeting those goals. - temporal declaration
- Defines e events and their associated
actions.(e.g., on, expect, assume)
18Fields
- ! field field-name type type min-val
int .. max-val int - ((bits bytes)num int)
- Syntax example
- type NetworkType IP0x0800, ARP0x8060 (bits
16) - struct header
- address uint (bits 48)
- hdr_type NetworkType
- !counter int
19Fields
- ! Ungenerated Fields
- A field defined as ungenerated (with the !
option) is not generated automatically. - This is useful for fields that are to be
explicitly assigned during the test, or whose
values involve computations that cannot be
expressed in constraints. - Ungenerated fields get default initial values (0
for scalars, NULL for structs, empty list for
lists). - An ungenerated field whose value is a range (such
as 0..100) gets the first value in the range. - If the field is a struct, it will not be
allocated and none of the fields in it will be
generated.
20Fields
- Physical Fields
- A field defined as a physical field (with the
option) is packed when the struct is packed. - Fields that represent data that is to be sent to
the HDL device in the simulator or that are to be
used for memories in the simulator or in Specman
Elite, need to be physical fields. - Nonphysical fields are called virtual fields and
are not packed automatically when the struct is
packed, although they can be packed individually. - If no range is specified, the width of the field
is determined by the fields type. For a physical
field, if the fields type does not have a known
width, you must use the (bits bytes num)
syntax to specify the width.
21Actions
- Actions are third-level constructs and are valid
only when associated with a struct member, such
as a method or an event. - lt'
- struct packet
- event xmit_ready is rise('top.ready')
- on xmit_ready transmit()
- transmit() is
- out("transmitting packet...")
-
-
- 'gt
22Actions
- Creating modifying variables
- var, , op,
- Interacting with the DUT
- force, release
- Flow control
- Conditionals
- if then else, labeled case, boolean case
- Iteratation
- While, repeat until, for each, for from-to, for
each-line, for each-file-matching - Flow control
- break, continue
23Actions
- Invoking methods and routines
- method(), tcm(), start tcm(), routine(), compute
method(), return - Performing time consuming actions
- emit, sync, wait, all of , first of, state
machine - Generating data items
- gen
- Detecting/handling errors
- check that, dut_error(), assert, warning(),
error(), fatal(), try - Printing
- print, set_config()
24Expressions
- Expressions are lower-level constructs that can
be used only within another e construct - Expressions are constructs that combine operands
and operators to represent a value - A literal value
- A constant
- An e entity, such as a method, field, list, or
struct - An HDL entity, such as a signal
- A compound expression applies one or more
operators to one or more operands.
25Struct Hierarchy
- global
- sys
- switch
- ctrl_stub
- port_stub1
- sender
- listener
- port_stub2
- port_stub3
- port_stub4
- packing
- files
- scheduler
- simulator
- session
26Implicit Variables
- it The implicit variable it always refers to
the current item. - for each in sys.packets
- it.len 5
- .good TRUE -- it is assumed
-
27Implicit Variables
- Me The implicit variable me refers to the
current struct and can be used anywhere in the
struct. - struct packet
- data uint
- stm() is
- var tmp uint
- gen tmp keeping it lt me.data - - it is tmp
- print data, tmp using hex
-
28Implicit Variables
- resultThe result variable returns a value of the
methods return type. If no return action is
encountered, result is returned by default. The
following method returns the sum of a and b - sum(a int, b int) int is
- result a b
29Implicit Variables
- index The index variable holds the current
index of the item referred to by it. The scope of
the index variable is limited to the action
block. - for each in packets do
- packetsindex.len 5
- .id index
30Operators Precedence
- List indexing (subscripting)
- .. List slicing
- Bit slicing (selection)
- f() Method and routine calls
- . Field selection
- Bitwise not
- ! (not) Boolean not
- List concatenation
- Bit concatenation
- - Unary plus, minus
- , /, Binary multiply, divide, modulus
- , - Binary add and subtract
- gtgt ltlt Shift right, shift left
- lt lt gt gt Comparison
- is not a Subtype identification
- ! Equality, inequality
- ! Verilog four-state comparison
- ! String matching
- in Range list operator
- Bitwise AND
- Bitwise OR
- Bitwise XOR
- (and) Boolean AND
- Boolean or
- gt Boolean implication
- ? Conditional operator
31Examples
num1 num2,num3
pack(packing.high,num2,num3) e.g. Num2
0x1234 Num3 0x7777 Num1 Num2,Num3 What
is Num3?
32Examples
var loc1 list of colors redgreenblue print
loc1
33Types Scalars
- int Represents numeric data, both negative and
non-negative integers. (32 bits) - uint Represents unsigned numeric data,
non-negative integers only. (32 bits) - bit An unsigned integer in the range 01. (1 bit)
- byte An unsigned integer in the range 0255. (8
bits) - time An unsigned integer in the range 0263 -1.(
64 bits) - bool Represents truth (logical) values, TRUE(1)
and FALSE(0). (1 bit)
34Subtypes
- By range
- int 0..100
- By width
- int (bits 8)
- Named Subtypes
- type int_count int 0..99 (bits7)
- var count int_count
35Enumerated Types
- You can define the valid values for a variable or
field as a list of symbolic constants. - var kind immediate, register
- You can extend the definition
- type packet_protocol
- extend the definition of the type with
- extend packet_protocol Ethernet, IEEE,
foreign
36Struct Subtypes
- type packet_protocol Ethernet, IEEE, foreign
- struct packet
- protocol packet_protocol
- size int 0..1k
- datasize list of byte
- legal bool
-
- extend sys
- gen_eth_packet () is
- var packet legal Ethernet packet -- local
sub-type - gen packet keeping it.size lt 10
- print packet
-
37Generate example
struct location address int gen l
keeping it.address 2i
38Subtypes with extend when
- type packet_protocol Ethernet, IEEE, foreign
- struct packet
- protocol packet_protocol
- size int 0..1k
- datasize list of byte
- // when Ethernet packet e_field int
-- same as extend below - // show() is out("I am an Ethernet packet")
- //
-
- extend Ethernet packet
- e_field int
- show() is out("I am an Ethernet packet")
39Accessing sub-typed structs
- type packet_protocol Ethernet, IEEE, foreign
- struct packet
- protocol packet_protocol
- when IEEE packet i_val int
-
- var pk_inst IEEE packet
- pk_inst.i_val 1
- if pk_inst is a IEEE packet (ip) ip.i_val 1
- pk_list.first(it is a IEEE packet (ip) and
ip.i_val 1)
40List functions
list.add, list.add0, list.clear, list.insert,
list.delete, list.first var ilist list of
int ilist.add(5) var iitem instr iitem
instr_list.first(it.op1 gt 15)
41List add usage
struct p_l ! packeti packet ! plst list of
packet mklst() _at_sysclk is gen packeti
plst.add(packeti) stop.run()
42_at_
event sim_ready is change(top\ready)
_at_sim Simulator object change _at_sys.any
predefined event occurs everytime anyother event
occurs extend sys event clk is rise(top.clk)
_at_sim
43List types
- perl-like array/list semantics
- my_list0 refers to the first item in the list
- var lob list of byte 153163127255
- print lob0..2
- No multi-dimensional lists. To create a list with
sublists in it, create a struct to contain the
sublists
44Example
- type packet_protocol Ethernet, IEEE, foreign
- struct packet
- protocol packet_protocol
- len int 0..10
-
- extend sys
- packets10 list of packet
- do_print() is
- var all_lengths list of packet'len
- all_lengths packets.len -- multi-element
assignment - print packets
- print all_lengths
-
45Run system
- sys packets
- item type protocol len
-
- 0. packet Ethernet 10
- 1. packet Ethernet 10
- 2. packet IEEE 4
- 3. packet IEEE 0
- 4. packet Ethernet 7
- 5. packet Ethernet 8
- 6. packet foreign 8
- 7. packet Ethernet 5
- 8. packet Ethernet 3
- 9. packet foreign 6
-
- all_lengths
- 0. 10
- 1. 10
- 2. 4
- 3. 0
- 4. 7
- 5. 8
- 6. 8
- 7. 5
- 8. 3
- 9. 6
46Keyed Lists
- A keyed list data type is similar to hash tables
or association lists found in other programming
languages. - struct person
- name string
- id int
-
- struct city
- persons list(key name) of person
- street_names list(key it) of string
47Constraints with Keep
- keep constraint-bool-exp
- Syntax example
- keep kind ! tx or len 16
- Parameters
- constraint-bool-exp A simple or a compound
Boolean expression. - States restrictions on the values generated for
fields in the struct or the struct subtree,or
describes required relationships between field
values and other items in the struct or its
subtree. - Hard constraints are applied whenever the
enclosing struct is generated. For any keep
constraint in a generated struct, the generator
either meets the constraint or issues a
constraint contradiction message. - Note If the keep constraint appears under a when
construct, the constraint is considered
48Keep examples
- struct pkt
- kind tx, rx
- len int
- keep kind tx gt len 16
- // when tx pkt -- this acts exactly the same
way - // keep len 16
- //
-
- Both these constraints are identical to the
constraint - keep kind ! tx or len 16
- Note this is just the true meaning of gt
Boolean implication
49Keep examples
- Using the predefined method is_a_permutation()
- struct astr
- l_1 list of int
- l_2 list of int
- keep l_2.is_a_permutation(l_1)
-
- struct transaction
- address uint
- keep soft address select -- using keep
soft and select - 10 0..49
- 60 50
- 30 51..99
-
-
50Keep examples
- struct transaction
- address uint
- keep soft address select
- 10 0..49
- 60 50
- 30 51..99
-
-
- extend transaction
- keep address in 10..50
- keep soft address select
- 10 min
- 60 others
- 30 max
-
- extend instr
- keep soft opcode select
- 40 ADD, ADDI, SUB, SUBI
- 20 AND, ANDI, XOR, XORI
- 10 JMP, CALL, RET, NOP
- top.carry' 90 JMPC
-
-
51Keep examples
- type transaction_kind good, bad
- struct transaction
- kind transaction_kind
- address uint
- length uint
- data list of byte
-
- extend transaction
- keep length lt 24
- keep data0 0x9a
- keep address in 0x100..0x200
- keep me.kind good
-
- extend sys
- t transaction
- keep me.t.length ! 0
-
52Generation with keep
- Generation order is important because it
influences the distribution of values. For
example, in the keep constraint shown below, if
kind is generated first, kind is tx about
1/2 the time because there are only two legal
values for kind - struct packet
- kind tx, rx
- size byte
- keep size gt 15 gt kind rx
-
- On the other hand, if size is generated first,
there is only a 1 in 16 chance that size will
be less than or equal to 15, so kind will be
tx about 1/16 of the time.
53Events --
54Specman Tutorial Example
- Use src files from tar archive
- CPU and Testbench are both modeled in specman
- No need for nclaunch simulator
- easy high level modeling of CPU
- Black box testing
55CPU_top.e
- lt'
- // Basic
- import CPU_instr, CPU_misc
- // Add dut and drive
- import CPU_dut, CPU_drive
- // Add Coverage
- import CPU_cover
- // Add Checking
- import CPU_checker
- 'gt
56CPU_instr.e
- lt'
- type cpu_opcode // Opcodes
- ADD, ADDI, SUB, SUBI,
- AND, ANDI, XOR, XORI,
- JMP, JMPC, CALL, RET,
- NOP
- (bits 4)
- type reg // Register names
- REG0, REG1, REG2, REG3
- (bits 2)
57Instruction Formats to test
- struct instr
- opcode cpu_opcode
- op1 reg
- kind imm, reg
- // defines 2nd op of reg instruction
- when reg instr
- op2 reg
-
- // defines 2nd op of imm instruction
- when imm instr
- op2 byte
-
-
- // defines legal opcodes for reg instr
- keep opcode in ADD, SUB, AND, XOR, RET, NOP
- gt kind reg
- // defines legal opcodes for imm instr
- keep opcode in ADDI, SUBI, ANDI, XORI, JMP,
JMPC, CALL - gt kind imm
- // ensures 4-bit addressing scheme
- when imm instr
- keep (opcode in JMP, JMPC, CALL) gt op2
lt 16 -
58Extend the system struc
- extend sys
- // creates the stream of instructions
- !instrs list of instr -- dont
pre-generate the list -
- 'gt
-
59CPU_misc.e
- lt'
- extend global
- setup_test() is also
- set_config(print,radix,hex)
set_config(cover,mode,normal,show_mode,both) - set_config(print, items, 100)
-
- finalize_test() is also
- specman("display print sys.instrs")
-
-
- 'gt
60CPU_drive
- lt
- extend sys
- event cpuclk is (fall('top.clk')_at_sys.any)
- cpu_env cpu_env
- cpu_dut cpu_dut //cpu_refmodel
cpu_refmodel -
- struct cpu_env
- reset_cpu() _at_sys.cpuclk is
- 'top.rst' 0
- wait 1 cycle
- 'top.rst' 1
- wait 5 cycle
- //sys.cpu_refmodel.reset() // reset
reference model - 'top.rst' 0
-
61CPU_drive
- drive_one_instr(instr instr) _at_sys.cpuclk is
- var fill0 uint(bits 2) 0b00
- wait until rise('top.fetch1')
- emit instr.start_drv_DUT
- if instr.kind reg then
- 'top.data' pack(packing.high,
instr) - else
- // immediate instruction
- 'top.data' pack(packing.high,
instr.opcode, instr.op1, fill0) - wait until rise('top.fetch2')
- 'top.data' pack(packing.high,
instr.imm'op2) -
- wait until rise('top.exec')
-
62CPU_drive
- !next_instr instr
- num_instrs uint
- keep soft num_instrs in 40..60
- gen_and_drive_instrs() _at_sys.cpuclk is
- for i from 0 to num_instrs do
- gen next_instr
- sys.instrs.add(next_instr)
- drive_one_instr(next_instr)
-
-
63CPU_drive
- drive_pregen_instrs() _at_sys.cpuclk is
- for i from 0 to sys.instrs.size() - 1
- drive_one_instr(sys.instrsi)
-
-
- drive_cpu() _at_sys.cpuclk is
- reset_cpu()
- if sys.instrs.size() gt 0 then
- drive_pregen_instrs()
- else
- gen_and_drive_instrs()
-
- wait 1 cycle
- stop_run()
-
-
64CPU_drive
- run() is also
- start drive_cpu()
-
-
- extend instr
- event start_drv_DUT
-
- 'gt
65Test1.e
- lt'
- import CPU_top
- extend instr // test constraints
- keep opcode in ADD, ADDI
- keep op1 REG0
- when reg instr keep op2 REG1 // when reg
instr - when imm instr keep op2 0x5 // when imm
instr -
- extend sys
- // generate 5 instructions
- keep instrs.size() 5
-
- extend sys
- post_generate() is also
- gen instrs // start generating
stream of instructions -
-
- 'gt
66Test2.e
lt'import CPU_topextend instr keep soft
opcode select 30 ADD, ADDI,
SUB, SUBI // arithmetic operation
30 AND, ANDI, XOR, XORI // Logic
operation 10 JMP, JMPC, CALL,
RET, NOP // Other operation 'gt
67State Coverage
extend cpu_env event cpu_fsm is
_at_sys.cpuclk // DUT Coverage State Machine
and State Machine transition coverage cover
cpu_fsm is item fsm FSM_type
'top.cpu.curr_FSM' transition fsm
68Test3.e
extend instr keep soft opcode select
// high weights on arithmetic instructions
40 ADD, ADDI, SUB, SUBI
20 AND, ANDI, XOR, XORI // Logic operation
10 JMP, CALL, RET, NOP // Other
operation // generation of JMPC
controlled by the carry signal value
'top.carry' 90 JMPC
extend cpu_env keep num_instrs
52extend global setup_test() is also
set_config(gen, seed, 7)
69Checker.e data checker
extend cpu_env // Data Checker event
exec_done is (fall('top.exec') and
true('top.rst' 0))_at_sys.cpuclk
on_exec_done() is // Compare PC -
program counter check that
sys.cpu_dut.pc sys.cpu_refmodel.pc else
dut_error("DATA MISMATCH(pc)")
70Temporal Checker
// Temporal (Protocol) Checker event
enter_exec_st is (change('top.cpu.curr_FSM')
and true('top.cpu.curr_FSM'
exec_st))_at_sys.cpuclk event fetch1_assert
is (change('top.fetch1') and
true('top.fetch1' 1))_at_sys.cpuclk
// Interface Spec After entering instruction
execution state, fetch1 //
signal must be asserted in the following cycle.
expect _at_enter_exec_st gt
_at_fetch1_assert_at_sys.cpuclk else
dut_error("PROTOCOL ERROR")
71Operation Coverage
extend instr cover start_drv_DUT is
item opcode item op1 item
carry bit 'top.carry' cross opcode,
carry
72Reference model
struct cpu_refmodel regs4 list of byte
pc byte // Current PC stack list of
byte // stack of PC values
fetch(rreg)byte is return(regsr.as_a(
int)) update(rreg, valbyte) is
// compute an ALU function
regsr.as_a(int) val
compare(rbyte, valbyte)bool is // compare
against a reg result (r val)
if ! result out("Register has
",r, " While HDL has ", val)
ret
73Contd.
jump(val byte) is pc val
jumpc(cpu_dut cpu_dut, val byte) is //
cheated a bit here pc cpu_dut.pc //if
(cpu_dut.carry 1) then pc val)
//pc val call(val byte) is
stack.add(pc2) pc val
74Reset operation
reset() is for i from 0 to 3 do
regsi 0 // Initialize Specman
reference regs pc 0
75Example of execution
execute(instr instr, cpu_dut cpu_dut) is
var op2_val byte var reg_instr
reg instr var imm_instr imm instr
// compute next PC case instr.opcode
ADD, SUB, XOR, AND, NOP jump(pc
1) ADDI, SUBI, XORI, ANDI,
JMPC jump(pc 2) if
(instr.kind reg) then reg_instr
instr.as_a(reg instr) op2_val
fetch(reg_instr.op2) else
imm_instr instr.as_a(imm instr)
op2_val imm_instr.op2 //
compute next CPU State