Real life experiences of PSL Magnus Björk 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 � hardware systems � ASIC � software systems � Other products: antennas, frequency converters, separation systems
Sentinel 1 satellite � 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
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
Case studies � Old modules � One module under development (memory interface for Sentinel 1 Thermal Control Unit)
PSL: harder than expected DMA Packet wire interface interface DmaAddr DmaReq PwtClock PWT DmaAck PwtValid DmaRdy PwtData DmaReadData PwtReady DmaErr BusClk Addr Control interface Reset Wr WrData � How to express that the PWT is in a certain state? � What is the minimal delay between packets currently set to?
Clarification: Packet delays Minimal delay End of packet Start of next configurable (in packet nr of PwtClocks) PwtValid PwtData PwtClock BusClock PwtClock speed configurable (divisor of BusClock)
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}});
VHDL observers � Implement an observer in VHDL which keeps track of specific properties � E.g. listen to writes to the register controlling minimal delays
Adding an observer for packet delay DMA Packet wire interface interface DmaAddr DmaReq PwtClock PWT DmaAck PwtValid DmaRdy PwtData DmaReadData PwtReady DmaErr BusClk Addr Control interface Reset Wr WrData Trivial VHDL implementation CurrentDelay Delay observer (~10 lines)
A new property prop_delay: assert always ({PwtValid; not PwtValid} |-> {not PwtValid[*CurrentDelay]}); Indexing over non- constants may not be supported by tool!
Doing more in the observer DMA Packet wire interface interface DmaAddr DmaReq PwtClock PWT DmaAck PwtValid DmaRdy PwtData DmaReadData PwtReady DmaErr BusClk Addr Control interface Reset Wr WrData Simple VHDL implementation DelayOk Delay observer (~20 lines) prop_delay: assert always(DelayOk);
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
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
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!
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 .
Designing with verification in mind DMA Serial Transmission logic interface interface Register bank Control interface Easy to verify is easier to use formally in properties Control interface
Designing with verification in mind DMA Serial Transmission logic interface interface Register bank Control Spend less effort interface on full module
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
Lessons learned � Different tools interpret PSL differently � Jasper: ”assume” statements are local to the respective vunit � Mentor: ”assume” statements are global In this case: Jasper correct according to IEEE-1850 � Different tools support different subsets of PSL
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!
More on PSL some examples, some pitfalls Based on Mary Sheeran’s slides from 2008
FSM start continue continue idle p1 p2 p3 cancel cancel done
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… one for each transition good, but very localised
Low level assertions assert always ((state = idle and start) -> next (state = p1)); Bit-vector assert always ((state = idle and not start) -> next (state = idle)); assert always ((state = p1 and continue) -> next (state = p2)); and so on… one for each transition good, but very localised
Low level assertions assert always ((state = idle and start) -> next (state = p1)); constant assert always ((state = idle and not start) -> next (state = idle)); assert always ((state = p1 and continue) -> next (state = p2)); and so on… one for each transition good, but very localised
Low level assertions assert always ((state = idle and start) -> next (state = p1)); assert always ((state = idle and not start) -> next (state = idle)); Implicit self-loop assert always ((state = p1 and continue) -> next (state = p2)); and so on… one for each transition good, but very localised
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)
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
Example: simple bus interface spec (2) 6. Reads and writes come with an address, on 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
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
Example: simple bus interface low level checks 3. assert always (not bus_req -> next (not gnt))
Example: simple bus interface low level checks 5. assert never (read and write)
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))
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))
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
Recommend
More recommend