```/// Notes  and Demos for LSU EE 4702-1 Spring 2001

//  Gate and Net Delays

//  Sources: Ci:  Ciletti, Modeling, synthesis, and rapid prototyping
//                         with the Verilog HDL
//           LRM: IEEE,    Verilog Language Reference Manual

/// Contents

// Gate Delay
// Wire Delay
// Module Delay

/// Gate Delay

//  Ci 6.3  LRM 7.15

//  GATE #DELAY NAME(TERMINALS)
//  GATE #(TO_1_DELAY,TO_0_DELAY) NAME(TERMINALS)
//  GATE #(TO_1_DELAY,TO_0_DELAY,TO_Z_DELAY) NAME(TERMINALS)

//  DELAY, TO_1_DELAY, TO_0_DELAY, and TO_Z_DELAY  can be
//    SINGLEDELAY
//    MIN:TYPICAL:MAX
//    where SINGLEDELAY, MIN, TYPICAL, and MAX are constant expressions.

//  DELAY specifies the time from a change in any input to
//   a change in an output.

//  Default delay is zero.

/// Demonstration of single delay.
module gde_1();  // Gate Delay Examples

reg a, b;
wire x;

// Specify a ten-cycle delay for *gate* and.
and #(10) and1(x,a,b);

// Specify a value of 10 for first parameter (covered later) to
// *module* bfa_structural.  This is not a delay because
// bfa_structural is a module, not a gate.
bfa_structural #(10) bfa1(sum,cout,a,b,c);

initial begin

a = 1; b = 0;

#20;

// Output goes to 1 ten cycles later.
b = 1;

#20;

// Output goes to 0 ten cycles later.
b = 0;

#20;

// Output goes to x ten cycles later.
b = 1'bx;

#20;

// Output goes to 1 ten cycles later.
b = 1;

#20;

// Output would go to 0 ten cycles later...
b = 0;

#5;

// ... but this "cancels" the transition to 0.
b = 1;

#20;

end

endmodule

/// Demonstration rising and falling delay.
module gde_2();  // Gate Delay Examples

reg a, b;
wire x;

// Specify a 5-cycle to-1 (rising) delay and a 10-cycle to-0 (falling) delay.
// The to-x and to-z delays are min {5,10} = 5.
and #(5,10) and1(x,a,b);

initial begin

a = 1; b = 0;

#20;

// Output goes to 1 five cycles later.
b = 1;

#20;

// Output goes to 1 ten cycles later.
b = 0;

#20;

// Output goes to x five cycles later.
b = 1'bx;

#20;

// Output goes to 1 five cycles later.
b = 1;

#20;

// Output would go to 0 ten cycles later...
b = 0;

#7;

// ... but this "cancels" the transition to 0.
b = 1;

#20;

b = 0;

#20;

b = 1;

#7;

b = 0;

#20;

end

endmodule

/// Demonstration rising,  falling, and to Z delay.
module gde_3();  // Gate Delay Examples

reg c; // Control
reg d; // Data.
wire x;

// Specify a 5-cycle to-1 (rising) delay, a 10-cycle to-0 (falling)
// delay, and a 15-cycle to-Z delay.  The to-x delay is
// min {5,10,15} = 5.
bufif1 #(5,10,15) tri_state_buffer_1(x,d,c);

initial begin

c = 1; d = 0;

#20;

// Output goes to 1 five cycles later.
d = 1;

#20;

// Output goes to 1 ten cycles later.
d = 0;

#20;

// Output goes to x five cycles later.
d = 1'bx;

#20;

// Output goes to 1 five cycles later.
d = 1;

#20;

// Output would go to 0 ten cycles later...
d = 0;

#7;

// ... but this "cancels" the transition to 0.
d = 1;

#20;

// Output goes to z in fifteen cycles.
c = 0;

#20;

end

endmodule

/// Wire Delay

//  Ci 6.5  LRM 6.1

//  NET_TYPE DELAY3 NETNAMES;

module delay_module(x,a);
output x;
input a;

wire #5 a;  // This delay isn't counted by modelsim.
wire #7 x = a;

endmodule

module wde();  // wire_delay_examples

reg     start;
wire    dmout;

delay_module dm(dmout,start);

wire #3 start_3 = start;
wire    first_out_0;
wire #9 first_out_9;
and #6  and1(first_out_9,start_3,start_3);
and #6  and2(first_out_0,start_3,start_3);
wire    second_out_0;
wire #4 second_out_4;
or #12  or1(second_out_4,first_out_9,first_out_9);
or #12  or2(second_out_0,first_out_9,first_out_9);

initial begin
start = 1;
wait( second_out_4 );
#2;
end

endmodule

/// Specifying Module Timing

// Ci 6.6  LRM 13.4

// Timing for a module can be specified explicitly. (As opposed
// to setting delays for gates, wires, and behavioral code.

// Timing specified for *paths* from input to output in a specify
// block.
// The specify block description below is for one of several
// forms, the others won't be covered.
// The specify block is placed anywhere within a module.

// specify
//   ( INPUTS1 *> OUTPUTS1 ) = DELAY1;
//   ( INPUTS2 *> OUTPUTS2 ) = DELAY2;
//   ..
// endspecify

//  INPUTS1 is an individual or comma-separated list of module inputs
//  OUTPUTS1 is an individual or comma-separated list of module outputs
//  DELAY1 is a delay specification which can be in the form used
//  for gate delays.

// In the example below a delay is specified for the behavioral
// pop module, perhaps to make its timing realistic.

module test_pop_delay();
reg [7:0]  a;
wire [3:0] pop;

pop_behavioral_8 pop1(pop,a);

initial begin
a = 8'b0;
#3;
a = 8'h3;
#10;
a = 8'hff;
#10;
end

endmodule

module pop_behavioral_8(pop,a);
input a;
output pop;

specify
( a *> pop ) = 5;
endspecify

wire [7:0] a;
reg [3:0]  pop;
integer    a_work, pop_work;

// Executes whenever a changes.
always @( a ) begin

pop_work = 0;
a_work   = a;

while( a_work )
begin
pop_work = pop_work + a_work[0];
a_work   = a_work >> 1;
end

// Note: pop changes once per change in a.
pop = pop_work;

end

endmodule

reg [7:0] a, b;
wire [7:0] sum;

initial begin
a = 0;  b = 0;
#5;
a = 100;  b = 50;
#20;
a = 77;  b = 33;
#20;
end

endmodule

input a, b;
output sum;

wire [7:0] a, b, sum;

wire [7:0] cry;

// (loop for i from 0 to 7 do (insert
//        (format "\nbfa_implicit bfa%d(sum[%d],cry[%d],a[%d],b[%d],cry[%d]);"
//                i i i i i (- i 1))))

bfa_implicit bfa0(sum[0],cry[0],a[0],b[0],1'b0);
bfa_implicit bfa1(sum[1],cry[1],a[1],b[1],cry[0]);
bfa_implicit bfa2(sum[2],cry[2],a[2],b[2],cry[1]);
bfa_implicit bfa3(sum[3],cry[3],a[3],b[3],cry[2]);
bfa_implicit bfa4(sum[4],cry[4],a[4],b[4],cry[3]);
bfa_implicit bfa5(sum[5],cry[5],a[5],b[5],cry[4]);
bfa_implicit bfa6(sum[6],cry[6],a[6],b[6],cry[5]);
bfa_implicit bfa7(sum[7],cry[7],a[7],b[7],cry[6]);

endmodule

module bfa_implicit(sum,cout,a,b,c);
input a,b,c;
output sum,cout;

assign #3 sum =
~a & ~b &  c |
~a &  b & ~c |
a & ~b & ~c |
a &  b &  c;

assign #2 cout = a & b | b & c | a & c;

endmodule
```