`define CYCLE 20
`timescale 1ns/1ns
module porttest;
  reg  clk;
  wire q, d, rst_n;

  initial begin
    clk <= 0;
    forever #(`CYCLE/2) clk <= ~clk;
  end

  initial begin
    $timeformat(-9,0,"ns",10);
    $monitor("%t: q=%b  d=%b  clk=%b  rst_n=%b", $stime, q, d, clk, rst_n);
  end

  test_dff t1 (.*);
  dff      u1 (.*);
endmodule

module dff (
  output reg q, 
  input      d, clk, rst_n);

  always @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 0;
    else        q <= d;
endmodule

`ifdef P1
program test_dff (
  input      q, clk,
  output reg d, rst_n);

  initial begin
    rst_n = '0;  // all blocking assignments
    @(posedge clk);
    @(negedge clk) rst_n = '1;
                   d     = '1;
    @(negedge clk) d     = ~d;
    @(negedge clk) d     = ~d;
    @(negedge clk) d     = '0;
    @(negedge clk) $finish;
  end
endprogram

`elsif P2
program test_dff (
  input      q, clk,
  output reg d, rst_n);
  reg        d_reg;

  assign d = d_reg;

  initial begin
    rst_n <= '0;  // nonblocking assignment
    @(posedge clk);
    @(negedge clk) rst_n <= '1; // nonblocking assignment
                   d_reg  = '1; // blocking assignment
    @(negedge clk) d_reg  = ~d; // blocking assignment
    @(negedge clk) d_reg  = ~d; // blocking assignment
    @(negedge clk) d_reg  = '0; // blocking assignment
    @(negedge clk) $finish;
  end
endprogram

`else
program test_dff (
  input      q, clk,
  output reg d, rst_n);

  initial begin
    rst_n <= '0;  // all nonblocking assignments
    @(posedge clk);
    @(negedge clk) rst_n <= '1;
                   d     <= '1;
    @(negedge clk) d     <= ~d;
    @(negedge clk) d     <= ~d;
    @(negedge clk) d     <= '0;
    @(negedge clk) $finish;
  end
endprogram
`endif
