Workshop_10

advertisement
Workshop Topics - Outline













Workshop 1 - Introduction
Workshop 2 - module instantiation
Workshop 3 - Lexical conventions
Workshop 4 - Value Logic System
Workshop 5 - Data types A
Workshop 6 - Data types B
Workshop 7 - Operators
Workshop 8 - Signed arithmetic
Workshop 9 - Behavioral modeling A
Workshop 10 - Behavioral modeling B
Workshop 11 - Behavioral modeling C
Workshop 12 - Data flow modeling
Workshop 13 - Coding Styles
1
Timing Control mechanism
 Timing control provides a way to specify simulation time
at which procedural statements will execute.
 Without timing control statements, simulation time does
not advance.
 Three methods of behavioral timing control constructs,
are available in Verilog:
 Delay-based Timing Control - #
Inter (regular) and Intra-Statement Delay statements
 Event-based Timing Control - @ ; // edge-sensitive
Regular – posedge, negedge , Named – event,
Event OR control – (a or b or ..),
Level-sensitive – wait statement // level-sensitive
2
Delay-based Timing Control
Delay Control (#) - Expression specifies the time duration
between initially encounter a statement and when statement
actually executed. Procedural Assignments delay examples:
#10 A = A + 1 ; // Inter-Statement . A inc 10 time units (tus) from now
A = #10 A + 1 ; // Intra-Statement. A evaluated now, inc 10 tus later
Examples – Regular (inter) Delay Control:
parameter latency = 20 ; parameter delta = 2 ; // Define parameters
reg x, y, z, p, q ;
// define register variables
initial begin
x=0;
// No delay control
#10 y = 1 ;
// Delay control with number
#latency z = 0 ;
// Delay control with identifier
#(latency + delta) p = 1 ; // Delay control with expression
#y x = x + 1 ;
// Delay control with identifier
#(4:5:6) q = 0 ;
// min., typ. and max. delay values
end
3
Event-based Timing Control
 Event is a change in value on register or a net
 There are 4 types of event-based timing control:




Regular, Named, OR, Level-sensitive.
The symbol @ is used to specify an event control
Statements can be executed on changes in signal value or at a
positive or negative transition of the signal value
Keywords posedge/negedge are used for positive/negative
transitions
Regular event control:
@(clk) q = d ; // q = d is executed whenever clk changes value
@(posedge clk) q = d ; // q = d is executed on clk positive transition
@(negedge clk) q = d ; // q = d is executed on clk negative transition
q = @(negedge clk) d ; /* d is evaluated immediately and assigned
to q at the negative edge of clock */
4
Named event control
An event can be declared and then triggered at the occurrence of
that event. A named event is declared by the keyword event.
Event does not hold any data. event is triggered by the symbol ->
Triggering of the event is recognized by the symbol @.
// A data buffer stores data. After the last data packet has arrived,
event received_data ;
// define an event called received_data
always @(posedge clock) // check at each positive clock edge
begin
if (last_data_packet) // If this is the last data packet
->received_data ; // trigger the event received_data
end
always @(received_data) /* Wait for triggered received_data event.
When the event is triggered, store all 4 packets of received data in
data buffer. Use concatenation operator { } */
data_buf = {data_pkt[0], data_pkt[1], data_pkt[2], data_pkt[3]} ;
5
Event OR and Edge-sensitive Control
 Transition of any one of multiple signals or events can trigger
execution of a statement or a block of statements
 The list of events or signals is also known as a sensitivity list
 The keyword or [or “,” or (*)] is used to specify multiple triggers
always @(reset or en or d) ; // D latch with reset
begin
// wait for reset or en or d to change
if (reset)
// if reset signal is high, set q to 0
q <= 1’b0 ;
else if (en)
// data latch enabled
q <= d ;
end
always @(posedge clk, negedge nrst) /* DFF with asynchronous reset.
Executed whenever clk swings to 1 or nrst swings to 0 */
begin
if (!nrst)
// nrst: active low reset
q <= 1’b0 ;
else
q <= d ;
end
6
Level-sensitive Time Control - Wait Statement
 Wait statement waits for its conditional expression to
become true before a statement or a block of statements is
executed.
 Level sensitive is primary used for synchronizing two
concurrent processes.
 The keyword wait is used for level-sensitive constructs.
Example:
always
wait (count_enable) #20 count = count + 1 ;
// The value of count_enable is monitored continuously.
If count_enable = 0, the statement is not entered.
If it is logical 1, the statement is executed after 20 time
units. If count_enable stays at 1, count will be incremented
every 20 time units.
7
Conditional Statements - If, else
 Used to make decisions based upon certain conditions.
 Keywords if and else are used for conditional
statements.
 Syntax:
- if <expression> true statement ;
- if <expression> true statement ; else false statement ;
- if <expression1> true statement1 ; // many alternatives
else if <expression2> true statement2 ;
else if <expression3> true statement3 ;
…………
else default statement ;
8
Conditional Statement example - BCD Adder
module BCDadder (sum, cout, a, b, cin) ;
input [3:0] a, b ;
Input cin ;
output reg [3:0] sum ;
output reg cout ;
reg [4:0] z ;
always @(a or b or cin)
begin
z = a + b + cin ;
// assume z = 1011 (11 decimal)
if (z > 9)
{cout, sum} = z + 6 ; // 1011 + 0110 = 1_0001 = 11d
else
{cout, sum} = z ;
end
endmodule
9
Multi-way Branching - case
 Having many alternatives, using nested if-else-if is not
practical. An easier way is to use the case statement
 The keywords case, endcase and default are used.
 Comparisons in a case statement are made bit by bit.
 No break statement is needed - first match executes and then
case is exited.
 If not all cases are enumerated, make sure to use default case.
 Multi way branching - case statement syntax:
case <expression>
alternative1: statement1 ;
alternative2: statement2 ;
……………………………………. ;
default: default_statement ; // missing alternative - avoid latch
endcase
10
case statement example - 2 to 4 Decoder
module dec2to4 (y, w, en) ;
input [1:0] w ;
input en ;
output reg [3:0] y ;
// implicit register
always @(w or en)
case ({en, w})
// concatenation of en & w
3’b100: y = 4’b0001 ;
3’b101: y = 4’b0010 ;
3’b110: y = 4’b0100 ;
3’b111: y = 4’b1000 ;
default: y = 4’b0000 ; // disabled module case
endcase
endmodule
11
case, casez, casex
 case treats each value 0, 1, X, and Z literally
 4’b01XZ only
matches 4’b01XZ
 Example: 4’b0110 does not match 4’b01XX in a case
 casez treats 0, 1, and X literally
 casez
treats Z as a don’t care
 Example: 4’b0110 matches 4’b01ZZ, but not 4’b01XZ
 casex treats 0 and 1 literally
 casex
// No match here
treats both X and Z as don’t cares
 Example: 4’b0110 matches 4’b01XX and also 4’b01XZ
12
casez example
module casez_example () ;
reg [3:0] opcode ;
reg [1:0] a, b, c, out ;
always @ (opcode or a or b or c)
casez(opcode)
4'b1ZZX : out = a ; /* Don't care about bits 2:1,
bit 0 match with X */
4'b01?? : out = b ; // bits 1:0 are don't care
4'b001? : out = c ; // bit 0 is don't care
default : out = 2’b0 ;
endcase
endmodule
13
casex example – 4 to 2 Priority Encoder
module priority (din, dout , valid) ;
input [3:0] din ;
output reg [1:0] dout ;
output reg valid ;
always @(din)
begin
valid = 1'b1 ; // assume valid output
casex (din)
// casex treats both x and z as don’t cares
4'b1XXX: dout = 2'b11 ;
4'b01XX: dout = 2'b10 ;
4'b001X: dout = 2'b01 ;
4'b0001: dout = 2'b00 ;
default: begin
valid = 1'b0 ;
// non-valid output
dout = 2'b0 ;
// don't care case
end
endcase
end
endmodule
14
Exercise 2
 Design a single bit 4 to 1 mux, employing always block
and case statement.
 Write a Test Bench for the 4 to 1 mux.
in0
in1
in2
M
U
X
in3
2
select
15
out
Download