Monday, March 31, 2014

some basic php syntax

1) show phpinfo
<?php
phpinfo();
?>

2) array
$data_arr = array();


some basic systemVerilog syntax

1) Integer data types
shortint 2-state SystemVerilog data type, 16 bit signed integer
int 2-state SystemVerilog data type, 32 bit signed integer
longint 2-state SystemVerilog data type, 64 bit signed integer
byte 2-state SystemVerilog data type, 8 bit signed integer or ASCII character
bit 2-state SystemVerilog data type, user-defined vector size
logic 4-state SystemVerilog data type, user-defined vector size
reg 4-state Verilog-2001 data type, user-defined vector size
integer 4-state Verilog-2001 data type, 32 bit signed integer
time 4-state Verilog-2001 data type, 64-bit unsigned integer

2) Default values
Type Default Initial value
4 state integral ’X
2 state integral ’0
real, shortreal 0.0
Enumeration First value in the enumeration
string "" (empty string)
event New event
class null
chandle (Opaque handle) null

10) class
/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
class cpu_transaction;

logic [7:0 ] addr ;
logic [31:0] data ;
logic        rw   ;

endclass: cpu_transaction

11) program
/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] data  ;
logic        rw    ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output data ;
    output rw   ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"

program test(cpu_interface.master cpu_intf);

initial begin
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`include "cpu_interface.svi"
`include "test.sv"
module top;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

endmodule

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/program
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/program
SVTB  = $(TB_DIR)/test.sv
SVTB += $(TB_DIR)/top.sv

INCDIR = +incdir+/mnt/program

COMPILE_LOG_ARG = -l vcs.log

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

12) interface
/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] data  ;
logic        rw    ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output data ;
    output rw   ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"

program test(cpu_interface.master cpu_intf);

event done;

initial begin
    cpu_intf.rst_n   <= 1'b0;
    cpu_intf.cb.addr <= 8'h0;
    cpu_intf.cb.data <= 32'h0;
    cpu_intf.cb.rw   <= 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n <= 1'b1;
    @(cpu_intf.cb);
    cpu_intf.cb.addr <= 8'h1;
    cpu_intf.cb.data <= 32'h1;
    cpu_intf.cb.rw <= 1'b0;
    @(cpu_intf.cb);
    cpu_intf.cb.addr <= 8'h2;
    cpu_intf.cb.data <= 32'h2;
    cpu_intf.cb.rw <= 1'b1;
    ->done;
end

initial begin
    @done;
    #10 $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`include "cpu_interface.svi"
`include "test.sv"
module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2)
            clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/interface
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/interface
SVTB  = $(TB_DIR)/test.sv
SVTB += $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

100) transaction
/////////////////////////////////////////////
//cpu_transaction
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

rand logic [7:0] addr;
rand logic [31:0] data;
string name;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, data = %0h", prefix, $realtime, name, addr, data);
endfunction

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_transaction.sv"

program test();

event done;

initial begin
    cpu_transaction cpu_tran;
    cpu_tran = new();
    repeat(10) begin
        if(!cpu_tran.randomize()) begin
            $display("Error to randomize cpu_tran");
        end
        cpu_tran.display();
        #1;
    end
    ->done;
end

initial begin
    @done;
    #10 $finish();
end

endprogram
`endif

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/transaction
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/transaction
SVTB  = $(TB_DIR)/test.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

101) generator
/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

rand logic [7:0] addr;
rand logic [31:0] data;
string name;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, data = %0h", prefix, $realtime, name, addr, data);
endfunction

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    for(int i=0; i<run_for_n_trans; i++) begin
        cpu_transaction cpu_tran = new();
        if(!cpu_tran.randomize()) begin
            $display("Error to randomize cpu_tran");
        end
        out_box.put(cpu_tran);
    end
    ->done;
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_generator.sv"
`include "cpu_define.sv"

program test();

event done;
cpu_tran_mbox mbox = new();
cpu_generator cpu_gen;

initial begin
    cpu_gen = new("CPU Generator", mbox);
    cpu_gen.run_for_n_trans = 10;
    cpu_gen.start();
end

initial begin
    cpu_transaction cpu_tran;
    forever begin
        mbox.get(cpu_tran);
        cpu_tran.display();
    end
end

initial begin
    @cpu_gen.done;
    #10 $finish();
end

endprogram
`endif

#############################################
#Makefile
#############################################
RTL_DIR = /mnt/generator
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/generator
SVTB  = $(TB_DIR)/test.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

102) driver
/////////////////////////////////////////////
/////////////////////////////////////////////
//driver and monitor in the same bfm
/////////////////////////////////////////////
/////////////////////////////////////////////

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

rand logic [7:0] addr;
rand logic [31:0] data;
rand logic rw;
string name;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, data = %0h, rw = %d", prefix, $realtime, name, addr, data, rw);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] data  ;
logic        rw    ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output data ;
    output rw   ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        for(int i=0; i<run_for_n_trans; i++) begin
            cpu_transaction cpu_tran = new();
            if(!cpu_tran.randomize()) begin
                $display("Error to randomize cpu_tran");
            end
            out_box.put(cpu_tran);
        end
        ->done;
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.data <= cpu_tran.data;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            @(cpu_intf.cb);
            cpu_intf.cb.addr <= 8'h0 ;
            cpu_intf.cb.data <= 32'h0 ;
            cpu_intf.cb.rw   <= 1'b1 ;
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"

program test(cpu_interface.master cpu_intf);

event done;
cpu_tran_mbox mbox = new();
cpu_generator cpu_gen;
cpu_driver    cpu_drv;

initial begin
    cpu_gen = new("CPU Generator", mbox);
    cpu_drv = new("CPU Driver", mbox, cpu_intf);

    cpu_gen.run_for_n_trans = 10;
    cpu_gen.start();
    cpu_drv.start();

    @cpu_gen.done;
    repeat(100) @(cpu_intf.cb);
    $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/driver
#RTL = $(RTL_DIR)/rtl/router.v

TB_DIR = /mnt/driver
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

103) monitor
/////////////////////////////////////////////
//dut.v
/////////////////////////////////////////////
`timescale 1ns/1ps

module dut(
    clk   ,
    rst_n ,
    addr  ,
    din   ,
    rw    ,
    dout
);

input         clk   ;
input         rst_n ;
input  [7:0 ] addr  ;
input  [31:0] din   ;
input         rw    ;

output [31:0] dout  ;

wire        clk   ;
wire        rst_n ;
wire [7:0 ] addr  ;
wire [31:0] din   ;
wire        rw    ;

reg  [31:0] dout  ;

wire        write ;
wire        read  ;

reg  [31:0] config_reg ;
reg  [31:0] max_pkt_size ;

assign write = (rw == 1'b0);
assign read  = (rw == 1'b1);

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        config_reg <= 32'h0;
    end
    else begin
        if((addr == 8'h0) && (write == 1'b1)) begin
            config_reg <= din;
        end
    end
end

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        max_pkt_size <= 32'h0;
    end
    else begin
        if((addr == 8'h4) && (write == 1'b1)) begin
            max_pkt_size <= din;
        end
    end
end

always @(addr) begin
    case(addr)
        8'h0    : dout = config_reg;
        8'h1    : dout = max_pkt_size;
        default : dout = 32'h0;
    endcase
end

endmodule

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] din   ;
logic        rw    ;
logic [31:0] dout  ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output din  ;
    output rw   ;
    input  dout ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

string name;
rand logic [7:0] addr;
rand logic rw;
rand logic [31:0] din;
logic [31:0] dout = 32'h0;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, din = %0h, rw = %d, dout = %0h", prefix, $realtime, name, addr, din, rw, dout);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
cpu_transaction cpu_tran;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        for(int i=0; i<run_for_n_trans; i++) begin
            cpu_transaction cpu_tran_cpy = new cpu_tran;
            if(!cpu_tran_cpy.randomize()) begin
                $display("Error to randomize cpu_tran_cpy");
            end
            out_box.put(cpu_tran_cpy);
        end
        ->done;
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
//driver and monitor in the same bfm
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
cpu_tran_mbox out_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.out_box = out_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.din  <= cpu_tran.din;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            @(cpu_intf.cb);
            cpu_tran.dout     = cpu_intf.cb.dout;
            cpu_intf.cb.addr <= 8'h0 ;
            cpu_intf.cb.din  <= 32'h0 ;
            cpu_intf.cb.rw   <= 1'b1 ;

            out_box.put(cpu_tran);
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"

program test(cpu_interface.master cpu_intf);

class cpu_transaction_ext extends cpu_transaction;
    constraint addr_range {addr[7:2] inside {[8'h0:8'h1]}; addr[1:0] == 2'h0;}
    //constraint write {rw == 1'b0;}
endclass

event done;
cpu_tran_mbox drv_mbox = new();
cpu_tran_mbox mon_mbox = new();
cpu_generator cpu_gen;
cpu_driver    cpu_drv;
cpu_transaction_ext cpu_tran_ext = new();

initial begin
    cpu_gen = new("CPU Generator", drv_mbox);
    cpu_drv = new("CPU Driver", drv_mbox, mon_mbox, cpu_intf);

    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b1;
    @(cpu_intf.cb);

    cpu_gen.cpu_tran = cpu_tran_ext;
    cpu_gen.run_for_n_trans = 100;
    cpu_gen.start();
    cpu_drv.start();

    @cpu_gen.done;
    repeat(100) @(cpu_intf.cb);
    $finish();
end

initial begin
    cpu_transaction cpu_tran = new();
    forever begin
        mon_mbox.get(cpu_tran);
        cpu_tran.display("Monitor Mbox");
    end
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

dut u_dut (
    .clk   (cpu_intf.clk   ) ,
    .rst_n (cpu_intf.rst_n ) ,
    .addr  (cpu_intf.addr  ) ,
    .din   (cpu_intf.din   ) ,
    .rw    (cpu_intf.rw    ) ,
    .dout  (cpu_intf.dout  )
);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/monitor
RTL = $(RTL_DIR)/dut.v

TB_DIR = /mnt/monitor
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

103) scoreboard
/////////////////////////////////////////////
//dut.v
/////////////////////////////////////////////
`timescale 1ns/1ps

module dut(
    clk   ,
    rst_n ,
    addr  ,
    din   ,
    rw    ,
    dout
);

input         clk   ;
input         rst_n ;
input  [7:0 ] addr  ;
input  [31:0] din   ;
input         rw    ;

output [31:0] dout  ;

wire        clk   ;
wire        rst_n ;
wire [7:0 ] addr  ;
wire [31:0] din   ;
wire        rw    ;

reg  [31:0] dout  ;

wire        write ;
wire        read  ;

reg  [31:0] config_reg ;
reg  [31:0] max_pkt_size ;

assign write = (rw == 1'b0);
assign read  = (rw == 1'b1);

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        config_reg <= 32'h0;
    end
    else begin
        if((addr == 8'h0) && (write == 1'b1)) begin
            config_reg <= din;
        end
    end
end

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        max_pkt_size <= 32'h0;
    end
    else begin
        if((addr == 8'h4) && (write == 1'b1)) begin
            max_pkt_size <= din;
        end
    end
end

always @(*) begin
    case(addr)
        8'h0    : dout = config_reg;
        8'h4    : dout = max_pkt_size;
        default : dout = 32'h0;
    endcase
end

endmodule

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] din   ;
logic        rw    ;
logic [31:0] dout  ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output din  ;
    output rw   ;
    input  dout ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

string name;
rand logic [7:0] addr;
rand logic rw;
rand logic [31:0] din;
logic [31:0] dout = 32'h0;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, din = %0h, rw = %d, dout = %0h", prefix, $realtime, name, addr, din, rw, dout);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
cpu_transaction cpu_tran;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        for(int i=0; i<run_for_n_trans; i++) begin
            cpu_transaction cpu_tran_cpy = new cpu_tran;
            if(!cpu_tran_cpy.randomize()) begin
                $display("Error to randomize cpu_tran_cpy");
            end
            out_box.put(cpu_tran_cpy);
        end
        ->done;
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
cpu_tran_mbox out_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.out_box = out_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.din  <= cpu_tran.din;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            if(cpu_tran.rw == 1'b1) begin
                @(cpu_intf.cb);
                cpu_tran.dout     = cpu_intf.cb.dout;
            end

            out_box.put(cpu_tran);
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_scoreboard.sv
/////////////////////////////////////////////
`ifndef __CPU_SCOREBOARD_SV__
`define __CPU_SCOREBOARD_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_scoreboard;

string name;
cpu_tran_mbox in_box;
cpu_transaction cpu_tran;

logic [31:0] cpu_reg [7:0];
integer error_no = 0;
integer total_no = 0;

extern function new(string name = "CPU Scoreboard", cpu_tran_mbox in_box);
extern task start();
extern task check();
extern function display(string prefix = "CPU Scoreboard Result");

endclass

function cpu_scoreboard::new(string name, cpu_tran_mbox in_box);
    this.name = name;
    this.in_box = in_box;

    for(int i=0; i<128; i++) begin
        cpu_reg[i] = 32'h0;
    end
endfunction

task cpu_scoreboard::start();
    fork
        forever begin
            in_box.get(cpu_tran);
            total_no++;
            check();
        end
    join_none
endtask

task cpu_scoreboard::check();
    string message;
    if(cpu_tran.rw == 1'b0) begin
        cpu_reg[cpu_tran.addr] = cpu_tran.din;
    end
    else if(cpu_tran.rw == 1'b1) begin
        if(cpu_reg[cpu_tran.addr] != cpu_tran.dout) begin
            message = $psprintf("[Error] %t Comparision result is not correct\n", $realtime);
            message = { message, $psprintf("cpu_reg[%d] = %0h, cpu_tran.dout = %0h\n", cpu_tran.addr, cpu_reg[cpu_tran.addr], cpu_tran.dout) };
            $display(message);
            error_no++;
        end
        else begin
            $display("[Note] %t comparison correct", $realtime);
        end
    end
    else begin
        $display("[Error] cpu_tran.rw can only be 0 or 1");
        error_no++;
    end
endtask

function cpu_scoreboard::display(string prefix);
    $display("Total: %d, Error: %d", total_no, error_no);
endfunction

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"
`include "cpu_scoreboard.sv"

program test(cpu_interface.master cpu_intf);

class cpu_transaction_ext extends cpu_transaction;
    constraint addr_range {addr[7:2] inside {[8'h0:8'h1]}; addr[1:0] == 2'h0;}
    //constraint write {rw == 1'b0;}
endclass

event done;
cpu_tran_mbox drv_mbox = new();
cpu_tran_mbox mon_mbox = new();
cpu_generator cpu_gen;
cpu_driver    cpu_drv;
cpu_transaction_ext cpu_tran_ext = new();
cpu_scoreboard cpu_sb;

initial begin
    cpu_gen = new("CPU Generator", drv_mbox);
    cpu_drv = new("CPU Driver", drv_mbox, mon_mbox, cpu_intf);
    cpu_sb  = new("CPU Scoreboard", mon_mbox);

    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b1;
    @(cpu_intf.cb);

    cpu_gen.cpu_tran = cpu_tran_ext;
    cpu_gen.run_for_n_trans = 100;
    cpu_gen.start();
    cpu_drv.start();
    cpu_sb.start();

    @cpu_gen.done;
    repeat(1000) begin
        @(cpu_intf.cb);
        if(cpu_sb.total_no == cpu_gen.run_for_n_trans) begin
            break;
        end
    end
    cpu_sb.display();
    $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

dut u_dut (
    .clk   (cpu_intf.clk   ) ,
    .rst_n (cpu_intf.rst_n ) ,
    .addr  (cpu_intf.addr  ) ,
    .din   (cpu_intf.din   ) ,
    .rw    (cpu_intf.rw    ) ,
    .dout  (cpu_intf.dout  )
);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/scoreboard
RTL = $(RTL_DIR)/dut.v

TB_DIR = /mnt/scoreboard
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

104) env
/////////////////////////////////////////////
//dut.v
/////////////////////////////////////////////
`timescale 1ns/1ps

module dut(
    clk   ,
    rst_n ,
    addr  ,
    din   ,
    rw    ,
    dout
);

input         clk   ;
input         rst_n ;
input  [7:0 ] addr  ;
input  [31:0] din   ;
input         rw    ;

output [31:0] dout  ;

wire        clk   ;
wire        rst_n ;
wire [7:0 ] addr  ;
wire [31:0] din   ;
wire        rw    ;

reg  [31:0] dout  ;

wire        write ;
wire        read  ;

reg  [31:0] config_reg ;
reg  [31:0] max_pkt_size ;

assign write = (rw == 1'b0);
assign read  = (rw == 1'b1);

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        config_reg <= 32'h0;
    end
    else begin
        if((addr == 8'h0) && (write == 1'b1)) begin
            config_reg <= din;
        end
    end
end

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        max_pkt_size <= 32'h0;
    end
    else begin
        if((addr == 8'h4) && (write == 1'b1)) begin
            max_pkt_size <= din;
        end
    end
end

always @(*) begin
    case(addr)
        8'h0    : dout = config_reg;
        8'h4    : dout = max_pkt_size;
        default : dout = 32'h0;
    endcase
end

endmodule

/////////////////////////////////////////////
//cpu_interface.svi
/////////////////////////////////////////////
`ifndef __CPU_INTERFACE_SVI__
`define __CPU_INTERFACE_SVI__
interface cpu_interface (input logic clk);

logic        rst_n ;
logic [7:0 ] addr  ;
logic [31:0] din   ;
logic        rw    ;
logic [31:0] dout  ;

clocking cb @(posedge clk);
    default input #1 output #1;
    output addr ;
    output din  ;
    output rw   ;
    input  dout ;
endclocking

modport master(clocking cb, output rst_n);

endinterface
`endif

/////////////////////////////////////////////
//cpu_transaction.sv
/////////////////////////////////////////////
`ifndef __CPU_TRANSACTION_SV__
`define __CPU_TRANSACTION_SV__

class cpu_transaction;

string name;
rand logic [7:0] addr;
rand logic rw;
rand logic [31:0] din;
logic [31:0] dout = 32'h0;

extern function new(string name = "CPU Transaction");
extern function void display(string prefix = "Note");

endclass

function cpu_transaction::new(string name);
    this.name = name;
endfunction

function void cpu_transaction::display(string prefix);
  $display("[%s]%t %s addr = %0h, din = %0h, rw = %d, dout = %0h", prefix, $realtime, name, addr, din, rw, dout);
endfunction

`endif

/////////////////////////////////////////////
//cpu_define.sv
/////////////////////////////////////////////
`ifndef __CPU_DEFINE_SV__
`define __CPU_DEFINE_SV__

typedef class cpu_transaction;
typedef mailbox #(cpu_transaction) cpu_tran_mbox;

`endif

/////////////////////////////////////////////
//cpu_generator.sv
/////////////////////////////////////////////
`ifndef __CPU_GENERATOR_SV__
`define __CPU_GENERATOR_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_generator;

string name;
cpu_tran_mbox out_box;
int run_for_n_trans = 0;
cpu_transaction cpu_tran;
event done;

extern function new(string name = "CPU Generator", cpu_tran_mbox out_box);
extern task start();

endclass

function cpu_generator::new(string name, cpu_tran_mbox out_box);
    this.name = name;
    this.out_box = out_box;
endfunction

task cpu_generator::start();
    fork
        begin
            for(int i=0; i<run_for_n_trans; i++) begin
                cpu_transaction cpu_tran_cpy = new cpu_tran;
                if(!cpu_tran_cpy.randomize()) begin
                    $display("Error to randomize cpu_tran_cpy");
                end
                out_box.put(cpu_tran_cpy);
            end
            ->done;
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_driver.sv
/////////////////////////////////////////////
`ifndef __CPU_DRIVER_SV__
`define __CPU_DRIVER_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"
`include "cpu_interface.svi"

class cpu_driver;

string name;
cpu_tran_mbox in_box;
cpu_tran_mbox out_box;
virtual cpu_interface.master cpu_intf;

extern function new(string name = "CPU Driver", cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
extern task start();

endclass

function cpu_driver::new(string name, cpu_tran_mbox in_box, cpu_tran_mbox out_box, virtual cpu_interface.master cpu_intf);
    this.name = name;
    this.in_box = in_box;
    this.out_box = out_box;
    this.cpu_intf = cpu_intf;
endfunction

task cpu_driver::start();
    fork
        forever begin
            cpu_transaction cpu_tran;
            in_box.get(cpu_tran);
            cpu_tran.display();

            @(cpu_intf.cb);
            cpu_intf.cb.addr <= cpu_tran.addr;
            cpu_intf.cb.din  <= cpu_tran.din;
            cpu_intf.cb.rw   <= cpu_tran.rw;
            if(cpu_tran.rw == 1'b1) begin
                @(cpu_intf.cb);
                cpu_tran.dout     = cpu_intf.cb.dout;
            end

            out_box.put(cpu_tran);
        end
    join_none
endtask

`endif

/////////////////////////////////////////////
//cpu_scoreboard.sv
/////////////////////////////////////////////
`ifndef __CPU_SCOREBOARD_SV__
`define __CPU_SCOREBOARD_SV__

`include "cpu_transaction.sv"
`include "cpu_define.sv"

class cpu_scoreboard;

string name;
cpu_tran_mbox in_box;
cpu_transaction cpu_tran;

logic [31:0] cpu_reg [7:0];
integer error_no = 0;
integer total_no = 0;

extern function new(string name = "CPU Scoreboard", cpu_tran_mbox in_box);
extern task start();
extern task check();
extern function display(string prefix = "CPU Scoreboard Result");

endclass

function cpu_scoreboard::new(string name, cpu_tran_mbox in_box);
    this.name = name;
    this.in_box = in_box;

    for(int i=0; i<128; i++) begin
        cpu_reg[i] = 32'h0;
    end
endfunction

task cpu_scoreboard::start();
    fork
        forever begin
            in_box.get(cpu_tran);
            total_no++;
            check();
        end
    join_none
endtask

task cpu_scoreboard::check();
    string message;
    if(cpu_tran.rw == 1'b0) begin
        cpu_reg[cpu_tran.addr] = cpu_tran.din;
    end
    else if(cpu_tran.rw == 1'b1) begin
        if(cpu_reg[cpu_tran.addr] != cpu_tran.dout) begin
            message = $psprintf("[Error] %t Comparision result is not correct\n", $realtime);
            message = { message, $psprintf("cpu_reg[%d] = %0h, cpu_tran.dout = %0h\n", cpu_tran.addr, cpu_reg[cpu_tran.addr], cpu_tran.dout) };
            $display(message);
            error_no++;
        end
        else begin
            $display("[Note] %t comparison correct", $realtime);
        end
    end
    else begin
        $display("[Error] cpu_tran.rw can only be 0 or 1");
        error_no++;
    end
endtask

function cpu_scoreboard::display(string prefix);
    $display("Total: %d, Error: %d", total_no, error_no);
endfunction

`endif

/////////////////////////////////////////////
//cpu_env.sv
/////////////////////////////////////////////
`ifndef __CPU_ENV_SV__
`define __CPU_ENV_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_generator.sv"
`include "cpu_define.sv"
`include "cpu_driver.sv"
`include "cpu_scoreboard.sv"

class cpu_env;

cpu_tran_mbox  drv_mbox = new();
cpu_tran_mbox  mon_mbox = new();
cpu_generator  cpu_gen;
cpu_driver     cpu_drv;
cpu_scoreboard cpu_sb;

virtual cpu_interface.master cpu_intf;

extern function new(virtual cpu_interface.master cpu_intf);
extern function configure();
extern task reset();
extern task start();

endclass

function cpu_env::new(virtual cpu_interface.master cpu_intf);
    this.cpu_intf = cpu_intf;
    cpu_gen = new("CPU Generator", drv_mbox);
    cpu_drv = new("CPU Driver", drv_mbox, mon_mbox, cpu_intf);
    cpu_sb  = new("CPU Scoreboard", mon_mbox);
endfunction

function cpu_env::configure();
endfunction

task cpu_env::reset();
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b0;
    @(cpu_intf.cb);
    cpu_intf.rst_n = 1'b1;
    @(cpu_intf.cb);
endtask

task cpu_env::start();
    cpu_gen.start();
    cpu_drv.start();
    cpu_sb.start();
endtask

`endif

/////////////////////////////////////////////
//test.sv
/////////////////////////////////////////////
`ifndef __TEST_SV__
`define __TEST_SV__

`include "cpu_interface.svi"
`include "cpu_transaction.sv"
`include "cpu_env.sv"

program test(cpu_interface.master cpu_intf);

class cpu_transaction_ext extends cpu_transaction;
    constraint addr_range {addr[7:2] inside {[8'h0:8'h1]}; addr[1:0] == 2'h0;}
    //constraint write {rw == 1'b0;}
endclass

cpu_transaction_ext cpu_tran_ext = new();
cpu_env cpu_e;

initial begin
    cpu_e = new(cpu_intf);
    cpu_e.configure();

    cpu_e.cpu_gen.cpu_tran = cpu_tran_ext;
    cpu_e.cpu_gen.run_for_n_trans = 100;

    cpu_e.reset();
    cpu_e.start();

    @cpu_e.cpu_gen.done;
    repeat(1000) begin
        @(cpu_intf.cb);
        if(cpu_e.cpu_sb.total_no == cpu_e.cpu_gen.run_for_n_trans) begin
            break;
        end
    end
    cpu_e.cpu_sb.display();
    $finish();
end

endprogram
`endif

/////////////////////////////////////////////
//top.sv
/////////////////////////////////////////////
`timescale 1ns/1ps

`include "cpu_interface.svi"
`include "test.sv"

module top;
parameter cpu_clock_cycle = 10;

logic clk;

cpu_interface cpu_intf(clk);

test u_test(cpu_intf);

dut u_dut (
    .clk   (cpu_intf.clk   ) ,
    .rst_n (cpu_intf.rst_n ) ,
    .addr  (cpu_intf.addr  ) ,
    .din   (cpu_intf.din   ) ,
    .rw    (cpu_intf.rw    ) ,
    .dout  (cpu_intf.dout  )
);

initial begin
    $timeformat(-9, 1, "ns", 10);
    clk = 0;
    forever begin
        #(cpu_clock_cycle/2) clk = ~clk;
    end
end

`ifdef WAVE_ON
initial begin
    $vcdpluson();
end
`endif

endmodule

#############################################
#Makefile
#############################################
ifeq ($(GUI), 1)
    GUI_ARG = -gui
endif
RTL_DIR = /mnt/env
RTL = $(RTL_DIR)/dut.v

TB_DIR = /mnt/env
SVTB  = $(TB_DIR)/top.sv

INCDIR = +incdir+$(TB_DIR)

COMPILE_LOG_ARG = -l vcs.log

WAVE_ARG = +define+WAVE_ON=1

COMPILE_ARG = -sverilog -debug_all
COMPILE_ARG += $(INCDIR) $(COMPILE_LOG_ARG) $(WAVE_ARG)

RUN_LOG_ARG = -l simv.log

RUN_ARG  =
RUN_ARG += $(RUN_LOG_ARG) $(GUI_ARG)

SEED = 1

default: test

test: compile run

run:
./simv $(RUN_ARG) +ntb_random_seed=$(SEED)

compile:
vcs $(COMPILE_ARG) $(SVTB) $(RTL)

clean:
rm -rf simv simv.* *log

110) driver and monitor are in 2 different class (bfm)
link: http://scott2595.blogspot.com/2014/08/an-example-of-systemverilog-tb.html

111) TB env with 2 TB envs
linke: http://scott2595.blogspot.com/2014/10/an-example-of-sv-tb-with-callback.html

some basic VHDL syntax

1) entity
library ieee;
use ieee.std_logic_1164.all;
entity dataProcess is
port (
    din  : in std_logic_vector(7 downto 0);
    dout : out std_logic_vector(7 downto 0);
    dio  : inout std_logic
);
end entity dataProcess;
architecture behavioral of dataProcess is
begin
end behavioral;

2) combinational logic
library ieee;
use ieee.std_logic_1164.all;

entity clkGen is
port (
    clk  : in std_logic;
    mode : in std_logic;
    sclk : out std_logic
);
end entity clkGen;
architecture behavioral of clkGen is
signal clk_en : std_logic;
begin

--generate sclk
sclk <= clk when clk_en = '1' else '0';

process(mode)
begin
    case mode is
        when '0' =>
            clk_en <= '0';
        when '1' =>
            clk_en <= '1';
        when others =>
            clk_en <= '0';
    end case;
end process;

end behavioral;

3) timing logic
library ieee;
use ieee.std_logic_1164.all;

entity dff_1 is
port (
    clk   : in std_logic;
    rst_n : in std_logic;
    din   : in std_logic;
    dout  : out std_logic
);
end entity dff_1;
architecture behavioral of dff_1 is
begin

process(clk, rst_n)
begin
    if(rst_n = '0') then
        dout <= '0';
    elsif(clk'event and clk = '1')  then
    -- elsif(rising_edge(clk)) then
        dout <= din;
    end if;
end process;

end behavioral;

4) tristate gate
library ieee;
use ieee.std_logic_1164.all;

entity dataProcess is
port (
    sclk  : in std_logic;
    rst_n : in std_logic;
    rw    : in std_logic;
    sdio  : inout std_logic
);
end entity dataProcess;

architecture behavioral of dataProcess is
signal sdi    : std_logic;
signal sdo    : std_logic;
signal sdo_en : std_logic;
signal data   : std_logic_vector(7 downto 0);
begin
    --generate sdio
    sdio <= sdo when sdo_en = '1' else 'Z';

    sdi  <= sdio;

    process(sclk, rst_n)
    begin
        if(rst_n = '0') then
            data <= (others => '0');
        elsif(rising_edge(sclk)) then
            if(rw = '0') then
                data <= data(6 downto 0) & sdi;
            else
                data <= data(6 downto 0) & '0';
            end if;
        end if;
    end process;

    process(sclk, rst_n)
    begin
        if(rst_n = '0') then
            sdo <= '0';
            sdo_en <= '0';
        elsif(rising_edge(sclk)) then
            if(rw = '1') then
                sdo    <= data(7);
                sdo_en <= '1';
            else
                sdo <= '0';
                sdo_en <= '0';
            end if;
        end if;
    end process;

end behavioral;

5) package with function
-------------------------------------------------------
-- package user_pkg
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

package user_pkg is
function to_stdulogic(V: Boolean) return std_ulogic;

end;

package body user_pkg is
--function to convert boolean to std_logic
function to_stdulogic(V: Boolean) return std_ulogic is
begin
    if V then
        return '1';
    else
        return '0';
    end if;
end to_stdulogic;

end package body;

-------------------------------------------------------
-- entity calling package
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.user_pkg.all;

entity test_package is
port (
    clk       : in  std_logic;
    rst_n     : in  std_logic;
    mode      : in  std_logic;
    mode_trig : out std_logic
);
end entity test_package;

architecture behavioral of test_package is
--signal declaration in architecture
signal mode_ff1    : std_logic;
signal mode_ff2    : std_logic;
signal mode_ff3    : std_logic;

--begin of architecture
begin

process(clk, rst_n)
begin
    if(rst_n = '0') then
        mode_ff1 <= '0';
        mode_ff2 <= '0';
        mode_ff3 <= '0';
    elsif(clk'event and clk = '1') then
        mode_ff1 <= mode;
        mode_ff2 <= mode_ff1;
        mode_ff3 <= mode_ff2;
    end if;
end process;

mode_trig <= to_stdulogic((mode_ff2 = '0') and (mode_ff3 = '1'));

end behavioral;

6) package with procedure
-------------------------------------------------------
-- package user_pkg
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

package user_pkg is
procedure segment_dec (signal bcd: in std_logic_vector(3 downto 0); signal segment : out std_logic_vector(6 downto 0));

end;

package body user_pkg is

procedure segment_dec (
    signal bcd: in std_logic_vector(3 downto 0);
    signal segment : out std_logic_vector(6 downto 0)
) is
begin
    case bcd is
        --decode from bcd to segment
        when x"0" => segment <= b"1000000";
        when x"1" => segment <= b"1111001";
        when x"2" => segment <= b"0100100";
        when x"3" => segment <= b"0110000";
        when x"4" => segment <= b"0011001";
        when x"5" => segment <= b"0010010";
        when x"6" => segment <= b"0000010";
        when x"7" => segment <= b"1111000";
        when x"8" => segment <= b"0000000";
        when x"9" => segment <= b"0010000";
        when others => segment <= b"1000000";
    end case;
end procedure segment_dec;

end package body;

-------------------------------------------------------
-- entity calling package
-------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.user_pkg.all;

entity bcd2segment is
port (
    bcd     : in std_logic_vector(3 downto 0);
    segment : out std_logic_vector(6 downto 0)
);
end entity bcd2segment;

architecture behavioral of bcd2segment is

begin

process(bcd)
begin
    segment_dec(bcd, segment);
end process;

end behavioral;

7) generic
-----------------------------------------------------------------
--clk dividor
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity clk_div is
generic (
    N: integer := 12499999
);
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end entity clk_div;

architecture behavioral of clk_div is
signal clk_cnt     : integer range 0 to N;
signal clk_out_tmp : std_logic;
begin
--counter for half second
process(clk, rst_n)
begin
    if(rst_n = '0')then
        clk_cnt <= 0;
        clk_out_tmp <= '0';
    elsif(clk'event and clk = '1')  then
        --when counter reaches to half second,
        --need to reset the counter to 0
        if(clk_cnt = N) then
            clk_cnt <= 0;
            clk_out_tmp <= not (clk_out_tmp);
        else
            clk_cnt <= clk_cnt + 1;
            clk_out_tmp <= clk_out_tmp;
        end if;
    end if;
end process;

clk_out <= clk_out_tmp;

end behavioral;

-----------------------------------------------------------------
--top
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
generic (
    N: integer := 20
);
port (
    clk      : in  std_logic;
    rst_n    : in  std_logic;
    clk_out  : out std_logic
);
end entity top;

architecture behavioral of top is

component clk_div is
generic (
    N: integer := 12499999
);
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end component;

--begin of architecture
begin

--instance clock dividor
u_clk_div: clk_div generic map (
    N => N
) PORT MAP (
    clk     => clk     ,
    rst_n   => rst_n   ,
    clk_out => clk_out
);

end behavioral;
--end of architecture

8) instance component
-----------------------------------------------------------------
--clk dividor
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity clk_div is
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end entity clk_div;

architecture behavioral of clk_div is
signal clk_out_tmp : std_logic;
begin
--counter for half second
process(clk, rst_n)
begin
    if(rst_n = '0')then
        clk_out_tmp <= '0';
    elsif(clk'event and clk = '1')  then
        clk_out_tmp <= not clk_out_tmp;
    end if;
end process;

clk_out <= clk_out_tmp;

end behavioral;

-----------------------------------------------------------------
--top
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
port (
    clk      : in  std_logic;
    rst_n    : in  std_logic;
    clk_out  : out std_logic
);
end entity top;

architecture behavioral of top is

component clk_div is
port (
    clk     : in  std_logic;
    rst_n   : in  std_logic;
    clk_out : out std_logic
);
end component;

--begin of architecture
begin

--instance clock dividor
u_clk_div: clk_div PORT MAP (
    clk     => clk     ,
    rst_n   => rst_n   ,
    clk_out => clk_out
);

end behavioral;

9) generate
library ieee;
use ieee.std_logic_1164.all;

entity bcd2segment is
generic (
    M: integer := 7
);
port (
    bcd     : in std_logic_vector(3 downto 0);
    segment : out std_logic_vector(M-1 downto 0)
);
end entity bcd2segment;

architecture behavioral of bcd2segment is

begin

SEGMENT_WITHOUT_DP: if M=7 generate
process(bcd)
begin
    case bcd is
        --decode from bcd to segment
        when x"0" => segment <= b"1111111";
        when x"1" => segment <= b"1111001";
        when x"2" => segment <= b"0100100";
        when x"3" => segment <= b"0110000";
        when x"4" => segment <= b"0011001";
        when x"5" => segment <= b"0010010";
        when x"6" => segment <= b"0000010";
        when x"7" => segment <= b"1111000";
        when x"8" => segment <= b"0000000";
        when x"9" => segment <= b"0010000";
        --when in selector 1, counter should add 1 after each half second
        --for other unknown selectors, set counter to 0
        when others => segment <= b"1111111";
    end case;
end process;

end generate SEGMENT_WITHOUT_DP;

SEGMENT_WITH_DP: if M=8 generate
process(bcd)
begin
    case bcd is
        --decode from bcd to segment
        when x"0" => segment <= b"11111111";
        when x"1" => segment <= b"11111001";
        when x"2" => segment <= b"10100100";
        when x"3" => segment <= b"10110000";
        when x"4" => segment <= b"10011001";
        when x"5" => segment <= b"10010010";
        when x"6" => segment <= b"10000010";
        when x"7" => segment <= b"11111000";
        when x"8" => segment <= b"10000000";
        when x"9" => segment <= b"10010000";
        --when in selector 1, counter should add 1 after each half second
        --for other unknown selectors, set counter to 0
        when others => segment <= b"11111111";
    end case;
end process;

end generate SEGMENT_WITH_DP;

end behavioral;

31) testbench
-----------------------------------------------------------------
--DUT
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

package user_pkg is
procedure new_logic (signal A, B, CIN: in std_logic; signal S, COUT : out std_logic);
end package;

package body user_pkg is

procedure new_logic (
    signal A, B, CIN: in std_logic;
    signal S, COUT : out std_logic
) is
begin
    S <= (A xor B) xor CIN;
    COUT <= (A and B) or ((A xor B) and CIN);
end procedure new_logic;

end package body;

library ieee;
use ieee.std_logic_1164.all;
library work;
use work.user_pkg.all;

entity adder is
port (
    clk    : in  std_logic                    ;
    rst_n  : in  std_logic                    ;
    enable : in  std_logic                    ;
    a      : in  std_logic_vector(3 downto 0) ;
    b      : in  std_logic_vector(3 downto 0) ;
    s      : out std_logic_vector(3 downto 0) ;
    cout   : out std_logic                    
);
end entity adder;

architecture behavioral of adder is
signal c : std_logic_vector(3 downto 0);
signal s_tmp : std_logic_vector(3 downto 0);
signal cout_tmp : std_logic;

begin

c(0) <= '0';
process(a, b, c)
begin
    new_logic(a(0), b(0), c(0), s_tmp(0), c(1));
    new_logic(a(1), b(1), c(1), s_tmp(1), c(2));
    new_logic(a(2), b(2), c(2), s_tmp(2), c(3));
    new_logic(a(3), b(3), c(3), s_tmp(3), cout_tmp);
end process;

process(clk, rst_n)
begin
    if(rst_n = '0') then
        s <= x"0";
        cout <= '0';
    elsif(clk'event and clk = '0') then
        if(enable = '1') then
            s <= s_tmp;
            cout <= cout_tmp;
        end if;
    end if;
end process;

end behavioral;

-----------------------------------------------------------------
--tb
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.all;

entity tb_adder is
end entity tb_adder;

architecture behavioral of tb_adder is
component adder is
port (
    clk    : in  std_logic                    ;
    rst_n  : in  std_logic                    ;
    enable : in  std_logic                    ;
    a      : in  std_logic_vector(3 downto 0) ;
    b      : in  std_logic_vector(3 downto 0) ;
    s      : out std_logic_vector(3 downto 0) ;
    cout   : out std_logic                  
);
end component;

signal clk    : std_logic                    ;
signal rst_n  : std_logic                    ;
signal enable : std_logic                    ;
signal a      : std_logic_vector(3 downto 0) ;
signal b      : std_logic_vector(3 downto 0) ;
signal s      : std_logic_vector(3 downto 0) ;
signal cout   : std_logic                    ;

begin

u_adder: adder port map (
    clk    => clk    ,
    rst_n  => rst_n  ,
    enable => enable ,
    a      => a      ,
    b      => b      ,
    s      => s      ,
    cout   => cout
);

process
begin
    clk <= '0';
    wait for 6.67 ns;
    clk <= '1';
    wait for 6.67 ns;
end process;

process
variable i, j, k: integer;
begin
    rst_n <= '0';
    wait for 600 ns;
    rst_n <= '1';
    wait;
end process;

process
variable i, j, k: integer;
begin
    enable <= '0';
    a <= x"0";
    b <= x"0";
    wait until rst_n'event and rst_n = '1';
    wait until clk'event and clk = '0';
    for i in 0 to 15 loop
        for j in 0 to 15 loop
            wait until clk'event and clk = '0';
            a <= std_logic_vector(to_unsigned(i, a'length));
            b <= std_logic_vector(to_unsigned(j, b'length));
            enable <= '0';
            wait until clk'event and clk = '0';
            enable <= '1';
        end loop;
    end loop;
    wait for 100 ns;
    finish(0);
end process;

end behavioral;

some basic verilog syntax

1) module
module dataProcess (
    din  ,
    dout ,
    dio
);

input  din  ;
output dout ;
inout  dio  ;

wire din  ;
wire dout ;
// reg dout ;
wire dio  ;

endmodule

2) combinational logic
input  clk  ;
input  mode ;
output sclk ;

wire clk  ;
wire mode ;
wire sclk ;

reg clk_en;

// generate sclk
assign sclk = (clk_en == 1'b1) ? clk : 1'b0;

always @(mode)
//verilog 2000
//always @(*)
begin
    case (mode)
        0 : begin
            clk_en = 1'b0;
        end
        1 : begin
            clk_en = 1'b1;
        end

        default : begin
            clk_en = 1'b0;
        end
    endcase
end

endmodule

3) timing logic
module dff_1 (
    clk   ,
    rst_n ,
    din   ,
    dout
);

input  clk   ;
input  rst_n ;
input  din   ;
output dout  ;

wire clk   ;
wire rst_n ;
wire din   ;
reg  dout  ;

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)
        dout <= 1'b0;
    else
        dout <= din;
end

endmodule

4) tristate gate
module dataProcess (
    sclk  ,
    rst_n ,
    rw    ,
    sdio
);

input sclk  ;
input rst_n ;
input rw    ;
inout sdio  ;

wire sclk  ;
wire rst_n ;
wire rw    ;
wire sdio  ;

wire       sdi    ;
reg        sdo    ;
reg        sdo_en ;
reg  [7:0] data   ;

//generate sdio
assign sdio = (sdo_en == 1'b1) ? sdo : 1'bz;

assign sdi  = sdio;

always @(posedge sclk or negedge rst_n) begin
    if(rst_n == 1'b0)
        data <= 'h0;
    else begin
        if(rw == 1'b0)
            data <= {data[6:0], sdi};
        else
            data <= {data[6:0], 1'b0};
    end
end

always @(posedge sclk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        sdo <= 1'b0;
        sdo_en <= 1'b0;
    end
    else begin
        if(rw == 1'b1) begin
            sdo    <= data[7];
            sdo_en <= 1'b1;
        end
        else begin
            sdo    <= 1'b0;
            sdo_en <= 1'b0;
        end
    end
end

endmodule

5) module calling function
///////////////////////////////////////////////////////
// module user_pkg contains the function
///////////////////////////////////////////////////////
module user_pkg;

function [31:0] factorial;
input [3:0] operand;
reg   [3:0] index  ;
begin
    factorial = operand ? 1 : 0;
    for(index = 2; index <= operand; index = index + 1)
        factorial = index * factorial;
end
endfunction

endmodule

///////////////////////////////////////////////////////
// module calling package
///////////////////////////////////////////////////////
module test_package (
    n      ,
    result
);

input  [3:0 ] n      ;
output [31:0] result ;

wire [3:0 ] n      ;
reg  [31:0] result ;

always @(n) begin
    result = n * user_pkg.factorial(n) / ((n * 2) + 1);
end

endmodule

6) module calling task
///////////////////////////////////////////////////////
// module user_pkg contains task
///////////////////////////////////////////////////////
module user_pkg;

task segment_dec;
input  [3:0] bcd    ;
output [6:0] segment;
begin
    case(bcd)
        //decode from bcd to segment
        4'h0: segment = 7'b1000000;
        4'h1: segment = 7'b1111001;
        4'h2: segment = 7'b0100100;
        4'h3: segment = 7'b0110000;
        4'h4: segment = 7'b0011001;
        4'h5: segment = 7'b0010010;
        4'h6: segment = 7'b0000010;
        4'h7: segment = 7'b1111000;
        4'h8: segment = 7'b0000000;
        4'h9: segment = 7'b0010000;
        default: segment = 7'b1000000;
    endcase
end
endtask

endmodule

///////////////////////////////////////////////////////
// module calling task
///////////////////////////////////////////////////////
module bcd2segment (
    bcd     ,
    segment
);

input  [3:0] bcd     ;
output [6:0] segment ;

wire [3:0] bcd     ;
reg  [6:0] segment ;

always @(bcd) begin
    user_pkg.segment_dec(bcd, segment);
end

endmodule

7) parameter
/////////////////////////////////////////////////////////////////
//clk dividor
/////////////////////////////////////////////////////////////////
module clk_div (
    clk     ,
    rst_n   ,
    clk_out
);

parameter N = 12499999;

input  clk     ;
input  rst_n   ;
output clk_out ;

wire clk     ;
wire rst_n   ;
reg  clk_out ;

integer clk_cnt;

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        clk_cnt <= 0;
        clk_out <= 1'b0;
    end
    else begin
        //when counter reaches to half second,
        //need to reset the counter to 0
        if(clk_cnt == N) begin
            clk_cnt <= 0;
            clk_out <= ~clk_out;
        end
        else begin
            clk_cnt <= clk_cnt + 1;
            clk_out <= clk_out;
        end
    end
end

endmodule

/////////////////////////////////////////////////////////////////
//top
/////////////////////////////////////////////////////////////////
module top (
    clk     ,
    rst_n   ,
    clk_out
);

parameter N = 20;

input  clk     ;
input  rst_n   ;
output clk_out ;

wire clk     ;
wire rst_n   ;
wire clk_out ;

//instance clock dividor
clk_div #(
    //verilog 2000
    //.N(N)

    N
) u_clk_div (
    .clk     (clk     ) ,
    .rst_n   (rst_n   ) ,
    .clk_out (clk_out )
);

endmodule

8) instance module
/////////////////////////////////////////////////////////////////
//clk dividor
/////////////////////////////////////////////////////////////////
module clk_div (
    clk     ,
    rst_n   ,
    clk_out
);

input  clk     ;
input  rst_n   ;
output clk_out ;

wire clk     ;
wire rst_n   ;
reg  clk_out ;

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
        clk_out <= 1'b0;
    end
    else begin
        clk_out <= ~clk_out;
    end
end

endmodule

/////////////////////////////////////////////////////////////////
//top
/////////////////////////////////////////////////////////////////
module top (
    clk     ,
    rst_n   ,
    clk_out
);

input  clk     ;
input  rst_n   ;
output clk_out ;

wire clk     ;
wire rst_n   ;
wire clk_out ;

//instance clock dividor
clk_div u_clk_div (
    .clk     (clk     ) ,
    .rst_n   (rst_n   ) ,
    .clk_out (clk_out )
);

endmodule

9) ifdef
`define M7 7
module bcd2segment (
    bcd     ,
    segment
);

input  [3:0    ] bcd    ;
output [`M7-1:0] segment;

wire [3:0    ] bcd    ;
reg  [`M7-1:0] segment;

always @(bcd) begin
    case(bcd)
`ifdef M7
        //decode from bcd to segment
        4'h0: segment = 7'b1111111;
        4'h1: segment = 7'b1111001;
        4'h2: segment = 7'b0100100;
        4'h3: segment = 7'b0110000;
        4'h4: segment = 7'b0011001;
        4'h5: segment = 7'b0010010;
        4'h6: segment = 7'b0000010;
        4'h7: segment = 7'b1111000;
        4'h8: segment = 7'b0000000;
        4'h9: segment = 7'b0010000;
        //for other unknown selectors, set counter to 0
        default: segment = 7'b1111111;
`else
        //decode from bcd to segment
        4'h0: segment = 8'b11111111;
        4'h1: segment = 8'b11111001;
        4'h2: segment = 8'b10100100;
        4'h3: segment = 8'b10110000;
        4'h4: segment = 8'b10011001;
        4'h5: segment = 8'b10010010;
        4'h6: segment = 8'b10000010;
        4'h7: segment = 8'b11111000;
        4'h8: segment = 8'b10000000;
        4'h9: segment = 8'b10010000;
        //for other unknown selectors, set counter to 0
        default: segment = 8'b11111111;
`endif
    endcase
end

endmodule

10) parameter used as data width
`define M7
module bcd2segment (
    bcd     ,
    segment
);

`ifdef M7
parameter M = 7;
`else
parameter M = 8;
`endif

input  [3:0  ] bcd    ;
output [M-1:0] segment;

wire [3:0  ] bcd    ;
reg  [M-1:0] segment;

always @(bcd) begin
    case(bcd)
`ifdef M7
        //decode from bcd to segment
        4'h0: segment = 7'b1111111;
        4'h1: segment = 7'b1111001;
        4'h2: segment = 7'b0100100;
        4'h3: segment = 7'b0110000;
        4'h4: segment = 7'b0011001;
        4'h5: segment = 7'b0010010;
        4'h6: segment = 7'b0000010;
        4'h7: segment = 7'b1111000;
        4'h8: segment = 7'b0000000;
        4'h9: segment = 7'b0010000;
        //for other unknown selectors, set counter to 0
        default: segment = 7'b1111111;
`else
        //decode from bcd to segment
        4'h0: segment = 8'b11111111;
        4'h1: segment = 8'b11111001;
        4'h2: segment = 8'b10100100;
        4'h3: segment = 8'b10110000;
        4'h4: segment = 8'b10011001;
        4'h5: segment = 8'b10010010;
        4'h6: segment = 8'b10000010;
        4'h7: segment = 8'b11111000;
        4'h8: segment = 8'b10000000;
        4'h9: segment = 8'b10010000;
        //for other unknown selectors, set counter to 0
        default: segment = 8'b11111111;
`endif
    endcase
end

endmodule

31) testbench
/////////////////////////////////////////////////////////////////
//DUT
/////////////////////////////////////////////////////////////////
module adder (
    clk    ,
    rst_n  ,
    enable ,
    a      ,
    b      ,
    s      ,
    cout  
);

input        clk    ;
input        rst_n  ;
input        enable ;
input  [3:0] a      ;
input  [3:0] b      ;
output [3:0] s      ;
output       cout   ;

wire       clk    ;
wire       rst_n  ;
wire       enable ;
wire [3:0] a      ;
wire [3:0] b      ;
wire [3:0] s      ;
wire       cout   ;

reg  [4:0] sum    ;

assign s = sum[3:0];
assign cout = sum[4];

always @(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0)
        sum <= 5'h0;
    else begin
        if(enable == 1)
            sum <= a + b;
    end
end

endmodule

/////////////////////////////////////////////////////////////////
//tb
/////////////////////////////////////////////////////////////////
module tb_adder();

reg        clk    ;
reg        rst_n  ;
reg        enable ;
reg  [3:0] a      ;
reg  [3:0] b      ;
wire [3:0] s      ;
wire       cout   ;

adder u_adder (
    .clk    (clk    ) ,
    .rst_n  (rst_n  ) ,
    .enable (enable ) ,
    .a      (a      ) ,
    .b      (b      ) ,
    .s      (s      ) ,
    .cout   (cout   )
);

initial begin
    clk = 1'b0;
    forever #6.67 clk = ~clk;
end


initial begin
    rst_n = 1'b0;
    #600;
    rst_n = 1'b1;
end

integer i;
integer j;
initial begin
    enable <= 1'b0;
    a <= 'h0;
    b <= 'h0;
    @(posedge rst_n);
    @(negedge clk)
    for(i=0; i<16; i=i+1) begin
        for(j=0; j<16; j=j+1) begin
            @(negedge clk);
            a = i[3:0];
            b = j[3:0];
            enable = 1'b0;
            @(posedge clk);
            #1 $display("a = %d, b = %d, enable = %d, s = %d, cout = %d", a, b, enable, s, cout);
            @(negedge clk);
            enable = 1'b1;
            @(posedge clk);
            #1 $display("a = %d, b = %d, enable = %d, s = %d, cout = %d", a, b, enable, s, cout);
        end
    end
    #100;
    $finish();
end

endmodule