Real life experiences of PSL Magnus Bjrk Hardware Description and - - PowerPoint PPT Presentation

real life experiences of psl
SMART_READER_LITE
LIVE PREVIEW

Real life experiences of PSL Magnus Bjrk Hardware Description and - - PowerPoint PPT Presentation

Real life experiences of PSL Magnus Bjrk Hardware Description and Verificatoin 2009-03-26 Saab Space / RUAG Aerospace Was owned by SAAB group Sold to RUAG Aerospace, summer 2008 Most interesting division: Digital products


slide-1
SLIDE 1

Real life experiences of PSL

Magnus Björk

Hardware Description and Verificatoin 2009-03-26

slide-2
SLIDE 2

Saab Space / RUAG Aerospace

Was owned by SAAB group Sold to RUAG Aerospace, summer 2008 Most interesting division: Digital products

hardware systems

ASIC

software systems

Other products: antennas, frequency

converters, separation systems

slide-3
SLIDE 3

To be launched by ESA in 2011 Surveillance of:

Polar ice (thickness, coverage) Continental drift, earthquakes Pollution (oil leaks in oceans) Forest fires …

Synthetic Aperture Radar

Sentinel 1 satellite

slide-4
SLIDE 4

Sentinel 1 satellite

slide-5
SLIDE 5

RUAG’s formal verification approach

Want to save effort (money) on

testbenches and debugging

Start by using FV on some small

modules

Increase usage with experience

slide-6
SLIDE 6

Case studies

Old modules One module under development

(memory interface for Sentinel 1 Thermal Control Unit)

slide-7
SLIDE 7

PSL: harder than expected

How to express that the PWT is in a certain state?

What is the minimal delay between packets currently set

to?

PWT

DmaAddr DmaReq DmaAck DmaRdy DmaReadData DmaErr PwtClock PwtValid PwtData PwtReady BusClk Reset Addr Wr WrData DMA interface Packet wire interface Control interface

slide-8
SLIDE 8

Clarification: Packet delays

PwtData PwtClock PwtValid BusClock End of packet Start of next packet Minimal delay configurable (in nr of PwtClocks) PwtClock speed configurable (divisor of BusClock)

slide-9
SLIDE 9

Attempt in PSL

impure function WritePwtRegV(register:integer, value:integer) return BOOLEAN … impure function SetClkMultiplier(mul:integer) return BOOLEAN... sequence initialize is {WritePwtRegV(PWT_CMDCLR, 1); -- no manual control WritePwtRegV(PWT_DELAY, DELAY); -- set minimal packet delay SetClkMultiplier(MULT)}; -- set transmission speed impure function deinit() return boolean is begin return WritePwtReg(PWT_DELAY) or WritePwtReg(PWT_CLK) or WritePwtReg(PWT_CMDSET); end function deinit; sequence deinit_seq is {{deinit()} within {[*MULT*(DELAY+1)]}}; prop_delay: assert always ({{initialize; not deinit()[*]} && {[*]; PwtValid; not PwtValid}} |-> {{not PwtValid[*MULT*(DELAY+1)]} |{deinit_seq}});

slide-10
SLIDE 10

VHDL observers

Implement an observer in VHDL which

keeps track of specific properties

E.g. listen to writes to the register controlling

minimal delays

slide-11
SLIDE 11

Adding an observer for packet delay

PWT

DmaAddr DmaReq DmaAck DmaRdy DmaReadData DmaErr PwtClock PwtValid PwtData PwtReady BusClk Reset Addr Wr WrData DMA interface Packet wire interface Control interface

Delay observer

CurrentDelay

Trivial VHDL implementation (~10 lines)

slide-12
SLIDE 12

A new property

prop_delay: assert always ({PwtValid; not PwtValid} |-> {not PwtValid[*CurrentDelay]});

Indexing over non- constants may not be supported by tool!

slide-13
SLIDE 13

Doing more in the observer

PWT

DmaAddr DmaReq DmaAck DmaRdy DmaReadData DmaErr PwtClock PwtValid PwtData PwtReady BusClk Reset Addr Wr WrData DMA interface Packet wire interface Control interface

Delay observer

DelayOk

Simple VHDL implementation (~20 lines) prop_delay: assert always(DelayOk);

slide-14
SLIDE 14

VHDL in properties

Either 20 lines of advanced PSL Or 20 lines of trivial VHDL

More general

No constants MULT and DELAY Initialization not fixed

Easier to write Easier for designers to understand Easier for tools to handle

slide-15
SLIDE 15

Combining PSL and VHDL

VHDL can be embedded in PSL PSL can be embedded in VHDL You are supposed to mix them! Mix them if it makes the verification

clearer

slide-16
SLIDE 16

Bottom line

PSL is very powerful in many cases In such cases, use PSL! In other cases, VHDL is better suited In such cases, use VHDL!

slide-17
SLIDE 17

A note on verification libraries

Open verification library (OVL) Questa verification library (QVL)

Mentor’s extension of OVL, also open

source

Open source verification libraries Contains loads of ready observers

Ranging from simple and, prev, and fifo to

advanced ones like USB 2.0 and AMBA.

slide-18
SLIDE 18

Designing with verification in mind

Transmission logic Register bank DMA interface Serial interface Control interface Control interface is easier to use in properties Easy to verify formally

slide-19
SLIDE 19

Designing with verification in mind

Transmission logic Register bank DMA interface Serial interface Control interface Spend less effort

  • n full module
slide-20
SLIDE 20

Reactions from staff

Quick feedback to designers Short counter examples easy to

understand

Very intricate bugs found Easy to use, once there infra structure

exists

Expect to continue and increase formal

verification usage

slide-21
SLIDE 21

Lessons learned

Different tools interpret PSL differently

Jasper: ”assume” statements are local to

the respective vunit

Mentor: ”assume” statements are global

Different tools support different subsets

  • f PSL

In this case: Jasper correct according to IEEE-1850

slide-22
SLIDE 22

More lessons learned

CTL and LTL are like assembly language

Low level, close to the underlying mechanism

PSL might be compared to C

Introduces convenient notation for common

constructs

…but we really want the equivalent of high

level languages like C++, Java, or Haskell

State machines, hierarchical structures (matching

begin-end-constructs), consensus about interpretation

Future work!

slide-23
SLIDE 23

More on PSL

some examples, some pitfalls Based on Mary Sheeran’s slides from 2008

slide-24
SLIDE 24

start idle p1 p2 p3 continue continue done cancel cancel

FSM

slide-25
SLIDE 25

Low level assertions

assert always ((state = idle and start) -> next (state = p1)); assert always ((state = idle and not start) -> next (state = idle)); assert always ((state = p1 and continue) -> next (state = p2)); and so on…

  • ne for each transition

good, but very localised

slide-26
SLIDE 26

Low level assertions

assert always ((state = idle and start) -> next (state = p1)); assert always ((state = idle and not start) -> next (state = idle)); assert always ((state = p1 and continue) -> next (state = p2)); and so on…

  • ne for each transition

good, but very localised

Bit-vector

slide-27
SLIDE 27

Low level assertions

assert always ((state = idle and start) -> next (state = p1)); assert always ((state = idle and not start) -> next (state = idle)); assert always ((state = p1 and continue) -> next (state = p2)); and so on…

  • ne for each transition

good, but very localised

constant

slide-28
SLIDE 28

Low level assertions

assert always ((state = idle and start) -> next (state = p1)); assert always ((state = idle and not start) -> next (state = idle)); assert always ((state = p1 and continue) -> next (state = p2)); and so on…

  • ne for each transition

good, but very localised

Implicit self-loop

slide-29
SLIDE 29

Higher level assertion

assert always (not (state = idle) -> eventually! (state = idle) Note: not a safety property!

Will also likely need to link the state machine to the system that it is controlling and check that the desired functionality is achieved Message: try to raise level of abstraction of properties (while keeping them short and simple)

slide-30
SLIDE 30

Example: simple bus interface spec (1)

  • 1. 2 commands, read and write (with corresponding

signals)

  • 2. Command can be issued only after requesting the bus,

indicated by a pulsed assertion of signal bus_req, and receiving a grant, indicated by the assertion of signal gnt one cycle after the assertion of bus_req

  • 3. If the bus was not requested, it shouldn’t be granted
  • 4. Command is issued the cycle following receipt of grant
  • 5. Either a read or a write can be issued, not both

simultaneously

slide-31
SLIDE 31

Example: simple bus interface spec (2)

  • 6. Reads and writes come with an address,
  • n addr[7 downto 0], that should be valid in the

following cycle

  • 7. Address validity is indicated by signal addr_valid
  • 8. If a read is issued, then one pulse of data on

data_in[63 downto 0] is expected the following cycle

  • 9. If a write is issued, then one pulse of data on

data_out[63 downto 0] is expected the following cycle

  • 10. Valid read data is indicated by data_in_valid and valid

write data by data_out_valid

slide-32
SLIDE 32

Example: simple bus interface low level checks

2, 4. assert always ((read or write) -> ended(bus_req; gnt; true))

Built in function Returns true when the SERE has just ended

slide-33
SLIDE 33

Example: simple bus interface low level checks

  • 3. assert always (not bus_req -> next (not gnt))
slide-34
SLIDE 34

Example: simple bus interface low level checks

  • 5. assert never (read and write)
slide-35
SLIDE 35

Example: simple bus interface low level checks

part of 6,7. assert always ((read or write) -> next addr_valid) assert always (not (read or write)

  • > next (not addr_valid))
slide-36
SLIDE 36

Example: simple bus interface low level checks

10. assert always (read -> next data_in_valid) assert always (not read -> next (not data_in_valid)) assert always (write -> next data_out_valid) assert always (not write -> next (not data_out_valid))

slide-37
SLIDE 37

Example: simple bus interface low level checks

Have checked the protocol but not mentioned the addr, data_in or data_out buses Need to think about overall functionality as well as low level details

slide-38
SLIDE 38

Example: simple bus interface high level checks

Let’s assume two input signals get_data and put_data indicating that a read or write is needed Assume also we have a way to recognise, at the assertion of get_data or put_data, the data that needs to be read or written (from address get_addr[7 downto 0] to read_buffer[63 downto 0] or from write_buffer[63 downto 0] to address put_addr[7 downto 0]) Assume also a suitable memory

slide-39
SLIDE 39

Example: simple bus interface high level checks

assert forall ADR[7 downto 0] in boolean: always ((get_data and get_adr[7 downto 0] = ADR[7 downto 0])

  • >

eventually! (read_buffer[63 downto 0] = mem[ADR[7 downto 0]])) Notes: have made some assumptions e.g. about memory not changing after read included to show some of the fancier PSL constructs and use of bus structures

slide-40
SLIDE 40

Main message

Write both low level and high level checks Low level checks will be easier to write – often transcribed from spec. High level specs consider desired functionality, which may be implicit in the spec. Hard to write but high pay-off For one approach to a methodology for use of PSL, see the Prosyd Eu project web page (www.prosyd.org) Contains many interesting examples both small and large (including the following example) OVL and QVL may be helpful to write higher level properties.

slide-41
SLIDE 41

Common PSL errors

Mixing up logical implication and suffix implication assert always {req; ack} -> {start;busy[*]; end} assert always {req; ack} |-> {start;busy[*]; end}

  • r

assert always {req; ack} |=> {start;busy[*]; end}

Source: the PSL book (Eisner and Fisman)

Probably meant suffix implication:

slide-42
SLIDE 42

Confusing and with implication

Every high priority request (req and high_pri) should be followed immediately by an ack and then by a gnt assert always (req and high_pri) -> next (ack -> next gnt)

  • r

assert always (req and high_pri) -> next (ack and next gnt)

  • r

assert always (req and high_pri) |=> {ack; gnt} Which? Why?

First attempt really means: Every high priority request that is followed immediately by an ack should be followed by a gnt.

slide-43
SLIDE 43

Confusing concatentation with implication

Are any of these equivalent? assert always {a; b; c} assert always( {a} |=> {b; c} ) assert always( {a;b} |=> {c} ) assert always ( a -> (next b -> next[2] c)) assert always ( a -> (next b and next[2] c))

At all points in time, the sequence {a; b; c} begins. Silly property. More likely: assert never {a; b; c} a is always followed by b and thereafter c. Whenever a is followed by b, c follows. If a and thereafter b, then thereafter c. Equivalent! Equivalent

slide-44
SLIDE 44

Confusing concatentation with suffix implication

Are these equivalent? assert always {a; b[+]; c} |=> {d} assert always {a; b[+]; c; d} Same mistake as last slide. assert never {a; b[+]; c; not d}

Equivalent!

slide-45
SLIDE 45

Using never with implication

req is always followed by ack: assert always (req -> next ack) Two consecutive reqs are not allowed: assert never (req -> next req)

  • r

assert always (req -> next (not req)) Or Assert never (req and next req)

  • r

assert never {req; req} Which? Why?

General rule: a -> b = (not a) or b never (a->b) = always (a and not b)

slide-46
SLIDE 46

Negating implications

High priority req gives an immediate ack assert always ((high_pri and req) -> ack) Low priority requests never give an immediate ack assert never ((low_pri and req) -> ack) ???? What should it be? assert always ((low_pri and req) -> not ack) assert never (low_pri and req and ack)

slide-47
SLIDE 47

Incorrect nesting of implications (1)

If a request (assertion of req) is acknowledged (assertion of ack the following cycle), then it must receive a grant (assertion of gnt) the cycle following ack assert always ((req -> next ack) -> next gnt) assert always (req -> (next ack -> next gnt)) assert always ((req and next ack) -> next gnt)

a -> (b -> c) = (a and b) -> c (a -> b) -> c = (a and not b) or c Almost never seen

slide-48
SLIDE 48

Incorrect nesting of implications (2)

If there is a granted read request (assertion of req followed by ack followed by gnt), then if there follows a complete data transfer {start; data[*], end}, then the whole thing should be followed by an assertion of signal read_complete. assert always ({req; gnt; ack} |=> {start; data[*]; end}) | => {read_complete} ?? Fault? Nested sequence implications does not make sense. What should it be? assert always ({req; gnt; ack; start; data[*]; end}) |=> {read_complete}

slide-49
SLIDE 49

Are you missing a ”first match” operator?

On the cycle after the first ack following a request, a data transfer should begin assert always ({req; [*]; ack} |=> {start; data[*]; end}) ?? Wrong: Demands a transfer after every assertion of ack after the req. assert always ({req; ack[->]} |=> {start; data[*]; end})

slide-50
SLIDE 50

”Extraneous” assertions of signals

assert always {ack} |=> {start ; busy[*] ; done} ack start busy done

slide-51
SLIDE 51

”Extraneous” assertions of signals

assert always {ack} |=> {start ; busy[*] ; done} ack start busy done

slide-52
SLIDE 52

May wish to rule out some behaviours

assert always (ack -> not (start or busy or done)) assert always {ack} | => {start and not busy and not done ; {not start and busy and not done}[*]; not start and not busy and done}

  • r add properties like:

assert never (busy and done); assert never (busy and start);