diff --git a/Complete_UVM_environment_4x4_Router.docx b/Complete_UVM_environment_4x4_Router.docx new file mode 100644 index 0000000..4330986 Binary files /dev/null and b/Complete_UVM_environment_4x4_Router.docx differ diff --git a/Complete_UVM_environment_4x4_Router.pdf b/Complete_UVM_environment_4x4_Router.pdf new file mode 100644 index 0000000..89f8a50 Binary files /dev/null and b/Complete_UVM_environment_4x4_Router.pdf differ diff --git a/UVM_ALU.docx b/UVM_ALU.docx new file mode 100644 index 0000000..f66ae1f Binary files /dev/null and b/UVM_ALU.docx differ diff --git a/UVM_ALU.pdf b/UVM_ALU.pdf new file mode 100644 index 0000000..014b952 Binary files /dev/null and b/UVM_ALU.pdf differ diff --git a/UVM_Memory.docx b/UVM_Memory.docx new file mode 100644 index 0000000..066c09e Binary files /dev/null and b/UVM_Memory.docx differ diff --git a/UVM_Memory.pdf b/UVM_Memory.pdf new file mode 100644 index 0000000..bc95618 Binary files /dev/null and b/UVM_Memory.pdf differ diff --git a/config_sequence.sv.txt b/config_sequence.sv.txt new file mode 100644 index 0000000..0d2cce6 --- /dev/null +++ b/config_sequence.sv.txt @@ -0,0 +1,25 @@ +class config_sequence extends uvm_sequence#(packet); +`uvm_object_utils(config_sequence) + +function new (string name="config_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +task body(); + `uvm_create(req); + req.mode=REG_WRITE; + req.reg_addr=8'h20; //sa_port_csr + req.reg_data=8'b0000_1111; + start_item(req); + finish_item(req); + + `uvm_create(req); + req.mode=REG_WRITE; + req.reg_addr=8'h22;//da_port_csr + req.reg_data=8'b0000_1111; + start_item(req); + finish_item(req); + `uvm_info("CFG_SEQ","Config Sequence : Transaction DONE",UVM_MEDIUM); +endtask +endclass diff --git a/coverage.sv.txt b/coverage.sv.txt new file mode 100644 index 0000000..0cbbf38 --- /dev/null +++ b/coverage.sv.txt @@ -0,0 +1,43 @@ +class coverage extends uvm_subscriber#(packet); +`uvm_component_utils(coverage) + +packet pkt; +real coverage_score; + + covergroup cov_mem with function sample(packet pkt) ; + coverpoint pkt.sa { // Source Port Coverage + bins sa_0 = {0}; + bins sa_1 = {1}; + bins sa_2 = {2}; + bins sa_3 = {3}; + } + coverpoint pkt.da { // Destination POrt Measure coverage + bins da_0 = {0}; + bins da_1 = {1}; + bins da_2 = {2}; + bins da_3 = {3}; + } + cross pkt.sa,pkt.da; + endgroup + +function new (string name="coverage",uvm_component parent); +super.new(name,parent); +cov_mem=new; +endfunction + +virtual function void write( T t); + +if (!$cast(pkt,t.clone)) begin + `uvm_fatal("COV","Transaction object supplied is NULL in coverage component"); +end + +cov_mem.sample(pkt); +coverage_score=cov_mem.get_coverage(); +`uvm_info("COV",$sformatf("Coverage=%0f ",coverage_score),UVM_NONE); +endfunction + +virtual function void extract_phase(uvm_phase phase); +uvm_config_db#(real)::set(null,"uvm_test_top.env","cov_score",coverage_score); +endfunction + +endclass diff --git a/driver.sv.txt b/driver.sv.txt new file mode 100644 index 0000000..aee7040 --- /dev/null +++ b/driver.sv.txt @@ -0,0 +1,99 @@ +class driver extends uvm_driver#(packet); +`uvm_component_utils(driver) +bit [31:0] pkt_id; +virtual router_if.tb vif; + +function new (string name="driver",uvm_component parent); + super.new(name,parent); +endfunction + +extern virtual task run_phase(uvm_phase phase); +extern virtual function void build_phase(uvm_phase phase); +extern virtual task drive(ref packet pkt); +extern virtual task drive_pkt(input packet pkt); +extern virtual task drive_reset(input packet pkt); +extern virtual task drive_reg_write(input packet pkt); +extern virtual task drive_reg_read(ref packet pkt); +endclass + +task driver::run_phase(uvm_phase phase); +forever begin + seq_item_port.get_next_item(req); + pkt_id++; + `uvm_info("get_pkt",$sformatf("Driver Received %0s Transaction %0d from TLM port ",req.mode.name(),pkt_id),UVM_HIGH); + drive(req); + seq_item_port.item_done(); + `uvm_info("get_pkt",$sformatf("Driver Transaction %0d Done ",pkt_id),UVM_MEDIUM); +end +endtask + +function void driver::build_phase(uvm_phase phase); + super.build_phase(phase); + uvm_config_db#(virtual router_if.tb)::get(get_parent(),"","drvr_if",vif); + assert(vif != null) else + `uvm_fatal("VIF_ERR","Virtual interface in driver is NULL "); +endfunction + +task driver::drive(ref packet pkt); + case (pkt.mode) + RESET : drive_reset(pkt); + REG_WRITE : drive_reg_write(pkt); + REG_READ : drive_reg_read(pkt); + default : drive_pkt(pkt); + endcase +endtask + +task driver::drive_reset(input packet pkt); +`uvm_info("Reset_PKT","Applying Reset to DUT",UVM_MEDIUM); + vif.rst=1'b1; + for(bit[7:0] i=0;i<4;i++) + vif.cb.inp_vld[i] <= 1'b0; + repeat(5) @(vif.cb); + vif.rst=1'b0; + +`uvm_info("Reset_PKT","DUT is out of Reset ",UVM_MEDIUM); +endtask + +task driver::drive_reg_write(input packet pkt); +`uvm_info("Reg_Write","Register Write Operation Started ",UVM_MEDIUM); + @(vif.cb); + vif.cb.reg_wr <= 1'b1; + vif.cb.reg_addr <= pkt.reg_addr; + vif.cb.reg_din <= pkt.reg_data; + @(vif.cb); + vif.cb.reg_wr <= 1'b0; +`uvm_info("Reg_Write","Register Write Operation Ended ",UVM_MEDIUM); +endtask + +task driver::drive_reg_read(ref packet pkt); +`uvm_info("Reg_Write","Register Read Operation Started ",UVM_MEDIUM); + @(vif.cb); + vif.cb.reg_rd <= 1'b1; + vif.cb.reg_addr <= pkt.reg_addr; + @(vif.cb); + @(vif.cb); + pkt.reg_data= vif.cb.reg_dout; + vif.cb.reg_rd <= 1'b0; +`uvm_info("Reg_Write","Register Read Operation Ended ",UVM_MEDIUM); +endtask + +task driver::drive_pkt(input packet pkt); +bit [7:0] tot_pkt[$]; +bit [31:0] length; +length=pkt.tot_pkt.size(); +tot_pkt=pkt.tot_pkt; + @(vif.cb); +`uvm_info("DRV_PKT"," Drive operation started...",UVM_FULL); +`uvm_info("DRV_PKT",pkt.convert2string(),UVM_MEDIUM); +vif.cb.inp_vld[pkt.sa] <= 1'b1; +vif.cb.data_in[pkt.sa] <= tot_pkt.pop_front();//driving value of sa +@(vif.cb); +vif.cb.data_in[pkt.sa] <= tot_pkt.pop_front();//driving value of da +for (bit [31:0] i=2; i < length;i++) begin + @(vif.cb); + vif.cb.data_in[pkt.sa] <= tot_pkt.pop_front(); +end +vif.cb.inp_vld[pkt.sa] <= 1'b0; +repeat(5) @(vif.cb); +`uvm_info("DRV_PKT"," Drive operation Ended ...",UVM_FULL); +endtask diff --git a/duttop.sv.txt b/duttop.sv.txt new file mode 100644 index 0000000..d2cbeea --- /dev/null +++ b/duttop.sv.txt @@ -0,0 +1,82 @@ +module duttop ( +input logic clk, +input logic rst, +input logic [7:0] in1,in2,in3,in4, +input logic in1v,in2v,in3v,in4v, +output logic [7:0] out1,out2,out3,out4, +output logic out1v,out2v,out3v,out4v, +input logic [7:0] din, +output logic [7:0] dout, +input logic [7:0] addr, +input logic wr, +input logic rd, +output logic i1wy1,i1wy2,i1wy3,i1wy4, +output logic i2wy1,i2wy2,i2wy3,i2wy4, +output logic i3wy1,i3wy2,i3wy3,i3wy4, +output logic i4wy1,i4wy2,i4wy3,i4wy4 +); + +logic [7:0] in1_del2,in2_del2,in3_del2,in4_del2; +logic busy1,busy2,busy3,busy4; +logic discy1,discy2,discy3,discy4; +logic [ 7:0] sa_port_csr; +logic [ 7:0] da_port_csr; +logic [31:0] dropped_pkt_count_csr; +logic [31:0] crc_dropped_csr; +logic drop; +always @(posedge clk or posedge rst) +begin + if (rst) sa_port_csr <= 0; //[7:4]=FutureUse_ + //[3:0]=SA4,SA3,SA2,SA1 + else if (wr && addr==8'h20) sa_port_csr<=din; +end +always @(posedge clk or posedge rst) +begin + if (rst) da_port_csr <= 0; //FutureUSE_4321 + else if (wr && addr==8'h22) da_port_csr<=din; +end +always @(posedge clk or posedge rst) +begin + if (rst) dropped_pkt_count_csr <= 0;// + else + begin + if (wr && addr==8'h40) dropped_pkt_count_csr<=din; + else if (drop) dropped_pkt_count_csr<=dropped_pkt_count_csr+1; + end +end +always @(posedge clk or posedge rst) +begin + if (rst) crc_dropped_csr <= 0;// + else + begin + //pending + end +end + +always @(posedge clk or posedge rst) +begin + if (rst) dout<=0; + else + if (rd) + case(addr) + 'h20 : dout <= sa_port_csr; + 'h22 : dout <= da_port_csr; + 'h40 : dout <= dropped_pkt_count_csr; + 'h44 : dout <= crc_dropped_csr; + endcase +end +ichtop ICHTOP (.*, + .discy1_d2(discy1), + .discy2_d2(discy2), + .discy3_d2(discy3), + .discy4_d2(discy4) + ); + +ochtop OCHTOP(.*, + .in1(in1_del2), + .in2(in2_del2), + .in3(in3_del2), + .in4(in4_del2) +); +endmodule + diff --git a/environment.sv.txt b/environment.sv.txt new file mode 100644 index 0000000..caf64af --- /dev/null +++ b/environment.sv.txt @@ -0,0 +1,68 @@ +class environment extends uvm_env; +`uvm_component_utils(environment) + +bit [31:0] exp_pkt_count; +real tot_cov_score; +bit [31:0] m_matches,mis_matches; + + master_agent m_agent; + slave_agent s_agent; + scoreboard scb; + coverage cov_comp; + + function new (string name="environment",uvm_component parent=null); + super.new(name,parent); + endfunction + + extern virtual function void build_phase(uvm_phase phase); + extern virtual function void connect_phase(uvm_phase phase); + extern virtual function void report_phase(uvm_phase phase); + extern virtual function void extract_phase(uvm_phase phase); + +endclass + +function void environment::build_phase(uvm_phase phase); + super.build_phase(phase); + m_agent=master_agent::type_id::create("m_agent",this); + s_agent=slave_agent::type_id::create("s_agent",this); + scb=scoreboard#(packet)::type_id::create("scb",this); + cov_comp=coverage::type_id::create("cov_comp",this); +endfunction + +function void environment::connect_phase(uvm_phase phase); + m_agent.ap.connect(scb.mon_in); + m_agent.ap.connect(cov_comp.analysis_export); + s_agent.ap.connect(scb.mon_out); +endfunction + +function void environment::extract_phase(uvm_phase phase); +uvm_config_db#(int)::get(this,"m_agent.seqr.*","item_count",exp_pkt_count); +uvm_config_db#(real)::get(this,"","cov_score",tot_cov_score); +uvm_config_db#(int)::get(this,"","matches",m_matches); +uvm_config_db#(int)::get(this,"","mis_matches",mis_matches); +endfunction + +function void environment::report_phase(uvm_phase phase); +bit [31:0] tot_scb_cnt; +tot_scb_cnt= m_matches + mis_matches; + +if(exp_pkt_count != tot_scb_cnt) begin + `uvm_info("","******************************************",UVM_NONE); + `uvm_info("FAIL","Test Failed due to packet count MIS_MATCH",UVM_NONE); + `uvm_info("FAIL",$sformatf("exp_pkt_count=%0d Received_in_scb=%0d ",exp_pkt_count,tot_scb_cnt),UVM_NONE); + `uvm_fatal("FAIL","******************Test FAILED ************"); +end +else if(mis_matches != 0) begin + `uvm_info("","******************************************",UVM_NONE); + `uvm_info("FAIL","Test Failed due to mis_matched packets in scoreboard",UVM_NONE); + `uvm_info("FAIL",$sformatf("matched_pkt_count=%0d mis_matched_pkt_count=%0d ",m_matches,mis_matches),UVM_NONE); + `uvm_fatal("FAIL","******************Test FAILED ***************"); +end +else begin + `uvm_info("PASS","******************Test PASSED ***************",UVM_NONE); + `uvm_info("PASS",$sformatf("exp_pkt_count=%0d Received_in_scb=%0d ",exp_pkt_count,tot_scb_cnt),UVM_NONE); + `uvm_info("PASS",$sformatf("matched_pkt_count=%0d mis_matched_pkt_count=%0d ",m_matches,mis_matches),UVM_NONE); + `uvm_info("PASS",$sformatf("Coverage=%0f%%",tot_cov_score),UVM_NONE); + `uvm_info("","******************************************",UVM_NONE); + end +endfunction diff --git a/filelist.txt b/filelist.txt new file mode 100644 index 0000000..b839dea --- /dev/null +++ b/filelist.txt @@ -0,0 +1,10 @@ +ich.sv +ichtop.sv ++define+PRIORITY +och.sv +ochtop.sv +resolver.sv +duttop.sv +intf.sv +program_router.sv +top.sv diff --git a/iMonitor.sv.txt b/iMonitor.sv.txt new file mode 100644 index 0000000..dac9ed1 --- /dev/null +++ b/iMonitor.sv.txt @@ -0,0 +1,65 @@ +class iMonitor extends uvm_monitor; +`uvm_component_utils(iMonitor) + +virtual router_if.tb_mon vif; + +// This TLM port is used to connect the monitor to the scoreboard +uvm_analysis_port #(packet) analysis_port; + +// Current monitored transaction +packet pkt; + +function new (string name="iMonitor",uvm_component parent); + super.new(name,parent); +endfunction + +extern virtual task run_phase(uvm_phase phase); +extern virtual function void build_phase(uvm_phase phase); +extern task collect_pkt(input bit [3:0] port); +endclass + +function void iMonitor::build_phase(uvm_phase phase) ; + super.build_phase(phase); + if (!uvm_config_db#(virtual router_if.tb_mon)::get(get_parent(), "", "iMon_if", vif)) begin + `uvm_fatal("VIF_ERR","iMonitor DUT interface not set"); + end +//create TLM port + analysis_port=new("analysis_port",this); +endfunction + +task iMonitor::run_phase(uvm_phase phase); + // The job of the iMonitor is to passively monitor the physical signals, + // interprete and report the activities that it sees. In this case, to + // re-construct the packet that it sees on the DUT's input port as specified +fork + collect_pkt(0); + collect_pkt(1); + collect_pkt(2); + collect_pkt(3); +join +endtask + +task iMonitor::collect_pkt(input bit [3:0] port); +packet pkt1; +bit [15:0] len1; + forever begin + @(vif.cb_mon.inp_vld[port]); + `uvm_info("iMon_PKT",$sformatf("Value change=%0d observed port %0d",vif.cb_mon.inp_vld[port],port),UVM_FULL); + if (vif.cb_mon.inp_vld[port] === 1'bx || vif.cb_mon.inp_vld[port] === 1'bz || vif.cb_mon.inp_vld[port] === 1'b0) continue; + `uvm_info("iMon_PKT",$sformatf("Started collecting pakcet on port %0d",port),UVM_MEDIUM); + pkt1 = packet::type_id::create("pkt1",this); + while(1) begin//collect packet + pkt1.tot_pkt.push_back(vif.cb_mon.data_in[port]); + if(pkt1.tot_pkt.size() == 6) len1= {pkt1.tot_pkt[2],pkt1.tot_pkt[3],pkt1.tot_pkt[4],pkt1.tot_pkt[5]}; + if(pkt1.tot_pkt.size() == (1+1+4+4+len1)) break; + @(vif.cb_mon); + end + pkt1.sa=pkt1.tot_pkt[0]; + pkt1.da=pkt1.tot_pkt[1]; + `uvm_info("iMon_PKT",pkt1.convert2string(),UVM_MEDIUM); + analysis_port.write(pkt1); + `uvm_info("iMon_PKT",$sformatf("Packet Sent to Scorboard from Port %0d",port),UVM_MEDIUM); + end + +endtask + diff --git a/ich.sv.txt b/ich.sv.txt new file mode 100644 index 0000000..0e93b36 --- /dev/null +++ b/ich.sv.txt @@ -0,0 +1,133 @@ +module ich ( + input logic clk,rst,inv, + input [7:0] in, + input sa_enable, + input [3:0] da_port_csr, + input busy1,busy2,busy3,busy4, + output logic iwy1b,iwy2b,iwy3b,iwy4b, + input iwy1c,iwy2c,iwy3c,iwy4c, + output logic disc1,disc2,disc3,disc4, + output logic [7:0] in_d2, + output logic inc_dropped_count + ); +logic iwy1a,iwy2a,iwy3a,iwy4a; +logic [7:0] in_d1; +logic inv_d; +logic inv_pe; +enum {IDLE,SA,DA,LEN3,LEN2,LEN1,LEN0,CRC3,CRC2,CRC1,CRC0,DATA} state,statei; +logic [31:0] count; +logic [7:0] da; + +always @(posedge clk or posedge rst) +begin + if (rst) {in_d2,in_d1}<='b0; + else{in_d2,in_d1}<={in_d1,in}; +end + +always @(posedge clk or posedge rst) +begin + if (rst) inv_d<=0; + else inv_d<=inv; +end +assign inv_pe = !inv_d && inv && sa_enable; + +always @(posedge clk or posedge rst) +begin +if (rst) + begin + statei<=IDLE; + count <=0; + da<=0; + inc_dropped_count<=1'b0; + end +else + inc_dropped_count<=1'b0; + case(statei) + IDLE: statei<= inv_pe ? DA : IDLE; + DA: + begin + if (iwy1c||iwy2c||iwy3c||iwy4c) + begin + statei <=LEN3; + end + else + begin + statei<=IDLE; + inc_dropped_count<=1; + end + da<=in; + end + LEN3: begin + statei<=LEN2; + count[31:24]<=in; + end + LEN2: begin + statei<=LEN1; + count[23:16]<=in; + end + LEN1: begin + statei<=LEN0; + count[15:8] <=in; + end + LEN0: begin + statei <=CRC3; + count[7:0]<=in; + end + CRC3: statei<=CRC2; + CRC2: statei<=CRC1; + CRC1: statei<=CRC0; + CRC0: statei<=DATA; + DATA: begin + if (count>1) + begin + statei<=DATA; + count<=count-1; + end + else + begin + statei<=IDLE; + da<=0; + count<=0; + end + //statei<=(count>1) ? DATA :IDLE; + //count<=count-1; + end + endcase +end + +always @* +begin +{iwy1a,iwy2a,iwy3a,iwy4a}='b0; + case(statei) + IDLE : state = inv_pe ? SA : IDLE; + DA : begin + state = statei; + case(in) + 1:iwy1a=da_port_csr[0]?1:0; + 2:iwy2a=da_port_csr[1]?1:0; + 3:iwy3a=da_port_csr[2]?1:0; + 4:iwy4a=da_port_csr[3]?1:0; + endcase + end + default: state=statei; + endcase +end + +assign iwy1b = busy1 ? 1'b0 : iwy1a; +assign iwy2b = busy2 ? 1'b0 : iwy2a; +assign iwy3b = busy3 ? 1'b0 : iwy3a; +assign iwy4b = busy4 ? 1'b0 : iwy4a; + +always @* +begin +{disc1,disc2,disc3,disc4}='b0; +if (state==DATA && count==1) + case(da) + 1: disc1=1; + 2: disc2=1; + 3: disc3=1; + 4: disc4=1; + endcase +end + +endmodule \ No newline at end of file diff --git a/ichtop.sv.txt b/ichtop.sv.txt new file mode 100644 index 0000000..9cf4db0 --- /dev/null +++ b/ichtop.sv.txt @@ -0,0 +1,143 @@ +module ichtop ( +input logic clk, +input logic rst, +input logic busy1,busy2,busy3,busy4, +input logic [7:0] in1,in2,in3,in4, +input logic in1v,in2v,in3v,in4v, +input logic [7:0] sa_port_csr, +input logic [7:0] da_port_csr, +output logic discy1_d2,discy2_d2,discy3_d2,discy4_d2, +output logic i1wy1,i1wy2,i1wy3,i1wy4, + i2wy1,i2wy2,i2wy3,i2wy4, + i3wy1,i3wy2,i3wy3,i3wy4, + i4wy1,i4wy2,i4wy3,i4wy4, +output logic [7:0] in1_del2,in2_del2,in3_del2,in4_del2, +output logic drop +); +logic discy1_d1,discy2_d1,discy3_d1,discy4_d1; +logic drop1,drop2,drop3,drop4; +ich ICH1 (.*, + .inv(in1v), + .in(in1), + .sa_enable(sa_port_csr[0]), + .da_port_csr(da_port_csr[3:0]), + .iwy1b(i1wy1b), + .iwy2b(i1wy2b), + .iwy3b(i1wy3b), + .iwy4b(i1wy4b), + .iwy1c(i1wy1), + .iwy2c(i1wy2), + .iwy3c(i1wy3), + .iwy4c(i1wy4), + .disc1(disc11), + .disc2(disc12), + .disc3(disc13), + .disc4(disc14), + .in_d2(in1_del2), + .inc_dropped_count(drop1) +); +ich ICH2 (.*, + .inv(in2v), + .in(in2), + .sa_enable(sa_port_csr[1]), + .da_port_csr(da_port_csr[3:0]), + .iwy1b(i2wy1b), + .iwy2b(i2wy2b), + .iwy3b(i2wy3b), + .iwy4b(i2wy4b), + .iwy1c(i2wy1), + .iwy2c(i2wy2), + .iwy3c(i2wy3), + .iwy4c(i2wy4), + .disc1(disc21), + .disc2(disc22), + .disc3(disc23), + .disc4(disc24), + .in_d2(in2_del2), + .inc_dropped_count(drop2) +); +ich ICH3 (.*, + .inv(in3v), + .in(in3), + .sa_enable(sa_port_csr[2]), + .da_port_csr(da_port_csr[3:0]), + .iwy1b(i3wy1b), + .iwy2b(i3wy2b), + .iwy3b(i3wy3b), + .iwy4b(i3wy4b), + .iwy1c(i3wy1), + .iwy2c(i3wy2), + .iwy3c(i3wy3), + .iwy4c(i3wy4), + .disc1(disc31), + .disc2(disc32), + .disc3(disc33), + .disc4(disc34), + .in_d2(in3_del2), + .inc_dropped_count(drop3) +); +ich ICH4 (.*, + .inv(in4v), + .in(in4), + .sa_enable(sa_port_csr[3]), + .da_port_csr(da_port_csr[3:0]), + .iwy1b(i4wy1b), + .iwy2b(i4wy2b), + .iwy3b(i4wy3b), + .iwy4b(i4wy4b), + .iwy1c(i4wy1), + .iwy2c(i4wy2), + .iwy3c(i4wy3), + .iwy4c(i4wy4), + .disc1(disc41), + .disc2(disc42), + .disc3(disc43), + .disc4(disc44), + .in_d2(in4_del2), + .inc_dropped_count(drop4) +); +assign drop = drop1 || drop2 || drop3 || drop4; +assign discy1 = disc11 || disc21 || disc31 || disc41; +assign discy2 = disc12 || disc22 || disc32 || disc42; +assign discy3 = disc13 || disc23 || disc33 || disc43; +assign discy4 = disc14 || disc24 || disc34 || disc44; + +always @(posedge clk or posedge rst) +begin + if (rst) {discy1_d2,discy1_d1} <=2'b00; + else {discy1_d2,discy1_d1} <= {discy1_d1,discy1}; +end + +always @(posedge clk or posedge rst) +begin + if (rst) {discy2_d2,discy2_d1} <=2'b00; + else {discy2_d2,discy2_d1} <= {discy2_d1,discy2}; +end + +always @(posedge clk or posedge rst) +begin + if (rst) {discy3_d2,discy3_d1} <=2'b00; + else {discy3_d2,discy3_d1} <= {discy3_d1,discy3}; +end + +always @(posedge clk or posedge rst) +begin + if (rst) {discy4_d2,discy4_d1} <=2'b00; + else {discy4_d2,discy4_d1} <= {discy4_d1,discy4}; +end + + +resolver R1 (i1wy1b,i2wy1b,i3wy1b,i4wy1b, + i1wy1,i2wy1,i3wy1,i4wy1 + ); +resolver R2(i2wy2b,i3wy2b,i4wy2b,i1wy2b, + i2wy2,i3wy2,i4wy2,i1wy2 + ); +resolver R3 (i3wy3b,i4wy3b,i1wy3b,i2wy3b, + i3wy3,i4wy3,i1wy3,i2wy3 + ); +resolver R4 (i4wy4b,i1wy4b,i2wy4b,i3wy4b, + i4wy4,i1wy4,i2wy4,i3wy4 + ); + +endmodule diff --git a/intf.sv.txt b/intf.sv.txt new file mode 100644 index 0000000..1c0d6eb --- /dev/null +++ b/intf.sv.txt @@ -0,0 +1,39 @@ +interface router_if (input clk); + +//Router inputs +logic rst; +logic [7:0] data_in[4];//input data +logic inp_vld[4]; //input valid + +//Router outputs +logic [7:0] data_out[4]; //output data +logic outp_vld[4]; + +logic i1wy[4]; +logic i2wy[4]; +logic i3wy[4]; +logic i4wy[4]; + +//RAL register operations +logic [7:0] reg_din; +logic [7:0] reg_dout; +logic [7:0] reg_addr; +logic reg_wr,reg_rd; + +clocking cb@(posedge clk); + output data_in; + output inp_vld; + output reg_din,reg_wr,reg_rd,reg_addr; + input i1wy,i2wy,i3wy,i4wy,reg_dout; +endclocking + +clocking cb_mon@(posedge clk); + input data_out,outp_vld; + input data_in,inp_vld; + input reg_dout; +endclocking + +modport tb(clocking cb,output rst); +modport tb_mon(clocking cb_mon); + +endinterface diff --git a/master_agent.sv.txt b/master_agent.sv.txt new file mode 100644 index 0000000..2a3eb40 --- /dev/null +++ b/master_agent.sv.txt @@ -0,0 +1,34 @@ +class master_agent extends uvm_agent; +`uvm_component_utils(master_agent) + +driver drvr; +iMonitor iMon; +sequencer seqr; +uvm_analysis_port#(packet) ap; + +function new (string name="master_agent",uvm_component parent); + super.new(name,parent); +endfunction + +extern virtual function void build_phase(uvm_phase phase); +extern virtual function void connect_phase(uvm_phase phase); +endclass + +function void master_agent::build_phase(uvm_phase phase); +super.build_phase(phase); +ap=new("master_ap",this); +if(is_active==UVM_ACTIVE) begin + seqr=sequencer::type_id::create("seqr",this); + drvr=driver::type_id::create("drvr",this); +end + iMon=iMonitor::type_id::create("iMon",this); +endfunction + +function void master_agent::connect_phase(uvm_phase phase); + super.connect_phase(phase); +if(is_active==UVM_ACTIVE) begin + drvr.seq_item_port.connect(seqr.seq_item_export); + end + iMon.analysis_port.connect(this.ap); +endfunction + diff --git a/oMonitor.sv.txt b/oMonitor.sv.txt new file mode 100644 index 0000000..7d987d9 --- /dev/null +++ b/oMonitor.sv.txt @@ -0,0 +1,65 @@ +class oMonitor extends uvm_monitor; +`uvm_component_utils(oMonitor) + +virtual router_if.tb_mon vif; + +// This TLM port is used to connect the monitor to the scoreboard +uvm_analysis_port #(packet) analysis_port; + +// Current monitored transaction +packet pkt; + +function new (string name="oMonitor",uvm_component parent); + super.new(name,parent); +endfunction + +extern virtual task run_phase(uvm_phase phase); +extern virtual function void build_phase(uvm_phase phase); +extern task collect_pkt(input bit [3:0] port); +endclass + +function void oMonitor::build_phase(uvm_phase phase) ; + super.build_phase(phase); + if (!uvm_config_db#(virtual router_if.tb_mon)::get(get_parent(), "", "oMon_if", vif)) begin + `uvm_fatal("VIF_ERR","oMonitor DUT interface not set"); + end +//create TLM port + analysis_port=new("analysis_port",this); +endfunction + +task oMonitor::run_phase(uvm_phase phase); + // The job of the oMonitor is to passively monitor the physical signals, + // interprete and report the activities that it sees. In this case, to + // re-construct the packet that it sees on the DUT's input port as specified +fork + collect_pkt(0); + collect_pkt(1); + collect_pkt(2); + collect_pkt(3); +join +endtask + +task oMonitor::collect_pkt(input bit [3:0] port); +packet pkt1; +bit [15:0] len1; + forever begin + @(vif.cb_mon.outp_vld[port]); + `uvm_info("oMon_PKT",$sformatf("Value change=%0d observed port %0d",vif.cb_mon.outp_vld[port],port),UVM_FULL); + if (vif.cb_mon.outp_vld[port] === 1'bx || vif.cb_mon.outp_vld[port] === 1'bz || vif.cb_mon.outp_vld[port] === 1'b0) continue; + `uvm_info("oMon_PKT",$sformatf("Started collecting Pakcet on Port %0d",port),UVM_MEDIUM); + pkt1 = packet::type_id::create("pkt1",this); + while(1) begin//collect packet + pkt1.tot_pkt.push_back(vif.cb_mon.data_out[port]); + if(pkt1.tot_pkt.size() == 6) len1= {pkt1.tot_pkt[2],pkt1.tot_pkt[3],pkt1.tot_pkt[4],pkt1.tot_pkt[5]}; + if(pkt1.tot_pkt.size() == (1+1+4+4+len1)) break; + @(vif.cb_mon); + end + pkt1.sa=pkt1.tot_pkt[0]; + pkt1.da=pkt1.tot_pkt[1]; + `uvm_info("oMon_PKT",pkt1.convert2string(),UVM_MEDIUM); + analysis_port.write(pkt1); + `uvm_info("oMon_PKT",$sformatf("Packet Sent to Scorboard from Port %0d",port),UVM_MEDIUM); + end + +endtask + diff --git a/och.sv.txt b/och.sv.txt new file mode 100644 index 0000000..aa37a07 --- /dev/null +++ b/och.sv.txt @@ -0,0 +1,30 @@ +module OCH ( +input logic clk, +input logic rst, +input logic r1,r2,r3,r4, +input logic [7:0] in1,in2,in3,in4, +output logic [7:0] out, +output logic outv, +input logic disc, +input logic [1:4] chaNo, +output logic busy +); + +`include "priority.sv" + +always @* +begin + case(state) + R1Y: out=in1; + R2Y: out=in2; + R3Y: out=in3; + R4Y: out=in4; + default: out = 'bz; + endcase +end + +assign outv = (state==R1Y|| state==R2Y||state==R3Y||state==R4Y); + +assign busy = !(state==NC); + +endmodule diff --git a/ochtop.sv.txt b/ochtop.sv.txt new file mode 100644 index 0000000..e9ec547 --- /dev/null +++ b/ochtop.sv.txt @@ -0,0 +1,60 @@ +module ochtop ( +input logic clk, +input logic rst, +output logic busy1,busy2,busy3,busy4, +input logic i1wy1,i1wy2,i1wy3,i1wy4, +input logic i2wy1,i2wy2,i2wy3,i2wy4, +input logic i3wy1,i3wy2,i3wy3,i3wy4, +input logic i4wy1,i4wy2,i4wy3,i4wy4, +input logic [7:0] in1,in2,in3,in4, +output logic [7:0] out1,out2,out3,out4, +input logic discy1,discy2,discy3,discy4, +output logic out1v,out2v,out3v,out4v +); + +OCH OCH1(.*, + .r1(i1wy1), + .r2(i2wy1), + .r3(i3wy1), + .r4(i4wy1), + .out(out1), + .disc(discy1), + .chaNo(4'b1000), + .busy(busy1), + .outv(out1v) + ); //name +OCH OCH2(.*, + .r1(i1wy2), + .r2(i2wy2), + .r3(i3wy2), + .r4(i4wy2), + .out(out2), + .disc(discy2), + .chaNo(4'b0100), + .busy(busy2), + .outv(out2v) + ); //name +OCH OCH3(.*, + .r1(i1wy3), + .r2(i2wy3), + .r3(i3wy3), + .r4(i4wy3), + .out(out3), + .disc(discy3), + .chaNo(4'b0010), + .busy(busy3), + .outv(out3v) + ); //name + +OCH OCH4(.*, + .r1(i1wy4), + .r2(i2wy4), + .r3(i3wy4), + .r4(i4wy4), + .out(out4), + .disc(discy4), + .chaNo(4'b0001), + .busy(busy4), + .outv(out4v) + ); //name +endmodule \ No newline at end of file diff --git a/packet.sv.txt b/packet.sv.txt new file mode 100644 index 0000000..615fd4d --- /dev/null +++ b/packet.sv.txt @@ -0,0 +1,111 @@ +// SA = 1 byte +// DA = 1 byte +// Length = 4 bytes +// CRC = 4 bytes +// Payload = 100 Bytes + +class packet extends uvm_sequence_item; + +//Router inputs +rand bit [7:0] sa,da; +rand bit [31:0] len; +bit [31:0] crc; +rand bit [7:0] payload[]; +bit [7:0] tot_pkt[$]; +op_type mode; + +bit [7:0] reg_addr; +bit [7:0] reg_data; + +constraint valid { + sa inside {[0:3]}; //valid sa ports + da inside {[0:3]}; //valid da ports + len > 10 ; //Min size + len < 100; //Max size + + payload.size == len; + foreach(payload[index]) + if (index > 0 )payload[index] != payload[index-1]; +} + +function void post_randomize(); + crc=calc_crc(payload); + $display("[crc] post_rand crc=%0h",crc); +endfunction + +`uvm_object_utils_begin(packet) +`uvm_field_int(sa,UVM_ALL_ON | UVM_NOCOMPARE) +`uvm_field_int(da,UVM_ALL_ON | UVM_NOCOMPARE) +`uvm_field_int(crc,UVM_ALL_ON | UVM_NOCOMPARE) +`uvm_field_int(len,UVM_ALL_ON | UVM_NOCOMPARE) +`uvm_field_array_int(payload,UVM_ALL_ON | UVM_NOCOMPARE) +`uvm_field_queue_int(tot_pkt,UVM_ALL_ON | UVM_NOCOMPARE ) +`uvm_object_utils_end + +virtual function string convert2string(); +return $sformatf("Pkt_Size=%0d sa=%0d da=%0d ",tot_pkt.size(),sa,da); +endfunction + + +function new(string name="packet"); + super.new(name); +endfunction +extern virtual function bit [31:0] calc_crc (ref bit [7:0] pkt[]); +extern function void pack(); +extern virtual function bit do_compare (uvm_object rhs , uvm_comparer comparer); + +endclass + +function bit packet::do_compare (uvm_object rhs , uvm_comparer comparer); +packet pkt; +bit status; +if (!$cast(pkt,rhs)) begin `uvm_fatal("CAST","do_compare casting failed \n"); end + +if(this.tot_pkt.size() == pkt.tot_pkt.size()) begin + foreach(pkt.tot_pkt[index]) begin + if(this.tot_pkt[index] == pkt.tot_pkt[index]) + status = 1; + else + return 0; + end//end_of_foreach + end//end_of_main_if + else return 0; +return status; +endfunction + +function void packet::pack(); +tot_pkt.push_back(sa); +tot_pkt.push_back(da+1); +tot_pkt.push_back(len[31:24]); +tot_pkt.push_back(len[23:16]); +tot_pkt.push_back(len[15:8]); +tot_pkt.push_back(len[7:0]); +tot_pkt.push_back(crc[31:24]); +tot_pkt.push_back(crc[23:16]); +tot_pkt.push_back(crc[15:8]); +tot_pkt.push_back(crc[7:0]); +for (int i=0;i> 31)) begin//3 + new_crc = (new_crc << 1) ^ 32'h04c11db7; + end //3 + else + begin //4 + new_crc = new_crc << 1; + end //4 + temp = temp >> 1; + end //2 + end//1 +return new_crc; +endfunction + diff --git a/priority.sv.txt b/priority.sv.txt new file mode 100644 index 0000000..152c6bf --- /dev/null +++ b/priority.sv.txt @@ -0,0 +1,129 @@ +enum {NC,R1Y,R2Y,R3Y,R4Y} state; + always @(posedge clk or posedge rst) + begin + if (rst) state<=NC; + else + case(state) + NC: + case(1) + r1: state<=R1Y; + r2: state<=R2Y; + r3: state<=R3Y; + r4: state<=R4Y; + default :state<=NC; + endcase + R1Y: + case(1) + disc: + case(1) + r2 : state<=R2Y; + r3 : state<=R3Y; + r4 : state<=R4Y; + default: state<=NC; + endcase + default: state<=state; + endcase + R2Y: + case(1) + disc: + case(1) + r1 : state<=R1Y; + r3 : state<=R3Y; + r4 : state<=R4Y; + default: state<=NC; + endcase + default: state<=state; + endcase + R3Y: + case(1) + disc: + case(1) + r1 : state<=R1Y; + r2 : state<=R2Y; + r4 : state<=R4Y; + default: state<=NC; + endcase + default: state<=state; + endcase + R4Y: + case(1) + disc: + case(1) + r1 : state<=R1Y; + r2 : state<=R2Y; + r3 : state<=R4Y; + default: state<=NC; + endcase + default: state<=state; + endcase + endcase + end +logic startpulse; +always @(*) +begin + startpulse=0; + case(state) + NC: if (r1||r2||r3||r4) startpulse=1; + endcase +end +bit [7:0] Q[$]; +int crc; +always @(posedge clk or posedge rst) +begin +if (rst) Q.delete(); +else + begin + case(1) + startpulse: + begin + //$display ("reached here at %t",$time); + repeat (6) @(posedge clk); + while (!disc) + begin + @(posedge clk); + //$display ("out is :%d",out); + Q.push_back(out); + end + //$display ("[RTL] Contents of packet Q received ",Q); + repeat(4) + begin + Q.push_back(Q[0]); + Q.delete(0); + end + //$display ("[RTL] Contents of Q received ",Q); + + calc_crc(Q,crc); + Q.delete(); + //$display ("[RTL] CRC received is %h",crc); + end + endcase + end +end + + +function automatic void +calc_crc +( + ref bit [7:0] pkt[$],//Queue of bit[7:0] + output int crc +); + bit [7:0] temp; + crc = 32'hFFFF_FFFF; +for(int i=0;i> 31)) + begin//(3 + crc = (crc << 1) ^ 32'h04c11db7; + end //3) + else + begin //(4 + crc = crc << 1; + end //4) + temp = temp >> 1; + end //2) + end//1) +endfunction diff --git a/program_router.sv.txt b/program_router.sv.txt new file mode 100644 index 0000000..e6a0f23 --- /dev/null +++ b/program_router.sv.txt @@ -0,0 +1,20 @@ +`include "router_env_pkg.pkg" +program program_router (router_if pif); + +import uvm_pkg::*; +import router_env_pkg::*; + +`include "test.sv" +`include "rand_test.sv" +`include "test_sa1_da1.sv" +`include "test_sa1_da2.sv" +`include "test_sa1_da3.sv" +`include "test_sa1_da4.sv" + +initial begin + $timeformat(-9, 1, "ns", 10); + uvm_config_db#(virtual router_if)::set(null,"uvm_test_top","vif",pif); + run_test(); +end + +endprogram diff --git a/rand_test.sv.txt b/rand_test.sv.txt new file mode 100644 index 0000000..64004de --- /dev/null +++ b/rand_test.sv.txt @@ -0,0 +1,49 @@ +class rand_test extends uvm_test; + +`uvm_component_utils(rand_test) + +virtual router_if vif; + + environment env; + + function new (string name="rand_test",uvm_component parent=null); + super.new(name,parent); + endfunction + + extern virtual function void build_phase(uvm_phase phase); + extern virtual function void final_phase(uvm_phase phase); + extern virtual task main_phase (uvm_phase phase); + +endclass + +function void rand_test::build_phase(uvm_phase phase); +super.build_phase(phase); +env=environment::type_id::create("env",this); +uvm_config_db#(virtual router_if)::get(this,"","vif",vif); + +uvm_config_db#(virtual router_if.tb)::set(this,"env.m_agent","drvr_if",vif.tb); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.m_agent","iMon_if",vif.tb_mon); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.s_agent","oMon_if",vif.tb_mon); + + uvm_config_db#(int)::set(this,"env.m_agent.seqr.*", "item_count", 100); + +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.reset_phase","default_sequence",reset_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.configure_phase","default_sequence",config_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.main_phase","default_sequence",random_sequence::get_type()); + +endfunction + +task rand_test::main_phase (uvm_phase phase); +uvm_objection objection; +super.main_phase(phase); +objection=phase.get_objection(); +objection.set_drain_time(this,1000ns); +//The drain time is the amount of time to wait once all objections have been dropped +endtask + + +function void rand_test::final_phase(uvm_phase phase); +super.final_phase(phase); +//uvm_top.print_topology(); +//factory.print(); +endfunction diff --git a/random_sequence.sv.txt b/random_sequence.sv.txt new file mode 100644 index 0000000..b957376 --- /dev/null +++ b/random_sequence.sv.txt @@ -0,0 +1,38 @@ +class random_sequence extends uvm_sequence#(packet); + int unsigned item_count; + +`uvm_object_utils(random_sequence) + +function new (string name="random_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +extern virtual task pre_start(); +extern virtual task body(); +endclass + +task random_sequence::pre_start(); +if(!uvm_config_db #(int):: get(null,this.get_full_name,"item_count",item_count)) +begin + `uvm_warning(get_full_name(),"item_count is not set in random_sequence "); + item_count=10; +end +endtask + +task random_sequence::body(); + bit [31:0] count; + REQ ref_pkt; + ref_pkt=packet::type_id::create("ref_pkt",,get_full_name()); + repeat(item_count) begin + `uvm_create(req); + assert(ref_pkt.randomize()); + req.copy(ref_pkt); + req.pack(); + start_item(req); + finish_item(req); + count++; + `uvm_info("SEQ",$sformatf("Master Sequence : Transaction %0d DONE ",count),UVM_MEDIUM); + end +endtask + diff --git a/reset_sequence.sv.txt b/reset_sequence.sv.txt new file mode 100644 index 0000000..4bada5a --- /dev/null +++ b/reset_sequence.sv.txt @@ -0,0 +1,16 @@ +class reset_sequence extends uvm_sequence#(packet); +`uvm_object_utils(reset_sequence) + +function new (string name="reset_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +task body(); + `uvm_create(req); + req.mode=RESET; + start_item(req); + finish_item(req); + `uvm_info("RESET_SEQ","Reset Sequence : Transaction DONE",UVM_MEDIUM); +endtask +endclass diff --git a/resolver.sv.txt b/resolver.sv.txt new file mode 100644 index 0000000..a9bcbf7 --- /dev/null +++ b/resolver.sv.txt @@ -0,0 +1,18 @@ +module resolver ( +input logic a,b,c,d, +output logic u,v,w,x +); + +always @* +begin +{u,v,w,x}='b0; + casex({a,b,c,d}) + 4'b1xxx:u=1'b1; + 4'b01xx:v=1'b1; + 4'b001x:w=1'b1; + 4'b0001:x=1'b1; + default: {u,v,w,x}='b0; + endcase +end + +endmodule \ No newline at end of file diff --git a/roundrobin.sv.txt b/roundrobin.sv.txt new file mode 100644 index 0000000..4ff26ce --- /dev/null +++ b/roundrobin.sv.txt @@ -0,0 +1,101 @@ +enum {R1Y,R2Y,R3Y,R4Y,RUR1,RUR2,RUR3,RUR4} state; + +always @(posedge clk or posedge rst) +begin + if (rst) + case(chaNo) + 4'busy1000: state<=RUR4; + 4'b0100: state<=RUR1; + 4'b0010: state<=RUR2; + 4'b0001: state<=RUR3; + default: state<=RUR4; + endcase + else + +case(state) +RUR4: + case(1) + disc: state<=RUR4; + r1: state<=R1Y; + r2: state<=R2Y; + r3: state<=R3Y; + r4: state<=R4Y; + default: state<=state; + endcase +R1Y: + case(1) + disc: + case(1) + r2: state<=R2Y; + r3: state<=R3Y; + r4: state<=R4Y; + default: state<=RUR1; + endcase + default: state<=state; + endcase +R2Y: + case(1) + disc: + case(1) + r3: state<=R3Y; + r4: state<=R4Y; + r1: state<=R1Y; + default: state<=RUR2; + endcase + default: state<=state; + endcase +R3Y: + case(1) + disc: + case(1) + r4: state<=R4Y; + r1: state<=R1Y; + r2: state<=R2Y; + default: state<=RUR3; + endcase + default: state<=state; + endcase + +R4Y: + case(1) + disc: + case(1) + r1: state<=R1Y; + r2: state<=R2Y; + r3: state<=R3Y; + default: state<=RUR4; + endcase + default: state<=state; + endcase +RUR1: + case(1) + disc: state<=RUR1; + r2: state<=R2Y; + r3: state<=R3Y; + r4: state<=R4Y; + r1: state<=R1Y; + default: state<=state; + endcase + +RUR2: + case(1) + disc: state<=RUR2; + r3: state<=R3Y; + r4: state<=R4Y; + r1: state<=R1Y; + r2: state<=R2Y; + default: state<=state; + endcase +RUR3: + case(1) + disc: state<=RUR3; + r4: state<=R4Y; + r1: state<=R1Y; + r2: state<=R2Y; + r3: state<=R3Y; + default: state<=state; + endcase + + endcase + +end \ No newline at end of file diff --git a/router_env_pkg.pkg.txt b/router_env_pkg.pkg.txt new file mode 100644 index 0000000..260fb67 --- /dev/null +++ b/router_env_pkg.pkg.txt @@ -0,0 +1,31 @@ +package router_env_pkg; + +typedef enum {NORMAL,RESET,REG_WRITE,REG_READ} op_type; + +// UVM class library compiled in a package +import uvm_pkg::*; + + +`include "packet.sv" +`include "reset_sequence.sv" +`include "config_sequence.sv" +`include "sa3_da4_sequence.sv" +`include "sequencer.sv" +`include "driver.sv" +`include "iMonitor.sv" +`include "master_agent.sv" + +`include "oMonitor.sv" +`include "slave_agent.sv" + +`include "coverage.sv" +`include "scoreboard.sv" +`include "environment.sv" + +`include "sa1_da1_sequence.sv" +`include "sa1_da2_sequence.sv" +`include "sa1_da3_sequence.sv" +`include "sa1_da4_sequence.sv" +`include "random_sequence.sv" + +endpackage diff --git a/sa1_da1_sequence.sv.txt b/sa1_da1_sequence.sv.txt new file mode 100644 index 0000000..8de0609 --- /dev/null +++ b/sa1_da1_sequence.sv.txt @@ -0,0 +1,38 @@ +class sa1da1_sequence extends uvm_sequence#(packet); + int unsigned item_count; + +`uvm_object_utils(sa1da1_sequence) + +function new (string name="sa1da1_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +extern virtual task pre_start(); +extern virtual task body(); +endclass + +task sa1da1_sequence::pre_start(); +if(!uvm_config_db #(int):: get(null,this.get_full_name,"item_count",item_count)) +begin + `uvm_warning(get_full_name(),"item_count is not set in sa1da1_sequence "); + item_count=10; +end +endtask + +task sa1da1_sequence::body(); + bit [31:0] count; + REQ ref_pkt; + ref_pkt=packet::type_id::create("ref_pkt",,get_full_name()); + repeat(item_count) begin + `uvm_create(req); + assert(ref_pkt.randomize() with {sa==0;da==0;payload.size()==50;}); + req.copy(ref_pkt); + req.pack(); + start_item(req); + finish_item(req); + count++; + `uvm_info("SEQ",$sformatf("Master Sequence : Transaction %0d DONE ",count),UVM_MEDIUM); + end +endtask + diff --git a/sa1_da2_sequence.sv.txt b/sa1_da2_sequence.sv.txt new file mode 100644 index 0000000..e0c1010 --- /dev/null +++ b/sa1_da2_sequence.sv.txt @@ -0,0 +1,38 @@ +class sa1da2_sequence extends uvm_sequence#(packet); + int unsigned item_count; + +`uvm_object_utils(sa1da2_sequence) + +function new (string name="sa1da2_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +extern virtual task pre_start(); +extern virtual task body(); +endclass + +task sa1da2_sequence::pre_start(); +if(!uvm_config_db #(int):: get(null,this.get_full_name,"item_count",item_count)) +begin + `uvm_warning(get_full_name(),"item_count is not set in sa1da2_sequence "); + item_count=10; +end +endtask + +task sa1da2_sequence::body(); + bit [31:0] count; + REQ ref_pkt; + ref_pkt=packet::type_id::create("ref_pkt",,get_full_name()); + repeat(item_count) begin + `uvm_create(req); + assert(ref_pkt.randomize() with {sa==0;da==1;payload.size()==50;}); + req.copy(ref_pkt); + req.pack(); + start_item(req); + finish_item(req); + count++; + `uvm_info("SEQ",$sformatf("Master Sequence : Transaction %0d DONE ",count),UVM_MEDIUM); + end +endtask + diff --git a/sa1_da3_sequence.sv.txt b/sa1_da3_sequence.sv.txt new file mode 100644 index 0000000..f7e58d3 --- /dev/null +++ b/sa1_da3_sequence.sv.txt @@ -0,0 +1,38 @@ +class sa1da3_sequence extends uvm_sequence#(packet); + int unsigned item_count; + +`uvm_object_utils(sa1da3_sequence) + +function new (string name="sa1da3_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +extern virtual task pre_start(); +extern virtual task body(); +endclass + +task sa1da3_sequence::pre_start(); +if(!uvm_config_db #(int):: get(null,this.get_full_name,"item_count",item_count)) +begin + `uvm_warning(get_full_name(),"item_count is not set in sa1da3_sequence "); + item_count=10; +end +endtask + +task sa1da3_sequence::body(); + bit [31:0] count; + REQ ref_pkt; + ref_pkt=packet::type_id::create("ref_pkt",,get_full_name()); + repeat(item_count) begin + `uvm_create(req); + assert(ref_pkt.randomize() with {sa==0;da==2;payload.size()==50;}); + req.copy(ref_pkt); + req.pack(); + start_item(req); + finish_item(req); + count++; + `uvm_info("SEQ",$sformatf("Master Sequence : Transaction %0d DONE ",count),UVM_MEDIUM); + end +endtask + diff --git a/sa1_da4_sequence.sv.txt b/sa1_da4_sequence.sv.txt new file mode 100644 index 0000000..7f11cf9 --- /dev/null +++ b/sa1_da4_sequence.sv.txt @@ -0,0 +1,38 @@ +class sa1da4_sequence extends uvm_sequence#(packet); + int unsigned item_count; + +`uvm_object_utils(sa1da4_sequence) + +function new (string name="sa1da4_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +extern virtual task pre_start(); +extern virtual task body(); +endclass + +task sa1da4_sequence::pre_start(); +if(!uvm_config_db #(int):: get(null,this.get_full_name,"item_count",item_count)) +begin + `uvm_warning(get_full_name(),"item_count is not set in sa1da4_sequence "); + item_count=10; +end +endtask + +task sa1da4_sequence::body(); + bit [31:0] count; + REQ ref_pkt; + ref_pkt=packet::type_id::create("ref_pkt",,get_full_name()); + repeat(item_count) begin + `uvm_create(req); + assert(ref_pkt.randomize() with {sa==0;da==3;payload.size()==50;}); + req.copy(ref_pkt); + req.pack(); + start_item(req); + finish_item(req); + count++; + `uvm_info("SEQ",$sformatf("Master Sequence : Transaction %0d DONE ",count),UVM_MEDIUM); + end +endtask + diff --git a/sa3_da4_sequence.sv.txt b/sa3_da4_sequence.sv.txt new file mode 100644 index 0000000..51382cd --- /dev/null +++ b/sa3_da4_sequence.sv.txt @@ -0,0 +1,38 @@ +class sa3da4_sequence extends uvm_sequence#(packet); + int unsigned item_count; + +`uvm_object_utils(sa3da4_sequence) + +function new (string name="sa3da4_sequence"); + super.new(name); + set_automatic_phase_objection(1);//uvm-1.2 only +endfunction + +extern virtual task pre_start(); +extern virtual task body(); +endclass + +task sa3da4_sequence::pre_start(); +if(!uvm_config_db #(int):: get(null,this.get_full_name,"item_count",item_count)) +begin + `uvm_warning(get_full_name(),"item_count is not set in sa3da4_sequence "); + item_count=10; +end +endtask + +task sa3da4_sequence::body(); + bit [31:0] count; + REQ ref_pkt; + ref_pkt=packet::type_id::create("ref_pkt",,get_full_name()); + repeat(item_count) begin + `uvm_create(req); + assert(ref_pkt.randomize() with {sa==2;da==3;payload.size()==20;}); + req.copy(ref_pkt); + req.pack(); + start_item(req); + finish_item(req); + count++; + `uvm_info("SEQ",$sformatf("Master Sequence : Transaction %0d DONE ",count),UVM_MEDIUM); + end +endtask + diff --git a/scoreboard.sv.txt b/scoreboard.sv.txt new file mode 100644 index 0000000..4864a50 --- /dev/null +++ b/scoreboard.sv.txt @@ -0,0 +1,74 @@ +class scoreboard #(type T=packet) extends uvm_scoreboard; +typedef scoreboard#(T) scb_type; +`uvm_component_param_utils(scb_type) + +//The $typename system function returns a string +//that represents the resolved type of its argument +const static string type_name = $sformatf("scoreboard#(%0s)",$typename(T)); +virtual function string get_type_name(); +return type_name; +endfunction + +`uvm_analysis_imp_decl(_inp) +`uvm_analysis_imp_decl(_outp) + +uvm_analysis_imp_inp #(T,scb_type) mon_in; +uvm_analysis_imp_outp #(T,scb_type) mon_out; + +T q_in [$]; +bit [31:0] m_matches,mis_matches; + +function new(string name="scoreboard",uvm_component parent=null); + super.new(name,parent); +`uvm_info(get_type_name(),"NEW scoreboard",UVM_NONE); +endfunction + +virtual function void build_phase(uvm_phase phase); +super.build_phase(phase); +mon_in=new("mon_in",this); +mon_out=new("mon_out",this); +endfunction + +virtual function void write_inp(T pkt); +T pkt_in; +$cast(pkt_in,pkt.clone()); +q_in.push_back(pkt_in); +endfunction + +virtual function void write_outp(T pkt); +T ref_pkt; +int get_index[$]; +int index; +bit done; +get_index = q_in.find_index() with (item.sa==pkt.sa && item.da==pkt.da); +foreach (get_index[i]) begin + index=get_index[i]; + ref_pkt=q_in[index]; + if(ref_pkt.compare(pkt)) begin + m_matches++; + q_in.delete(index); + `uvm_info("SCB_MATCH","Packet matched ",UVM_NONE); + done=1; + break; + end else done=0; + end + if (!done) begin + mis_matches++; + `uvm_error("SCB_NO_MATCH","Error ***** No Matching packet found *******"); + `uvm_info("SCB",$sformatf("Expected::%0p ",ref_pkt.tot_pkt),UVM_NONE); + `uvm_info("SCB",$sformatf("Received::%0p ",pkt.tot_pkt),UVM_NONE); + done=0; + end +endfunction + +virtual function void extract_phase(uvm_phase phase); +uvm_config_db#(int)::set(null,"uvm_test_top.env","matches",m_matches); +uvm_config_db#(int)::set(null,"uvm_test_top.env","mis_matches",mis_matches); +endfunction + +function void report_phase(uvm_phase phase); +`uvm_info("SCB",$sformatf("Scoreboard completed with matches=%0d mismatches=%0d ",m_matches,mis_matches),UVM_NONE); +endfunction + +endclass + diff --git a/sequencer.sv.txt b/sequencer.sv.txt new file mode 100644 index 0000000..e10b8e0 --- /dev/null +++ b/sequencer.sv.txt @@ -0,0 +1,2 @@ +typedef uvm_sequencer #(packet) sequencer; + diff --git a/slave_agent.sv.txt b/slave_agent.sv.txt new file mode 100644 index 0000000..ec64895 --- /dev/null +++ b/slave_agent.sv.txt @@ -0,0 +1,24 @@ +class slave_agent extends uvm_agent; +`uvm_component_utils(slave_agent) + +oMonitor oMon; +uvm_analysis_port#(packet) ap; + +function new (string name="slave_agent",uvm_component parent); + super.new(name,parent); +endfunction + +extern virtual function void build_phase(uvm_phase phase); +extern virtual function void connect_phase(uvm_phase phase); +endclass + +function void slave_agent::build_phase(uvm_phase phase); +super.build_phase(phase); +ap=new("slave_ap",this); + oMon=oMonitor::type_id::create("oMon",this); +endfunction + +function void slave_agent::connect_phase(uvm_phase phase); +super.connect_phase(phase); +oMon.analysis_port.connect(this.ap); +endfunction diff --git a/test.sv.txt b/test.sv.txt new file mode 100644 index 0000000..f5fff01 --- /dev/null +++ b/test.sv.txt @@ -0,0 +1,49 @@ +class test_sa3_da4 extends uvm_test; + +`uvm_component_utils(test_sa3_da4) + +virtual router_if vif; + + environment env; + + function new (string name="test_sa3_da4",uvm_component parent=null); + super.new(name,parent); + endfunction + + extern virtual function void build_phase(uvm_phase phase); + extern virtual function void final_phase(uvm_phase phase); + extern virtual task main_phase (uvm_phase phase); + +endclass + +function void test_sa3_da4::build_phase(uvm_phase phase); +super.build_phase(phase); +env=environment::type_id::create("env",this); +uvm_config_db#(virtual router_if)::get(this,"","vif",vif); + +uvm_config_db#(virtual router_if.tb)::set(this,"env.m_agent","drvr_if",vif.tb); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.m_agent","iMon_if",vif.tb_mon); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.s_agent","oMon_if",vif.tb_mon); + + uvm_config_db#(int)::set(this,"env.m_agent.seqr.*", "item_count", 100); + +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.reset_phase","default_sequence",reset_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.configure_phase","default_sequence",config_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.main_phase","default_sequence",sa3da4_sequence::get_type()); + +endfunction + +task test_sa3_da4::main_phase (uvm_phase phase); +uvm_objection objection; +super.main_phase(phase); +objection=phase.get_objection(); +objection.set_drain_time(this,1000ns); +//The drain time is the amount of time to wait once all objections have been dropped +endtask + + +function void test_sa3_da4::final_phase(uvm_phase phase); +super.final_phase(phase); +//uvm_top.print_topology(); +//factory.print(); +endfunction diff --git a/test_sa1_da1.sv.txt b/test_sa1_da1.sv.txt new file mode 100644 index 0000000..8deb05d --- /dev/null +++ b/test_sa1_da1.sv.txt @@ -0,0 +1,49 @@ +class test_sa1_da1 extends uvm_test; + +`uvm_component_utils(test_sa1_da1) + +virtual router_if vif; + + environment env; + + function new (string name="test_sa1_da1",uvm_component parent=null); + super.new(name,parent); + endfunction + + extern virtual function void build_phase(uvm_phase phase); + extern virtual function void final_phase(uvm_phase phase); + extern virtual task main_phase (uvm_phase phase); + +endclass + +function void test_sa1_da1::build_phase(uvm_phase phase); +super.build_phase(phase); +env=environment::type_id::create("env",this); +uvm_config_db#(virtual router_if)::get(this,"","vif",vif); + +uvm_config_db#(virtual router_if.tb)::set(this,"env.m_agent","drvr_if",vif.tb); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.m_agent","iMon_if",vif.tb_mon); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.s_agent","oMon_if",vif.tb_mon); + + uvm_config_db#(int)::set(this,"env.m_agent.seqr.*", "item_count", 100); + +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.reset_phase","default_sequence",reset_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.configure_phase","default_sequence",config_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.main_phase","default_sequence",sa1da1_sequence::get_type()); + +endfunction + +task test_sa1_da1::main_phase (uvm_phase phase); +uvm_objection objection; +super.main_phase(phase); +objection=phase.get_objection(); +objection.set_drain_time(this,1000ns); +//The drain time is the amount of time to wait once all objections have been dropped +endtask + + +function void test_sa1_da1::final_phase(uvm_phase phase); +super.final_phase(phase); +//uvm_top.print_topology(); +//factory.print(); +endfunction diff --git a/test_sa1_da2.sv.txt b/test_sa1_da2.sv.txt new file mode 100644 index 0000000..0cb7a9f --- /dev/null +++ b/test_sa1_da2.sv.txt @@ -0,0 +1,49 @@ +class test_sa1_da2 extends uvm_test; + +`uvm_component_utils(test_sa1_da2) + +virtual router_if vif; + + environment env; + + function new (string name="test_sa1_da2",uvm_component parent=null); + super.new(name,parent); + endfunction + + extern virtual function void build_phase(uvm_phase phase); + extern virtual function void final_phase(uvm_phase phase); + extern virtual task main_phase (uvm_phase phase); + +endclass + +function void test_sa1_da2::build_phase(uvm_phase phase); +super.build_phase(phase); +env=environment::type_id::create("env",this); +uvm_config_db#(virtual router_if)::get(this,"","vif",vif); + +uvm_config_db#(virtual router_if.tb)::set(this,"env.m_agent","drvr_if",vif.tb); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.m_agent","iMon_if",vif.tb_mon); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.s_agent","oMon_if",vif.tb_mon); + + uvm_config_db#(int)::set(this,"env.m_agent.seqr.*", "item_count", 100); + +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.reset_phase","default_sequence",reset_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.configure_phase","default_sequence",config_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.main_phase","default_sequence",sa1da2_sequence::get_type()); + +endfunction + +task test_sa1_da2::main_phase (uvm_phase phase); +uvm_objection objection; +super.main_phase(phase); +objection=phase.get_objection(); +objection.set_drain_time(this,1000ns); +//The drain time is the amount of time to wait once all objections have been dropped +endtask + + +function void test_sa1_da2::final_phase(uvm_phase phase); +super.final_phase(phase); +//uvm_top.print_topology(); +//factory.print(); +endfunction diff --git a/test_sa1_da3.sv.txt b/test_sa1_da3.sv.txt new file mode 100644 index 0000000..d8ee21c --- /dev/null +++ b/test_sa1_da3.sv.txt @@ -0,0 +1,49 @@ +class test_sa1_da3 extends uvm_test; + +`uvm_component_utils(test_sa1_da3) + +virtual router_if vif; + + environment env; + + function new (string name="test_sa1_da3",uvm_component parent=null); + super.new(name,parent); + endfunction + + extern virtual function void build_phase(uvm_phase phase); + extern virtual function void final_phase(uvm_phase phase); + extern virtual task main_phase (uvm_phase phase); + +endclass + +function void test_sa1_da3::build_phase(uvm_phase phase); +super.build_phase(phase); +env=environment::type_id::create("env",this); +uvm_config_db#(virtual router_if)::get(this,"","vif",vif); + +uvm_config_db#(virtual router_if.tb)::set(this,"env.m_agent","drvr_if",vif.tb); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.m_agent","iMon_if",vif.tb_mon); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.s_agent","oMon_if",vif.tb_mon); + + uvm_config_db#(int)::set(this,"env.m_agent.seqr.*", "item_count", 100); + +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.reset_phase","default_sequence",reset_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.configure_phase","default_sequence",config_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.main_phase","default_sequence",sa1da3_sequence::get_type()); + +endfunction + +task test_sa1_da3::main_phase (uvm_phase phase); +uvm_objection objection; +super.main_phase(phase); +objection=phase.get_objection(); +objection.set_drain_time(this,1000ns); +//The drain time is the amount of time to wait once all objections have been dropped +endtask + + +function void test_sa1_da3::final_phase(uvm_phase phase); +super.final_phase(phase); +//uvm_top.print_topology(); +//factory.print(); +endfunction diff --git a/test_sa1_da4.sv.txt b/test_sa1_da4.sv.txt new file mode 100644 index 0000000..ef93858 --- /dev/null +++ b/test_sa1_da4.sv.txt @@ -0,0 +1,49 @@ +class test_sa1_da4 extends uvm_test; + +`uvm_component_utils(test_sa1_da4) + +virtual router_if vif; + + environment env; + + function new (string name="test_sa1_da4",uvm_component parent=null); + super.new(name,parent); + endfunction + + extern virtual function void build_phase(uvm_phase phase); + extern virtual function void final_phase(uvm_phase phase); + extern virtual task main_phase (uvm_phase phase); + +endclass + +function void test_sa1_da4::build_phase(uvm_phase phase); +super.build_phase(phase); +env=environment::type_id::create("env",this); +uvm_config_db#(virtual router_if)::get(this,"","vif",vif); + +uvm_config_db#(virtual router_if.tb)::set(this,"env.m_agent","drvr_if",vif.tb); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.m_agent","iMon_if",vif.tb_mon); +uvm_config_db#(virtual router_if.tb_mon)::set(this,"env.s_agent","oMon_if",vif.tb_mon); + + uvm_config_db#(int)::set(this,"env.m_agent.seqr.*", "item_count", 100); + +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.reset_phase","default_sequence",reset_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.configure_phase","default_sequence",config_sequence::get_type()); +uvm_config_db#(uvm_object_wrapper)::set(this,"env.m_agent.seqr.main_phase","default_sequence",sa1da4_sequence::get_type()); + +endfunction + +task test_sa1_da4::main_phase (uvm_phase phase); +uvm_objection objection; +super.main_phase(phase); +objection=phase.get_objection(); +objection.set_drain_time(this,1000ns); +//The drain time is the amount of time to wait once all objections have been dropped +endtask + + +function void test_sa1_da4::final_phase(uvm_phase phase); +super.final_phase(phase); +//uvm_top.print_topology(); +//factory.print(); +endfunction diff --git a/top.sv.txt b/top.sv.txt new file mode 100644 index 0000000..1ef7d41 --- /dev/null +++ b/top.sv.txt @@ -0,0 +1,52 @@ +module top; + +bit clk; +always #5 clk++; + +router_if rif (clk); +program_router tb_inst (rif); + +duttop duttop_inst ( +.clk(clk) , +.rst(rif.rst), +.in1(rif.data_in[0]), +.in2(rif.data_in[1]), +.in3(rif.data_in[2]), +.in4(rif.data_in[3]), +.in1v(rif.inp_vld[0]), +.in2v(rif.inp_vld[1]), +.in3v(rif.inp_vld[2]), +.in4v(rif.inp_vld[3]), +.out1(rif.data_out[0]), +.out2(rif.data_out[1]), +.out3(rif.data_out[2]), +.out4(rif.data_out[3]), +.out1v(rif.outp_vld[0]), +.out2v(rif.outp_vld[1]), +.out3v(rif.outp_vld[2]), +.out4v(rif.outp_vld[3]), +.din(rif.reg_din), +.dout(rif.reg_dout), +.addr(rif.reg_addr), +.wr(rif.reg_wr), +.rd(rif.reg_rd), +.i1wy1(rif.i1wy[0]), +.i1wy2(rif.i1wy[1]), +.i1wy3(rif.i1wy[2]), +.i1wy4(rif.i1wy[3]), +.i2wy1(rif.i2wy[0]), +.i2wy2(rif.i2wy[1]), +.i2wy3(rif.i2wy[2]), +.i2wy4(rif.i2wy[3]), +.i3wy1(rif.i3wy[0]), +.i3wy2(rif.i3wy[1]), +.i3wy3(rif.i3wy[2]), +.i3wy4(rif.i3wy[3]), +.i4wy1(rif.i4wy[0]), +.i4wy2(rif.i4wy[1]), +.i4wy3(rif.i4wy[2]), +.i4wy4(rif.i4wy[3]) +); + + +endmodule