Download as pdf or txt
Download as pdf or txt
You are on page 1of 70

6.

Transmitting
Data Words

Gisselquist Daniel E. Gisselquist, Ph.D.

Technology, LLC
Lesson Overview
Ź Lesson Overview Debugging is one of the hardest parts of digital logic design
Data Transmitter
Desired Structure ˝ You can’t see what’s happening inside the FPGA
Counter
Change Detection
˝ LED’s are one solution
txdata
State diagram – FPGA’s operate 50MHz+
Outgoing Data
Formal Verification
– Your eye operates at ă 60Hz
Cover
Assertions
˝ The serial port can be a second solution
Sequence
Sequence Let’s learn to send data through our serial port!
Concurrent
Assertions
Objectives
Simulation
ncurses ˝ Transform Hello World into a debugging output
Verilator data ˝ Learn about formal abstraction
Testbench build
Exercise #2 ˝ Experiment with using ncurses with Verilator
Exercise #3
˝ Extract internal design variables from within Verilator
Conclusion

2 / 54
Data Transmitter
Lesson Overview Let’s transmit a word of data
Data
Ź Transmitter
i_clk
Desired Structure
Counter i_stb
Change Detection
txdata o_busy
State diagram
i_data data
Outgoing Data
Formal Verification
tx_stb
Cover
0 x h h h h h h h h \r \n
Assertions tx_data
Sequence
Sequence
Concurrent
Assertions
Each word will . . .
Simulation
ncurses
˝ Start with 0x
Verilator data ˝ Contain the number sent, but in hexadecimal
Testbench build
Exercise #2 this is much easier than doing decimal!
Exercise #3
Conclusion Four bits can be encoded at a time
˝ End with a carriage return / line-feed pair

3 / 54
Data Transmitter
Lesson Overview You should know how to build this design already
Data
Ź Transmitter
Desired Structure i_clk
Counter
Change Detection
i_stb
txdata o_busy
State diagram
i_data data
Outgoing Data
Formal Verification
Cover
tx_stb
Assertions 0 x h h h h h h h h \r \n
tx_data
Sequence
Sequence
Concurrent
Assertions Remember how we’ve built state machines before
Simulation
ncurses ˝ In this case, you have two triggers
Verilator data
Testbench build – One trigger, i_stb, starts the process
Exercise #2
Exercise #3
– A busy line from the serial port, tx_busy (not shown),
Conclusion controls the movement from one character to the next
˝ This design will be the focus of this lesson

4 / 54
Data Transmitter
Lesson Overview You should know how to build this design already
Data
Ź Transmitter
Desired Structure i_clk
Counter
i_stb i_stb requests sending a word of data
Change Detection
txdata o_busy o_busy: unable to accept another word
State diagram
i_data data
Outgoing Data
Formal Verification
tx_stb tx_stb requests a char be transmitted
Cover
Assertions 0 x h h h h h h h h \r \n
tx_data
Sequence
Sequence
Concurrent
Assertions Remember how we’ve built state machines before
Simulation
ncurses ˝ In this case, you have two triggers
Verilator data
Testbench build – One trigger, i_stb, starts the process
Exercise #2
Exercise #3
– A busy line from the serial port, tx_busy (not shown),
Conclusion controls the movement from one character to the next
˝ This design will be the focus of this lesson

4 / 54
Desired Structure
Lesson Overview Our overall design will look like this:
Data Transmitter
Desired
Ź Structure
Counter
Change Detection
txdata
State diagram
Outgoing Data
Formal Verification
Cover
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation ˝ Some event will trigger a counter
ncurses
Verilator data
˝ A second module will detect that the counter has changed
Testbench build ˝ Finally we’ll output the result
Exercise #2
Exercise #3 ˝ We’ll use txuart.v from the last exercise
Conclusion
Let’s take a quick look at counter.v and chgdetector.v

5 / 54
Creating a Counter
Lesson Overview You should already know how to make an event counter
Data Transmitter
Desired Structure module counter ( i_clk , i_event , o_counter ) ;
Ź Counter
input wire i_clk , i_event ;
Change Detection
txdata output reg [ 3 1 : 0 ] o_counter ;
State diagram
Outgoing Data
Formal Verification i n i t i a l o_counter = 0 ;
Cover always @ ( posedge i_clk )
Assertions
Sequence
i f ( i_event )
Sequence o_counter <= o_counter + 1 ’ b1 ;
Concurrent
Assertions
endmodule
Simulation
ncurses Feel free to add a reset if you would like
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

6 / 54
Change Detection
Lesson Overview Detecting a change in the counter is also pretty easy
Data Transmitter
Desired Structure module chgdetector ( i_clk , i_data ,
Counter
Change o_stb , o_data , i_busy ) ;
Ź Detection // . . .
txdata
State diagram i n i t i a l { o_stb , o_data } = 0 ;
Outgoing Data always @ ( posedge i_clk )
Formal Verification
Cover
i f ( ! i_busy )
Assertions begin
Sequence stb <= 0 ;
Sequence
Concurrent i f ( o_data != i_data )
Assertions begin
Simulation
ncurses stb <= 1 ’ b1 ;
Verilator data o_data <= i_data ;
Testbench build
Exercise #2
end
Exercise #3 end
Conclusion endmodule

7 / 54
Change Detection
Lesson Overview Detecting a change in the counter is also pretty easy
Data Transmitter
Desired Structure module chgdetector ( i_clk , i_data ,
Counter
Change o_stb , o_data , i_busy ) ;
Ź Detection // . . .
txdata
State diagram i n i t i a l { o_stb , o_data } = 0 ;
Outgoing Data always @ ( posedge i_clk )
Formal Verification
Cover
i f ( ! i_busy )
Assertions begin
Sequence stb <= 0 ;
Sequence
Concurrent
Nothing
i f (iso_data
allowed !=
to change
i_dataif) i_busy
Assertions is true. That’s the case where a request
begin
Simulation
ncurses has been made,stb but<= 1 ’ yet
it has b1 ; to be ac-
Verilator data
cepted. o_data <= i_data ;
Testbench build
Exercise #2
end
Exercise #3 end
Conclusion endmodule

7 / 54
Change Detection
Lesson Overview Detecting a change in the counter is also pretty easy
Data Transmitter
Desired Structure module chgdetector ( i_clk , i_data ,
Counter
Change o_stb , o_data , i_busy ) ;
Ź Detection // . . .
txdata
State diagram i n i t i a l { o_stb , o_data } = 0 ;
Outgoing Data always @ ( posedge i_clk )
Formal Verification
Cover
i f ( ! i_busy )
Assertions begin
Sequence stb <= 0 ;
Sequence
Concurrent i f ( o_data != i_data )
Assertions begin
Simulation
ncurses stb <= 1 ’ b1 ;
Verilator data o_data <= i_data ;
Testbench build
Exercise #2
end anytime the data changes, we set up
Otherwise,
Exercise #3 end
a request to transmit the new data.
Conclusion endmodule

7 / 54
Change Detection
Lesson Overview What formal properties might we use here?
Data Transmitter
Desired Structure ˝ Any output value should remain unchanged until accepted
Counter
Change
Ź Detection
// Remember t h i s p r o p e r t y ?
txdata always @ ( posedge i_clk )
State diagram
Outgoing Data
i f ( ( f_past_valid )
Formal Verification &( $past ( o_stb ))&&( $past ( i_busy ) ) )
Cover a s s e r t ( ( o_stb)&&( $ s t a b l e ( o_data ) ) ) ;
Assertions
Sequence
Sequence Remember how this works? This says that . . .
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

8 / 54
Change Detection
Lesson Overview What formal properties might we use here?
Data Transmitter
Desired Structure ˝ Any output value should remain unchanged until accepted
Counter
Change
Ź Detection
// Remember t h i s p r o p e r t y ?
txdata always @ ( posedge i_clk )
State diagram
Outgoing Data
i f ( ( f_past_valid )
Formal Verification &( $past ( o_stb ))&&( $past ( i_busy ) ) )
Cover a s s e r t ( ( o_stb)&&( $ s t a b l e ( o_data ) ) ) ;
Assertions
Sequence
Sequence Remember how this works? This says that . . .
Concurrent
Assertions – If both o_stb and i_busy are true on the same clock cycle
Simulation
ncurses (i.e., the interface is stalled)
Verilator data
Testbench build
– Then request should remain outstanding on the next cycle
Exercise #2 – . . . and the data should be the same on that next cycle
Exercise #3
Conclusion – $stable(o_data) is shorthand for o_data == $past(o_data)

8 / 54
Change Detection
Lesson Overview What formal properties might we use here?
Data Transmitter
Desired Structure ˝ Any output value should remain unchanged until accepted
Counter
Change
Ź Detection
// Remember t h i s p r o p e r t y ?
txdata always @ ( posedge i_clk )
State diagram
Outgoing Data
i f ( ( f_past_valid )
Formal Verification &( $past ( o_stb ))&&( $past ( i_busy ) ) )
Cover a s s e r t ( ( o_stb)&&( $ s t a b l e ( o_data ) ) ) ;
Assertions
Sequence
Sequence ˝ When o_stb rises, o_data should reflect the input
Concurrent
Assertions
always @ ( posedge i_clk )
Simulation
ncurses i f ( ( f_past_valid)&&( $ros e ( o_stb ) ) )
Verilator data a s s e r t ( o_data == $past ( i_data ) ) ;
Testbench build
Exercise #2
Exercise #3 $rose(o_stb) is shorthand for (o_stb[0] && !$past(o_stb[0]))
Conclusion

9 / 54
Change Detection
Lesson Overview What formal properties might we use here?
Data Transmitter
Desired Structure ˝ Any output value should remain unchanged until accepted
Counter
Change
Ź Detection
// Remember t h i s p r o p e r t y ?
txdata always @ ( posedge i_clk )
State diagram
Outgoing Data
i f ( ( f_past_valid )
Formal Verification &( $past ( o_stb ))&&( $past ( i_busy ) ) )
Cover a s s e r t ( ( o_stb)&&( $ s t a b l e ( o_data ) ) ) ;
Assertions
Sequence
Sequence ˝ When o_stb rises, o_data should reflect the input
Concurrent
Assertions
always @ ( posedge i_clk )
Simulation
ncurses i f ( ( f_past_valid)&&( $ros e ( o_stb ) ) )
Verilator data a s s e r t ( o_data == $past ( i_data ) ) ;
Testbench build
Exercise #2
Exercise #3 $rose(o_stb) is shorthand for (o_stb[0] && !$past(o_stb[0]))
Conclusion
˝ Can you think of any other properties we might need?

9 / 54
Our focus: txdata
Lesson Overview This lesson will focus on txdata.v
Data Transmitter
Desired Structure ˝ We’ve already built txuart.v
Counter
Change Detection
˝ You should have no problems designing counter.v or
Ź txdata chgdetector.v
State diagram
Outgoing Data
Formal Verification
You are encouraged to do so on your own
Cover – If not, you can find counter.v and chgdetector.v in
Assertions
Sequence
the course handouts
Sequence
Concurrent You should also have a good idea how to start on txdata.v.
Assertions
Simulation ˝ It’s not all that different from txuart.v or helloworld.v
ncurses
Verilator data ˝ The example in the course handouts is broken
Testbench build
Exercise #2
Exercise #3
Conclusion

10 / 54
Our focus: txdata
Lesson Overview Here’s the port list(s) we’ll design to
Data Transmitter
Desired Structure module txdata ( i_clk , i_stb , i_data , o_busy ,
Counter
Change Detection
o_uart_tx ) ;
Ź txdata // . . .
State diagram txuart #(UART_SETUP [ 2 3 : 0 ] ) txuarti ( i_clk ,
Outgoing Data
Formal Verification tx_stb , tx_data , o_uart_tx , tx_busy ) ;
Cover // . . .
Assertions
Sequence
endmodule
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

11 / 54
Our focus: txdata
Lesson Overview Here’s the port list(s) we’ll design to
Data Transmitter
Desired Structure module txdata ( i_clk , i_stb , i_data , o_busy ,
Counter
Change Detection
o_uart_tx ) ;
Ź txdata // . . .
State diagram txuart #(UART_SETUP [ 2 3 : 0 ] ) txuarti ( i_clk ,
Outgoing Data
Formal Verification tx_stb , tx_data , o_uart_tx , tx_busy ) ;
Cover // . . .
Assertions
Sequence
endmodule
Sequence
Concurrent
Assertions
Simulation
ncurses
˝ If i_stb is true, we have a new value to send
Verilator data ˝ i_data will then contain that 32-bit value
Testbench build
Exercise #2 ˝ o_busy means we cannot accept data
Exercise #3
˝ o_uart_tx is the 1-bit serial port output
Conclusion

11 / 54
Our focus: txdata
Lesson Overview Here’s the port list(s) we’ll design to
Data Transmitter
Desired Structure module txdata ( i_clk , i_stb , i_data , o_busy ,
Counter
Change Detection
o_uart_tx ) ;
Ź txdata // . . .
State diagram txuart #(UART_SETUP [ 2 3 : 0 ] ) txuarti ( i_clk ,
Outgoing Data
Formal Verification tx_stb , tx_data , o_uart_tx , tx_busy ) ;
Cover // . . .
Assertions
Sequence
endmodule
Sequence
Concurrent
Assertions
Simulation
ncurses
˝ tx_stb requests data be transmitted
Verilator data ˝ tx_data is the 8-bit character to transmit
Testbench build
Exercise #2 ˝ tx_busy means the serial port transmitter is busy and cannot
Exercise #3
Conclusion
accept data

12 / 54
State diagram
Lesson Overview We can create a state diagram for this state machine too
Data Transmitter
Desired Structure
Counter
Change Detection
txdata
Ź State diagram
Outgoing Data
Formal Verification
Cover
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

13 / 54
State diagram
Lesson Overview We can create a state diagram for this state machine too
Data Transmitter
Desired Structure
Counter
Change Detection
txdata
Ź State diagram
Outgoing Data
Formal Verification
Cover
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build We’ll start sending our message upon request (i_stb is true),
Exercise #2
Exercise #3
and advance to the next character any time the transmitter is
Conclusion not busy (tx_busy is false)

13 / 54
State diagram
Lesson Overview We can create a state diagram for this state machine too
Data Transmitter
Desired Structure
Counter
Change Detection
txdata
Ź State diagram
Outgoing Data
Formal Verification
Cover
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build In this chart, data is the 32-bit word we are sending, and hextu
Exercise #2
Exercise #3
just references the fact that we need to convert the various
Conclusion nibbles to hexadecimal before outputting them

13 / 54
State diagram
Lesson Overview We can create a state diagram for this state machine too
Data Transmitter
Desired Structure
Counter
Change Detection
txdata
Ź State diagram
Outgoing Data
Formal Verification
Cover
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data Remember, input data such as i_data are only valid as long
Testbench build
Exercise #2
as the incoming request is valid (i_stb is high). We’ll need
Exercise #3 to make a copy of that data once the request is made,
Conclusion
(i_stb) && (!o_busy), and then work off of that copy.

13 / 54
State diagram
Lesson Overview We can even annotate this with state ID numbers
Data Transmitter
Desired Structure
Counter
Change Detection
txdata
Ź State diagram
Outgoing Data
Formal Verification
Cover
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

14 / 54
State diagram
Lesson Overview The state machine should remind you of helloworld.v
Data Transmitter
Desired Structure always @ ( posedge i_clk )
Counter
Change Detection
i f ( ! o_busy )
txdata begin
Ź State diagram i f ( i_stb )
Outgoing Data
Formal Verification begin
Cover state <= 1 ;
Assertions
Sequence
tx_stb <= 1 ;
Sequence end // e l s e s t a t e a l r e a d y == 0
Concurrent
Assertions
end e l s e i f ( ( tx_stb )&&(! tx_busy ) )
Simulation begin
ncurses state <= state + 1 ;
Verilator data
Testbench build i f ( state >= 4 ’ hd )
Exercise #2 begin
Exercise #3
Conclusion
tx_stb <= 1 ’ b0 ;
state <= 0 ;
// . . .

15 / 54
Outgoing Data
Lesson Overview The outgoing data is just a shift register
Data Transmitter
Desired Structure i n i t i a l sreg = 0 ;
Counter
Change Detection
always @ ( posedge i_clk )
txdata i f ( ! o_busy ) // && ( i s t b )
State diagram sreg <= i_data ;
Ź Outgoing Data
Formal Verification e l s e i f ( ( ! tx_busy)&&(state > 4 ’ h1 ) )
Cover // Hold c o n s t a n t u n t i l r e a d
Assertions
Sequence
sreg <= { i_data [ 2 7 : 0 ] , 4 ’ h0 } ;
Sequence
Concurrent
Assertions
Question:
Simulation
ncurses
Why aren’t we conditioning our load on i_stb as well?
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

16 / 54
Outgoing Data
Lesson Overview Converting to hex is very straight forward
Data Transmitter
Desired Structure always @ ( posedge i_clk )
Counter
Change Detection
case ( sreg [ 3 1 : 2 8 ] )
txdata 4 ’ h0 : hex <= ”0 ” ;
State diagram 4 ’ h1 : hex <= ”1 ” ;
Ź Outgoing Data
Formal Verification 4 ’ h2 : hex <= ”2 ” ;
Cover 4 ’ h3 : hex <= ”3 ” ;
Assertions
Sequence
// . . .
Sequence 4 ’ h9 : hex <= ”9 ” ;
Concurrent
Assertions
4 ’ ha : hex <= ” a ” ;
Simulation 4 ’ hb : hex <= ”b” ;
ncurses 4 ’ hc : hex <= ” c ” ;
Verilator data
Testbench build 4 ’ hd : hex <= ”d” ;
Exercise #2 4 ’ he : hex <= ” e ” ;
Exercise #3
Conclusion
4 ’ hf : hex <= ” f ” ;
d e f a u l t : begin end
endcase

17 / 54
Outgoing Data
Lesson Overview Converting to hex is very straight forward
Data Transmitter
Desired Structure always @ ( posedge i_clk )
Counter
Change Detection
case ( sreg [ 3 1 : 2 8 ] )
txdata 4 ’ h0 : hex <= ”0 ” ; // V a l u e s i n q u o t a t i o n
State diagram 4 ’ h1 : hex <= ”1 ” ; // marks s p e c i f y l i t e r a l
Ź Outgoing Data
Formal Verification 4 ’ h2 : hex <= ”2 ” ; // 8´ b i t v a l u e s w i t h an
Cover 4 ’ h3 : hex <= ”3 ” ; // ASCII e n c o d i n g
Assertions
Sequence
// . . .
Sequence 4 ’ h9 : hex <= ”9 ” ;
Concurrent
Assertions
4 ’ ha : hex <= ” a ” ;
Simulation 4 ’ hb : hex <= ”b” ;
ncurses 4 ’ hc : hex <= ” c ” ;
Verilator data
Testbench build 4 ’ hd : hex <= ”d” ;
Exercise #2 4 ’ he : hex <= ” e ” ;
Exercise #3
Conclusion
4 ’ hf : hex <= ” f ” ;
d e f a u l t : begin end
endcase

18 / 54
Outgoing Data
Lesson Overview Converting to hex is very straight forward
Data Transmitter
Desired Structure always @ ( posedge i_clk )
Counter
Change Detection
case ( sreg [ 3 1 : 2 8 ] )
txdata 4 ’ h0 : hex <= ”0 ” ; // V a l u e s i n q u o t a t i o n
State diagram 4 ’ h1 : hex <= ”1 ” ; // marks s p e c i f y l i t e r a l
Ź Outgoing Data
Formal Verification 4 ’ h2 : hex <= ”2 ” ; // 8´ b i t v a l u e s w i t h an
Cover 4 ’ h3 : hex <= ”3 ” ; // ASCII e n c o d i n g
Assertions
Sequence
// . . .
Sequence 4 ’ h9 : hex <= ”9 ” ; // S t r i n g s work s i m i l a r l y
Concurrent
Assertions
4 ’ ha : hex <= ” a ” ; // w i t h t h e o n l y d i f f e r e n c e
Simulation 4 ’ hb : hex <= ”b” ; // b e i n g t h a t s t r i n g
ncurses 4 ’ hc : hex <= ” c ” ; // l i t e r a l s may be much
Verilator data
Testbench build 4 ’ hd : hex <= ”d” ; // l o n g e r t h a n 8´ b i t s
Exercise #2 4 ’ he : hex <= ” e ” ;
Exercise #3
Conclusion
4 ’ hf : hex <= ” f ” ; // Example : A <= ” 1 2 3 4 ” ;
d e f a u l t : begin end
endcase

19 / 54
Outgoing Data
Lesson Overview Put together, here’s our code to transmit a byte
Data Transmitter
Desired Structure always @ ( posedge i_clk )
Counter
Change Detection
case ( state )
txdata i f ( ! tx_busy )
State diagram case ( state )
Ź Outgoing Data
Formal Verification 4 ’ h1 : tx_data <= ” 0” ; // These a r e t h e
Cover 4 ’ h2 : tx_data <= ”x” ; // v a l u e s we ’ l l
Assertions
Sequence
4 ’ h3 : tx_data <= hex ; // want t o o u t p u t
Sequence 4 ’ h4 : tx_data <= hex ; // at each s t a t e
Concurrent
Assertions
// . . .
Simulation 4 ’ h9 : tx_data <= hex ;
ncurses 4 ’ ha : tx_data <= hex ;
Verilator data
Testbench build 4 ’ hb : tx_data <= ” \ r ” ; // C a r r i a g e r e t u r n
Exercise #2 4 ’ hc : tx_data <= ” \n” ; // L i n e ´f e e d
Exercise #3
Conclusion
d e f a u l t : tx_data <= ”Q” ; // A bad v a l u e
endcase

20 / 54
Simulation
Lesson Overview Let’s do simulation after formal verification
Data Transmitter
Desired Structure ˝ It’s easier to get a trace from formal
Counter
Change Detection
˝ Formal methods are often done faster
txdata ˝ etc.
State diagram
Ź Outgoing Data
Formal Verification
Cover
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

21 / 54
Formal Verification
Lesson Overview Our design is getting large
Data Transmitter
Desired Structure ˝ We’ve already verified txuart.v
Counter
Change Detection
˝ It would be nice not to have to do it again
txdata
State diagram Let’s simplify things instead!
Outgoing Data
Formal ˝ Let’s replace txuart.v with something that . . .
Ź Verification
Cover
Assertions
– Might or might not act like txuart.v
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

22 / 54
Formal Verification
Lesson Overview Our design is getting large
Data Transmitter
Desired Structure ˝ We’ve already verified txuart.v
Counter
Change Detection
˝ It would be nice not to have to do it again
txdata
State diagram Let’s simplify things instead!
Outgoing Data
Formal ˝ Let’s replace txuart.v with something that . . .
Ź Verification
Cover
Assertions
– Might or might not act like txuart.v
Sequence – . . . at the solver’s discretion
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

22 / 54
Formal Verification
Lesson Overview Our design is getting large
Data Transmitter
Desired Structure ˝ We’ve already verified txuart.v
Counter
Change Detection
˝ It would be nice not to have to do it again
txdata
State diagram Let’s simplify things instead!
Outgoing Data
Formal ˝ Let’s replace txuart.v with something that . . .
Ź Verification
Cover
Assertions
– Might or might not act like txuart.v
Sequence – . . . at the solver’s discretion
Sequence
Concurrent
– Acting like txuart.v must remain a possibility
Assertions
Simulation
ncurses
This is called abstraction
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

22 / 54
Formal Verification
Lesson Overview Here’s how we’ll do it:
Data Transmitter
Desired Structure ‘ i f n d e f FORMAL
Counter
Change Detection
txuart #(UART_SETUP [ 2 3 : 0 ] ) txuarti ( i_clk ,
txdata tx_stb , tx_data , o_uart_tx , tx_busy ) ;
State diagram ‘else
Outgoing Data
Formal ( ∗ anyseq ∗ ) w i r e serial_busy , serial_out ;
Ź Verification a s s i g n o_uart_tx = serial_out ;
Cover
Assertions a s s i g n tx_busy = serial_busy ;
Sequence
Sequence
Concurrent
Assertions
˝ (∗ anyseq ∗) allows the solver to pick the values of
Simulation serial_busy and serial_out
ncurses
Verilator data ˝ (∗ anyseq ∗) values can change from one clock to the next
Testbench build ˝ They might match what txuart would’ve done
Exercise #2
Exercise #3
Conclusion

23 / 54
Formal Verification
Lesson Overview Here’s how we’ll do it:
Data Transmitter
Desired Structure ‘ i f n d e f FORMAL
Counter
Change Detection
txuart #(UART_SETUP [ 2 3 : 0 ] ) txuarti ( i_clk ,
txdata tx_stb , tx_data , o_uart_tx , tx_busy ) ;
State diagram ‘else
Outgoing Data
Formal ( ∗ anyseq ∗ ) w i r e serial_busy , serial_out ;
Ź Verification a s s i g n o_uart_tx = serial_out ;
Cover
Assertions a s s i g n tx_busy = serial_busy ;
Sequence
Sequence
Concurrent
Assertions
˝ (∗ anyseq ∗) allows the solver to pick the values of
Simulation serial_busy and serial_out
ncurses
Verilator data ˝ (∗ anyseq ∗) values can change from one clock to the next
Testbench build ˝ They might match what txuart would’ve done, or they
Exercise #2
Exercise #3 might not
Conclusion

23 / 54
Formal Verification
Lesson Overview Here’s how we’ll do it:
Data Transmitter
Desired Structure ‘ i f n d e f FORMAL
Counter
Change Detection
txuart #(UART_SETUP [ 2 3 : 0 ] ) txuarti ( i_clk ,
txdata tx_stb , tx_data , o_uart_tx , tx_busy ) ;
State diagram ‘else
Outgoing Data
Formal ( ∗ anyseq ∗ ) w i r e serial_busy , serial_out ;
Ź Verification a s s i g n o_uart_tx = serial_out ;
Cover
Assertions a s s i g n tx_busy = serial_busy ;
Sequence
Sequence
Concurrent
Assertions
˝ (∗ anyseq ∗) allows the solver to pick the values of
Simulation serial_busy and serial_out
ncurses
Verilator data ˝ (∗ anyseq ∗) values can change from one clock to the next
Testbench build ˝ They might match what txuart would’ve done, or they
Exercise #2
Exercise #3 might not
Conclusion
˝ If our design passes in spite of what this abstract txuart does

23 / 54
Formal Verification
Lesson Overview Here’s how we’ll do it:
Data Transmitter
Desired Structure ‘ i f n d e f FORMAL
Counter
Change Detection
txuart #(UART_SETUP [ 2 3 : 0 ] ) txuarti ( i_clk ,
txdata tx_stb , tx_data , o_uart_tx , tx_busy ) ;
State diagram ‘else
Outgoing Data
Formal ( ∗ anyseq ∗ ) w i r e serial_busy , serial_out ;
Ź Verification a s s i g n o_uart_tx = serial_out ;
Cover
Assertions a s s i g n tx_busy = serial_busy ;
Sequence
Sequence
Concurrent
Assertions
˝ (∗ anyseq ∗) allows the solver to pick the values of
Simulation serial_busy and serial_out
ncurses
Verilator data ˝ (∗ anyseq ∗) values can change from one clock to the next
Testbench build ˝ They might match what txuart would’ve done, or they
Exercise #2
Exercise #3 might not
Conclusion
˝ If our design passes in spite of what this abstract txuart does,
then it will pass if txuart acts like it should

23 / 54
Formal Verification
Lesson Overview We’ll insist that our abstract UART is busy following any request
Data Transmitter
Desired Structure reg [1:0] f_minbusy ;
Counter
Change Detection
txdata i n i t i a l f_minbusy = 0 ;
State diagram always @ ( posedge i_clk )
Outgoing Data
Formal i f ( ( tx_stb )&&(! tx_busy ) )
Ź Verification f_minbusy <= 2 ’ b01 ;
Cover
Assertions e l s e i f ( f_minbusy != 2 ’ b00 )
Sequence f_minbusy <= f_minbusy + 1 ’ b1 ;
Sequence
Concurrent
Assertions We can use f_minbusy to force any transmit request to take at
Simulation
ncurses
least four cycles before dropping the busy line
Verilator data
Testbench build ˝ f_minbusy is just a 2-bit counter
Exercise #2
Exercise #3
˝ After passing 3, it waits at zero for the next byte
Conclusion

24 / 54
Formal Verification
Lesson Overview We’ll insist that our abstract UART is busy following any request
Data Transmitter
Desired Structure reg [1:0] f_minbusy ;
Counter
Change Detection
txdata i n i t i a l f_minbusy = 0 ;
State diagram always @ ( posedge i_clk )
Outgoing Data
Formal i f ( ( tx_stb )&&(! tx_busy ) )
Ź Verification f_minbusy <= 2 ’ b01 ;
Cover
Assertions e l s e i f ( f_minbusy != 2 ’ b00 )
Sequence f_minbusy <= f_minbusy + 1 ’ b1 ;
Sequence
Concurrent
Assertions always @ ( ∗ )
Simulation
ncurses
i f ( f_minbusy != 0 )
Verilator data assume ( tx_busy ) ;
Testbench build
Exercise #2
Exercise #3
Since (∗ anyseq ∗) values act like inputs to our design,
Conclusion constraining them by an assumption is appropriate

25 / 54
Formal Verification
Lesson Overview We’ll also insist it doesn’t become busy on its own
Data Transmitter
Desired Structure i n i t i a l assume ( ! tx_busy ) ; // S t a r t s i d l e
Counter
Change Detection
always @ ( posedge i_clk )
txdata i f ( $past ( i_reset ) ) // Becomes i d l e a f t e r r e s e t
State diagram assume ( ! tx_busy ) ;
Outgoing Data
Formal e l s e i f ( ( $past ( tx_stb ))&&(! $past ( tx_busy ) ) )
Ź Verification // Must become b u s y a f t e r a new r e q u e s t
Cover
Assertions assume ( tx_busy ) ;
Sequence e l s e i f ( ! $past ( tx_busy ) )
Sequence
Concurrent
// O t h e r w i s e , i t c a n n o t become b u s y
Assertions // w i t h o u t a r e q u e s t
Simulation
ncurses
assume ( ! tx_busy ) ;
Verilator data
Testbench build Now we can build a proof without re-verifying txuart.v!
Exercise #2
Exercise #3
Conclusion

26 / 54
Cover
Lesson Overview Let’s see if this design works:
Data Transmitter
Desired Structure // Don ’ t f o r g e t t o s e t t h e mode t o c o v e r
Counter
Change Detection
// i n y o u r SBY f i l e !
txdata always @ ( posedge i_clk )
State diagram i f ( f_past_valid )
Outgoing Data
Formal Verification cover ( $ f e l l ( o_busy ) ) ;
Ź Cover
Assertions
This would yield a trace with a reset
Sequence
Sequence
Concurrent
˝ It works, but it’s not very informative
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

27 / 54
Cover
Lesson Overview What if we except the reset?
Data Transmitter
Desired Structure // Don ’ t f o r g e t t o s e t t h e mode t o c o v e r
Counter
Change Detection
// i n y o u r SBY f i l e !
txdata always @ ( posedge i_clk )
State diagram i f ( ( f_past_valid )&&(! $past ( i_reset ) ) )
Outgoing Data
Formal Verification cover ( $ f e l l ( o_busy ) ) ;
Ź Cover
Assertions
We can now get a useful trace
Sequence
Sequence
Concurrent
˝ The trace starts with a request
Assertions
˝ Works through the whole sequence
Simulation
ncurses ˝ Stops when the state machine is ready to start again
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

28 / 54
Cover
Lesson Overview What if we look for 0x12345678\r\n?
Data Transmitter
Desired Structure reg f_seen_data ;
Counter
Change Detection
i n i t i a l f_seen_data = 0 ;
txdata always @ ( posedge i_clk )
State diagram i f ( i_reset )
Outgoing Data
Formal Verification f_seen_data <= 1 ’ b0 ;
Ź Cover e l s e i f ( ( i_stb )&&(! o_busy )
Assertions
Sequence
&&(i_data == 3 2 ’ h12345678 ) )
Sequence f_seen_data <= 1 ’ b1 ;
Concurrent
Assertions
Simulation always @ ( posedge i_clk )
ncurses
i f ( ( f_past_valid )&&(! $past ( i_reset ) )
Verilator data
Testbench build &&(f_seen_data ) )
Exercise #2 cover ( $ f e l l ( o_busy ) ) ;
Exercise #3
Conclusion
Check out the trace.

29 / 54
Cover
Lesson Overview What if we look for 0x12345678\r\n?
Data Transmitter
Desired Structure reg f_seen_data ;
Counter
Change Detection
i n i t i a l f_seen_data = 0 ;
txdata always @ ( posedge i_clk )
State diagram i f ( i_reset )
Outgoing Data
Formal Verification f_seen_data <= 1 ’ b0 ;
Ź Cover e l s e i f ( ( i_stb )&&(! o_busy )
Assertions
Sequence
&&(i_data == 3 2 ’ h12345678 ) )
Sequence f_seen_data <= 1 ’ b1 ;
Concurrent
Assertions
Simulation always @ ( posedge i_clk )
ncurses
i f ( ( f_past_valid )&&(! $past ( i_reset ) )
Verilator data
Testbench build &&(f_seen_data ) )
Exercise #2 cover ( $ f e l l ( o_busy ) ) ;
Exercise #3
Conclusion
Check out the trace. Does your design work?

29 / 54
Cover
Lesson Overview What if we look for 0x12345678\r\n?
Data Transmitter
Desired Structure reg f_seen_data ;
Counter
Change Detection
i n i t i a l f_seen_data = 0 ;
txdata always @ ( posedge i_clk )
State diagram i f ( i_reset )
Outgoing Data
Formal Verification f_seen_data <= 1 ’ b0 ;
Ź Cover e l s e i f ( ( i_stb )&&(! o_busy )
Assertions
Sequence
&&(i_data == 3 2 ’ h12345678 ) )
Sequence f_seen_data <= 1 ’ b1 ;
Concurrent
Assertions
Simulation Caution: It’s a snare to use something like f_seen_data outside
ncurses
Verilator data
of a cover context
Testbench build
Exercise #2
˝ We aren’t doing directed simulation
Exercise #3 ˝ The great power of formal is that it applies to all inputs
Conclusion
˝ We’re just picking an interesting input for a trace

30 / 54
Assertions
Lesson Overview Now, what assertions would be appropriate?
Data Transmitter
Desired Structure ˝ We can assert state is legal
Counter
Change Detection
˝ That tx_stb != (state == 0)
txdata ˝ Can we assert that the first data output is a ”0”?
State diagram
Outgoing Data ˝ That the second output is a ”1”?
Formal Verification
Cover Your turn: what would make the most sense here?
Ź Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

31 / 54
Sequence
Lesson Overview Yes, we can assert a sequence takes place!
Data Transmitter
Desired Structure reg [12:0] f_p1reg ; // P r o p e r t y s´r e g
Counter
Change Detection
txdata i n i t i a l f_p1reg = 0 ;
State diagram always @ ( posedge i_clk )
Outgoing Data
Formal Verification i f ( i_reset )
Cover f_p1reg <= 0 ;
Assertions
Ź Sequence
e l s e i f ( ( i_stb )&&(! o_busy ) )
Sequence begin
Concurrent
Assertions
f_p1reg <= 1 ;
Simulation a s s e r t ( f_p1reg == 0 ) ;
ncurses end e l s e i f ( ! tx_busy )
Verilator data
Testbench build f_p1reg <= { f_p1reg [ 1 1 : 0 ] , 1 ’ b0 } ;
Exercise #2
Exercise #3
f_p1reg[x] will now be true for stage x of any output sequence
Conclusion

32 / 54
Sequence
Lesson Overview But what is f_p1reg? It’s a shift register
Data Transmitter
Desired Structure
Counter
Change Detection i stb
txdata
State diagram
o busy
Outgoing Data tx stb
Formal Verification
x
Cover tx data 0 h h h h h h h h \r \n
Assertions
Sequence
f_p1reg[0]
Ź Sequence f_p1reg[1]
Concurrent
Assertions f_p1reg[2]
Simulation
ncurses f_p1reg[3]
Verilator data
Testbench build
f_p1reg[4]
Exercise #2
Exercise #3
Conclusion ˝ f_p1reg[x] is true anytime we are in stage x of our sequence
˝ We can use this when constructing formal properties

33 / 54
Sequence
Lesson Overview Using f_p1reg[x] we can make assertions about the different
Data Transmitter
Desired Structure
states in our sequence
Counter
Change Detection always @ ( posedge i_clk )
txdata i f ( ( ! tx_busy ) | | ( f_minbusy == 0 ) )
State diagram
Outgoing Data
begin
Formal Verification // I f t h e s e r i a l p o r t i s r e a d y f o r
Cover // t h e n e x t c h a r a c t e r , o r w h i l e we a r e
Assertions
Sequence
// w a i t i n g f o r t h e n e x t c h a r a c t e r , . . .
Ź Sequence i f ( f_p1reg [ 0 ] )
Concurrent
Assertions a s s e r t ( ( tx_data == ”0 ” )
Simulation &&(state == 1 ) ) ;
ncurses
Verilator data
i f ( f_p1reg [ 1 ] )
Testbench build a s s e r t ( ( tx_data == ” x ” )
Exercise #2 &&(state == 2 ) ) ;
Exercise #3
Conclusion // e t c .
end

34 / 54
Sequence
Lesson Overview Why use a shift register for f_p1reg[x]?
Data Transmitter
Desired Structure ˝ A counter would also work for this sequence
Counter
Change Detection
˝ A shift register is more general and powerful
txdata
State diagram – A shift register can represent states in a sequence that
Outgoing Data
Formal Verification
might overlap itself
Cover – Perhaps such a sequence may be entered on every clock
Assertions
Sequence
cycle
Ź Sequence – An example would be a peripheral that always responds to
Concurrent
Assertions any request in N cycles, yet never stalls
Simulation
ncurses f_p1reg[x] allows us to represent general sequence states
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

35 / 54
Concurrent Assertions
Lesson Overview Full System Verilog support would make this easier
Data Transmitter
Desired Structure sequence SEND ( A , B ) ;
Counter
Change Detection
( tx_stb)&&(state == A)&&(tx_data == B )
txdata throughout
State diagram ( tx_busy ) [ ∗ 0 : $ ] ##1 ( ! tx_busy )
Outgoing Data
Formal Verification endsequence
Cover
Assertions
This defines a sequence where
Sequence
Sequence
Concurrent
˝ (tx_stb)&&... must be true
Ź Assertions
˝ while tx_busy is true, and then
Simulation
ncurses ˝ until (and including) the clock where tx_busy is false
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

36 / 54
Sequence
Lesson Overview Full System Verilog support would make this easier
Data Transmitter
Desired Structure sequence SEND ( A , B ) ;
Counter
Change Detection
// . . . .
txdata
State diagram We could then string such sequences together in a property that
Outgoing Data
Formal Verification could be asserted
Cover
Assertions a s s e r t p r o p e r t y ( @ ( posedge i_clk ) )
Sequence d i s a b l e iff ( i_reset )
Sequence
Concurrent ( i_stb )&&(! o_busy )
Ź Assertions
|=> SEND ( 1 , ” 0” ) // F i r s t s t a t e
Simulation
ncurses ##1 SEND ( 2 , ” x ” ) // Second , e t c
Verilator data // . . .
Testbench build
Exercise #2
Exercise #3
Conclusion ˝ A |=> B means if A, then B is asserted true on the next clock
˝ ##1 here means one clock later

37 / 54
Sequence
Lesson Overview Full System Verilog support would make this easier
Data Transmitter
Desired Structure sequence SEND ( A , B ) ;
Counter
Change Detection
// . . . .
txdata
State diagram We could then string such sequences together in a property that
Outgoing Data
Formal Verification could be asserted
Cover
Assertions a s s e r t p r o p e r t y ( @ ( posedge i_clk ) )
Sequence d i s a b l e iff ( i_reset )
Sequence
Concurrent ( i_stb )&&(! o_busy )
Ź Assertions
|=> SEND ( 1 , ” 0” ) // F i r s t s t a t e
Simulation
ncurses ##1 SEND ( 2 , ” x ” ) // Second , e t c
Verilator data // . . .
Testbench build
Exercise #2
Exercise #3 SymbiYosys support for sequences requires a license
Conclusion

38 / 54
Sequence
Lesson Overview Full System Verilog support would make this easier
Data Transmitter
Desired Structure sequence SEND ( A , B ) ;
Counter
Change Detection
// . . . .
txdata
State diagram We could then string such sequences together in a property that
Outgoing Data
Formal Verification could be asserted
Cover
Assertions a s s e r t p r o p e r t y ( @ ( posedge i_clk ) )
Sequence d i s a b l e iff ( i_reset )
Sequence
Concurrent ( i_stb )&&(! o_busy )
Ź Assertions
|=> SEND ( 1 , ” 0” ) // F i r s t s t a t e
Simulation
ncurses ##1 SEND ( 2 , ” x ” ) // Second , e t c
Verilator data // . . .
Testbench build
Exercise #2
Exercise #3 SymbiYosys support for sequences requires a license
Conclusion
˝ f_p1reg let’s us do roughly the same thing

38 / 54
Exercise #1
Lesson Overview Your turn!
Data Transmitter
Desired Structure
Take a moment now to . . .
Counter
Change Detection
˝ Create your txdata.v, or
txdata ˝ Download my broken one, and then
State diagram
Outgoing Data ˝ Formally verify it
Formal Verification
Cover – Add such assertions as you deem fit
Assertions
Sequence
– Make sure you get a trace showing it working
Sequence

Ź
Concurrent
Assertions
Does your design work?
Simulation
ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

39 / 54
Simulation
Lesson Overview Let’s move on to simulation
Data Transmitter
Desired Structure ˝ Let’s use the simulator to count key presses
Counter
Change Detection
˝ ncurses + Verilator offers a quick debugging environment
txdata
State diagram – Every time a key is pressed, output a new count value
Outgoing Data
Formal Verification
– We’ll use getch() to get key presses immediately
Cover
Assertions
You may need to download and install ncurses-dev
Sequence
Sequence – We’ll adjust uartsim() to print to the screen
Concurrent
Assertions ˝ You can also examine internal register values with Verilator
Ź Simulation
ncurses – While the design is running
Verilator data
Testbench build
Exercise #2
Let’s look at how we’d do these things
Exercise #3
Conclusion

40 / 54
ncurses
Lesson Overview ncurses is an old-fashioned text library
Data Transmitter
Desired Structure ˝ It allows us easy access to key press information
Counter
Change Detection
˝ We can write to various locations of the screen
txdata ˝ etc.
State diagram
Outgoing Data ˝ The original ZipCPU debugger was written with ncurses
Formal Verification
Cover We’ll only scratch the surface here
Assertions
Sequence
Sequence
Concurrent
Assertions
Simulation
Ź ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

41 / 54
ncurses
Lesson Overview Starting ncurses requires some boilerplate
Data Transmitter
Desired Structure #i n c l u d e < ncurses >
Counter
Change Detection
// ...
txdata i n t main ( i n t argc , c h a r ** a r g v ) {
State diagram // ...
Outgoing Data
Formal Verification i n i t s c r ();
Cover raw ();
Assertions
Sequence
noecho ();
Sequence keypad ( s t d s c r , t r u e );
Concurrent
Assertions
h a l f d e l a y (1);
Simulation
Ź ncurses
Verilator data ˝ This initializes the curses environment
Testbench build
Exercise #2 ˝ Turns off line handling and echo
Exercise #3 ˝ Decodes special keys (like escape) for us
Conclusion
˝ halfdelay (1) – Doesn’t wait for keypresses

42 / 54
ncurses
Lesson Overview Our inner loop will start by checking for keypresses
Data Transmitter
Desired Structure do {
Counter
Change Detection
done = f a l s e ;
txdata tb - > m core - > i e v e n t = 0;
State diagram // Ket a keypress
Outgoing Data
Formal Verification chv = g e t c h ();
Cover i f ( chv == KEY ESCAPE)
Assertions
Sequence
// Exit on escape
Sequence done = t r u e ;
Concurrent
Assertions
e l s e i f ( chv != ERR)
Simulation // Key was pressed
Ź ncurses tb - > m core - > i e v e n t = 1;
Verilator data
Testbench build
Exercise #2 tb - > t i c k ();
Exercise #3
Conclusion
(* u a r t )( tb - > m core - > o u a r t t x );
} w h i l e (! done );

43 / 54
ncurses
Lesson Overview We can speed this up too:
Data Transmitter
Desired Structure do {
Counter
Change Detection
// ...
txdata f o r ( i n t k =0; k <1000; k ++) {
State diagram tb - > t i c k ();
Outgoing Data
Formal Verification (* u a r t )( tb - > m core - > o u a r t t x );
Cover tb - > m core - > i e v e n t = 0;
Assertions
Sequence
}
Sequence } w h i l e (! done );
Concurrent
Assertions
Simulation
Ź ncurses ˝ getch() waits 1{10th of a second for a keypress
Verilator data
Testbench build – This is because we called halfdelay (1);
Exercise #2
Exercise #3
Conclusion
˝ This will run 1000 simulation ticks per getch() call

44 / 54
ncurses
Lesson Overview We can also count given keypresses
Data Transmitter
Desired Structure do {
Counter
Change Detection
// ...
txdata f o r ( i n t k =0; k <1000; k ++) {
State diagram tb - > t i c k ();
Outgoing Data
Formal Verification (* u a r t )( tb - > m core - > o u a r t t x );
Cover keypresses
Assertions
Sequence
+= tb - > m core - > i e v e n t ;
Sequence tb - > m core - > i e v e n t = 0;
Concurrent }
Assertions
Simulation } w h i l e (! done );
Ź ncurses
Verilator data
Testbench build
We’ll print this number out before we are done
Exercise #2
Exercise #3
Conclusion

45 / 54
ncurses
Lesson Overview We’ll also need to replace the putchar() in uartsim.cpp
Data Transmitter
Desired Structure ˝ ncurses requires we use addch()
Counter
Change Detection
txdata // if character received
State diagram i f ( m r x d a t a != ’\ r ’)
Outgoing Data
Formal Verification addch ( m r x d a t a );
Cover
Assertions
Sequence ˝ No flush is necessary, getch() handles that
Sequence
Concurrent ˝ ’\r’ would clear our line, so we keep from printing it
Assertions
Simulation
Ź ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

46 / 54
ncurses
Lesson Overview endwin() ends the ncurses environment
Data Transmitter
Desired Structure endwin ();
Counter
Change Detection
txdata p r i n t f ( " \ n \ nSimulation complete \ n " );
State diagram p r i n t f ( " %4 d key presses sent \ n " , k e y p r e s s e s );
Outgoing Data
Formal Verification
Cover This is nice, but
Assertions
Sequence ˝ wouldn’t you also like a summary of keypresses the design
Sequence
Concurrent counted?
Assertions
Simulation
Ź ncurses
Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

47 / 54
Verilator data
Lesson Overview Verilator maintains your entire design in a C++ object
Data Transmitter
Desired Structure ˝ With a little work, we can find our variables
Counter
Change Detection
˝ A quick grep through Vthedesign.h reveals ...
txdata ˝ v DOT counterv contains our counter’s value
State diagram
Outgoing Data
Formal Verification
– I use an older version of Verilator
Cover – Modern versions place this in thedesign DOT counterv
Assertions
Sequence
– Supporting both requires a little work
Sequence
Concurrent ˝ You can often find other values like this
Assertions
Simulation – Grep on your variables name
ncurses
Ź Verilator data – Be aware, Verilator will pick which of many names to give
Testbench build a value
Exercise #2
Exercise #3 – Output wires may go by the name of their parent’s value
Conclusion

48 / 54
Verilator data
Lesson Overview This little adjustment will allow us to simplify the reference to
Data Transmitter
Desired Structure
our counter
Counter
Change Detection #i f d e f OLD_VERILATOR
txdata #d e f i n e VVAR ( X ) v__DOT_ ## A
State diagram
Outgoing Data
#e l s e
Formal Verification #d e f i n e VVAR ( X ) thedesign__DOT_ ## A
Cover #e n d i f
Assertions
Sequence
Sequence #d e f i n e counterv VVAR ( _counterv )
Concurrent
Assertions
Simulation
ncurses ˝ If OLD VERILATOR is defined (my old version)
Ź Verilator data
Testbench build – counterv evaluates to v DOT counterv
Exercise #2
Exercise #3
Conclusion
˝ Otherwise counterv is replaced by
– thedesign DOT counterv

49 / 54
Verilator data
Lesson Overview We can now output our current counter
Data Transmitter
Desired Structure endwin ();
Counter
Change Detection
txdata p r i n t f ( " \ n \ nSimulation complete \ n " );
State diagram p r i n t f ( " %4 d key presses sent \ n " ,
Outgoing Data
Formal Verification k e y p r e s s e s );
Cover p r i n t f ( " %4 d key presses registered \ n " ,
Assertions
Sequence
tb - > m core - > c o u n t e r v );
Sequence
Concurrent
Assertions
Simulation
ncurses
Ź Verilator data
Testbench build
Exercise #2
Exercise #3
Conclusion

50 / 54
Testbench build
Lesson Overview Two changes are required to our build script
Data Transmitter
Desired Structure ˝ If you want to define NEW VERILATOR or
Counter
Change Detection
OLD VERILATOR . . .
txdata
State diagram – You’ll need to do some processing on Verilator’s version
Outgoing Data
Formal Verification
– The vversion.sh file does this, returning either
Cover -DOLD VERILATOR or -DNEW VERILATOR
Assertions
Sequence
– We can use this output in our g++ command line
Sequence – Alternatively, you can just adjust the file for your version
Concurrent
Assertions
Simulation
˝ We need to reference -lncurses in our Makefile when
ncurses building our executable
Verilator data
Ź Testbench build
Exercise #2
Exercise #3
Conclusion

51 / 54
Exercise #2
Lesson Overview Your turn!
Data Transmitter
Desired Structure
Build and experiment with the simulation
Counter
Change Detection
˝ Using your txdata.v
txdata ˝ main() is found in thedesign tb.cpp in the handouts
State diagram
Outgoing Data ˝ Experiment with . . .
Formal Verification
Cover – Adjusting the number of tb->tick() calls between calls to
Assertions
Sequence
getch()
Sequence – Does this speed up or slow down your design?
Concurrent
Assertions – Are all of your keypresses recognized?
Simulation
ncurses
– What happens when you press the key while the design is
Verilator data busy?
Testbench build
Ź Exercise #2
Exercise #3
Conclusion

52 / 54
Exercise #3
Lesson Overview Only now is it time to test this in hardware
Data Transmitter
Desired Structure
Counter
˝ You’ll need to test for button changes
Change Detection
txdata
always @ ( posedge i_clk )
State diagram last_btn <= i_btn ;
Outgoing Data
Formal Verification
Cover assign w_event = ( i_btn )&&(! last_btn ) ;
Assertions
Sequence
Sequence
˝ Does it work?
Concurrent
Assertions – Does it count once per keypress?
Simulation
ncurses
– Does the counter look reasonable?
Verilator data
Testbench build My implementation experienced several anomalies.
Exercise #2
Ź Exercise #3 ˝ We’ll discuss those in the next lesson
Conclusion

53 / 54
Conclusion
Lesson Overview What did we learn this lesson?
Data Transmitter
Desired Structure ˝ How to formally verify a part of a design, and not just the
Counter
Change Detection
leaf modules
txdata ˝ Creating interesting traces with cover
State diagram
Outgoing Data ˝ Subtle timing differences can be annoying
Formal Verification
Cover
˝ How to use Verilator with ncurses
Assertions ˝ Extracting an internal design value from within a Verilator
Sequence
Sequence
simulation
Concurrent
Assertions We learned how to get information back out from within the
Simulation
ncurses
hardware
Verilator data
Testbench build ˝ We’ll discuss the hazards of asynchronous inputs more in the
Exercise #2 next lesson
Exercise #3
Ź Conclusion

54 / 54

You might also like