0% found this document useful (0 votes)
41 views146 pages

Uart Protocol Desing and Verificaton

Uploaded by

dlwaysi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views146 pages

Uart Protocol Desing and Verificaton

Uploaded by

dlwaysi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 146

DESIGN AND

VERIFICATION OF
UART

UART (VERILOG DESIGN AND


VERILOG, SV, UVM TESTBENCH)
INDEX
==UART TRANSMITTER==

UART DESCRIPTION - -1 TO06

UART TRANSMITTER VERILOG DESIGN CODE -- -7T014

UART TRANSMITTER DESIGN SCHEMATIC - -14

UART TRANSMITTER VERILOG TESTBENCH - -15TO 16

UART TRANSMITTER VERILOG TB WAVEFORM - =17


UART TRANSMITTER SYSTEM_VERILOG TESTBENCH - -18T0 31

UART TRANSMITTER SYSTEM_VERILOG WAVEFORM - -32


UART TRANSMITTER COVERAGE - -33

UART TRANSMITTER UVM TESTBENCH - -34TO53


==UART_RECIEVER==

UART RECIEVER VERILOG DESIGN CODE - -54T0 64

UART RECIEVER DESIGN SCHEMATIC - -65

UART RECIEVER VERILOG TESTBENCH - -66TO67

UART RECIEVER VERILOG TB WAVEFORM - -68

UART RECIEVER SYSTEM_VERILOG TESTBENCH - -697T0 82

UART RECIEVER SYSTEM_VERILOG WAVEFORM - -83


UART RECIEVER COVERAGE - -84
UART RECIEVER UVM TESTBENCH - -85TO 101

==FULL _UART==
FULL_UART VERILOG DESIGN CODE - -102TO

FULL_UART DESIGN SCHEMATIC - -103TO


FULL_UART VERILOG TESTBENCH - -104TO 105

FULL_UART VERILOG TB WAVEFORM - -106

FULL_UART SYSTEM_VERILOG TESTBENCH - -107TO 122

FULL_UART SYSTEM_VERILOG WAVEFORM -- -123T0O

FULL_UART COVERAGE - -124T70


FULL_UART UVM TESTBENCH - -125TO 144
UART Specification
Introduction
• There are many serial communication protocols as I2C, UART and SPI.
• A Universal Asynchronous Receiver/Transmitter (UART) is a block of
circuitry responsible for implementing serial communication.
UART is Full Duplex protocol (data transmission in both directions
simultaneously).

• Transmitting UART converts parallel data from the master device (e.g.,
CPU) into serial form and transmit in serial to receiving UART.
• Receiving UART will then convert the serial data back into parallel data
for the receiving device.

1
UART Transmitter
Block Diagram

Specifications
1. UART TX receives the new data on p_data Bus only when data_valid
Signal is high.
2. Registers are cleared using asynchronous active low reset.
3. data_valid is high for only 1 clock cycle.
4. busy signal is high as long as UART_TX is transmitting the frame,
otherwise low.
5. UART_TX couldn't accept any data on p_data during UART_TX
processing, however data_valid get high.
6. s_data is high in the IDLE case (No transmission).
7. parity_en (Configuration)
0: To disable frame parity bit
1: To enable frame parity bit
8. parity_type (Configuration)
0: Even parity bit
1: Odd parity bit
9. 200 MHz clock frequency.

2
All Expected Output Frames
1. Data Frame (in case of Parity is enabled & Parity Type is even)
– One start bit (1'b0)
– Data (LSB first or MSB, 8 bits)
– Even Parity bit
– One stop bit

2. Data Frame (in case of Parity is enabled & Parity Type is odd)
– One start bit (1'b0)
– Data (LSB first or MSB, 8 bits)
– Odd Parity bit
– One stop bit

3. Data Frame (in case of Parity is not Enabled)


– One start bit (1'b0)
– Data (LSB first or MSB, 8 bits)
– One stop bit

3
Waveforms
1. Expected Input

data_valid
p_data

2. Expected Output

s_data

busy

UART Receiver
Block Diagram

4
Specifications
1. UART TX receives a UART frame on s_data.
2. UART_RX supports oversampling by 8.
3. s_data is high in the IDLE case (No transmission).
4. parity_error signal is high when the calculated parity bit does not equal
the received frame parity bit as this means that the frame is corrupted.
5. stop_error signal is high when the received stop bit does not equal 1 as
this means that the frame is corrupted.
6. DATA is extracted from the received frame and then sent through p_data
bus associated with data_valid signal only after checking that the frame is
received correctly and not corrupted. (parity_error=0 && stop_error=0).
7. UART_RX can accept consequent frames.
8. Registers are cleared using asynchronous active low reset.
9. parity_en (Configuration)
0: To disable frame parity bit
1: To enable frame parity bit
10. parity_type (Configuration)
0: Even parity bit
1: Odd parity bit

Oversampling
1. Oversampling by 4: This means that the clock speed of UART_RX is 4
times the speed of UART_TX.

5
2. Oversampling by 8: This means that the clock speed of UART_RX is 8
times the speed of UART_TX.

Waveforms
1. Expected Input
In case of one frame

s_data

In case of multiple frames

s_data

2. Expected Output

data_valid
p_data

6
mux.v Page 1

module mux (clk, rst, mux_sel, start_bit, ser_data, parity_bit, stop_bit, tx_out);
input clk, rst;
input [2:0] mux_sel;
input start_bit, ser_data, parity_bit, stop_bit;
output reg tx_out;

localparam IDLE_BIT =0, START_BIT =1, SER_DATA =2, PARITY_BIT =3, STOP_BIT =4;

always @(posedge clk, negedge rst) begin


if(!rst)
tx_out <= 1'b1;

else begin
case (mux_sel)
IDLE_BIT: tx_out <= 1'b1;
START_BIT: tx_out <= start_bit;
SER_DATA: tx_out <= ser_data;
PARITY_BIT: tx_out <= parity_bit;
STOP_BIT: tx_out <= stop_bit;
default: tx_out <= 1'b1;
endcase
end
end
endmodule

7
parity_calc.v Page 1

module parity_calc #(parameter DWIDTH = 8)(clk, rst, data, parity_type, parity_bit);


input clk, rst;
input [DWIDTH-1:0]data;
input parity_type;
output reg parity_bit;

wire even_parity;

localparam EVEN =0, ODD =1;

assign even_parity = ^data;

always @(posedge clk, negedge rst) begin


if(!rst) // active low asynch rst
parity_bit <= 1'b0;
else begin
case(parity_type)
EVEN: parity_bit <= even_parity;
ODD : parity_bit <= ~even_parity;
default: parity_bit <= 1'b0;
endcase
end
end
endmodule

/*
module parity_test;
reg clk, rst;
reg [7:0]data;
reg parity_type;
wire parity_bit;

parity_calc #(8)dut(clk, rst, data, parity_type, parity_bit);

initial begin
clk = 0;
forever begin
#5ns; clk = ~clk;
end
end
initial begin
rst = 0; #25ns; rst = 1;
parity_type = 1; //odd
data = 8'b1100_1001; //1
#20ns;
data = 8'b1100_1000; //0
#40ns;
parity_type = 0; //even
data = 8'b1100_1000; //1
#20ns;
data = 8'b1100_1001; //0
#40ns;
$finish;
end

initial begin
$dumpfile("test.vcd");
$dumpvars;
end
endmodule
*/

8
serializer.v Page 1

module serializer #(parameter DWIDTH =8)(clk, rst, p_data, ser_en, s_data, ser_done);
input clk, rst;
input [DWIDTH-1:0]p_data;
input ser_en;
output reg s_data, ser_done;

integer check_done;

always @(posedge clk, negedge rst) begin

if(!rst) begin
s_data <= 1'b1;
ser_done <= 1'b0;
check_done <= 0;
end
else begin
if (ser_en) begin
if (check_done == DWIDTH-1) begin
s_data <= p_data[check_done];
ser_done <= 1'b1;
check_done <= 0;
end
else begin
s_data <= p_data[check_done];
ser_done <= 1'b0;
check_done <= check_done+1;
end
end
else begin
s_data <= 1'b1;
ser_done <= 1'b0;
end
end
end
endmodule

/*
module ser_test;
reg clk, rst;
reg [7:0]p_data;
reg ser_en;
wire s_data, ser_done;

serializer #(8)dut(clk, rst, p_data, ser_en, s_data, ser_done);

initial begin
clk = 0;
forever begin
#5ns; clk = ~clk;
end
end
initial begin
rst = 0; #25ns; rst = 1;
ser_en = 0;
#10ns; ser_en = 1;
p_data = 8'b1011_0010;
#80ns;
ser_en = 0;
#10ns; ser_en = 1;
p_data = 8'b1000_0011;
#80ns;
ser_en = 0;
#40ns;

9
serializer.v Page 2

$finish;
end

initial begin
$dumpfile("test.vcd");
$dumpvars;
end
endmodule
*/

10
tx_fsm.v Page 1

module tx_fsm (clk, rst, valid_data, parity_en, ser_done, ser_en, mux_sel, busy);
input clk, rst;
input valid_data, parity_en, ser_done;
output reg ser_en, busy;
output reg [2:0] mux_sel;

reg [2:0] current_state, next_state;


reg busy_reg;

localparam IDLE =0, START =1, DATA =2, PARITY =3, STOP =4;

always @(posedge clk, negedge rst) begin


if(!rst) begin
current_state <= IDLE;
busy <= 1'b0;
end
else begin
current_state <= next_state;
busy <= busy_reg;
end
end

always @(*) begin


case(current_state)
IDLE: begin
ser_en = 1'b0;
mux_sel = 3'b000;
busy_reg = 1'b0;

if (valid_data)
next_state = START;

else
next_state = IDLE;
end

START: begin
ser_en = 1'b1;
mux_sel = 3'b001;
busy_reg = 1'b1;

next_state = DATA;
end

DATA: begin
mux_sel = 3'b010;
busy_reg = 1'b1;

if(ser_done) begin
ser_en =1'b0;

if(parity_en)
next_state = PARITY;

else
next_state = STOP;
end
else begin
ser_en = 1'b1;

next_state = DATA;
end
end

11
tx_fsm.v Page 2

PARITY: begin
ser_en = 1'b0;
mux_sel = 3'b011;
busy_reg = 1'b1;

next_state = STOP;
end

STOP: begin
ser_en = 1'b0;
mux_sel = 3'b100;
busy_reg = 1'b1;

next_state = IDLE;
end

default: begin
ser_en = 1'b0;
mux_sel = 2'b00;
busy_reg = 1'b0;

next_state = IDLE;
end
endcase
end
endmodule

12
uart_tx.v Page 1

module uart_tx #(parameter DWIDTH = 8)(clk, rst, p_data, data_valid, parity_en, parity
_type, s_data, busy);
input [DWIDTH-1:0]p_data;
input data_valid, parity_en, parity_type;
input clk, rst;
output s_data, busy;

wire parity_bit, ser_en, ser_done, ser_data;


wire [2:0] mux_sel;

parity_calc #(DWIDTH) par_c(


.clk(clk),
.rst(rst),
.data(p_data),
.parity_type(parity_type),
.parity_bit(parity_bit)
);

serializer #(DWIDTH) ser(


.clk(clk),
.rst(rst),
.p_data(p_data),
.ser_en(ser_en),
.s_data(ser_data),
.ser_done(ser_done)
);

tx_fsm fsm(
.clk(clk),
.rst(rst),
.valid_data(data_valid),
.parity_en(parity_en),
.ser_done(ser_done),
.ser_en(ser_en),
.mux_sel(mux_sel),
.busy(busy)
);

mux m(
.clk(clk),
.rst(rst),
.mux_sel(mux_sel),
.start_bit(1'b0),
.ser_data(ser_data),
.parity_bit(parity_bit),
.stop_bit(1'b1),
.tx_out(s_data)
);

endmodule

13
p_data_IBUF[0]_inst
I O
p_data[7:0]
IBUF

p_data_IBUF[1]_inst
I O

IBUF

p_data_IBUF[2]_inst
I O

IBUF

p_data_IBUF[3]_inst
I O

IBUF

p_data_IBUF[4]_inst
I O ser

IBUF CLK
E
p_data_IBUF[5]_inst
I O Q[2:0] s_data_reg_0
SR ser_done
IBUF
p_data_IBUF[7:0]
p_data_IBUF[6]_inst s_data_reg_1
I O
serializer
IBUF
fsm
p_data_IBUF[7]_inst
I O CLK

SR E
IBUF data_valid_IBUF_inst
I O data_valid_IBUF FSM_sequential_current_state_reg[0]_0
data_valid
parity_bit Q[2:0]
IBUF busy_OBUF_inst
parity_en_IBUF busy_OBUF I O
parity_en busy
parity_en_IBUF_inst ser_done tx_out
clk_IBUF_inst clk_IBUF_BUFG_inst I O OBUF
I O I O tx_out_reg
clk m
IBUF
IBUF BUFG tx_fsm
CLK
par_c s_data_OBUF_inst
rst_IBUF_inst SR s_data_OBUF I O
I O s_data
rst CLK tx_out
OBUF
IBUF SR parity_bit mux
p_data_IBUF[7:0]
parity_type_IBUF_inst
I O parity_type_IBUF
parity_type
IBUF parity_calc

14
uart_tx_tb.v Page 1

module uart_tx_tb;
// Testbench signals
reg clk;
reg rst;
reg [7:0] p_data;
reg data_valid;
reg parity_en;
reg parity_type;
wire s_data;
wire busy;

// Instantiate UART transmitter


uart_tx #(8) uut (
.clk(clk),
.rst(rst),
.p_data(p_data),
.data_valid(data_valid),
.parity_en(parity_en),
.parity_type(parity_type),
.s_data(s_data),
.busy(busy)
);

// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk;
end

// Test sequence
initial begin
// Initialize inputs
rst = 0;
p_data = 8'b00000000;
data_valid = 0;
parity_en = 0;
parity_type = 0;

// Apply reset
#10 rst = 1;

// Test case 1: Transmit data with no parity


#20;
p_data = 8'b01010101;
data_valid = 1;
parity_en = 0;
parity_type = 0;

#150 ;

p_data = 8'b10101010;
data_valid = 1;
parity_en = 0;
parity_type = 1;

#150 ;

p_data = 8'b01010101;
data_valid = 1;
parity_en = 1;
parity_type = 0;

#150 ;

15
uart_tx_tb.v Page 2

p_data = 8'b10101010;
data_valid = 1;
parity_en = 1;
parity_type = 1;

#150 ;
$finish;
end

// Display the values


initial begin
$monitor("p_data : %0b , parity_enable : %0b , s_data : %0b , busy : %0b ",p_data
, parity_en , s_data , busy);
end
endmodule

16
17
list.sv Page 1

`include "uart_transmitter.v"
`include "uart_common.sv"
`include "uart_intf.sv"
`include "uart_tx.sv"
`include "uart_sbd.sv"
`include "uart_cov.sv"
`include "uart_mon.sv"
`include "uart_bfm.sv"
`include "uart_gen.sv"
`include "uart_agent.sv"
`include "uart_env.sv"
`include "uart_top.sv"

18
uart_common.sv Page 1

`define D_WIDTH 8
`define TIME_PERIOD 8

class uart_common;
//static int count;
static mailbox gen2bfm = new();
static mailbox mon2sbd = new();
static mailbox mon2cov = new();
static string testname;
endclass

19
uart_tx.sv Page 1

class uart_tx;

bit valid_data;
rand bit parity_en;
rand bit parity_type;
rand bit [`D_WIDTH-1:0] p_data;
bit s_data;
bit busy;

function void print(input string name="tx");


$display("The Print Statement is from ###%s###",name);
//$display("Valid_data=%0s",valid_data?"YES":"NO");
$display("Valid_data=%0b",valid_data);
$display("Parity_enabled=%0S",parity_en?"YES":"NO");
$display("Parity_type=%0S",parity_type?"ODD":"EVEN");
$display("Given_Parallel_data=%8b",p_data);
$display("Serial_Data=%0b",s_data);
$display("Busy=%0b",busy);
endfunction

endclass

20
uart_intf.sv Page 1

interface uart_intf#(parameter DWIDTH = 8)(input clk,rst);


logic valid_data;
logic parity_en;
logic parity_type;
logic [`D_WIDTH-1:0] p_data;
logic s_data;
logic busy;

clocking bfm_cb @(posedge clk);

default input #0 output #1;

output valid_data;
output parity_en;
output parity_type;
output p_data;
input s_data;
input busy;

endclocking

clocking mon_cb @(posedge clk);

default input #0 output #1;

input valid_data;
input parity_en;
input parity_type;
input p_data;
input s_data;
input busy;

endclocking

endinterface

21
uart_env.sv Page 1

class uart_env;

uart_agent agent;
uart_sbd sbd ;

task run();
agent = new();
sbd = new();

fork
agent.run();
sbd.run();
join
endtask

endclass

22
uart_gen.sv Page 1

class uart_gen;

//uart_tx tx;
//tx = new();
task run();

//uart_tx tx = new();
repeat (4)
begin
uart_tx tx = new();
case(uart_common::testname)
//randcase
"no_parity1":begin
assert(tx.randomize() with {tx.parity_en ==0; tx.parity_type ==0;});
uart_common::gen2bfm.put(tx);
end
"no_parity2":begin
assert(tx.randomize() with {tx.parity_en ==0; tx.parity_type ==1;});
uart_common::gen2bfm.put(tx);
end
"even_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==0;});
uart_common::gen2bfm.put(tx);
end
"odd_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==1;});
uart_common::gen2bfm.put(tx);
end
endcase
#100;
wait((top.pif.bfm_cb.busy==0) && (top.pif.bfm_cb.valid_data==0));
end
endtask

endclass

23
uart_intf.sv Page 1

interface uart_intf#(parameter DWIDTH = 8)(input clk,rst);


logic valid_data;
logic parity_en;
logic parity_type;
logic [`D_WIDTH-1:0] p_data;
logic s_data;
logic busy;

clocking bfm_cb @(posedge clk);

default input #0 output #1;

output valid_data;
output parity_en;
output parity_type;
output p_data;
input s_data;
input busy;

endclocking

clocking mon_cb @(posedge clk);

default input #0 output #1;

input valid_data;
input parity_en;
input parity_type;
input p_data;
input s_data;
input busy;

endclocking

endinterface

24
uart_mon.sv Page 1

class uart_mon;
uart_tx tx;
virtual uart_intf #(`D_WIDTH) vif;

function new();
vif = top.pif;
endfunction
task run();
forever begin
//wait(vif.mon_cb.busy==1);
@(vif.mon_cb)begin
tx = new();
tx.valid_data = vif.mon_cb.valid_data ;
tx.parity_en = vif.mon_cb.parity_en ;
tx.parity_type = vif.mon_cb.parity_type;
tx.p_data = vif.mon_cb.p_data ;
tx.s_data = vif.mon_cb.s_data ;
tx.busy = vif.mon_cb.busy ;

//tx.print("Monitor");
end
uart_common::mon2sbd.put(tx);
uart_common::mon2cov.put(tx);
end
endtask
endclass

25
uart_sbd.sv Page 1

class uart_sbd;

uart_tx tx;

bit start_bit;
bit parity_bit;
bit parity_bit_expected;
bit stop_bit;
bit data_q[`D_WIDTH];
bit [`D_WIDTH-1:0] data;

uart_tx data_queue[$];
bit s_data_queue[$:`D_WIDTH+3];

///run method of task run


task run();

bit start_bit, parity_bit, parity_bit_expected, stop_bit;


bit data_q[`D_WIDTH];
bit [`D_WIDTH-1:0] data;

forever begin

uart_common::mon2sbd.get(tx);

if (tx.busy) begin
data_queue.push_front(tx);
end
//else begin
// $display("Idle");

if (data_queue.size() != 0) begin
tx = data_queue.pop_back();
s_data_queue.push_front(tx.s_data);

if (tx.parity_en) begin
if (s_data_queue.size() == `D_WIDTH+3) begin
start_bit = s_data_queue.pop_back();
foreach (data_q[i]) begin
data_q[`D_WIDTH-(i+1)] = s_data_queue.pop_back();
end
parity_bit = s_data_queue.pop_back();
stop_bit = s_data_queue.pop_back();
data = {>>{data_q}};

// Display and checks


$display("start = %0b", start_bit);
$display("data = %8b", data);
$display("parity = %0b", parity_bit);
$display("stop = %0b", stop_bit);

if (start_bit == 0)
$display("PASSED START: The start bit = %0b", start_bit);
else
$error("FAILED START: The start bit = %0b", start_bit);

if (tx.p_data == data)
$display("PASSED DATA: The data = %8b, p_data = %8b", data, tx.p_data);
else
$error("FAILED DATA: The data = %8b, p_data = %8b", data, tx.p_data);

parity_bit_expected = (tx.parity_type == 0) ? ^tx.p_data : ~(^tx.p_data);

if (parity_bit == parity_bit_expected)

26
uart_sbd.sv Page 2

$display("PASSED PARITY: The parity bit = %0b, Expected parity bit = %0b", pa
rity_bit, parity_bit_expected);
else
$error("FAILED PARITY: The parity bit = %0b, Expected parity bit = %0b", parity_bit, p
arity_bit_expected);

if (stop_bit == 1)
$display("PASSED STOP: The stop bit = %0b", stop_bit);
else
$error("FAILED STOP: The stop bit = %0b", stop_bit);
end
end else begin
if (s_data_queue.size() == `D_WIDTH+2) begin
start_bit = s_data_queue.pop_back();
foreach (data_q[i]) begin
data_q[`D_WIDTH-(i+1)] = s_data_queue.pop_back();
end
stop_bit = s_data_queue.pop_back();
data = {>>{data_q}};

// Display and checks


$display("start = %0b", start_bit);
$display("data = %0b", data);
$display("stop = %0b", stop_bit);

if (start_bit == 0)
$display("PASSED START: The start bit = %0b", start_bit);
else
$error("FAILED START: The start bit = %0b", start_bit);

if (tx.p_data == data)
$display("PASSED DATA: The data = %0b, p_data = %0b", data, tx.p_data);
else
$error("FAILED DATA: The data = %0b, p_data = %0b", data, tx.p_data);

if (stop_bit == 1)
$display("PASSED STOP: The stop bit = %0b", stop_bit);
else
$error("FAILED STOP: The stop bit = %0b", stop_bit);
end
end
end
end
endtask

endclass

27
uart_top.sv Page 1

module top;
bit clk;
bit rst;
uart_env env;
event e;

uart_transmitter#(`D_WIDTH)dut(
.clk(clk),
.rst(rst),
.p_data(pif.p_data),
.valid_data(pif.valid_data),
.parity_en(pif.parity_en),
.parity_type(pif.parity_type),
.s_data(pif.s_data),
.busy(pif.busy)
);

uart_intf pif(clk,rst);

initial begin
clk = 1'b0;
forever begin
#(`TIME_PERIOD/2) clk = ~ clk;
end
end

initial begin
rst = 1'b0;

repeat(2)
@(posedge clk);

rst = 1'b1;
->e;
end

initial begin
wait(e.triggered);
env = new();
env.run();
end

initial begin
uart_common::testname = "no_parity1";
#140;
uart_common::testname = "no_parity2";
#140;
uart_common::testname = "even_parity";
#140;
uart_common::testname = "odd_parity";
#140;

$finish;
end
endmodule

28
uart_tx.sv Page 1

class uart_tx;

bit valid_data;
rand bit parity_en;
rand bit parity_type;
rand bit [`D_WIDTH-1:0] p_data;
bit s_data;
bit busy;

function void print(input string name="tx");


$display("The Print Statement is from ###%s###",name);
//$display("Valid_data=%0s",valid_data?"YES":"NO");
$display("Valid_data=%0b",valid_data);
$display("Parity_enabled=%0S",parity_en?"YES":"NO");
$display("Parity_type=%0S",parity_type?"ODD":"EVEN");
$display("Given_Parallel_data=%8b",p_data);
$display("Serial_Data=%0b",s_data);
$display("Busy=%0b",busy);
endfunction

endclass

29
list.sv Page 1

`include "uart_transmitter.v"
`include "uart_common.sv"
`include "uart_intf.sv"
`include "uart_tx.sv"
`include "uart_sbd.sv"
`include "uart_cov.sv"
`include "uart_mon.sv"
`include "uart_bfm.sv"
`include "uart_gen.sv"
`include "uart_agent.sv"
`include "uart_env.sv"
`include "uart_top.sv"

30
uart_tx_sv.log Page 1

# End time: 10:19:05 on Dec 25,2024, Elapsed time: 0:05:32


# Errors: 0, Warnings: 1
# vsim -voptargs="+acc" top -l uart_tx_sv.log
# Start time: 10:19:05 on Dec 25,2024
# ** Note: (vsim-3813) Design is being optimized due to module recompilation...
# Loading sv_std.std
# Loading work.list_sv_unit(fast)
# Loading work.top(fast)
# Loading work.uart_transmitter(fast)
# Loading work.parity_calc(fast)
# Loading work.serializer(fast)
# Loading work.tx_fsm(fast)
# Loading work.mux(fast)
# Loading work.uart_intf(fast)
# Loading work.uart_intf(fast)
# ** Warning: (vsim-8441) Clocking block output $root.top.pif.bfm_cb.valid_data is not
legal in this
# or another expression.
# Time: 0 ns Iteration: 0 Region: /list_sv_unit File: uart_gen.sv Line: 32
# start = 0
# data = 11011001
# stop = 1
# PASSED START: The start bit = 0
# PASSED DATA: The data = 11011001, p_data = 11011001
# PASSED STOP: The stop bit = 1
# start = 0
# data = 1110010
# stop = 1
# PASSED START: The start bit = 0
# PASSED DATA: The data = 1110010, p_data = 1110010
# PASSED STOP: The stop bit = 1
# start = 0
# data = 10100110
# stop = 1
# PASSED START: The start bit = 0
# PASSED DATA: The data = 10100110, p_data = 10100110
# PASSED STOP: The stop bit = 1
# start = 0
# data = 00000101
# parity = 0
# stop = 1
# PASSED START: The start bit = 0
# PASSED DATA: The data = 00000101, p_data = 00000101
# PASSED PARITY: The parity bit = 0, Expected parity bit = 0
# PASSED STOP: The stop bit = 1
# ** Note: $finish : uart_top.sv(55)
# Time: 560 ns Iteration: 0 Instance: /top
# 1
# Break in Module top at uart_top.sv line 55
cd {E:\VLSI_GURU_PDFS\SV\PROJECTS\VERIFICATION_OF_UART\UART_RX_SV}
# Cannot change directory while a simulation is in progress.
# Use the "quit -sim" command to unload the design first.
quit -sim

31
32
33
list.sv Page 1

//include necessary uvm pkages


`include "uvm_pkg.sv"
import uvm_pkg::*;

`include "uart_common.sv"
`include "uart_transmitter.v"
`include "uart_tx.sv"
`include "uart_intf.sv"
`include "uart_cov.sv"
`include "uart_driver.sv"
`include "uart_monitor.sv"
`include "uart_sqr.sv"
`include "uart_agent.sv"
`include "uart_sbd.sv"
`include "uart_env.sv"
`include "uart_seq_lib.sv"
`include "uart_test_lib.sv"
`include "top.sv"

34
uart_common.sv Page 1

`define D_WIDTH 8
`define TIMEPERIOD 8

`define NEW_OBJ function new(string name="");\


super.new(name);\
endfunction

`define NEW_COMP function new(string name="",uvm_component parent);\


super.new(name,parent);\
endfunction

35
uart_tx.sv Page 1

//--------------- uart_tx ---------------//


class uart_tx extends uvm_sequence_item;//uart_tx is also a object
//propery/fields
bit valid_data ;
rand bit parity_en ;
rand bit parity_type ;
rand bit [`D_WIDTH-1:0] p_data;
bit s_data ;
bit busy ;

//1. factory registeration + field registeration


`uvm_object_utils_begin(uart_tx)
`uvm_field_int(valid_data ,UVM_ALL_ON )
`uvm_field_int(parity_en ,UVM_ALL_ON )
`uvm_field_int(parity_type,UVM_ALL_ON )
`uvm_field_int(p_data ,UVM_ALL_ON )
`uvm_field_int(s_data ,UVM_ALL_ON )
`uvm_field_int(busy ,UVM_ALL_ON )
`uvm_object_utils_end

//methods
//constraints

//function new
function new(string name="");
super.new(name);
endfunction

endclass

36
uart_intf.sv Page 1

interface uart_intf#(parameter DWIDTH = 8)(input clk,rst);


logic valid_data;
logic parity_en;
logic parity_type;
logic [`D_WIDTH-1:0] p_data;
logic s_data;
logic busy;

clocking bfm_cb @(posedge clk);

default input #0 output #1;

output valid_data;
output parity_en;
output parity_type;
output p_data;
input s_data;
input busy;

endclocking

clocking mon_cb @(posedge clk);

default input #0 output #1;

input valid_data;
input parity_en;
input parity_type;
input p_data;
input s_data;
input busy;

endclocking

endinterface

37
top.sv Page 1

//---------------------- top.sv file -----------------------//

//top module declaration


module top;
//clk rst decalration
bit clk,rst;

uart_transmitter#(`D_WIDTH)dut(
.clk(clk),
.rst(rst),
.p_data(pif.p_data),
.valid_data(pif.valid_data),
.parity_en(pif.parity_en),
.parity_type(pif.parity_type),
.s_data(pif.s_data),
.busy(pif.busy)
);

uart_intf pif(clk,rst);

//clk rst generation


always #5 clk = ~clk;//100MHz

initial begin
rst = 0;
repeat(2) @(posedge clk);
rst = 1;
end

initial begin
uvm_config_db#(virtual uart_intf)::set(null, "*", "VIF",pif);
//run_test("uart_base_test");
// run_test("uart_no_parity1_test");
// run_test("uart_no_parity2_test");
// run_test("uart_even_parity_test");
run_test("uart_odd_parity_test");
end
endmodule

38
uart_env.sv Page 1

//---------------- uart_env -----------------//


class uart_env extends uvm_env;
//1. factory registeration
`uvm_component_utils(uart_env)

//2. sub_compoennt instantiation


uart_agent uart_agent_h;

uart_sbd uart_sbd_h;

//3. function new defination wrt components


function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE ",UVM_NONE)
uart_agent_h = uart_agent::type_id::create("uart_agent_h",this);
uart_sbd_h = uart_sbd::type_id::create("uart_sbd_h",this);
endfunction

//connect_phase
function void connect_phase(uvm_phase phase);
//connect agent.mon to sbd
uart_agent_h.uart_mon_h.mon_ap.connect(uart_sbd_h.uart_imp_port);

endfunction
endclass

39
uart_agent.sv Page 1

//--------------- uart_agent -----------------//


class uart_agent extends uvm_agent;
//1. factory registeration
`uvm_component_utils(uart_agent)

//2. sub_compoennt instantiation


uart_sqr uart_sqr_h;
uart_driver uart_drv_h;
uart_monitor uart_mon_h;
uart_cov uart_cov_h;

//3. function new defination wrt components


function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE",UVM_NONE)
uart_sqr_h = uart_sqr::type_id::create("uart_sqr_h",this);
uart_drv_h = uart_driver::type_id::create("uart_drv_h",this);
uart_mon_h = uart_monitor::type_id::create("uart_mon_h",this);
uart_cov_h = uart_cov::type_id::create("uart_cov_h",this);
endfunction

//connect_phase
function void connect_phase(uvm_phase phase);
`uvm_info(get_name,"CONNECT_PHASE of uart_agent",UVM_NONE)
uart_drv_h.seq_item_port.connect(uart_sqr_h.seq_item_export);
//driver and sqr connections are 1 to 1
//mon to cov connection
uart_mon_h.mon_ap.connect(uart_cov_h.analysis_export);
endfunction

endclass

40
uart_sqr.sv Page 1

//--------------- uart_sqr -----------------//


typedef uvm_sequencer#(uart_tx) uart_sqr;

41
uart_test_lib.sv Page 1

//----------------------- uart_base_test -------------------//


class uart_base_test extends uvm_test;
`uvm_component_utils(uart_base_test)

`NEW_COMP

//2. sub_compoennt instantiation


uart_env uart_env_h;

function void build_phase(uvm_phase phase);


super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE ",UVM_NONE)
uart_env_h = uart_env::type_id::create("uart_env_h",this);
endfunction

//end_of_elaboration_phase
function void end_of_elaboration_phase(uvm_phase phase);
`uvm_info(get_name,"END_OF_ELABORATION_PHASE ",UVM_NONE)
uvm_top.print_topology();//tb structure print
endfunction

task run_phase(uvm_phase phase);


`uvm_info(get_name(),"running just uart_base_test No tx are driven in this test to
DUT",UVM_NONE)
endtask

//report_phase
function void report_phase(uvm_phase phase);
`uvm_info(get_name(),"REPORT_PHASE of uart_test",UVM_NONE)

endfunction

endclass

//-------------------uart_complete_all_parity_test -------------------------//
class uart_complete_all_parity_test extends uart_base_test;
`uvm_component_utils(uart_complete_all_parity_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity1 no_parity1;
uart_odd_parity odd_parity;
uart_no_parity2 no_parity2;
uart_even_parity even_parity;

no_parity1 = uart_no_parity1::type_id::create("no_parity1");
no_parity2 = uart_no_parity2::type_id::create("no_parity2");
even_parity = uart_even_parity::type_id::create("even_parity");
odd_parity = uart_odd_parity::type_id::create("odd_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
no_parity1.start(uart_env_h.uart_agent_h.uart_sqr_h);
no_parity2.start(uart_env_h.uart_agent_h.uart_sqr_h);
even_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);
odd_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join

42
uart_test_lib.sv Page 2

phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_no_parity_test1 -------------------------//
class uart_no_parity1_test extends uart_base_test;
`uvm_component_utils(uart_no_parity1_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity1 no_parity1;

no_parity1 = uart_no_parity1::type_id::create("no_parity1");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);

no_parity1.start(uart_env_h.uart_agent_h.uart_sqr_h);

phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_no_parity_test2 -------------------------//
class uart_no_parity2_test extends uart_base_test;
`uvm_component_utils(uart_no_parity2_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity2 no_parity2;

no_parity2 = uart_no_parity2::type_id::create("no_parity2");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);

no_parity2.start(uart_env_h.uart_agent_h.uart_sqr_h);

phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_even_parity_test -------------------------//
class uart_even_parity_test extends uart_base_test;
`uvm_component_utils(uart_even_parity_test)

43
uart_test_lib.sv Page 3

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_even_parity even_parity;

even_parity = uart_even_parity::type_id::create("even_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
even_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_odd_parity_test -------------------------//
class uart_odd_parity_test extends uart_base_test;
`uvm_component_utils(uart_odd_parity_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_odd_parity odd_parity;

odd_parity = uart_odd_parity::type_id::create("odd_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
odd_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

44
uart_seq_lib.sv Page 1

//-------------- uart_base_seq ---------------//


class uart_base_seq extends uvm_sequence#(uart_tx);
//1. factory registeration
`uvm_object_utils(uart_base_seq)

`NEW_OBJ

uvm_phase phase;

task pre_body();
//raise the objections
phase = get_starting_phase();
if(phase != null) begin
`uvm_info(get_name(),"PREBODY PHASE IS NOT NULL",UVM_NONE)
phase.raise_objection(this);
end
endtask

task body();
`uvm_info(get_name(),"BODY With nothing",UVM_NONE)
endtask

task post_body();
//raise the objections
phase = get_starting_phase();
if(phase != null) begin
`uvm_info(get_name(),"POSTBODY PHASE IS NOT NULL",UVM_NONE)
phase.phase_done.set_drain_time(this,50);
phase.drop_objection(this);
end
endtask
endclass

//-------------------- uart_no_parity1--------------------//
class uart_no_parity1 extends uart_base_seq;
`uvm_object_utils(uart_no_parity1)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==0; req.parity_type ==0;})
endtask

endclass

//-------------------- uart_no_parity2--------------------//
class uart_no_parity2 extends uart_base_seq;
`uvm_object_utils(uart_no_parity2)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==0; req.parity_type ==1;})
endtask

endclass

//-------------------- uart_even_parity--------------------//
class uart_even_parity extends uart_base_seq;
`uvm_object_utils(uart_even_parity)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==1; req.parity_type ==0;})

45
uart_seq_lib.sv Page 2

endtask

endclass

//-------------------- uart_odd_parity--------------------//
class uart_odd_parity extends uart_base_seq;
`uvm_object_utils(uart_odd_parity)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==1; req.parity_type ==1;})
endtask

endclass

46
uart_driver.sv Page 1

//--------------- uart_driver -----------------//


class uart_driver extends uvm_driver#(uart_tx);
//1. factory registeration
`uvm_component_utils(uart_driver)

//virtual interface instantiation


virtual uart_intf vif;

//3. function new defination wrt components


`NEW_COMP

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE",UVM_NONE)
//In SV - vif = top.pif;
if(!(uvm_config_db#(virtual uart_intf)::get(this, "", "VIF", vif))) begin
`uvm_error(get_name(), "FAILED TO RETRIVE INTERFACE HANDLE FROM CONFIG DB")
end
else begin
`uvm_info(get_name(),"RETRIVED INTERFACE HANDLE FROM CONFIG DB",UVM_NONE)
end
endfunction

//run_phase
task run_phase(uvm_phase phase);
`uvm_info(get_name,"RUN_PHASE",UVM_NONE)
wait(vif.rst == 1);
forever begin
//1. driver needs to req item/tx from sqr
seq_item_port.get_next_item(req);//what is req -> handle of uart_tx
//2. print the tx
//req.print();//tx.print
//3. driver needs to drive the tx/item to dut usig interface
drive_tx(req);//user defined
//4. driver needs to send ack to sqr - indicating item done driving to DUT
seq_item_port.item_done();
end
endtask

//user defined method drive_tx


task drive_tx(uart_tx tx);
//implemnt uart driving logic
if(!vif.bfm_cb.busy)
begin
repeat(2) begin
@(vif.bfm_cb)
vif.bfm_cb.p_data <= tx.p_data;
vif.bfm_cb.parity_en <= tx.parity_en;
vif.bfm_cb.parity_type <= tx.parity_type;
//vif.bfm_cb.valid_data <= 1'b1;
end
end
@(vif.bfm_cb)
vif.bfm_cb.valid_data <= 1'b1;
@(vif.bfm_cb) begin
tx.s_data = vif.bfm_cb.s_data;
tx.busy = vif.bfm_cb.busy;
end

wait(vif.bfm_cb.busy==1)
@(vif.bfm_cb)
vif.bfm_cb.valid_data <= 1'b0;

47
uart_driver.sv Page 2

endtask
endclass

48
uart_monitor.sv Page 1

//---------------- uart_monitor ----------------//


class uart_monitor extends uvm_monitor;
`uvm_component_utils(uart_monitor)
`NEW_COMP
//virtual interface instantiation
virtual uart_intf vif;

//declare a analysis port


uvm_analysis_port#(uart_tx) mon_ap;

uart_tx tx;

//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name(),"BUILD_PHASE ",UVM_NONE)
tx = uart_tx::type_id::create("tx");
mon_ap = new("mon_ap",this);
if(!(uvm_config_db#(virtual uart_intf)::get(this, "", "VIF", vif))) begin
`uvm_error(get_name(), "FAILED TO RETRIVE INTERFACE HANDLE FROM CONFIG DB")
end
else begin
`uvm_info(get_name(),"RETRIVED INTERFACE HANDLE FROM CONFIG DB",UVM_NONE)
end

endfunction
//run_phase
task run_phase(uvm_phase phase);
`uvm_info(get_name(),"RUN_PHASE ",UVM_NONE)
forever begin

@(vif.mon_cb)begin

tx.valid_data = vif.mon_cb.valid_data ;
tx.parity_en = vif.mon_cb.parity_en ;
tx.parity_type = vif.mon_cb.parity_type;
tx.p_data = vif.mon_cb.p_data ;
tx.s_data = vif.mon_cb.s_data ;
tx.busy = vif.mon_cb.busy ;

end

mon_ap.write(tx);
end

endtask

endclass

49
uart_cov.sv Page 1

//-------------------- uart_cov ------------------//


class uart_cov extends uvm_subscriber#(uart_tx);
`uvm_component_utils(uart_cov)

uart_tx tx;

//covergroup
covergroup cg;
// option.per_instance = 1;

cov_valid_data : coverpoint tx.valid_data {


bins valid_data_1_0[] = (1'b1=>1'b0);
bins valid_data_0_1[] = (1'b0=>1'b1);
}

cov_busy_check : coverpoint tx.busy {


bins busy_1_0[] = (1'b1=>1'b0);
bins busy_0_1[] = (1'b0=>1'b1);
}

cov_parity_en : coverpoint tx.parity_en {


bins parity_en_yes[] = {1'b1};
bins parity_en_no[] = {1'b0};
}

cov_parity_type : coverpoint tx.parity_type {


bins parity_type_odd[] = {1'b1};
bins parity_type_even[] = {1'b0};
}

//CROSS_COVERAGE1:cross cov_valid_data ,cov_parity_en , cov_parity_type;


//CROSS_COVERAGE2:cross cov_busy_check ,cov_parity_en , cov_parity_type;

endgroup

function new(string name="",uvm_component parent);


super.new(name,parent);
//allocate memory for the covergroup
cg = new();
endfunction

//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction

endclass

50
uart_sbd.sv Page 1

//--------------- uart_sbd ------------------//


class uart_sbd extends uvm_scoreboard;
`uvm_component_utils(uart_sbd)

//declare a uvm_analysis_imp_port

uvm_analysis_imp#(uart_tx,uart_sbd) uart_imp_port;

uart_tx tx;

bit start_bit;
bit parity_bit;
bit parity_bit_expected;
bit stop_bit;
bit data_q[`D_WIDTH];
bit [`D_WIDTH-1:0] data;

uart_tx data_queue[$];
bit s_data_queue[$:`D_WIDTH+3];

function new(string name="",uvm_component parent);


super.new(name,parent);
endfunction

function void build_phase(uvm_phase phase);


super.build_phase(phase);
uart_imp_port = new("uart_imp_port",this);
endfunction

function void write(uart_tx tx);


//collect the data store the wdata into the sbd associative array
if (tx.busy) begin
data_queue.push_front(tx);
end
//else begin
// $display("Idle");

if (data_queue.size() != 0) begin
tx = data_queue.pop_back();
s_data_queue.push_front(tx.s_data);

if (tx.parity_en) begin
if (s_data_queue.size() == `D_WIDTH+3) begin
start_bit = s_data_queue.pop_back();
foreach (data_q[i]) begin
data_q[`D_WIDTH-(i+1)] = s_data_queue.pop_back();
end
parity_bit = s_data_queue.pop_back();
stop_bit = s_data_queue.pop_back();
data = {>>{data_q}};

// Display and checks

`uvm_info(get_name(),$sformatf("start = %b", start_bit),UVM_NONE)

`uvm_info(get_name(),$sformatf("data = %b", data),UVM_NONE)

`uvm_info(get_name(),$sformatf("parity = %b", parity_bit),UVM_NONE)

`uvm_info(get_name(),$sformatf("stop = %b", stop_bit),UVM_NONE)

if (start_bit == 0)
`uvm_info(get_name(),$sformatf("PASSED START: The start bit = %b", start_bit),U
VM_NONE)

51
uart_sbd.sv Page 2

else
`uvm_error(get_name(),$sformatf("FAILED START: The start bit = %b", start_bit))

if (tx.p_data == data)
`uvm_info(get_name(),$sformatf("PASSED DATA: The data = %b, p_data = %b", data, tx.
p_data),UVM_NONE)

else
`uvm_error(get_name(),$sformatf("FAILED DATA: The data = %b, p_data = %b", data, tx
.p_data))

parity_bit_expected = (tx.parity_type == 0) ? ^tx.p_data : ~(^tx.p_data);

if (parity_bit == parity_bit_expected)
`uvm_info(get_name(),$sformatf("PASSED PARITY: The parity bit = %b, Expected
parity bit = %b", parity_bit, parity_bit_expected),UVM_NONE)

else

`uvm_error(get_name(),$sformatf("FAILED PARITY: The parity bit = %b, Expected parity b


it = %b", parity_bit, parity_bit_expected))

if (stop_bit == 1)
`uvm_info(get_name(),$sformatf("PASSED STOP: The stop bit = %b", stop_bit),UVM_NONE)

else
`uvm_error(get_name(),$sformatf("FAILED STOP: The stop bit = %b", stop_bit))

end
end else begin
if (s_data_queue.size() == `D_WIDTH+2) begin
start_bit = s_data_queue.pop_back();
foreach (data_q[i]) begin
data_q[`D_WIDTH-(i+1)] = s_data_queue.pop_back();
end
stop_bit = s_data_queue.pop_back();
data = {>>{data_q}};

// Display and checks


`uvm_info(get_name(),$sformatf("start = %b", start_bit),UVM_NONE)

`uvm_info(get_name(),$sformatf("data = %b", data),UVM_NONE)

`uvm_info(get_name(),$sformatf("stop = %b", stop_bit),UVM_NONE)

if (start_bit == 0)
`uvm_info(get_name(),$sformatf("PASSED START: The start bit = %b", start_bit),UV
M_NONE)

else
`uvm_error(get_name(),$sformatf("FAILED START: The start bit = %b", start_bit))

if (tx.p_data == data)
`uvm_info(get_name(),$sformatf("PASSED DATA: The data = %b, p_data = %b", data, tx.p_d
ata),UVM_NONE)

else
`uvm_error(get_name(),$sformatf("FAILED DATA: The data = %b, p_data = %b", data, tx.p_
data))

52
uart_sbd.sv Page 3

if (stop_bit == 1)
`uvm_info(get_name(),$sformatf("PASSED STOP: The stop bit = %b", stop_bit),UVM_NONE)

else
`uvm_error(get_name(),$sformatf("FAILED STOP: The stop bit = %b", stop_bit))

end
end
end
endfunction

endclass

53
data_sampling.v Page 1

module data_sampling #(parameter PWIDTH =6)(clk, rst, prescale, edge_counter, data_sam


pling_en, rx_in, sampled_bit);
input clk, rst;
input [PWIDTH-1:0] prescale, edge_counter;
input data_sampling_en;
input rx_in;

output reg sampled_bit;

wire [PWIDTH-1:0]num_samples;
reg [PWIDTH-1:0]counter, ones, zeros;

assign num_samples = ( prescale >> 2 ) +1;

always@(posedge clk or negedge rst) begin


if(!rst)
counter <= 0;
else if(data_sampling_en) begin
if((edge_counter >= num_samples) && (counter != num_samples))
counter <= counter +1;
else
counter <= 0;
end
end

always @(posedge clk or negedge rst) begin


if(!rst) begin
ones <= 0;
zeros <= 0;
sampled_bit <= 0;
end
else if(data_sampling_en) begin
if((edge_counter >= num_samples) && (counter != num_samples)) begin
if(rx_in)
ones <= ones +1;
else
zeros <= zeros +1;
end
else begin
if(ones > zeros) begin
sampled_bit <= 1'b1; // the sampled bit is one
ones <= 0;
zeros <= 0;
end
else begin
sampled_bit <= 1'b0; // the sampled bit is zero
ones <= 0;
zeros <= 0;
end
end
end
end
endmodule

54
edge_bit_counter.v Page 1

module edge_bit_counter #(parameter PWIDTH = 6)(clk, rst, enable, prescale, bit_counte


r, edge_counter);
input clk, rst, enable;
input [PWIDTH-1:0]prescale;
output reg [PWIDTH-2:0] bit_counter;
output reg [PWIDTH-1:0] edge_counter;

wire edge_counter_done;

// (prescale =8) --> (0:7) --> (edge_counter ==8) --> (done)


assign edge_counter_done = (edge_counter == prescale-1)? 1'b1:1'b0;

always @(posedge clk, negedge rst) begin


if(!rst) begin
edge_counter <= 0;
end
else if(enable) begin
if(!edge_counter_done)
edge_counter <= edge_counter +1;
else
edge_counter <= 0;
end
else
edge_counter <= 0;
end

always @(posedge clk, negedge rst) begin


if(!rst) begin
bit_counter <= 0;
end
else if(enable) begin
if(edge_counter_done)
bit_counter <= bit_counter +1;
else
bit_counter <= bit_counter;
end
else
bit_counter <= 0;
end
endmodule

55
parity_check.v Page 1

module parity_check #(parameter DWIDTH =8)(clk, rst, parity_type, parity_check_en, sam


pled_bit, p_data, parity_error);
input clk, rst;
input parity_type, parity_check_en, sampled_bit;
input [DWIDTH-1:0] p_data;

output reg parity_error;

reg parity_bit;

always @(posedge clk, negedge rst) begin


if(!rst)
parity_error <= 1'b0;

else if (parity_check_en) begin


if (parity_bit != sampled_bit)
parity_error <= 1'b1;
else
parity_error <= 1'b0;
end
end

always @(*) begin


if (parity_check_en) begin
case(parity_type)
1'b0: parity_bit = ^p_data;
1'b1: parity_bit = ~^p_data;
default: parity_bit = 1'b0;
endcase
end
end
endmodule

56
rx_fsm.v Page 1

module rx_fsm #(parameter PWIDTH =6)(clk, rst, prescale, edge_counter, bit_counter, rx


_in, parity_en, stop_error, start_error, parity_error, data_sampling_en, deser_en, sta
rt_check_en, stop_check_en, parity_check_en, enable, data_valid);
input clk, rst;
input [PWIDTH-1:0]prescale, edge_counter;
input [PWIDTH-2:0]bit_counter;
input rx_in, parity_en;
input stop_error, start_error, parity_error;

output reg data_sampling_en, deser_en;


output reg start_check_en, stop_check_en, parity_check_en;
output reg enable, data_valid;

reg [2:0] current_state, next_state;

localparam IDLE =0, START =1, DATA =2, PARITY =3, STOP =4, CERROR =5, DVALID =6;

always @(posedge clk or negedge rst) begin


if(!rst)
current_state <= IDLE;
else
current_state <= next_state;
end

always @(*) begin


case (current_state)
IDLE: begin
if(!rx_in) begin
data_sampling_en = 1;
enable = 1;
deser_en = 0;
data_valid = 0;
stop_check_en = 0;
start_check_en = 1;
parity_check_en = 0;

next_state = START;
end
else begin
data_sampling_en = 0;
enable = 0;
deser_en = 0;
data_valid = 0;
stop_check_en = 0;
start_check_en = 0;
parity_check_en = 0;

next_state = IDLE;
end
end

START: begin
data_sampling_en = 1;
enable = 1;
deser_en = 0;
data_valid = 0;
stop_check_en = 0;
start_check_en = 1;
parity_check_en = 0;

if((bit_counter ==0) && (edge_counter == prescale-1)) begin


if(!start_error) begin
next_state = DATA;
end

57
rx_fsm.v Page 2

else begin
next_state = IDLE;
end
end
else begin
next_state = START;
end
end

DATA: begin
data_sampling_en = 1;
enable = 1;
deser_en = 1;
data_valid = 0;
stop_check_en = 0;
start_check_en = 0;
parity_check_en = 0;

if((bit_counter ==8) && (edge_counter == prescale-1)) begin


if(parity_en) begin
next_state = PARITY;
end
else begin
next_state = STOP;
end
end
else begin
next_state = DATA;
end
end

PARITY: begin
data_sampling_en = 1;
enable = 1;
deser_en = 0;
data_valid = 0;
stop_check_en = 0;
start_check_en = 0;
parity_check_en = 1;

if((bit_counter ==9) && (edge_counter == prescale-1)) begin


next_state = STOP;
end
else begin
next_state = PARITY;
end
end

STOP: begin
data_sampling_en = 1;
enable = 1;
deser_en = 0;
data_valid = 0;
stop_check_en = 1;
start_check_en = 0;
parity_check_en = 0;

if((bit_counter ==10) && (edge_counter == prescale-1)) begin


next_state = CERROR;
end
else begin
next_state = STOP;
end
end

58
rx_fsm.v Page 3

CERROR: begin
data_sampling_en = 1;
enable = 0;
deser_en = 0;
data_valid = 0;
stop_check_en = 0;
start_check_en = 0;
parity_check_en = 0;

if(parity_error || stop_error) begin


next_state = IDLE;
end
else begin
next_state = DVALID;
end
end

DVALID: begin
data_sampling_en = 0;
enable = 0;
deser_en = 0;
data_valid = 1;
stop_check_en = 0;
start_check_en = 0;
parity_check_en = 0;

if(!rx_in) begin
next_state = START;
end
else begin
next_state = IDLE;
end
end

default: begin
data_sampling_en = 0;
enable = 0;
deser_en = 0;
data_valid = 0;
stop_check_en = 0;
start_check_en = 0;
parity_check_en = 0;

next_state = IDLE;
end
endcase
end
endmodule

59
start_check.v Page 1

module start_check (clk, rst, sampled_bit, start_check_en, start_error);


input clk, rst, sampled_bit;
input start_check_en;

output reg start_error;

always @(posedge clk, negedge rst) begin


if(!rst)
start_error <= 1'b0;

else if (start_check_en)
start_error <= sampled_bit; // if sampled bit is 1 so there is an error
end
endmodule

60
deserializer.v Page 1

module deserializer #(parameter DWIDTH =8, PWIDTH =6)(clk, rst, deser_en, sampled_bit,
prescale, edge_counter, p_data);
input clk, rst;
input deser_en, sampled_bit;
input [PWIDTH-1:0]prescale, edge_counter;

output reg [DWIDTH-1:0]p_data;

reg [DWIDTH-1:0]bit_index;

always @(posedge clk or negedge rst) begin


if(!rst) begin
p_data <= 0;
bit_index <= 0;
end
else if (deser_en && (bit_index != DWIDTH) && (edge_counter == prescale-1)) be
gin
p_data[bit_index] <= sampled_bit;
bit_index <= bit_index +1;
end

if(bit_index == DWIDTH)
bit_index <= 0;
end
endmodule

61
stop_check.v Page 1

module stop_check (clk, rst, stop_check_en, sampled_bit, stop_error);


input clk, rst;
input stop_check_en;
input sampled_bit;

output reg stop_error;

always @(posedge clk, negedge rst) begin


if(!rst)
stop_error <= 1'b0;

else if (stop_check_en) begin


if (!sampled_bit)
stop_error <= 1'b1;
else
stop_error <= 1'b0;
end
end
endmodule

62
uart_rx.v Page 1

module uart_rx #(parameter DWIDTH =8, PWIDTH =6)


(clk, rst, s_data, parity_type, parity_en, prescale, p_data, data_valid);

input clk, rst;


input s_data, parity_type, parity_en;
input [PWIDTH-1:0]prescale;

output [DWIDTH-1:0]p_data;
output data_valid;

wire data_sampling_en, enable, deser_en, stop_check_en, start_check_en, parity_che


ck_en;
wire start_error, stop_error, parity_error;
wire sampled_bit;
wire [PWIDTH-1:0] edge_counter;
wire [PWIDTH-2:0] bit_counter;

data_sampling #(PWIDTH) dsample(


.clk(clk),
.rst(rst),
.prescale(prescale),
.edge_counter(edge_counter),
.data_sampling_en(data_sampling_en),
.rx_in(s_data),
.sampled_bit(sampled_bit)
);

deserializer #(DWIDTH, PWIDTH) deser(


.clk(clk),
.rst(rst),
.deser_en(deser_en),
.sampled_bit(sampled_bit),
.prescale(prescale),
.edge_counter(edge_counter),
.p_data(p_data)
);

edge_bit_counter #(PWIDTH) count(


.clk(clk),
.rst(rst),
.enable(enable),
.prescale(prescale),
.bit_counter(bit_counter),
.edge_counter(edge_counter)
);

rx_fsm #(PWIDTH) fsm(


.clk(clk),
.rst(rst),
.prescale(prescale),
.edge_counter(edge_counter),
.bit_counter(bit_counter),
.rx_in(s_data),
.parity_en(parity_en),
.stop_error(stop_error),
.start_error(start_error),
.parity_error(parity_error),
.data_sampling_en(data_sampling_en),
.deser_en(deser_en),
.start_check_en(start_check_en),
.stop_check_en(stop_check_en),
.parity_check_en(parity_check_en),
.enable(enable),
.data_valid(data_valid)

63
uart_rx.v Page 2

);

start_check start(
.clk(clk),
.rst(rst),
.sampled_bit(sampled_bit),
.start_check_en(start_check_en),
.start_error(start_error)
);

parity_check #(DWIDTH)parity(
.clk(clk),
.rst(rst),
.parity_type(parity_type),
.parity_check_en(parity_check_en),
.sampled_bit(sampled_bit),
.p_data(p_data),
.parity_error(parity_error)
);

stop_check stop(
.clk(clk),
.rst(rst),
.stop_check_en(stop_check_en),
.sampled_bit(sampled_bit),
.stop_error(stop_error)
);
endmodule

64
count

CO
FSM_onehot_current_state_reg[4][3:0]

SR
SS D[3:0]
clk_IBUF_BUFG Q

edge_counter_reg[0]_0 S[1:0]
edge_counter_reg[1]_0 bit_counter_reg[0]_0
edge_counter_reg[4]_0 edge_counter_reg[5]_0

p_data2_carry prescale[5][2:0]
parity_en_IBUF_inst
I O parity_en_IBUF
parity_en
prescale_IBUF[5:0]
IBUF
start_error
zeros[5]_i_3

edge_bit_counter
stop

SS
clk_IBUF_inst clk_IBUF_BUFG_inst
I O I O clk_IBUF_BUFG stop_error
clk
stop_error_reg_0
IBUF BUFG dsample deser
stop_check
E Q
Q[1:0] S[1:0]
fsm
SR SS

clk_IBUF_BUFG SS bit_counter_reg[4][2:0] CO CO
counter_reg[5]_0 counter_reg[3]_0 bit_index_reg[2]_0 edge_counter_reg[0] D[3:0] E
ones_reg[5]_0 prescale[3] clk_IBUF_BUFG p_data_OBUF[7:0] FSM_onehot_current_state_reg[0]_2 FSM_onehot_current_state_reg[0]_0
parity
prescale_IBUF[3:0] sampled_bit edge_counter_reg[0]_0 p_data_reg[6]_0 SS FSM_onehot_current_state_reg[0]_1 p_data_OBUF[0]_inst
I O
rst_IBUF sampled_bit_reg_0 parity_type_IBUF prescale[3] Q clk_IBUF_BUFG FSM_onehot_current_state_reg[5]_0
sampled_bit_reg_1 prescale_IBUF[5:0] SS parity_error FSM_onehot_current_state_reg[5]_1 OBUF

sampled_bit_reg_2 rst_IBUF clk_IBUF_BUFG parity_error rst_IBUF FSM_onehot_current_state_reg[5]_2


data_valid_OBUF_inst
stop_error sampled_bit parity_error_reg_0 s_data_IBUF Q[5:0] I O
data_valid
prescale_IBUF[0]_inst sampled_bit sampled_bit SR
data_sampling deserializer OBUF
I O
start_error sampled_bit_reg p_data[7:0]
parity_check
IBUF stop_error p_data_OBUF[1]_inst
I O
zeros_reg[5]
prescale_IBUF[1]_inst
I O OBUF
start rx_fsm
IBUF parity_type_IBUF_inst p_data_OBUF[2]_inst
I O SS I O
parity_type
clk_IBUF_BUFG start_error
rst_IBUF_inst IBUF OBUF
I O start_error_reg_0
rst
p_data_OBUF[3]_inst
IBUF start_check
I O

prescale_IBUF[2]_inst OBUF
I O
p_data_OBUF[4]_inst
IBUF I O

prescale_IBUF[3]_inst OBUF
I O
p_data_OBUF[5]_inst
IBUF s_data_IBUF_inst I O
I O
s_data
OBUF
prescale_IBUF[4]_inst IBUF
prescale[5:0] I O
p_data_OBUF[6]_inst
I O
IBUF
OBUF
prescale_IBUF[5]_inst
I O
p_data_OBUF[7]_inst
I O
IBUF
OBUF

65
uart_rx_tb.v Page 1

`define TIMEPERIOD 8
module uart_rx_tb;
// Testbench signals
reg clk;
reg rst;
reg s_data;
reg parity_type;
reg parity_en;
reg [5:0] prescale;
wire [7:0] p_data;
wire data_valid;

// Instantiate UART receiver


uart_rx #(8, 6) uut (
.clk(clk),
.rst(rst),
.s_data(s_data),
.parity_type(parity_type),
.parity_en(parity_en),
.prescale(prescale),
.p_data(p_data),
.data_valid(data_valid)
);

// Clock generation
initial begin
clk = 0;
forever #(`TIMEPERIOD/2) clk = ~clk;
end

// Test sequence
initial begin
// Initialize inputs
rst = 0;
s_data = 1;
parity_type = 0;
parity_en = 0;
prescale = 8;

// Apply reset
#10 rst = 1;

#(prescale * 2);

parity_en = 1'b0;
parity_type = 1'b0;

send_uart_frame(8'b10101010, 1'b0,1'b0, 1'b1); // no parity

#(prescale * 20);
parity_en = 1'b0;
parity_type = 1'b1;
send_uart_frame(8'b01010101, 1'b0,1'b1, 1'b1); // no parity

#(prescale * 20);

parity_en = 1'b1;
parity_type = 1'b1;
send_uart_frame(8'b10101010, 1'b1,1'b1, 1'b1); // odd parity

#(prescale * 20);

parity_en = 1'b1;

66
uart_rx_tb.v Page 2

parity_type = 1'b0;
send_uart_frame(8'b01010101, 1'b1,1'b0, 1'b1); // even parity

#(prescale * 30);

// End simulation
$finish;
end

// Task to send a UART frame


task send_uart_frame;
input [7:0] data;
input parity_en;
input parity_type;
input stop_bit;
integer i;
begin
// Start bit
s_data = 0;
#(prescale * `TIMEPERIOD);

// Data bits
for (i = 0; i < 8; i = i + 1) begin
s_data = data[i];
#(prescale * `TIMEPERIOD);
end

// Parity bit (if enabled)


if (parity_en) begin
if(parity_type)begin
s_data = ~^(data);
#(prescale * `TIMEPERIOD);
end
else begin
s_data = ^(data);
#(prescale * `TIMEPERIOD);
end
end
// Stop bit
s_data = stop_bit;
#(prescale * `TIMEPERIOD);

end
endtask
endmodule

67
68
list.sv Page 1

`include "uart_reciever.v"
`include "uart_common.sv"
`include "uart_intf.sv"
`include "uart_tx.sv"
`include "uart_sbd.sv"
`include "uart_cov.sv"
`include "uart_mon.sv"
`include "uart_bfm.sv"
`include "uart_gen.sv"
`include "uart_agent.sv"
`include "uart_env.sv"
`include "uart_top.sv"

69
uart_common.sv Page 1

`define D_WIDTH 8
`define P_WIDTH 6
`define TIME_PERIOD 8
`define PRESCALE 8
class uart_common;
static int count;
static mailbox gen2bfm = new();
static mailbox mon2sbd = new();
static mailbox mon2cov = new();
static string testname;
endclass

70
uart_tx.sv Page 1

class uart_tx;

rand logic pd_in[$]; //for creating random_data

bit s_data;
rand bit parity_type;
rand bit parity_en;
rand bit [`P_WIDTH-1:0] prescale;
bit [`D_WIDTH-1:0] p_data;
bit valid_data;

bit [`D_WIDTH-1:0]actual_p_data;

constraint pd_in_size {

(parity_en ==0) -> (pd_in.size()==10);


(parity_en ==1) -> (pd_in.size()==11);

constraint start_stop_bit {
soft pd_in[0]==0;//start_bit
soft (parity_en ==0) -> (pd_in[9]==1); //for stop_bit
soft (parity_en ==1) -> (pd_in[10]==1); //for stop_bit
}

constraint parity_generator{
if(parity_en==1)
{
(parity_type ==0)->(pd_in[9]==(pd_in[1]^pd_in[2]^pd_in[3]^pd_in[4]^pd_in[5]^pd_in[6]^p
d_in[7]^pd_in[8]));
(parity_type ==1)->(pd_in[9]==~(pd_in[1]^pd_in[2]^pd_in[3]^pd_in[4]^pd_in[5]^pd_in[6]^
pd_in[7]^pd_in[8]));
}
}

function void print(input string name="tx");


actual_p_data = {<<{p_data}};

$display("The Print Statement is from ###%s###",name);


$display("Valid_data=%0b",valid_data);
$display("Random_Data=%0p",pd_in);
$display("Parity_enabled=%0S",parity_en?"YES":"NO");
$display("Parity_type=%0S",parity_type?"ODD":"EVEN");
$display("Recieved_Parallel_data=%8b",actual_p_data);
$display("Recieved_Data=%0b",s_data);
endfunction

function void data_print(input string name="tx");


actual_p_data = {<<{p_data}};
$display("The Print Statement is from ###%s###",name);
$display("Given_data = %0p <=> Recieved_data = %8b",pd_in[1:8],actual_p_d
ata);
endfunction

endclass

71
uart_intf.sv Page 1

interface uart_intf#(parameter DWIDTH = 8, parameter PWIDTH = 6)(input clk,rst);


logic s_data;
logic parity_type;
logic parity_en;
logic [PWIDTH-1:0] prescale;
logic [DWIDTH-1:0] p_data;
logic valid_data;
logic pd_in[$];

clocking bfm_cb @(posedge clk);

default input #0 output #1;

input valid_data;
input p_data;
output prescale;
output parity_en;
output parity_type;
output s_data;

endclocking

clocking mon_cb @(posedge clk);

default input #0 output #1;

input valid_data;
input p_data;
input prescale;
input parity_en;
input parity_type;
input s_data;

endclocking

endinterface

72
uart_top.sv Page 1

module top;
bit clk;
bit rst;
uart_env env;
event e;

uart_reciever #(`D_WIDTH, `P_WIDTH) dut (


.clk(pif.clk),
.rst(pif.rst),
.s_data(pif.s_data),
.parity_type(pif.parity_type),
.parity_en(pif.parity_en),
.prescale(pif.prescale),
.p_data(pif.p_data),
.data_valid(pif.valid_data)
);
uart_intf#(`D_WIDTH , `P_WIDTH) pif(clk,rst);

initial begin
clk = 1'b0;
forever begin
#(`TIME_PERIOD/2) clk = ~ clk;
end
end

initial begin
rst = 1'b0;

repeat(2)
@(posedge clk);

rst = 1'b1;
->e;
end

initial begin
wait(e.triggered);
env = new();
env.run();
end

initial begin
uart_common::testname = "even_parity";
#(`PRESCALE*100);
uart_common::testname = "no_parity1";
#(`PRESCALE*100);
uart_common::testname = "odd_parity";
#(`PRESCALE*100);
uart_common::testname = "no_parity2";
#(`PRESCALE*100);
uart_common::testname = "no_stop_with_no_parity";
#(`PRESCALE*100);
uart_common::testname = "no_stop_with_even_parity";
#(`PRESCALE*100);
uart_common::testname = "no_stop_with_odd_parity";
#(`PRESCALE*100);
uart_common::testname = "no_start";
#(`PRESCALE*100);

$finish;
end
endmodule

73
uart_env.sv Page 1

class uart_env;

uart_agent agent;
uart_sbd sbd ;

task run();
agent = new();
sbd = new();

fork
agent.run();
sbd.run();
join
endtask

endclass

74
uart_agent.sv Page 1

class uart_agent ;

uart_gen gen ;
uart_bfm bfm ;
uart_mon mon ;
uart_cov cov ;

task run();
gen = new();
bfm = new();
mon = new();
cov = new();

fork
gen.run();
bfm.run();
mon.run();
cov.run();
join
endtask

endclass

75
uart_gen.sv Page 1

class uart_gen;

//uart_tx tx;
//tx = new();
task run();

//uart_tx tx = new();
repeat (8)
begin
uart_tx tx = new();
case(uart_common::testname)
//randcase

"no_parity1":begin
assert(tx.randomize() with {tx.parity_en ==0; tx.parity_type ==0;tx.prescale ==`PRESCA
LE;});
uart_common::gen2bfm.put(tx);
end

"no_parity2":begin
assert(tx.randomize() with {tx.parity_en ==0; tx.parity_type ==1;tx.prescale ==`PRESCA
LE;});
uart_common::gen2bfm.put(tx);
end

"even_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==0;tx.prescale ==`PRESCA
LE;});
uart_common::gen2bfm.put(tx);
end

"no_stop_with_no_parity":begin
assert(tx.randomize() with {tx.parity_en ==0; tx.parity_type ==1;tx.prescale ==`PRESCA
LE;pd_in[9]==0;});
uart_common::gen2bfm.put(tx);
end

"no_stop_with_even_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==0;tx.prescale ==`PRESCA
LE;pd_in[10]==0;});
uart_common::gen2bfm.put(tx);
end

"no_stop_with_odd_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==1;tx.prescale ==`PRESCA
LE;pd_in[10]==0;});
uart_common::gen2bfm.put(tx);
end

"odd_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==1;tx.prescale ==`PRESCA
LE;});
uart_common::gen2bfm.put(tx);
end

"no_start":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==1;tx.prescale ==`PRESCA
LE;pd_in[0]==1;});
uart_common::gen2bfm.put(tx);
end

endcase
#(`PRESCALE*100);

76
uart_gen.sv Page 2

end
endtask

endclass

77
uart_bfm.sv Page 1

class uart_bfm;

uart_tx tx;

virtual uart_intf#(`D_WIDTH ,`P_WIDTH) vif;


function new();
vif = top.pif;
endfunction

task run();
forever begin
uart_common::gen2bfm.get(tx);
uart_drive(tx);
end
endtask

task uart_drive(uart_tx tx);

foreach(tx.pd_in[i])begin
@(vif.bfm_cb) begin
vif.bfm_cb.s_data <= tx.pd_in[i] ;
vif.bfm_cb.parity_type <= tx.parity_type ;
vif.bfm_cb.parity_en <= tx.parity_en ;
vif.bfm_cb.prescale <= tx.prescale ;
vif.pd_in <= tx.pd_in ;
tx.p_data <= vif.bfm_cb.p_data ;
tx.valid_data <= vif.bfm_cb.valid_data;
repeat(`PRESCALE-1) begin
@(vif.bfm_cb);
end
end
end
endtask

endclass

78
uart_mon.sv Page 1

class uart_mon;
uart_tx tx;
virtual uart_intf #(`D_WIDTH) vif;

function new();
vif = top.pif;
endfunction
task run();
forever begin
//wait(vif.mon_cb.busy==1);
@(vif.mon_cb)begin
tx = new();
tx.s_data = vif.mon_cb.s_data ;
tx.prescale = vif.mon_cb.prescale ;
tx.parity_en = vif.mon_cb.parity_en ;
tx.parity_type = vif.mon_cb.parity_type;
tx.pd_in = vif.pd_in ;
tx.p_data = vif.mon_cb.p_data ;
tx.valid_data = vif.mon_cb.valid_data ;

if(vif.mon_cb.valid_data==1) begin
//tx.print("Monitor");
//tx.data_print("Monitor");
end
//else begin
//tx.data_print("Monitor");
//end

end
uart_common::mon2sbd.put(tx);
uart_common::mon2cov.put(tx);
end
endtask
endclass

79
uart_cov.sv Page 1

class uart_cov;

uart_tx tx;

covergroup uart_cg;
// option.per_instance = 1;

cov_valid_data : coverpoint tx.valid_data {


bins valid_data_1_0[] = (1'b1=>1'b0);
bins valid_data_0_1[] = (1'b0=>1'b1);
}

cov_busy_check : coverpoint tx.s_data {


bins s_data_1_0[] = (1'b1=>1'b0);
bins s_data_0_1[] = (1'b0=>1'b1);
}

cov_parity_en : coverpoint tx.parity_en {


bins parity_en_yes[] = {1'b1};
bins parity_en_no[] = {1'b0};
}

cov_parity_type : coverpoint tx.parity_type {


bins parity_type_odd[] = {1'b1};
bins parity_type_even[] = {1'b0};
}

//CROSS_COVERAGE1:cross cov_valid_data ,cov_parity_en , cov_parity_type;


//CROSS_COVERAGE2:cross cov_busy_check ,cov_parity_en , cov_parity_type;

endgroup

function new();
uart_cg = new();
endfunction

task run();
forever begin
uart_common::mon2cov.get(tx);
uart_cg.sample();
end
endtask

endclass

80
uart_sbd.sv Page 1

class uart_sbd;

uart_tx tx;

///run method of task run


task run();

forever begin

uart_common::mon2sbd.get(tx);
if(tx.valid_data==1) begin
if(tx.pd_in[1] == tx.p_data[0]&&
tx.pd_in[2] == tx.p_data[1]&&
tx.pd_in[3] == tx.p_data[2]&&
tx.pd_in[4] == tx.p_data[3]&&
tx.pd_in[5] == tx.p_data[4]&&
tx.pd_in[6] == tx.p_data[5]&&
tx.pd_in[7] == tx.p_data[6]&&
tx.pd_in[8] == tx.p_data[7])begin
tx.data_print("ScoreBoard");
$display("Recieved Data correctly from testname : %0s\n",uart_common::testname);
end
else begin
tx.data_print("ScoreBoard");
$display("Recieved Data wrong from testname : %0s\n",uart_common::testname);
end
end
else begin
//$display("Recieved Data wrong/not yet recieved from testname : %0s\n",uart_common::t
estname);
end
end
endtask

endclass

81
uart_rx_sv.log Page 1

# vsim -voptargs="+acc" top -l uart_rx_sv.log


# Start time: 10:25:05 on Dec 25,2024
# ** Note: (vsim-3812) Design is being optimized...
# ** Note: (vopt-143) Recognized 1 FSM in module "rx_fsm(fast)".
# Loading sv_std.std
# Loading work.list_sv_unit(fast)
# Loading work.top(fast)
# Loading work.uart_reciever(fast)
# Loading work.data_sampling(fast)
# Loading work.deserializer(fast)
# Loading work.edge_bit_counter(fast)
# Loading work.rx_fsm(fast)
# Loading work.start_check(fast)
# Loading work.parity_check(fast)
# Loading work.stop_check(fast)
# Loading work.uart_intf(fast)
# Loading work.uart_intf(fast)
# The Print Statement is from ###ScoreBoard###
# Given_data = 0 0 1 0 1 1 0 0 <=> Recieved_data = 00101100
# Recieved Data correctly from testname : even_parity
#
# The Print Statement is from ###ScoreBoard###
# Given_data = 1 0 0 1 1 0 0 0 <=> Recieved_data = 10011000
# Recieved Data correctly from testname : no_parity1
#
# The Print Statement is from ###ScoreBoard###
# Given_data = 0 1 0 0 1 0 0 1 <=> Recieved_data = 01001001
# Recieved Data correctly from testname : odd_parity
#
# The Print Statement is from ###ScoreBoard###
# Given_data = 0 0 1 0 1 1 0 0 <=> Recieved_data = 00101100
# Recieved Data correctly from testname : no_parity2
#
# ** Note: $finish : uart_top.sv(62)
# Time: 6400 ns Iteration: 0 Instance: /top
# 1
# Break in Module top at uart_top.sv line 62
quit
# End time: 10:55:23 on Dec 25,2024, Elapsed time: 0:30:18
# Errors: 0, Warnings: 0

82
83
84
list.sv Page 1

//include necessary uvm pkages


`include "uvm_pkg.sv"
import uvm_pkg::*;

`include "uart_common.sv"
`include "uart_reciever.v"
`include "uart_tx.sv"
`include "uart_intf.sv"
`include "uart_cov.sv"
`include "uart_driver.sv"
`include "uart_monitor.sv"
`include "uart_sqr.sv"
`include "uart_agent.sv"
`include "uart_sbd.sv"
`include "uart_env.sv"
`include "uart_seq_lib.sv"
`include "uart_test_lib.sv"
`include "top.sv"

85
uart_common.sv Page 1

`define D_WIDTH 8
`define P_WIDTH 6
`define TIME_PERIOD 8
`define PRESCALE 8
`define NEW_OBJ function new(string name="");\
super.new(name);\
endfunction

`define NEW_COMP function new(string name="",uvm_component parent);\


super.new(name,parent);\
endfunction

86
uart_tx.sv Page 1

//--------------- uart_tx ---------------//


class uart_tx extends uvm_sequence_item;//uart_tx is also a object
//propery/fields
rand logic pd_in[$] ;
bit s_data ;
rand bit parity_type ;
rand bit parity_en ;
rand bit [`P_WIDTH-1:0] prescale ;
bit [`D_WIDTH-1:0] p_data ;
bit valid_data ;

bit [`D_WIDTH-1:0]actual_p_data;

//1. factory registeration + field registeration


`uvm_object_utils_begin(uart_tx)
`uvm_field_queue_int(pd_in ,UVM_ALL_ON )
`uvm_field_int(s_data ,UVM_ALL_ON )
`uvm_field_int(parity_type ,UVM_ALL_ON )
`uvm_field_int(parity_en ,UVM_ALL_ON )
`uvm_field_int(prescale ,UVM_ALL_ON )
`uvm_field_int(p_data ,UVM_ALL_ON )
`uvm_field_int(valid_data ,UVM_ALL_ON )
`uvm_field_int(actual_p_data ,UVM_ALL_ON )
`uvm_object_utils_end

//methods
//constraints

constraint pd_in_size {

(parity_en ==0) -> (pd_in.size()==10);


(parity_en ==1) -> (pd_in.size()==11);

constraint start_stop_bit {
soft pd_in[0]==0;//start_bit
soft (parity_en ==0) -> (pd_in[9]==1); //for stop_bit
soft (parity_en ==1) -> (pd_in[10]==1); //for stop_bit
}

constraint parity_generator{
if(parity_en==1)
{
(parity_type ==0)->(pd_in[9]==(pd_in[1]^pd_in[2]^pd_in[3]^pd_in[4]^pd_in[5]^pd_in[6]^p
d_in[7]^pd_in[8]));
(parity_type ==1)->(pd_in[9]==~(pd_in[1]^pd_in[2]^pd_in[3]^pd_in[4]^pd_in[5]^pd_in[6]^
pd_in[7]^pd_in[8]));
}
}

//function new
function new(string name="");
super.new(name);
endfunction

endclass

87
uart_intf.sv Page 1

interface uart_intf#(parameter DWIDTH = 8, parameter PWIDTH = 6)(input clk,rst);


logic s_data;
logic parity_type;
logic parity_en;
logic [PWIDTH-1:0] prescale;
logic [DWIDTH-1:0] p_data;
logic valid_data;
logic pd_in[$];

clocking bfm_cb @(posedge clk);

default input #0 output #1;

input valid_data;
input p_data;
output prescale;
output parity_en;
output parity_type;
output s_data;

endclocking

clocking mon_cb @(posedge clk);

default input #0 output #1;

input valid_data;
input p_data;
input prescale;
input parity_en;
input parity_type;
input s_data;

endclocking

endinterface

88
top.sv Page 1

//---------------------- top.sv file -----------------------//

//top module declaration


module top;
//clk rst decalration
bit clk,rst;

uart_reciever #(`D_WIDTH, `P_WIDTH) dut (


.clk(pif.clk),
.rst(pif.rst),
.s_data(pif.s_data),
.parity_type(pif.parity_type),
.parity_en(pif.parity_en),
.prescale(pif.prescale),
.p_data(pif.p_data),
.data_valid(pif.valid_data)
);
uart_intf#(`D_WIDTH , `P_WIDTH) pif(clk,rst);

initial begin
clk = 1'b0;
forever begin
#(`TIME_PERIOD/2) clk = ~ clk;
end
end

initial begin
rst = 0;
repeat(2) @(posedge clk);
rst = 1;
end

initial begin
uvm_config_db#(virtual uart_intf)::set(null, "*", "VIF",pif);
//run_test("uart_base_test");
// run_test("uart_no_parity1_test");
// run_test("uart_no_parity2_test");
// run_test("uart_even_parity_test");
run_test("uart_odd_parity_test");
end

initial begin
$dumpfile("dump.vcd");
$dumpvars;
end

endmodule

89
uart_env.sv Page 1

//---------------- uart_env -----------------//


class uart_env extends uvm_env;
//1. factory registeration
`uvm_component_utils(uart_env)

//2. sub_compoennt instantiation


uart_agent uart_agent_h;

uart_sbd uart_sbd_h;

//3. function new defination wrt components


function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE ",UVM_NONE)
uart_agent_h = uart_agent::type_id::create("uart_agent_h",this);
uart_sbd_h = uart_sbd::type_id::create("uart_sbd_h",this);
endfunction

//connect_phase
function void connect_phase(uvm_phase phase);
//connect agent.mon to sbd
uart_agent_h.uart_mon_h.mon_ap.connect(uart_sbd_h.uart_imp_port);

endfunction
endclass

90
uart_agent.sv Page 1

//--------------- uart_agent -----------------//


class uart_agent extends uvm_agent;
//1. factory registeration
`uvm_component_utils(uart_agent)

//2. sub_compoennt instantiation


uart_sqr uart_sqr_h;
uart_driver uart_drv_h;
uart_monitor uart_mon_h;
uart_cov uart_cov_h;

//3. function new defination wrt components


function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE",UVM_NONE)
uart_sqr_h = uart_sqr::type_id::create("uart_sqr_h",this);
uart_drv_h = uart_driver::type_id::create("uart_drv_h",this);
uart_mon_h = uart_monitor::type_id::create("uart_mon_h",this);
uart_cov_h = uart_cov::type_id::create("uart_cov_h",this);
endfunction

//connect_phase
function void connect_phase(uvm_phase phase);
`uvm_info(get_name,"CONNECT_PHASE of uart_agent",UVM_NONE)
uart_drv_h.seq_item_port.connect(uart_sqr_h.seq_item_export);
//driver and sqr connections are 1 to 1
//mon to cov connection
uart_mon_h.mon_ap.connect(uart_cov_h.analysis_export);
endfunction

endclass

91
uart_sqr.sv Page 1

//--------------- uart_sqr -----------------//


typedef uvm_sequencer#(uart_tx) uart_sqr;

92
uart_test_lib.sv Page 1

//----------------------- uart_base_test -------------------//


class uart_base_test extends uvm_test;
`uvm_component_utils(uart_base_test)

`NEW_COMP

//2. sub_compoennt instantiation


uart_env uart_env_h;

function void build_phase(uvm_phase phase);


super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE ",UVM_NONE)
uart_env_h = uart_env::type_id::create("uart_env_h",this);
endfunction

//end_of_elaboration_phase
function void end_of_elaboration_phase(uvm_phase phase);
`uvm_info(get_name,"END_OF_ELABORATION_PHASE ",UVM_NONE)
uvm_top.print_topology();//tb structure print
endfunction

task run_phase(uvm_phase phase);


`uvm_info(get_name(),"running just uart_base_test No tx are driven in this test to
DUT",UVM_NONE)
endtask

//report_phase
function void report_phase(uvm_phase phase);
`uvm_info(get_name(),"REPORT_PHASE of uart_test",UVM_NONE)
endfunction

endclass

//-------------------uart_complete_all_parity_test -------------------------//
class uart_complete_all_parity_test extends uart_base_test;
`uvm_component_utils(uart_complete_all_parity_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity1 no_parity1;
uart_odd_parity odd_parity;
uart_no_parity2 no_parity2;
uart_even_parity even_parity;

no_parity1 = uart_no_parity1::type_id::create("no_parity1");
no_parity2 = uart_no_parity2::type_id::create("no_parity2");
even_parity = uart_even_parity::type_id::create("even_parity");
odd_parity = uart_odd_parity::type_id::create("odd_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
no_parity1.start(uart_env_h.uart_agent_h.uart_sqr_h);
no_parity2.start(uart_env_h.uart_agent_h.uart_sqr_h);
even_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);
odd_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);

93
uart_test_lib.sv Page 2

phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_no_parity_test1 -------------------------//
class uart_no_parity1_test extends uart_base_test;
`uvm_component_utils(uart_no_parity1_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity1 no_parity1;

no_parity1 = uart_no_parity1::type_id::create("no_parity1");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);

no_parity1.start(uart_env_h.uart_agent_h.uart_sqr_h);

phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_no_parity_test2 -------------------------//
class uart_no_parity2_test extends uart_base_test;
`uvm_component_utils(uart_no_parity2_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity2 no_parity2;

no_parity2 = uart_no_parity2::type_id::create("no_parity2");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);

no_parity2.start(uart_env_h.uart_agent_h.uart_sqr_h);

phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_even_parity_test -------------------------//
class uart_even_parity_test extends uart_base_test;
`uvm_component_utils(uart_even_parity_test)

94
uart_test_lib.sv Page 3

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_even_parity even_parity;

even_parity = uart_even_parity::type_id::create("even_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
even_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_odd_parity_test -------------------------//
class uart_odd_parity_test extends uart_base_test;
`uvm_component_utils(uart_odd_parity_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_odd_parity odd_parity;

odd_parity = uart_odd_parity::type_id::create("odd_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
odd_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

95
uart_seq_lib.sv Page 1

//-------------- uart_base_seq ---------------//


class uart_base_seq extends uvm_sequence#(uart_tx);
//1. factory registeration
`uvm_object_utils(uart_base_seq)

`NEW_OBJ

uvm_phase phase;

task pre_body();
//raise the objections
phase = get_starting_phase();
if(phase != null) begin
`uvm_info(get_name(),"PREBODY PHASE IS NOT NULL",UVM_NONE)
phase.raise_objection(this);
end
endtask

task body();
`uvm_info(get_name(),"BODY With nothing",UVM_NONE)
endtask

task post_body();
//raise the objections
phase = get_starting_phase();
if(phase != null) begin
`uvm_info(get_name(),"POSTBODY PHASE IS NOT NULL",UVM_NONE)
phase.phase_done.set_drain_time(this,50);
phase.drop_objection(this);
end
endtask
endclass

//-------------------- uart_no_parity1--------------------//
class uart_no_parity1 extends uart_base_seq;
`uvm_object_utils(uart_no_parity1)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==0; req.parity_type ==0;req.prescale ==`PRESC
ALE;})
endtask

endclass

//-------------------- uart_no_parity2--------------------//
class uart_no_parity2 extends uart_base_seq;
`uvm_object_utils(uart_no_parity2)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==0; req.parity_type ==1;req.prescale ==`PRESC
ALE;})
endtask

endclass

//-------------------- uart_even_parity--------------------//
class uart_even_parity extends uart_base_seq;
`uvm_object_utils(uart_even_parity)

`NEW_OBJ

96
uart_seq_lib.sv Page 2

task body();
`uvm_do_with(req,{req.parity_en ==1; req.parity_type ==0;req.prescale ==`PRESC
ALE;})
endtask

endclass

//-------------------- uart_odd_parity--------------------//
class uart_odd_parity extends uart_base_seq;
`uvm_object_utils(uart_odd_parity)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==1; req.parity_type ==1;req.prescale ==`PRESC
ALE;})
endtask

endclass

97
uart_driver.sv Page 1

//--------------- uart_driver -----------------//


class uart_driver extends uvm_driver#(uart_tx);
//1. factory registeration
`uvm_component_utils(uart_driver)

//virtual interface instantiation


virtual uart_intf vif;

//3. function new defination wrt components


`NEW_COMP

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE",UVM_NONE)
//In SV - vif = top.pif;
if(!(uvm_config_db#(virtual uart_intf)::get(this, "", "VIF", vif))) begin
`uvm_error(get_name(), "FAILED TO RETRIVE INTERFACE HANDLE FROM CONFIG DB")
end
else begin
`uvm_info(get_name(),"RETRIVED INTERFACE HANDLE FROM CONFIG DB",UVM_NONE)
end
endfunction

//run_phase
task run_phase(uvm_phase phase);
`uvm_info(get_name,"RUN_PHASE",UVM_NONE)
wait(vif.rst == 1);
forever begin
//1. driver needs to req item/tx from sqr
seq_item_port.get_next_item(req);//what is req -> handle of uart_tx
//2. print the tx
//req.print();//tx.print
//3. driver needs to drive the tx/item to dut usig interface
drive_tx(req);//user defined
//4. driver needs to send ack to sqr - indicating item done driving to DUT
seq_item_port.item_done();
end
endtask

//user defined method drive_tx


task drive_tx(uart_tx tx);
//implemnt uart driving logic

foreach(tx.pd_in[i])begin
@(vif.bfm_cb) begin
vif.bfm_cb.s_data <= tx.pd_in[i] ;
vif.bfm_cb.parity_type <= tx.parity_type ;
vif.bfm_cb.parity_en <= tx.parity_en ;
vif.bfm_cb.prescale <= tx.prescale ;
vif.pd_in <= tx.pd_in ;
tx.p_data <= vif.bfm_cb.p_data ;
tx.valid_data <= vif.bfm_cb.valid_data;
repeat(`PRESCALE-1) begin
@(vif.bfm_cb);
end
end
end

endtask
endclass

98
uart_monitor.sv Page 1

//---------------- uart_monitor ----------------//


class uart_monitor extends uvm_monitor;
`uvm_component_utils(uart_monitor)
`NEW_COMP
//virtual interface instantiation
virtual uart_intf vif;

//declare a analysis port


uvm_analysis_port#(uart_tx) mon_ap;

uart_tx tx;

//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name(),"BUILD_PHASE ",UVM_NONE)
tx = uart_tx::type_id::create("tx");
mon_ap = new("mon_ap",this);
if(!(uvm_config_db#(virtual uart_intf)::get(this, "", "VIF", vif))) begin
`uvm_error(get_name(), "FAILED TO RETRIVE INTERFACE HANDLE FROM CONFIG DB")
end
else begin
`uvm_info(get_name(),"RETRIVED INTERFACE HANDLE FROM CONFIG DB",UVM_NONE)
end

endfunction
//run_phase
task run_phase(uvm_phase phase);
`uvm_info(get_name(),"RUN_PHASE ",UVM_NONE)
forever begin

@(vif.mon_cb)begin
tx = new();
tx.s_data = vif.mon_cb.s_data ;
tx.prescale = vif.mon_cb.prescale ;
tx.parity_en = vif.mon_cb.parity_en ;
tx.parity_type = vif.mon_cb.parity_type;
tx.pd_in = vif.pd_in ;
tx.p_data = vif.mon_cb.p_data ;
tx.valid_data = vif.mon_cb.valid_data ;

if(vif.mon_cb.valid_data==1) begin
//tx.print("Monitor");
end
end

mon_ap.write(tx);
end

endtask

endclass

99
uart_cov.sv Page 1

//-------------------- uart_cov ------------------//


class uart_cov extends uvm_subscriber#(uart_tx);
`uvm_component_utils(uart_cov)

uart_tx tx;

//covergroup
covergroup cg;
// option.per_instance = 1;

cov_valid_data : coverpoint tx.valid_data {


bins valid_data_1_0[] = (1'b1=>1'b0);
bins valid_data_0_1[] = (1'b0=>1'b1);
}

cov_busy_check : coverpoint tx.s_data {


bins s_data_1_0[] = (1'b1=>1'b0);
bins s_data_0_1[] = (1'b0=>1'b1);
}

cov_parity_en : coverpoint tx.parity_en {


bins parity_en_yes[] = {1'b1};
bins parity_en_no[] = {1'b0};
}

cov_parity_type : coverpoint tx.parity_type {


bins parity_type_odd[] = {1'b1};
bins parity_type_even[] = {1'b0};
}

//CROSS_COVERAGE1:cross cov_valid_data ,cov_parity_en , cov_parity_type;


//CROSS_COVERAGE2:cross cov_busy_check ,cov_parity_en , cov_parity_type;

endgroup

function new(string name="",uvm_component parent);


super.new(name,parent);
//allocate memory for the covergroup
cg = new();
endfunction

//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction

endclass

100
uart_sbd.sv Page 1

//--------------- uart_sbd ------------------//


class uart_sbd extends uvm_scoreboard;
`uvm_component_utils(uart_sbd)

//declare a uvm_analysis_imp_port

uvm_analysis_imp#(uart_tx,uart_sbd) uart_imp_port;

uart_tx tx;

function new(string name="",uvm_component parent);


super.new(name,parent);
endfunction

function void build_phase(uvm_phase phase);


super.build_phase(phase);
uart_imp_port = new("uart_imp_port",this);
endfunction

function void write(uart_tx tx);


//collect the data store the wdata into the sbd associative array

if(tx.valid_data==1) begin
if(tx.pd_in[1] == tx.p_data[0]&&
tx.pd_in[2] == tx.p_data[1]&&
tx.pd_in[3] == tx.p_data[2]&&
tx.pd_in[4] == tx.p_data[3]&&
tx.pd_in[5] == tx.p_data[4]&&
tx.pd_in[6] == tx.p_data[5]&&
tx.pd_in[7] == tx.p_data[6]&&
tx.pd_in[8] == tx.p_data[7])begin
//tx.print("ScoreBoard");

`uvm_info(get_name(),$sformatf("PASSED : RECIEVED_CORRECT_DATA"),UVM_NONE)
`uvm_info(get_name(),$sformatf("Valid_data=%0b",tx.valid_data),UVM_NONE)
`uvm_info(get_name(),$sformatf("Random_Data=%0p",tx.pd_in),UVM_NONE)
`uvm_info(get_name(),$sformatf("Parity_enabled=%0S",tx.parity_en?"YES":"NO"),UVM_NONE)
`uvm_info(get_name(),$sformatf("Parity_type=%0S",tx.parity_type?"ODD":"EVEN"),UVM_NONE
)
`uvm_info(get_name(),$sformatf("Recieved_Parallel_data=%8b",tx.actual_p_data),UVM_NONE
)

end
else begin
//tx.print("ScoreBoard");

`uvm_error(get_name(),$sformatf("FAILED : RECIEVED_WRONG_DATA"))
`uvm_info(get_name(),$sformatf("Valid_data=%0b",tx.valid_data),UVM_NONE)
`uvm_info(get_name(),$sformatf("Random_Data=%0p",tx.pd_in),UVM_NONE)
`uvm_info(get_name(),$sformatf("Parity_enabled=%0S",tx.parity_en?"YES":"NO"),UVM_NONE)
`uvm_info(get_name(),$sformatf("Parity_type=%0S",tx.parity_type?"ODD":"EVEN"),UVM_NONE
)
`uvm_info(get_name(),$sformatf("Recieved_Parallel_data=%8b",tx.actual_p_data),UVM_NONE
)

end
end

endfunction

endclass

101
uart.v Page 1

`include "uart_transmitter.v"
`include "uart_reciever.v"

module uart #(parameter DWIDTH = 8, PWIDTH =6, PRESCALE = 8)


(clk_tx, clk_rx, rst, p_data_tx, data_valid_tx, parity_en, parity_type, busy_tx, p
_data_rx, data_valid_rx);

input clk_tx, clk_rx, rst;


input [DWIDTH-1:0] p_data_tx;
input data_valid_tx;
input parity_en, parity_type;
output busy_tx;
output [DWIDTH-1:0] p_data_rx;
output data_valid_rx;

wire s_data;

uart_transmitter #(DWIDTH) tx(


.clk(clk_tx),
.rst(rst),
.p_data(p_data_tx),
.valid_data(data_valid_tx),
.parity_en(parity_en),
.parity_type(parity_type),
.s_data(s_data),
.busy(busy_tx)
);
uart_reciever #(DWIDTH, PWIDTH) rx(
.clk(clk_rx),
.rst(rst),
.s_data(s_data),
.parity_type(parity_type),
.parity_en(parity_en),
.prescale(PRESCALE),
.p_data(p_data_rx),
.data_valid(data_valid_rx)
);
endmodule

102
clk_tx_IBUF_inst clk_tx_IBUF_BUFG_inst
I O I O
clk_tx
IBUF BUFG

data_valid_tx_IBUF_inst data_valid_rx_OBUF_inst
I O I O
data_valid_tx data_valid_rx
clk_rx_IBUF_inst clk_rx_IBUF_BUFG_inst IBUF tx OBUF
I O I O
clk_rx
CLK
IBUF BUFG rx
data_valid_tx_IBUF
busy_tx_OBUF_inst
parity_en_IBUF_inst clk_rx_IBUF_BUFG p_data_tx_IBUF[7:0] busy_tx_OBUF I O
I O busy_tx
parity_en parity_en_IBUF Q parity_en_IBUF s_data
OBUF
IBUF parity_type_IBUF p_data_rx_OBUF[7:0] parity_type_IBUF

rst_IBUF rst ser_done_reg p_data_rx_OBUF[0]_inst


parity_type_IBUF_inst I O
I O s_data p_data_rx[7:0]
parity_type uart_transmitter
OBUF
IBUF uart_reciever
p_data_rx_OBUF[1]_inst
rst_IBUF_inst I O
I O
rst
p_data_tx_IBUF[0]_inst OBUF
IBUF I O
p_data_tx[7:0] p_data_rx_OBUF[2]_inst
IBUF I O

p_data_tx_IBUF[1]_inst OBUF
I O
p_data_rx_OBUF[3]_inst
IBUF I O

p_data_tx_IBUF[2]_inst OBUF
I O
p_data_rx_OBUF[4]_inst
IBUF I O

p_data_tx_IBUF[3]_inst OBUF
I O
p_data_rx_OBUF[5]_inst
IBUF I O

p_data_tx_IBUF[4]_inst OBUF
I O
p_data_rx_OBUF[6]_inst
IBUF I O

p_data_tx_IBUF[5]_inst OBUF
I O
p_data_rx_OBUF[7]_inst
IBUF I O

p_data_tx_IBUF[6]_inst OBUF
I O

IBUF

p_data_tx_IBUF[7]_inst
I O

IBUF

103
tb_uart.v Page 1

`define TIMEPERIOD 8
module tb_uart();

// Parameters
parameter DWIDTH = 8;
parameter PWIDTH = 6;
parameter PRESCALE = 8;

// Testbench signals
reg clk_tx;
reg clk_rx;
reg rst;
reg [DWIDTH-1:0] p_data_tx;
reg data_valid_tx;
reg parity_en;
reg parity_type; // 0 for even, 1 for odd
wire busy_tx;
wire [DWIDTH-1:0] p_data_rx;
wire data_valid_rx;

// Clock generation
initial begin
clk_tx = 0;
forever begin
#(4*`TIMEPERIOD) clk_tx = ~clk_tx;
end
end

initial begin
clk_rx = 0;
forever begin
#(`TIMEPERIOD/2) clk_rx = ~clk_rx;
end
end

// DUT instantiation
uart #(DWIDTH, PWIDTH, PRESCALE) uut (
.clk_tx(clk_tx),
.clk_rx(clk_rx),
.rst(rst),
.p_data_tx(p_data_tx),
.data_valid_tx(data_valid_tx),
.parity_en(parity_en),
.parity_type(parity_type),
.busy_tx(busy_tx),
.p_data_rx(p_data_rx),
.data_valid_rx(data_valid_rx)
);

// Test sequence
initial begin
// Reset
rst = 0;
data_valid_tx = 0;
parity_en = 0;
parity_type = 0;
p_data_tx = 0;
#20 rst = 1;

$display("#########Testing no parity");
parity_en = 0;
parity_type = 0;
p_data_tx = 8'b10101010;

104
tb_uart.v Page 2

data_valid_tx = 1;
#100 data_valid_tx = 0;
#900;
$display("Given Data: %h", p_data_rx);
$display("Received Data: %h\n", p_data_rx);

$display("###########Testing no parity");
parity_en = 0;
parity_type = 1;
p_data_tx = 8'b01010101;
data_valid_tx = 1;
#100 data_valid_tx = 0;
#900;
$display("Given Data: %h", p_data_rx);
$display("Received Data: %h\n", p_data_rx);

$display("###########Testing even parity");


parity_en = 1;
parity_type = 0;
p_data_tx = 8'b10101010;
data_valid_tx = 1;
#100 data_valid_tx = 0;
#900;
$display("Given Data: %h", p_data_rx);
$display("Received Data: %h\n", p_data_rx);

$display("########Testing odd parity");


parity_en = 1;
parity_type = 1;
p_data_tx = 8'b01010101;
data_valid_tx = 1;
#100 data_valid_tx = 0;
#900;
$display("Given Data: %h", p_data_rx);
$display("Received Data: %h\n", p_data_rx);

$finish;
end
endmodule

105
106
list.sv Page 1

`include "uart.v"
`include "uart_common.sv"
`include "uart_intf.sv"
`include "uart_tx.sv"
`include "uart_sbd.sv"
`include "tx_uart_cov.sv"
`include "tx_uart_mon.sv"
`include "tx_uart_bfm.sv"
`include "rx_uart_cov.sv"
`include "rx_uart_mon.sv"
`include "rx_uart_bfm.sv"
`include "uart_gen.sv"
`include "uart_agent.sv"
`include "uart_env.sv"
`include "uart_top.sv"

107
uart_common.sv Page 1

`define D_WIDTH 8
`define P_WIDTH 32
`define TIME_PERIOD 8
`define PRESCALE 8
class uart_common;
static int count;

static mailbox gen2bfm = new();

static mailbox mon_tx2sbd = new();


static mailbox mon_tx2cov = new();

static mailbox mon_rx2sbd = new();


static mailbox mon_rx2cov = new();

static string testname;


endclass

108
uart_tx.sv Page 1

class uart_tx;

rand bit [`D_WIDTH-1:0] p_data_tx;


rand bit valid_data_tx;
rand bit parity_en;
rand bit parity_type;
bit busy_tx;
bit [`D_WIDTH-1:0] p_data_rx;
bit valid_data_rx;

function void tx_print(input string name="tx");

$display("The Print Statement is from ###%s###",name);


$display("Testname is ###%s###",uart_common::testname);
$display("Valid_data_tx = %0b",valid_data_tx);
$display("Given_Random_Data = %b",p_data_tx);
$display("Parity_enabled = %0S",parity_en?"YES":"NO");
$display("Parity_type = %0S",parity_type?"ODD":"EVEN");
$display("Is UART_Transmitter Busy Transmitting Data = %0S",busy_tx?"YES":"NO");

endfunction

function void rx_print(input string name="tx");

$display("The Print Statement is from ###%s###",name);


$display("Testname is ###%s###",uart_common::testname);
$display("Valid_data_rx = %0b",valid_data_rx);
$display("Recieved_Data = %b",p_data_rx);

endfunction

endclass

109
uart_intf.sv Page 1

interface uart_intf#(parameter DWIDTH = 8)(input clk_tx,clk_rx,rst);

logic [DWIDTH-1:0] p_data_tx;


logic valid_data_tx;
logic parity_en, parity_type;
logic busy_tx;
logic [DWIDTH-1:0] p_data_rx;
logic valid_data_rx;

clocking tx_bfm_cb @(posedge clk_tx);

default input #0 output #1;

output p_data_tx;
output valid_data_tx;
output parity_en, parity_type;
input busy_tx;

endclocking

clocking tx_mon_cb @(posedge clk_tx);

default input #0 output #1;

input p_data_tx;
input valid_data_tx;
input parity_en, parity_type;
input busy_tx;

endclocking

clocking rx_bfm_cb @(posedge clk_rx);

default input #0 output #1;

input p_data_rx;
input valid_data_rx;

endclocking

clocking rx_mon_cb @(posedge clk_rx);

default input #0 output #1;

input p_data_rx;
input valid_data_rx;

endclocking

endinterface

110
uart_top.sv Page 1

module top;
bit clk_tx,clk_rx;
bit rst;
uart_env env;
event e;

uart #(`D_WIDTH , `P_WIDTH , `PRESCALE )


dut (
.clk_tx (pif.clk_tx),
.clk_rx (pif.clk_rx),
.rst (pif.rst),
.p_data_tx (pif.p_data_tx),
.data_valid_tx(pif.valid_data_tx),
.parity_en (pif.parity_en),
.parity_type (pif.parity_type),
.busy_tx (pif.busy_tx),
.p_data_rx (pif.p_data_rx),
.data_valid_rx(pif.valid_data_rx)
);

uart_intf#(`D_WIDTH ) pif(clk_tx,clk_rx,rst);

initial begin
clk_tx = 1'b0;
forever begin
#(4*`TIME_PERIOD) clk_tx = ~ clk_tx; //((8*`TIME_PERIOD)/2) = (4*`TIME_PERIOD)
end
end

initial begin
clk_rx = 1'b0;
forever begin
#(`TIME_PERIOD/2) clk_rx = ~ clk_rx;
end
end

initial begin
rst = 1'b0;

repeat(2)
@(posedge clk_tx);

rst = 1'b1;
->e;
end

initial begin
wait(e.triggered);
env = new();
env.run();
end

initial begin
uart_common::testname = "even_parity";
#(`PRESCALE*200);
uart_common::testname = "odd_parity";
#(`PRESCALE*200);
uart_common::testname = "no_parity2";
#(`PRESCALE*200);
uart_common::testname = "no_parity1";
#(`PRESCALE*200);
$finish;

111
uart_top.sv Page 2

end
endmodule

112
uart_env.sv Page 1

class uart_env;

uart_agent agent;
uart_sbd sbd ;

task run();
agent = new();
sbd = new();

fork
agent.run();
sbd.run();
join
endtask

endclass

113
uart_agent.sv Page 1

class uart_agent ;

uart_gen gen ;
tx_uart_bfm tx_bfm ;
tx_uart_mon tx_mon ;
tx_uart_cov tx_cov ;
rx_uart_bfm rx_bfm ;
rx_uart_mon rx_mon ;
rx_uart_cov rx_cov ;

task run();
gen = new();
tx_bfm = new();
tx_mon = new();
tx_cov = new();
rx_bfm = new();
rx_mon = new();
rx_cov = new();

fork
gen.run();
tx_bfm.run();
tx_mon.run();
tx_cov.run();
rx_bfm.run();
rx_mon.run();
rx_cov.run();
join

endtask

endclass

114
uart_gen.sv Page 1

class uart_gen;

//uart_tx tx;
//tx = new();
task run();

//uart_tx tx = new();
repeat (9)
begin
uart_tx tx = new();
case(uart_common::testname)
//randcase

"no_parity1":begin
assert(tx.randomize() with {tx.parity_en ==0; tx.parity_type ==0;});
uart_common::gen2bfm.put(tx);
end

"no_parity2":begin
assert(tx.randomize() with {tx.parity_en ==0; tx.parity_type ==1;});
uart_common::gen2bfm.put(tx);
end

"even_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==0;});
uart_common::gen2bfm.put(tx);
end

"odd_parity":begin
assert(tx.randomize() with {tx.parity_en ==1; tx.parity_type ==1;});
uart_common::gen2bfm.put(tx);
end

endcase
#(`PRESCALE*100);
end
endtask

endclass

115
tx_uart_bfm.sv Page 1

class tx_uart_bfm;

uart_tx tx;
virtual uart_intf#(`D_WIDTH) vif;
function new();
vif = top.pif;
endfunction
task run();
forever begin
uart_common::gen2bfm.get(tx);
uart_drive(tx);
end
endtask

task uart_drive(uart_tx tx);


if(!vif.tx_bfm_cb.busy_tx)
begin
repeat(2) begin
@(vif.tx_bfm_cb)
vif.tx_bfm_cb.p_data_tx <= tx.p_data_tx;
vif.tx_bfm_cb.parity_en <= tx.parity_en;
vif.tx_bfm_cb.parity_type <= tx.parity_type;
//vif.tx_bfm_cb.valid_data_tx <= 1'b1;
end
end
@(vif.tx_bfm_cb)
vif.tx_bfm_cb.valid_data_tx <= 1'b1;
@(vif.tx_bfm_cb) begin
tx.busy_tx = vif.tx_bfm_cb.busy_tx;
end

wait(vif.tx_bfm_cb.busy_tx==1)
@(vif.tx_bfm_cb)
vif.tx_bfm_cb.valid_data_tx <= 1'b0;

endtask

endclass

116
tx_uart_mon.sv Page 1

class tx_uart_mon;
uart_tx tx;
virtual uart_intf #(`D_WIDTH) vif;

function new();
vif = top.pif;
endfunction
task run();
forever begin

@(vif.tx_mon_cb)begin
tx = new();
tx.valid_data_tx = vif.tx_mon_cb.valid_data_tx ;
tx.parity_en = vif.tx_mon_cb.parity_en ;
tx.parity_type = vif.tx_mon_cb.parity_type ;
tx.p_data_tx = vif.tx_mon_cb.p_data_tx ;
tx.busy_tx = vif.tx_mon_cb.busy_tx ;

//tx.tx_print("Tx_Monitor");
end
uart_common::mon_tx2sbd.put(tx);
uart_common::mon_tx2cov.put(tx);
end
endtask
endclass

117
tx_uart_cov.sv Page 1

class tx_uart_cov;

uart_tx tx;

covergroup uart_cg;
// option.per_instance = 1;

cov_valid_data_tx : coverpoint tx.valid_data_tx {


bins valid_data_tx_1_0[] = (1'b1=>1'b0);
bins valid_data_tx_0_1[] = (1'b0=>1'b1);
}

cov_busy_tx_check : coverpoint tx.busy_tx {


bins busy_tx_1_0[] = (1'b1=>1'b0);
bins busy_tx_0_1[] = (1'b0=>1'b1);
}

cov_parity_en : coverpoint tx.parity_en {


bins parity_en_yes[] = {1'b1};
bins parity_en_no[] = {1'b0};
}

cov_parity_type : coverpoint tx.parity_type {


bins parity_type_odd[] = {1'b1};
bins parity_type_even[] = {1'b0};
}

//CROSS_COVERAGE1:cross cov_valid_data_tx ,cov_parity_en , cov_parity_type;


//CROSS_COVERAGE2:cross cov_busy_tx_check ,cov_parity_en , cov_parity_type;

endgroup

function new();
uart_cg = new();
endfunction

task run();
forever begin
uart_common::mon_tx2cov.get(tx);
uart_cg.sample();
end
endtask

endclass

118
rx_uart_bfm.sv Page 1

class rx_uart_bfm;

uart_tx tx;

virtual uart_intf#(`D_WIDTH ) vif;


function new();
vif = top.pif;
endfunction

task run();
forever begin
uart_common::gen2bfm.get(tx);
uart_drive(tx);
end
endtask

task uart_drive(uart_tx tx);

@(vif.rx_bfm_cb) begin

tx.p_data_rx = vif.rx_bfm_cb.p_data_rx ;
tx.valid_data_rx = vif.rx_bfm_cb.valid_data_rx;

end
endtask

endclass

119
rx_uart_mon.sv Page 1

class rx_uart_mon;
uart_tx tx;
virtual uart_intf #(`D_WIDTH) vif;

function new();
vif = top.pif;
endfunction
task run();
forever begin
//wait(vif.rx_mon_cb.busy==1);
@(vif.rx_mon_cb)begin
tx = new();

tx.p_data_rx = vif.rx_mon_cb.p_data_rx ;
tx.valid_data_rx = vif.rx_mon_cb.valid_data_rx ;

if(vif.rx_mon_cb.valid_data_rx==1) begin
//$display("Given Random Data = %b",vif.tx_mon_cb.p_data_tx);
//tx.rx_print("Rx_Monitor");
end
//else begin
//tx.data_print("Monitor");
//end

end
uart_common::mon_rx2cov.put(tx);
uart_common::mon_rx2sbd.put(tx);
end
endtask
endclass

120
rx_uart_cov.sv Page 1

class rx_uart_cov;

uart_tx tx1;

covergroup uart_cg1;
// option.per_instance = 1;

cov_valid_data_rx : coverpoint tx1.valid_data_rx {

bins valid_data_rx_1_0[] = (1'b1=>1'b0);


bins valid_data_rx_0_1[] = (1'b0=>1'b1);

bins valid_data_rx_1[] = {1'b1};


bins valid_data_rx_0[] = {1'b0};

//CROSS_COVERAGE1:cross cov_valid_data_rx ,cov_parity_en , cov_parity_type;


//CROSS_COVERAGE2:cross cov_busy_check ,cov_parity_en , cov_parity_type;

endgroup

function new();
uart_cg1 = new();
endfunction

task run();
forever begin
uart_common::mon_rx2cov.get(tx1);
uart_cg1.sample();
end
endtask

endclass

121
uart_sbd.sv Page 1

class uart_sbd;

uart_tx tx;
uart_tx tx1;

bit past_busy_tx;
bit [`D_WIDTH-1:0] given_data[$];
bit [`D_WIDTH-1:0] recieved_data[$];
bit [`D_WIDTH-1:0] given_data_final;
bit [`D_WIDTH-1:0] recieved_data_final;

///run method of task run


task run();
// uart_tx tx;
// uart_tx tx1;
forever begin
uart_common::mon_tx2sbd.get(tx);
uart_common::mon_rx2sbd.get(tx1);
given_data.push_back(tx.p_data_tx);
recieved_data.push_back(tx.p_data_rx);
if((tx.busy_tx == 0 && past_busy_tx == 1)) begin
#200;
given_data_final=given_data.pop_back();
recieved_data_final=recieved_data.pop_back();
if(recieved_data_final == given_data_final)begin

$display("Generated/Given Data : %b => Recieved Data : %b",tx.p_data_tx ,tx1.p_data_rx


);
$display("Recieved Data correctly from testname : %0s",uart_common::testname);
//tx.tx_print("SBD");
//tx1.rx_print("SBD");

end
else begin

$display("Generated/Given Data : %b => Recieved Data : %b",tx.p_data_tx ,tx1.p_data_rx


);
$display("Recieved Data wrong/not yet recieved from testname : %0s",uart_common::testn
ame);
end
end
past_busy_tx = tx.busy_tx;
end
endtask

endclass

122
123
124
list.sv Page 1

//include necessary uvm pkages


`include "uvm_pkg.sv"
import uvm_pkg::*;

`include "uart_common.sv"
`include "uart.v"
`include "uart_tx.sv"
`include "uart_intf.sv"
`include "tx_uart_cov.sv"
`include "tx_uart_driver.sv"
`include "tx_uart_monitor.sv"
`include "rx_uart_cov.sv"
`include "rx_uart_monitor.sv"
`include "uart_sqr.sv"
`include "uart_agent.sv"
`include "uart_sbd.sv"
`include "uart_env.sv"
`include "uart_seq_lib.sv"
`include "uart_test_lib.sv"
`include "top.sv"

125
uart_common.sv Page 1

`define D_WIDTH 8
`define P_WIDTH 6
`define TIME_PERIOD 8
`define PRESCALE 8

`define NEW_OBJ function new(string name="");\


super.new(name);\
endfunction

`define NEW_COMP function new(string name="",uvm_component parent);\


super.new(name,parent);\
endfunction

126
uart_tx.sv Page 1

//--------------- uart_tx ---------------//


class uart_tx extends uvm_sequence_item;//uart_tx is also a object
//propery/fields
rand bit [`D_WIDTH-1:0] p_data_tx;
rand bit valid_data_tx ;
rand bit parity_en ;
rand bit parity_type ;
bit busy_tx ;
bit [`D_WIDTH-1:0] p_data_rx;
bit valid_data_rx ;

//1. factory registeration + field registeration


`uvm_object_utils_begin(uart_tx)
`uvm_field_int(p_data_tx ,UVM_ALL_ON )
`uvm_field_int(valid_data_tx,UVM_ALL_ON )
`uvm_field_int(parity_en ,UVM_ALL_ON )
`uvm_field_int(parity_type ,UVM_ALL_ON )
`uvm_field_int(busy_tx ,UVM_ALL_ON )
`uvm_field_int(p_data_rx ,UVM_ALL_ON )
`uvm_field_int(valid_data_rx,UVM_ALL_ON )
`uvm_object_utils_end

//methods
//constraints

//function new
function new(string name="");
super.new(name);
endfunction

endclass

127
uart_intf.sv Page 1

interface uart_intf#(parameter DWIDTH = 8)(input clk_tx,clk_rx,rst);

logic [DWIDTH-1:0] p_data_tx;


logic valid_data_tx;
logic parity_en, parity_type;
logic busy_tx;
logic [DWIDTH-1:0] p_data_rx;
logic valid_data_rx;

clocking tx_bfm_cb @(posedge clk_tx);

default input #0 output #1;

output p_data_tx;
output valid_data_tx;
output parity_en, parity_type;
input busy_tx;

endclocking

clocking tx_mon_cb @(posedge clk_tx);

default input #0 output #1;

input p_data_tx;
input valid_data_tx;
input parity_en, parity_type;
input busy_tx;

endclocking

clocking rx_bfm_cb @(posedge clk_rx);

default input #0 output #1;

input p_data_rx;
input valid_data_rx;

endclocking

clocking rx_mon_cb @(posedge clk_rx);

default input #0 output #1;

input p_data_rx;
input valid_data_rx;

endclocking

endinterface

128
top.sv Page 1

//---------------------- top.sv file -----------------------//

//top module declaration


module top;
//clk rst decalration
bit clk_tx,clk_rx,rst;

uart #(`D_WIDTH , `P_WIDTH , `PRESCALE )


dut (
.clk_tx (pif.clk_tx),
.clk_rx (pif.clk_rx),
.rst (pif.rst),
.p_data_tx (pif.p_data_tx),
.data_valid_tx(pif.valid_data_tx),
.parity_en (pif.parity_en),
.parity_type (pif.parity_type),
.busy_tx (pif.busy_tx),
.p_data_rx (pif.p_data_rx),
.data_valid_rx(pif.valid_data_rx)
);

uart_intf#(`D_WIDTH ) pif(clk_tx,clk_rx,rst);

initial begin
clk_tx = 1'b0;
forever begin
#(4*`TIME_PERIOD) clk_tx = ~ clk_tx; //((8*`TIME_PERIOD)/2) = (4*`TIME_PERIOD)
end
end

initial begin
clk_rx = 1'b0;
forever begin
#(`TIME_PERIOD/2) clk_rx = ~ clk_rx;
end
end

initial begin
rst = 0;
repeat(2) @(posedge clk_tx);
rst = 1;
end

initial begin
uvm_config_db#(virtual uart_intf)::set(null, "*", "VIF",pif);
//run_test("uart_base_test");
// run_test("uart_no_parity1_test");
// run_test("uart_no_parity2_test");
// run_test("uart_even_parity_test");
run_test("uart_odd_parity_test");
end
endmodule

129
uart_env.sv Page 1

//---------------- uart_env -----------------//


class uart_env extends uvm_env;
//1. factory registeration
`uvm_component_utils(uart_env)

//2. sub_compoennt instantiation


uart_agent uart_agent_h;

uart_sbd uart_sbd_h;

//3. function new defination wrt components


function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE ",UVM_NONE)
uart_agent_h = uart_agent::type_id::create("uart_agent_h",this);
uart_sbd_h = uart_sbd::type_id::create("uart_sbd_h",this);
endfunction

//connect_phase
function void connect_phase(uvm_phase phase);
//connect agent.mon to sbd
uart_agent_h.tx_uart_mon_h.tx_mon_ap.connect(uart_sbd_h.uart_tx_imp_port);
uart_agent_h.rx_uart_mon_h.rx_mon_ap.connect(uart_sbd_h.uart_rx_imp_port);

endfunction
endclass

130
uart_agent.sv Page 1

//--------------- uart_agent -----------------//


class uart_agent extends uvm_agent;
//1. factory registeration
`uvm_component_utils(uart_agent)

//2. sub_compoennt instantiation


uart_sqr uart_sqr_h;
tx_uart_driver tx_uart_drv_h;
tx_uart_monitor tx_uart_mon_h;
tx_uart_cov tx_uart_cov_h;
rx_uart_monitor rx_uart_mon_h;
rx_uart_cov rx_uart_cov_h;

//3. function new defination wrt components


function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE",UVM_NONE)
uart_sqr_h = uart_sqr::type_id::create("uart_sqr_h",this);
tx_uart_drv_h = tx_uart_driver::type_id::create("tx_uart_drv_h",this);
tx_uart_mon_h = tx_uart_monitor::type_id::create("tx_uart_mon_h",this);
tx_uart_cov_h = tx_uart_cov::type_id::create("tx_uart_cov_h",this);
rx_uart_mon_h = rx_uart_monitor::type_id::create("rx_uart_mon_h",this);
rx_uart_cov_h = rx_uart_cov::type_id::create("rx_uart_cov_h",this);

endfunction

//connect_phase
function void connect_phase(uvm_phase phase);
`uvm_info(get_name,"CONNECT_PHASE of uart_agent",UVM_NONE)
//tx_connections
tx_uart_drv_h.seq_item_port.connect(uart_sqr_h.seq_item_export);
tx_uart_mon_h.tx_mon_ap.connect(tx_uart_cov_h.analysis_export);
//rx_connections
rx_uart_mon_h.rx_mon_ap.connect(rx_uart_cov_h.analysis_export);

endfunction

endclass

131
uart_sqr.sv Page 1

//--------------- uart_sqr -----------------//


typedef uvm_sequencer#(uart_tx) uart_sqr;

132
uart_seq_lib.sv Page 1

//-------------- uart_base_seq ---------------//


class uart_base_seq extends uvm_sequence#(uart_tx);
//1. factory registeration
`uvm_object_utils(uart_base_seq)

`NEW_OBJ

uvm_phase phase;

task pre_body();
//raise the objections
phase = get_starting_phase();
if(phase != null) begin
`uvm_info(get_name(),"PREBODY PHASE IS NOT NULL",UVM_NONE)
phase.raise_objection(this);
end
endtask

task body();
`uvm_info(get_name(),"BODY With nothing",UVM_NONE)
endtask

task post_body();
//raise the objections
phase = get_starting_phase();
if(phase != null) begin
`uvm_info(get_name(),"POSTBODY PHASE IS NOT NULL",UVM_NONE)
phase.phase_done.set_drain_time(this,50);
phase.drop_objection(this);
end
endtask
endclass

//-------------------- uart_no_parity1--------------------//
class uart_no_parity1 extends uart_base_seq;
`uvm_object_utils(uart_no_parity1)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==0; req.parity_type ==0;})
endtask

endclass

//-------------------- uart_no_parity2--------------------//
class uart_no_parity2 extends uart_base_seq;
`uvm_object_utils(uart_no_parity2)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==0; req.parity_type ==1;})
endtask

endclass

//-------------------- uart_even_parity--------------------//
class uart_even_parity extends uart_base_seq;
`uvm_object_utils(uart_even_parity)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==1; req.parity_type ==0;})

133
uart_seq_lib.sv Page 2

endtask

endclass

//-------------------- uart_odd_parity--------------------//
class uart_odd_parity extends uart_base_seq;
`uvm_object_utils(uart_odd_parity)

`NEW_OBJ

task body();
`uvm_do_with(req,{req.parity_en ==1; req.parity_type ==1;})
endtask

endclass

134
uart_test_lib.sv Page 1

//----------------------- uart_base_test -------------------//


class uart_base_test extends uvm_test;
`uvm_component_utils(uart_base_test)

`NEW_COMP

//2. sub_compoennt instantiation


uart_env uart_env_h;

function void build_phase(uvm_phase phase);


super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE ",UVM_NONE)
uart_env_h = uart_env::type_id::create("uart_env_h",this);
endfunction

//end_of_elaboration_phase
function void end_of_elaboration_phase(uvm_phase phase);
`uvm_info(get_name,"END_OF_ELABORATION_PHASE ",UVM_NONE)
uvm_top.print_topology();//tb structure print
endfunction

task run_phase(uvm_phase phase);


`uvm_info(get_name(),"running just uart_base_test No tx are driven in this test to
DUT",UVM_NONE)
endtask

//report_phase
function void report_phase(uvm_phase phase);
`uvm_info(get_name(),"REPORT_PHASE of uart_test",UVM_NONE)
endfunction

endclass

//-------------------uart_complete_all_parity_test -------------------------//
class uart_complete_all_parity_test extends uart_base_test;
`uvm_component_utils(uart_complete_all_parity_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity1 no_parity1;
uart_odd_parity odd_parity;
uart_no_parity2 no_parity2;
uart_even_parity even_parity;

no_parity1 = uart_no_parity1::type_id::create("no_parity1");
no_parity2 = uart_no_parity2::type_id::create("no_parity2");
even_parity = uart_even_parity::type_id::create("even_parity");
odd_parity = uart_odd_parity::type_id::create("odd_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
no_parity1.start(uart_env_h.uart_agent_h.uart_sqr_h);
no_parity2.start(uart_env_h.uart_agent_h.uart_sqr_h);
even_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);
odd_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);

135
uart_test_lib.sv Page 2

phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_no_parity_test1 -------------------------//
class uart_no_parity1_test extends uart_base_test;
`uvm_component_utils(uart_no_parity1_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity1 no_parity1;

no_parity1 = uart_no_parity1::type_id::create("no_parity1");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);

no_parity1.start(uart_env_h.uart_agent_h.uart_sqr_h);

phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_no_parity_test2 -------------------------//
class uart_no_parity2_test extends uart_base_test;
`uvm_component_utils(uart_no_parity2_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_no_parity2 no_parity2;

no_parity2 = uart_no_parity2::type_id::create("no_parity2");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);

no_parity2.start(uart_env_h.uart_agent_h.uart_sqr_h);

phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_even_parity_test -------------------------//
class uart_even_parity_test extends uart_base_test;
`uvm_component_utils(uart_even_parity_test)

136
uart_test_lib.sv Page 3

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_even_parity even_parity;

even_parity = uart_even_parity::type_id::create("even_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
even_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

//-------------------uart_odd_parity_test -------------------------//
class uart_odd_parity_test extends uart_base_test;
`uvm_component_utils(uart_odd_parity_test)

`NEW_COMP

function void build_phase(uvm_phase phase);


super.build_phase(phase);
endfunction

task run_phase(uvm_phase phase);


uart_odd_parity odd_parity;

odd_parity = uart_odd_parity::type_id::create("odd_parity");

`uvm_info(get_name(),"RUN_PHASE START",UVM_NONE)
phase.raise_objection(this);
fork
odd_parity.start(uart_env_h.uart_agent_h.uart_sqr_h);

join
phase.phase_done.set_drain_time(this,200);
phase.drop_objection(this);
`uvm_info(get_name(),"RUN_PHASE END",UVM_NONE)
endtask

endclass

137
tx_uart_driver.sv Page 1

//--------------- uart_driver -----------------//


class tx_uart_driver extends uvm_driver#(uart_tx);
//1. factory registeration
`uvm_component_utils(tx_uart_driver)

//virtual interface instantiation


virtual uart_intf vif;

//3. function new defination wrt components


`NEW_COMP

//4. uvm_common_phases
//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name,"BUILD_PHASE",UVM_NONE)
//In SV - vif = top.pif;
if(!(uvm_config_db#(virtual uart_intf)::get(this, "", "VIF", vif))) begin
`uvm_error(get_name(), "FAILED TO RETRIVE INTERFACE HANDLE FROM CONFIG DB")
end
else begin
`uvm_info(get_name(),"RETRIVED INTERFACE HANDLE FROM CONFIG DB",UVM_NONE)
end
endfunction

//run_phase
task run_phase(uvm_phase phase);
`uvm_info(get_name,"RUN_PHASE",UVM_NONE)
wait(vif.rst == 1);
forever begin
//1. driver needs to req item/tx from sqr
seq_item_port.get_next_item(req);//what is req -> handle of uart_tx
//2. print the tx
//req.print();//tx.print
//3. driver needs to drive the tx/item to dut usig interface
drive_tx(req);//user defined
//4. driver needs to send ack to sqr - indicating item done driving to DUT
seq_item_port.item_done();
end
endtask

//user defined method drive_tx


task drive_tx(uart_tx tx);
fork
//tx_driver
begin
if(!vif.tx_bfm_cb.busy_tx)
begin
repeat(2) begin
@(vif.tx_bfm_cb)
vif.tx_bfm_cb.p_data_tx <= tx.p_data_tx;
vif.tx_bfm_cb.parity_en <= tx.parity_en;
vif.tx_bfm_cb.parity_type <= tx.parity_type;
//vif.tx_bfm_cb.valid_data_tx <= 1'b1;
end
end
@(vif.tx_bfm_cb)
vif.tx_bfm_cb.valid_data_tx <= 1'b1;
@(vif.tx_bfm_cb) begin
tx.busy_tx = vif.tx_bfm_cb.busy_tx;
end

wait(vif.tx_bfm_cb.busy_tx==1)
@(vif.tx_bfm_cb)
vif.tx_bfm_cb.valid_data_tx <= 1'b0;

138
tx_uart_driver.sv Page 2

end
//rx_driver
begin
@(vif.rx_bfm_cb) begin

tx.p_data_rx = vif.rx_bfm_cb.p_data_rx ;
tx.valid_data_rx = vif.rx_bfm_cb.valid_data_rx;
end
end
join

endtask
endclass

139
tx_uart_monitor.sv Page 1

//---------------- uart_monitor ----------------//


class tx_uart_monitor extends uvm_monitor;
`uvm_component_utils(tx_uart_monitor)
`NEW_COMP
//virtual interface instantiation
virtual uart_intf vif;

//declare a analysis port


uvm_analysis_port#(uart_tx) tx_mon_ap;

uart_tx tx;

//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name(),"BUILD_PHASE ",UVM_NONE)
tx = uart_tx::type_id::create("tx");
tx_mon_ap = new("tx_mon_ap",this);
if(!(uvm_config_db#(virtual uart_intf)::get(this, "", "VIF", vif))) begin
`uvm_error(get_name(), "FAILED TO RETRIVE INTERFACE HANDLE FROM CONFIG DB")
end
else begin
`uvm_info(get_name(),"RETRIVED INTERFACE HANDLE FROM CONFIG DB",UVM_NONE)
end

endfunction
//run_phase
task run_phase(uvm_phase phase);
`uvm_info(get_name(),"RUN_PHASE ",UVM_NONE)
forever begin

@(vif.tx_mon_cb)begin
tx = new();
tx.valid_data_tx = vif.tx_mon_cb.valid_data_tx ;
tx.parity_en = vif.tx_mon_cb.parity_en ;
tx.parity_type = vif.tx_mon_cb.parity_type ;
tx.p_data_tx = vif.tx_mon_cb.p_data_tx ;
tx.busy_tx = vif.tx_mon_cb.busy_tx ;

end
tx_mon_ap.write(tx);
end

endtask

endclass

140
tx_uart_cov.sv Page 1

//-------------------- uart_cov ------------------//


class tx_uart_cov extends uvm_subscriber#(uart_tx);
`uvm_component_utils(tx_uart_cov)

uart_tx tx;

//covergroup
covergroup cg;
// option.per_instance = 1;

cov_valid_data_tx : coverpoint tx.valid_data_tx {


bins valid_data_tx_1_0[] = (1'b1=>1'b0);
bins valid_data_tx_0_1[] = (1'b0=>1'b1);
}

cov_busy_tx_check : coverpoint tx.busy_tx {


bins busy_tx_1_0[] = (1'b1=>1'b0);
bins busy_tx_0_1[] = (1'b0=>1'b1);
}

cov_parity_en : coverpoint tx.parity_en {


bins parity_en_yes[] = {1'b1};
bins parity_en_no[] = {1'b0};
}

cov_parity_type : coverpoint tx.parity_type {


bins parity_type_odd[] = {1'b1};
bins parity_type_even[] = {1'b0};
}

//CROSS_COVERAGE1:cross cov_valid_data_tx ,cov_parity_en , cov_parity_type;


//CROSS_COVERAGE2:cross cov_busy_tx_check ,cov_parity_en , cov_parity_type;

endgroup

function new(string name="",uvm_component parent);


super.new(name,parent);
//allocate memory for the covergroup
cg = new();
endfunction

//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction

endclass

141
rx_uart_monitor.sv Page 1

//---------------- uart_monitor ----------------//


class rx_uart_monitor extends uvm_monitor;
`uvm_component_utils(rx_uart_monitor)
`NEW_COMP
//virtual interface instantiation
virtual uart_intf vif;

//declare a analysis port


uvm_analysis_port#(uart_tx) rx_mon_ap;

uart_tx tx;

//build_phase
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info(get_name(),"BUILD_PHASE ",UVM_NONE)
tx = uart_tx::type_id::create("tx");
rx_mon_ap = new("mon_ap",this);
if(!(uvm_config_db#(virtual uart_intf)::get(this, "", "VIF", vif))) begin
`uvm_error(get_name(), "FAILED TO RETRIVE INTERFACE HANDLE FROM CONFIG DB")
end
else begin
`uvm_info(get_name(),"RETRIVED INTERFACE HANDLE FROM CONFIG DB",UVM_NONE)
end

endfunction
//run_phase
task run_phase(uvm_phase phase);
`uvm_info(get_name(),"RUN_PHASE ",UVM_NONE)
forever begin

@(vif.rx_mon_cb)begin
tx = new();

tx.p_data_rx = vif.rx_mon_cb.p_data_rx ;
tx.valid_data_rx = vif.rx_mon_cb.valid_data_rx ;

end
rx_mon_ap.write(tx);
end

endtask

endclass

142
rx_uart_cov.sv Page 1

//-------------------- uart_cov ------------------//


class rx_uart_cov extends uvm_subscriber#(uart_tx);
`uvm_component_utils(rx_uart_cov)

uart_tx tx;

//covergroup
covergroup cg;
// option.per_instance = 1;

cov_valid_data_rx : coverpoint tx.valid_data_rx {

bins valid_data_rx_1_0[] = (1'b1=>1'b0);


bins valid_data_rx_0_1[] = (1'b0=>1'b1);

bins valid_data_rx_1[] = {1'b1};


bins valid_data_rx_0[] = {1'b0};

//CROSS_COVERAGE1:cross cov_valid_data_rx ,cov_parity_en , cov_parity_type;


//CROSS_COVERAGE2:cross cov_busy_check ,cov_parity_en , cov_parity_type;

endgroup

function new(string name="",uvm_component parent);


super.new(name,parent);
//allocate memory for the covergroup
cg = new();
endfunction

//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction

endclass

143
uart_sbd.sv Page 1

//--------------- uart_sbd ------------------//


class uart_sbd extends uvm_scoreboard;
`uvm_component_utils(uart_sbd)

//declare a uvm_analysis_imp_decl
`uvm_analysis_imp_decl(_tx_imp)
`uvm_analysis_imp_decl(_rx_imp)
uvm_analysis_imp_tx_imp#(uart_tx,uart_sbd) uart_tx_imp_port;
uvm_analysis_imp_rx_imp#(uart_tx,uart_sbd) uart_rx_imp_port;

uart_tx tx;
bit[`D_WIDTH-1:0]given_data[$];
bit[`D_WIDTH-1:0]recieved_data[$];
bit[`D_WIDTH-1:0]given_data_final;
bit[`D_WIDTH-1:0]recieved_data_final;
function new(string name="",uvm_component parent);
super.new(name,parent);
endfunction

function void build_phase(uvm_phase phase);


super.build_phase(phase);
uart_tx_imp_port = new("uart_tx_imp_port",this);
uart_rx_imp_port = new("uart_rx_imp_port",this);
endfunction

function void write_tx_imp(uart_tx tx);


given_data.push_back(tx.p_data_tx);
if(tx.valid_data_tx==1) begin
`uvm_info(get_name(),$sformatf("Given_Data = %b",tx.p_data_tx),UVM_NONE);
end
endfunction
function void write_rx_imp(uart_tx tx);
//compare the rcvd data(rdata) with sbd data
if(tx.valid_data_rx==1) begin
recieved_data.push_back(tx.p_data_rx);
`uvm_info(get_name(),$sformatf("Recieved_Data = %b",tx.p_data_rx),UVM_NONE);
recieved_data_final = recieved_data.pop_back();
given_data_final = given_data.pop_back();
begin
if(recieved_data_final==given_data_final)begin
`uvm_info(get_name(),$sformatf("PASSED : DATA RECIEVED CORRECTLY"),UVM_NONE);
end
else begin
`uvm_error(get_name(),$sformatf("FAILED : DATA RECIEVED WRONGLY"));
end
end
end
endfunction

endclass

144

You might also like