Uart Protocol Desing and Verificaton
Uart Protocol Desing and Verificaton
VERIFICATION OF
UART
==FULL _UART==
FULL_UART VERILOG DESIGN CODE - -102TO
• 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
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
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;
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
wire even_parity;
/*
module parity_test;
reg clk, rst;
reg [7:0]data;
reg parity_type;
wire 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;
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;
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;
localparam IDLE =0, START =1, DATA =2, PARITY =3, STOP =4;
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;
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;
// 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;
#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
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;
endclass
20
uart_intf.sv Page 1
output valid_data;
output parity_en;
output parity_type;
output p_data;
input s_data;
input busy;
endclocking
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
output valid_data;
output parity_en;
output parity_type;
output p_data;
input s_data;
input busy;
endclocking
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];
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}};
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);
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}};
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;
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
31
32
33
list.sv Page 1
`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
35
uart_tx.sv Page 1
//methods
//constraints
//function new
function new(string name="");
super.new(name);
endfunction
endclass
36
uart_intf.sv Page 1
output valid_data;
output parity_en;
output parity_type;
output p_data;
input s_data;
input busy;
endclocking
input valid_data;
input parity_en;
input parity_type;
input p_data;
input s_data;
input busy;
endclocking
endinterface
37
top.sv Page 1
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
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_sbd uart_sbd_h;
//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
//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
41
uart_test_lib.sv Page 1
`NEW_COMP
//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
//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
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
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
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
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
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
`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
//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
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_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_tx tx;
//covergroup
covergroup cg;
// option.per_instance = 1;
endgroup
//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction
endclass
50
uart_sbd.sv Page 1
//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];
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}};
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))
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
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}};
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
wire [PWIDTH-1:0]num_samples;
reg [PWIDTH-1:0]counter, ones, zeros;
54
edge_bit_counter.v Page 1
wire edge_counter_done;
55
parity_check.v Page 1
reg parity_bit;
56
rx_fsm.v Page 1
localparam IDLE =0, START =1, DATA =2, PARITY =3, STOP =4, CERROR =5, DVALID =6;
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;
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;
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;
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;
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;
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
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;
reg [DWIDTH-1:0]bit_index;
if(bit_index == DWIDTH)
bit_index <= 0;
end
endmodule
61
stop_check.v Page 1
62
uart_rx.v Page 1
output [DWIDTH-1:0]p_data;
output 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
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;
// 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;
#(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
// Data bits
for (i = 0; i < 8; i = i + 1) begin
s_data = data[i];
#(prescale * `TIMEPERIOD);
end
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;
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 {
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]));
}
}
endclass
71
uart_intf.sv Page 1
input valid_data;
input p_data;
output prescale;
output parity_en;
output parity_type;
output s_data;
endclocking
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;
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;
task run();
forever begin
uart_common::gen2bfm.get(tx);
uart_drive(tx);
end
endtask
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;
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;
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
82
83
84
list.sv Page 1
`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
86
uart_tx.sv Page 1
bit [`D_WIDTH-1:0]actual_p_data;
//methods
//constraints
constraint pd_in_size {
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
input valid_data;
input p_data;
output prescale;
output parity_en;
output parity_type;
output s_data;
endclocking
input valid_data;
input p_data;
input prescale;
input parity_en;
input parity_type;
input s_data;
endclocking
endinterface
88
top.sv Page 1
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_sbd uart_sbd_h;
//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
//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
92
uart_test_lib.sv Page 1
`NEW_COMP
//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
//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
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
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
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
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
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
`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
//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
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_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_tx tx;
//covergroup
covergroup cg;
// option.per_instance = 1;
endgroup
//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction
endclass
100
uart_sbd.sv Page 1
//declare a uvm_analysis_imp_port
uvm_analysis_imp#(uart_tx,uart_sbd) uart_imp_port;
uart_tx 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.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"
wire s_data;
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
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);
$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;
108
uart_tx.sv Page 1
class uart_tx;
endfunction
endfunction
endclass
109
uart_intf.sv Page 1
output p_data_tx;
output valid_data_tx;
output parity_en, parity_type;
input busy_tx;
endclocking
input p_data_tx;
input valid_data_tx;
input parity_en, parity_type;
input busy_tx;
endclocking
input p_data_rx;
input valid_data_rx;
endclocking
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_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
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;
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;
task run();
forever begin
uart_common::gen2bfm.get(tx);
uart_drive(tx);
end
endtask
@(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;
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;
end
else begin
endclass
122
123
124
list.sv Page 1
`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
126
uart_tx.sv Page 1
//methods
//constraints
//function new
function new(string name="");
super.new(name);
endfunction
endclass
127
uart_intf.sv Page 1
output p_data_tx;
output valid_data_tx;
output parity_en, parity_type;
input busy_tx;
endclocking
input p_data_tx;
input valid_data_tx;
input parity_en, parity_type;
input busy_tx;
endclocking
input p_data_rx;
input valid_data_rx;
endclocking
input p_data_rx;
input valid_data_rx;
endclocking
endinterface
128
top.sv Page 1
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_sbd uart_sbd_h;
//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
//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
132
uart_seq_lib.sv Page 1
`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
`NEW_COMP
//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
//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
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
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
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
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
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
//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
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_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_tx tx;
//covergroup
covergroup cg;
// option.per_instance = 1;
endgroup
//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction
endclass
141
rx_uart_monitor.sv Page 1
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_tx tx;
//covergroup
covergroup cg;
// option.per_instance = 1;
endgroup
//write method
virtual function void write(uart_tx t);
$cast(tx,t);
cg.sample();
endfunction
endclass
143
uart_sbd.sv Page 1
//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
endclass
144