| @@ -1,2 +0,0 @@ | |||
| # charan_axi_code | |||
| @@ -0,0 +1,11 @@ | |||
| class axi_coverage extends uvm_subscriber#(sequence_item); | |||
| `uvm_component_utils(axi_coverage); | |||
| axi_seq_item txn; | |||
| covergroup axi_cvrg; | |||
| @(posedge clk) | |||
| coverpoint awlen{ bins b1[]={[1,3,7,15]};} | |||
| coverpoint awsize{ bins b2[]={[1:7]};} | |||
| coverpoint awburst{ bins b3[]={0,1,2}; | |||
| ignore_bins b31={3};} | |||
| endgroup | |||
| @@ -0,0 +1,460 @@ | |||
| class driver extends uvm_driver #(seq); | |||
| `uvm_component_utils(driver) | |||
| virtual axi_driver_if vif; | |||
| sequence seq; | |||
| function new(string name="driver", uvm_component parent=null); | |||
| super.new(name, parent); | |||
| endfunction | |||
| virtual function void build_phase(uvm_phase phase); | |||
| super.build_phase(phase); | |||
| seq=sequence::type_id::create("seq"); | |||
| if(!uvm_config_db#(virtual axi_driver_if)::get(this," ","vif",vif)) | |||
| `uvm_error("driver"," Interface not set"); | |||
| endfunction | |||
| task reset(); | |||
| begin | |||
| vif.awvalid <= 0; | |||
| vif.awready <= 0; | |||
| vif.awid <= 0; | |||
| vif.awlen <= 0; | |||
| vif.awsize <= 0; | |||
| vif.awaddr <= 0; | |||
| vif.awburst <= 0; | |||
| vif.wvalid <= 0; | |||
| vif.wready <= 0; | |||
| vif.wid <= 0; | |||
| vif.wdata <= 0; | |||
| vif.wstrb <= 0; | |||
| vif.wlast <= 0; | |||
| vif.bready <= 0; | |||
| vif.bvalid <= 0; | |||
| vif.bid <= 0; | |||
| vif.bresp <= 0; | |||
| vif.arvalid <= 0; | |||
| vif.arready <= 0; | |||
| vif.arid <= 0; | |||
| vif.arlen <= 0; | |||
| vif.arsize <= 0; | |||
| vif.araddr <= 0; | |||
| vif.arburst <= 0; | |||
| vif.rvalid <= 0; | |||
| vif.rready <= 0; | |||
| vif.rid <= 0; | |||
| vif.rdata <= 0; | |||
| vif.rstrb <= 0; | |||
| vif.rlast <= 0; | |||
| vif.rresp <= 0; | |||
| @(posedge vif.clk); | |||
| `uvm_info(get_type_name(),"reset applied",UVM_MEDIUM) | |||
| end | |||
| endtask | |||
| virtual task run_phase(uvm_phase phase); | |||
| reset(); | |||
| seq_tem_port.get_next_item(txn); | |||
| if(wr_rd==1) | |||
| begin | |||
| wrtie_address(); | |||
| write_data(); | |||
| write_response(); | |||
| end | |||
| else | |||
| begin | |||
| read_address(); | |||
| read_data(); | |||
| end | |||
| endtask | |||
| virtual task write_address(); | |||
| vif.awready<=0; | |||
| vif.awaddr<= txn.awaddr; | |||
| vif.awsize<= txn.awsize; | |||
| vif.awlen<= txn.awlen; | |||
| vif.awcache<= txn.awcache; | |||
| vif.awburst<= txn.awburst; | |||
| vif.awvalid<=1'b1; | |||
| case (txn.awburst) | |||
| 2'b00 : write_ad_fixed_burst; | |||
| 2'b01 : write_ad_incr_burst; | |||
| 2'b10 : write_ad_wrap_burst; | |||
| endcase | |||
| while(vif.awready==0) | |||
| $display("within loop"); | |||
| begin | |||
| @(posedge vif.clk); | |||
| if(vif.awvalid==1) | |||
| begin | |||
| awready=1; | |||
| $display("write address phase is completed"); | |||
| end | |||
| end | |||
| vif.awvalid=0; | |||
| endtask | |||
| ////////////////// wridte_fixed burst//////////////// | |||
| virtual task write_ad_fixed_burst(); | |||
| vif.awlen <= txn.awlen; | |||
| vif.awid <= txn.awid; | |||
| vif.awaddr <= txn.awaddr; | |||
| vif.awsize<= txn.awsize; | |||
| vif.awvalid<= 1; | |||
| wait(vif.awready); | |||
| vif.awvalid<=0; | |||
| write_data(); | |||
| endtask | |||
| virtual task write_data(); | |||
| vif.wready<=0; | |||
| for(int i=0;i<=txn.awlen+1;i++) begin | |||
| $display("write data started"); | |||
| vif.wdata<=txn.wdata[i]; | |||
| vif.wstrb<=txn.wstrb[i]; | |||
| vif.wid<=txn.wid; | |||
| vif.wvalid<=1'b1; | |||
| if(i=txn.awlen+1) vif.wlast=1; | |||
| while (wready=0) | |||
| begin @(posedge vif.clk) | |||
| if (vif.wready==1) | |||
| txn.wready=1; | |||
| end | |||
| vif.wlast=0; | |||
| vif.wvalid=0; | |||
| vif.wready=0; | |||
| $display("write data completed"); | |||
| end | |||
| write_ad_incr(); | |||
| endtask | |||
| //////////////////////write_address_incremental///////////////// | |||
| virtual task write_ad_incr(); | |||
| vif.awlen <= txn.awlen; | |||
| for(int i=0; i<(txn.awlen +1);i++) | |||
| vif.awid <= txn.awid; | |||
| vif.awaddr <= txn.awaddr; | |||
| vif.awsize<= txn.awsize; | |||
| txn.awaddr<= txn.awaddr+(2**awsize); | |||
| vif.awvalid<= 1; | |||
| wait(vif.awready); | |||
| vif.awvalid<=0; | |||
| write_data(); | |||
| endtask | |||
| virtual task write_data(); | |||
| vif.wready<=0; | |||
| for(int i=0;i<=txn.awlen+1;i++) begin | |||
| $display("write data started"); | |||
| vif.wdata<=txn.wdata[i]; | |||
| vif.wstrb<=txn.wstrb[i]; | |||
| vif.wid<=txn.wid; | |||
| vif.wvalid<=1'b1; | |||
| if(i=txn.awlen+1) vif.wlast=1; | |||
| while (wready=0) | |||
| begin @(posedge vif.clk) | |||
| if (vif.wready==1) | |||
| txn.wready=1; | |||
| end | |||
| vif.wlast=0; | |||
| vif.wvalid=0; | |||
| vif.wready=0; | |||
| $display("write data completed"); | |||
| write_ad_wrap(); | |||
| end | |||
| endtask | |||
| ///////////wri_address_wrap/////////////////////// | |||
| virtual task write_ad_wrap(); | |||
| vif.awlen <= '{1,3,7,15}; | |||
| vif.awid <= txn.awid; | |||
| vif.awaddr <= txn.awaddr; | |||
| vif.awsize<= txn.awsize; | |||
| begin | |||
| int burst_length=(awlen+1); | |||
| int burst_size=(awsize+1); | |||
| int lower_boundary=INT[awaddr/(burst_length*burst_size)]*(burst_length*burst_size); | |||
| int upper_boundary=lower_boundar+(burst_length*burst_size); | |||
| for (int i=0; i< (pkt.awlen+1);i++) | |||
| begin | |||
| if(vif.awaddr==upper_boundary) | |||
| vif.awaddr=lower_boundary; | |||
| else | |||
| vif.awaddr <= vif.awaddr+ (2**vif.awsize); | |||
| vif.awvalid<= 1; | |||
| wait(vif.awready); | |||
| vif.awvalid<=0; | |||
| end | |||
| write_data(); | |||
| endtask | |||
| virtual task write_data(); | |||
| vif.wready<=0; | |||
| for(int i=0;i<=txn.awlen+1;i++) begin | |||
| $display("write data started"); | |||
| vif.wdata<=txn.wdata[i]; | |||
| vif.wstrb<=txn.wstrb[i]; | |||
| vif.wid<=txn.wid; | |||
| vif.wvalid<=1'b1; | |||
| if(i=txn.awlen+1) vif.wlast=1; | |||
| while (wready=0) | |||
| begin @(posedge vif.clk) | |||
| if (vif.wready==1) | |||
| txn.wready=1; | |||
| end | |||
| vif.wlast=0; | |||
| vif.wvalid=0; | |||
| vif.wready=0; | |||
| $display("write data completed"); | |||
| write_response(); | |||
| end | |||
| endtask | |||
| virtual task write_response(); | |||
| if(vif.wvalid&&vif.wready&&vif.wlast) | |||
| wait(bvalid) | |||
| begin | |||
| vif.bid = pkt.bid; | |||
| vif.bresp = pkt.bresp; | |||
| end | |||
| vif.bready <= 1 ; | |||
| for(i=0;i<=awlen+1;i++) | |||
| begin | |||
| if(vif.awid==vif.bid) | |||
| case(vif.bresp) | |||
| 2'b00:"okay"; | |||
| 2'b01:"exclusive okay"; | |||
| 2'b10:"slave error"; | |||
| 2'b11:"decode error"; | |||
| endcase | |||
| end | |||
| vif.bready<=0; | |||
| endtask | |||
| ///////////////////////Read address//////////////////////////////////////////////// | |||
| task read_adress(); | |||
| `uvm_info("master_driver",$sformatf("message from driver\n %s",pkt.sprint()),UVM_HIGH) | |||
| vif.arid <= pkt.arid; | |||
| vif.araddr <= pkt.araddr; | |||
| vif.arlen <= pkt.arlen; | |||
| vif.arsize <= pkt.arsize; | |||
| vif.arburst <= pkt.arburst; | |||
| vif.arvalid <= 1; | |||
| `uvm_info("master_driver",$sformatf("message from driver \n %s",pkt.sprint()),UVM_HIGH) | |||
| case (txn.arburst) | |||
| 2'b00 : read_address_fixed_burst; | |||
| 2'b01 : read_address_incr_burst; | |||
| 2'b10 : read_address_wrap_burst; | |||
| endcase | |||
| @(posedge vif.clk); | |||
| wait (vif.arready); | |||
| vif.arvalid <= 0; | |||
| endtask | |||
| //////////////////////////////////////// raed wrap burst//////////////////// | |||
| virtual task read_ad_wrap(); | |||
| vif.awlen <= '{1,3,7,15}; | |||
| vif.arid <= txn.arid; | |||
| vif.araddr <= txn.araddr; | |||
| vif.arsize<= txn.arsize; | |||
| begin | |||
| int burst_length=(arlen+1); | |||
| int burst_size=(arsize+1); | |||
| int lower_boundary=INT[araddr/(burst_length*burst_size)]*(burst_length*burst_size); | |||
| int upper_boundary=lower_boundar+(burst_length*burst_size); | |||
| for (int i=0; i< (txn.arlen+1);i++) | |||
| begin | |||
| if(vif.araddr==upper_boundary) | |||
| vif.araddr=lower_boundary; | |||
| else | |||
| vif.araddr <= vif.araddr+ (2**vif.arsize); | |||
| vif.arvalid<= 1; | |||
| wait(vif.arready); | |||
| vif.arvalid<=0; | |||
| end | |||
| read_data1(); | |||
| endtask | |||
| virtual task read_data1(); | |||
| vif.rready<=0; | |||
| for(int i=0;i<=txn.arlen+1;i++) begin | |||
| $display("read data started"); | |||
| vif.rdata<=txn.rdata[i]; | |||
| vif.rid<=txn.rid; | |||
| vif.rvalid<=1'b1; | |||
| if(i=txn.arlen+1) vif.rlast=1; | |||
| while (rready=0) | |||
| begin @(posedge vif.clk) | |||
| if (vif.rready==1) | |||
| txn.rready=1; | |||
| end | |||
| vif.rlast=0; | |||
| vif.rvalid=0; | |||
| $display("read data completed"); | |||
| end | |||
| foreach (vif.rdata[i]) | |||
| begin | |||
| if (vif.arid == vif.rid) | |||
| begin | |||
| case (vif.rresp) | |||
| 2'b00 : s = "Transaction OKAY"; | |||
| 2'b01 : s = "Transaction FAILED"; | |||
| 2'b10 : s = "SLAVE ERROR"; | |||
| 2'b11 : s = "DEEOCDE ERROR"; | |||
| endcase | |||
| `uvm_info("axi master_driver",$sformatf("\n t %s response for the received data \n",s),UVM_MEDIUM) | |||
| end | |||
| end | |||
| vif.rready <= 0; | |||
| endtask | |||
| //////////////////////////////////////// INCR address //////////////// | |||
| task read_address_incr_burst(); | |||
| vif.arlen <=txn.arlen; | |||
| for(int i=0; i<(arlen +1);i++) | |||
| begin | |||
| vif.araddr<=txn.araddr; | |||
| vif.arid <= txn.arid; | |||
| vif.arvalid<= 1; | |||
| txn.araddr<= txn.araddr +(2**vif.arsize); | |||
| wait(vif.arready); | |||
| vif.arvalid<=0; | |||
| end | |||
| read_data(); | |||
| endtask | |||
| virtual task read_data(); | |||
| vif.rready<=0; | |||
| for(int i=0;i<=txn.arlen+1;i++) begin | |||
| $display("read data started"); | |||
| vif.rdata<=txn.rdata[i]; | |||
| vif.rid<=txn.rid; | |||
| vif.rvalid<=1'b1; | |||
| if(i=txn.arlen+1) vif.rlast=1; | |||
| while (rready=0) | |||
| begin @(posedge vif.clk) | |||
| if (vif.rready==1) | |||
| txn.rready=1; | |||
| end | |||
| vif.rlast=0; | |||
| vif.rvalid=0; | |||
| $display("read data completed"); | |||
| end | |||
| vif.rready <= 1; | |||
| foreach (vif.rdata[i]) | |||
| begin | |||
| if (vif.arid == vif.rid) | |||
| begin | |||
| case (vif.rresp) | |||
| 2'b00 : s = "Transaction OKAY"; | |||
| 2'b01 : s = "Transaction FAILED"; | |||
| 2'b10 : s = "SLAVE ERROR"; | |||
| 2'b11 : s = "DEEOCDE ERROR"; | |||
| endcase | |||
| `uvm_info("master_driver",$sformatf("\n\t %s response for the recieved data \n",s),UVM_MEDIUM) | |||
| end | |||
| end | |||
| vif.rready <= 0; | |||
| endtask | |||
| ///////////////read address fixed burst//////////////////////// | |||
| task read_address_fixed_burst (); | |||
| begin | |||
| vif.arlen <= txn.arlen; | |||
| vif.arid <= txn.arid; | |||
| vif.araddr <= txn.araddr; | |||
| vif.arvalid<= 1; | |||
| wait(vif.arready); | |||
| vif.arvalid<=0; | |||
| end | |||
| rd_dt_fixed_burst(); | |||
| endtask | |||
| task rd_dt_fixed_burst (); | |||
| vif.rready<=0; | |||
| for(int i=0;i<=txn.arlen+1;i++) begin | |||
| $display("read data started"); | |||
| vif.rdata<=txn.rdata[i]; | |||
| vif.rid<=txn.rid; | |||
| vif.rvalid<=1'b1; | |||
| if(i=txn.arlen+1) vif.rlast=1; | |||
| while (rready=0) | |||
| begin @(posedge vif.clk) | |||
| if (vif.rready==1) | |||
| txn.rready=1; | |||
| end | |||
| vif.rlast=0; | |||
| vif.rvalid=0; | |||
| $display("read data completed"); | |||
| end | |||
| foreach (vif.rdata[i]) | |||
| begin | |||
| if (vif.arid == vif.rid) | |||
| begin | |||
| case (vif.rresp) | |||
| 2'b00 : s = "Transaction OKAY"; | |||
| 2'b01 : s = "Transaction FAILED"; | |||
| 2'b10 : s = "SLAVE ERROR"; | |||
| 2'b11 : s = "DEEOCDE ERROR"; | |||
| endcase | |||
| `uvm_info("master_driver",$sformatf("\n\t %s response for recieved data \n",s),UVM_MEDIUM) | |||
| end | |||
| end | |||
| vif.rready <= 0; | |||
| endtask | |||
| if(txn.reset==1) begin | |||
| reset(); | |||
| end | |||
| //Write operation support | |||
| else if(txn.wr_rd==1) begin | |||
| `uvm_info(get_type_name()," write packet is received in driver ",UVM_MEDIUM) | |||
| begin | |||
| write_address(); | |||
| end | |||
| //read operation support | |||
| else if( txn.wr_rd==0) | |||
| begin | |||
| read_address(); | |||
| end | |||
| seq_item_port.item_done(); | |||
| end | |||
| endtask | |||
| endclass | |||
| @@ -0,0 +1,73 @@ | |||
| class axi_env extends uvm_env; | |||
| axi_env_config env_cfg_h; | |||
| master_agent_top mst_agt_top; | |||
| slave_agent_top slv_agt_top; | |||
| virtual_sequencer vseqr_h; | |||
| scoreboard sb; | |||
| extern function new(string name="axi_env",uvm_component parent); | |||
| extern function void build_phase(uvm_phase phase); | |||
| extern function void connect_phase(uvm_phase phase); | |||
| `uvm_component_utils(axi_env) | |||
| endclass | |||
| function axi_env::new(string name="axi_env",uvm_component parent); | |||
| super.new(name,parent); | |||
| endfunction | |||
| function void axi_env::build_phase(uvm_phase phase); | |||
| if(!uvm_config_db#(axi_env_config)::get(this,"","axi_env_config",env_cfg_h)) | |||
| `uvm_fatal("AXI Env","Unable to get axi env config, have you set it in test?") | |||
| if(env_cfg_h.has_master_agent) | |||
| begin | |||
| uvm_config_db#(master_config)::set(this,"mst_agt_top*","master_config",env_cfg_h.mst_cfg_h); | |||
| mst_agt_top=master_agent_top::type_id::create("mst_agt_top",this); | |||
| end | |||
| if(env_cfg_h.has_slave_agent) | |||
| begin | |||
| uvm_config_db#(slave_config)::set(this,"slv_agt_top*","slave_config",env_cfg_h.slv_cfg_h); | |||
| slv_agt_top=slave_agent_top::type_id::create("slv_agt_top",this); | |||
| end | |||
| if(env_cfg_h.has_virtual_sequencer) | |||
| begin | |||
| vseqr_h=virtual_sequencer::type_id::create("vseqr_h",this); | |||
| end | |||
| if(env_cfg_h.has_scoreboard) | |||
| sb=scoreboard::type_id::create("sb",this); | |||
| super.build_phase(phase); | |||
| endfunction | |||
| function void axi_env::connect_phase(uvm_phase phase); | |||
| if(env_cfg_h.has_virtual_sequencer) | |||
| begin | |||
| if(env_cfg_h.has_master_agent) | |||
| begin | |||
| foreach(mst_agt_top.mst_agt_h[i]) | |||
| vseqr_h.mst_seqr_h[i]=mst_agt_top.mst_agt_h[i].mst_seqr_h; | |||
| end | |||
| if(env_cfg_h.has_slave_agent) | |||
| begin | |||
| foreach(slv_agt_top.slv_agt_h[i]) | |||
| vseqr_h.slv_seqr_h[i]=slv_agt_top.slv_agt_h[i].slv_seqr_h; | |||
| end | |||
| end | |||
| if(env_cfg_h.has_scoreboard) | |||
| begin | |||
| foreach(mst_agt_top.mst_agt_h[i]) | |||
| mst_agt_top.mst_agt_h[i].mst_mon_h.mst_mon_port.connect(sb.mst_fifo_h[i].analysis_export); | |||
| foreach(slv_agt_top.slv_agt_h[i]) | |||
| slv_agt_top.slv_agt_h[i].slv_mon_h.slv_mon_port.connect(sb.slv_fifo_h[i].analysis_export); | |||
| end | |||
| endfunction | |||
| @@ -0,0 +1,65 @@ | |||
| Interfate axi_intf(input bit clk, reset); | |||
| ///////////////////write address channel///////////// | |||
| input logic awvalid; | |||
| output logic awready; input logic [3:0] awid; | |||
| input logic [3:0] awlen; | |||
| input logic [2:0] awsize; | |||
| input logic [31:0] awaddr; | |||
| input logic [1:0] awburst; | |||
| /////////////////////write data channel////////////////////////// | |||
| input logic wvalid; | |||
| output logic wready; | |||
| input logic [3:0] wid; | |||
| input logic [31:0] wdata; | |||
| input logic [3:0] wstrb; | |||
| input logic wlast; | |||
| ///////////////write response channel///////////////////// | |||
| input logic bready; | |||
| output logic bvalid; | |||
| output logic [3:0] bid; | |||
| output logic [1:0] bresp; | |||
| ////////////// read address channel//////////////// | |||
| output logic reg arready; | |||
| input logic [3:0] arid; | |||
| input logic [31:0] araddr; | |||
| input logic [3:0] arlen; | |||
| input logic [2:0] arsize; | |||
| input logic [1:0] arburst; | |||
| input logic arvalid; | |||
| ///////////////////read data channel//////////////////// | |||
| output logic [3:0] rid; | |||
| output logic [31:0]rdata; | |||
| output logic [1:0] rresp; | |||
| output logic rlast; | |||
| output logic rvalid; | |||
| input logic rready; | |||
| ////////////////////bvalid assertion////////////// | |||
| property wvalid_wready; | |||
| @(posedge clk) (wvalid && wready)|=> bvalid; | |||
| endproperty | |||
| assert property(wvalid_wready) | |||
| $display("bvalid is asserted after wvalid and wready:assertion passed"); | |||
| else | |||
| 'uvm_error("assertion failed"); | |||
| ////////////////////rvalid assertion////////////// | |||
| property arvalid_arready; | |||
| @(posedge clk) (arvalid && arready)|=> rvalid; | |||
| endproperty | |||
| assert property(arvalid_arready) | |||
| $display("rvalid is asserted after arvalid and arready:assertion passed"); | |||
| else | |||
| 'uvm_error("assertion failed"); | |||
| endinterface | |||
| @@ -0,0 +1,123 @@ | |||
| class scoreboard extends uvm_scoreboard; | |||
| `uvm_component_utils(scoreboard) | |||
| uvm_tlm_analysis_fifo#(axi_xtn) mst_fifo_h[]; | |||
| uvm_tlm_analysis_fifo#(axi_xtn) slv_fifo_h[]; | |||
| axi_env_config env_cfg_h; | |||
| axi_xtn wr_xtn,rd_xtn; | |||
| axi_xtn mst_xtn,slv_xtn; | |||
| static int pkt_rcvd,pkt_cmprd; | |||
| covergroup write_cg; | |||
| option.per_instance=1; | |||
| awaddr_cp: coverpoint wr_xtn.AWADDR{bins awaddr_bin={[0:'hffff_ffff]};} | |||
| awburst_cp: coverpoint wr_xtn.AWBURST{bins awburst_bin[]={[0:2]};} | |||
| awsize_cp : coverpoint wr_xtn.AWSIZE{bins awsize_bin[]={[0:2]};} | |||
| awlen_cp : coverpoint wr_xtn.AWLEN{bins awlen_bin={[0:11]};} | |||
| bresp_cp : coverpoint wr_xtn.BRESP{bins bresp_bin={0};} | |||
| WRITE_ADDR_CROSS: cross awburst_cp,awsize_cp,awlen_cp; | |||
| endgroup | |||
| covergroup write_cg1 with function sample(int i); | |||
| option.per_instance=1; | |||
| wdata_cp : coverpoint wr_xtn.WDATA[i]{bins wdata_bin={[0:'hffff_ffff]};} | |||
| wstrb_cp : coverpoint wr_xtn.WSTRB[i]{bins wstrobe_bin0={4'b1111}; | |||
| bins wstrobe_bin1={4'b1100}; | |||
| bins wstrobe_bin2={4'b0011}; | |||
| bins wstrobe_bin3={4'b1000}; | |||
| bins wstrobe_bin4={4'b0100}; | |||
| bins wstrobe_bin5={4'b0010}; | |||
| bins wstrobe_bin6={4'b0001}; | |||
| bins wstrobe_bin7={4'b1110}; | |||
| } | |||
| WRITE_DATA_CROSS: cross wdata_cp,wstrb_cp; | |||
| endgroup | |||
| covergroup read_cg; | |||
| option.per_instance=1; | |||
| araddr_cp: coverpoint rd_xtn.ARADDR{bins araddr_bin={[0:'hffff_ffff]};} | |||
| arburst_cp: coverpoint rd_xtn.ARBURST{bins arburst_bin[]={[0:2]};} | |||
| arsize_cp : coverpoint rd_xtn.ARSIZE{bins arsize_bin[]={[0:2]};} | |||
| arlen_cp : coverpoint rd_xtn.ARLEN{bins arlen_bin={[0:11]};} | |||
| READ_ADDR_CROSS: cross arburst_cp,arsize_cp,arlen_cp; | |||
| endgroup | |||
| covergroup read_cg1 with function sample(int i); | |||
| option.per_instance=1; | |||
| rdata_cp : coverpoint rd_xtn.RDATA[i]{bins rdata_bin={[0:'hffff_ffff]};} | |||
| rresp_cp : coverpoint rd_xtn.RRESP[i]{bins rresp_bin={0};} | |||
| endgroup | |||
| extern function new(string name="scoreboard",uvm_component parent); | |||
| extern function void build_phase(uvm_phase phase); | |||
| extern task run_phase(uvm_phase); | |||
| extern function void report_phase(uvm_phase phase); | |||
| endclass | |||
| function scoreboard::new(string name="scoreboard",uvm_component parent); | |||
| super.new(name,parent); | |||
| write_cg=new(); | |||
| write_cg1=new(); | |||
| read_cg=new(); | |||
| read_cg1=new(); | |||
| endfunction | |||
| function void scoreboard::build_phase(uvm_phase phase); | |||
| if(!uvm_config_db #(axi_env_config)::get(this,"","axi_env_config",env_cfg_h)) | |||
| `uvm_fatal("Scoreboard","cannot get env config, have you set it?"); | |||
| mst_fifo_h=new[env_cfg_h.no_of_master]; | |||
| slv_fifo_h=new[env_cfg_h.no_of_slave]; | |||
| foreach(mst_fifo_h[i]) | |||
| mst_fifo_h[i]=new($sformatf("mst_fifo_h[%0d]",i),this); | |||
| foreach(slv_fifo_h[i]) | |||
| slv_fifo_h[i]=new($sformatf("slv_fifo_h[%0d]",i),this); | |||
| super.build_phase(phase); | |||
| endfunction | |||
| task scoreboard::run_phase(uvm_phase phase); | |||
| forever | |||
| begin | |||
| mst_fifo_h[0].get(mst_xtn); | |||
| slv_fifo_h[0].get(slv_xtn); | |||
| pkt_rcvd++; | |||
| if(mst_xtn.compare(slv_xtn)) | |||
| begin | |||
| wr_xtn=mst_xtn; | |||
| rd_xtn=mst_xtn; | |||
| pkt_cmprd++; | |||
| write_cg.sample(); | |||
| read_cg.sample(); | |||
| if(mst_xtn.WVALID) | |||
| begin | |||
| foreach(mst_xtn.WDATA[i]) | |||
| begin | |||
| write_cg1.sample(i); | |||
| end | |||
| end | |||
| if(mst_xtn.RVALID) | |||
| begin | |||
| foreach(mst_xtn.RDATA[i]) | |||
| begin | |||
| read_cg1.sample(i); | |||
| end | |||
| end | |||
| end | |||
| else | |||
| `uvm_error("Scoreboard","Master and Slave Packet Mismatch"); | |||
| end | |||
| endtask | |||
| function void scoreboard::report_phase(uvm_phase phase); | |||
| `uvm_info("SCOREBOARD",$sformatf("No. of packets received:%0d",pkt_rcvd),UVM_LOW); | |||
| `uvm_info("SCOREBOARD",$sformatf("No. of packets compared:%0d",pkt_cmprd),UVM_LOW); | |||
| endfunction | |||
| @@ -0,0 +1,61 @@ | |||
| class write_sequence_fixed extends uvm_sequence#(axi_seq_item); | |||
| `uvm_object_utils(write_sequence) | |||
| axi_seq_item txn; | |||
| function new(string name = "write_sequence"); | |||
| super.new(name); | |||
| endfunction | |||
| virtual task body(); | |||
| `uvm_info(get_type_name(), $sformatf("//---------------- FIXED SEQUENCE is started -----------------//"), UVM_MEDIUM) | |||
| txn = axi_seq_item::type_id::create("txn"); | |||
| start_item(txn); | |||
| assert(txn.randomize() with {awburst=2'b00;awlen=3;awsize=4};} );//FIXED | |||
| txn.wr_rd=1; | |||
| finish_item(txn); | |||
| endtask | |||
| endclass | |||
| class write_sequence_incremental extends uvm_sequence#(axi_seq_item); | |||
| `uvm_object_utils(write_sequence) | |||
| axi_seq_item txn; | |||
| function new(string name = "write_sequence"); | |||
| super.new(name); | |||
| endfunction | |||
| virtual task body(); | |||
| `uvm_info(get_type_name(), $sformatf("//---------------- INCREMENTAL SEQUENCE is started -----------------//"), UVM_MEDIUM) | |||
| txn = axi_seq_item::type_id::create("txn"); | |||
| start_item(txn); | |||
| assert(txn.randomize() with {awburst=2'b10;awaddr==awaddr+2**awsize};} );//INCREMENTAL | |||
| txn.wr_rd=1; | |||
| finish_item(txn); | |||
| endtask | |||
| endclass | |||
| class write_sequence_wrap extends uvm_sequence#(axi_seq_item); | |||
| `uvm_object_utils(write_sequence) | |||
| axi_seq_item txn; | |||
| function new(string name = "write_sequence"); | |||
| super.new(name); | |||
| endfunction | |||
| virtual task body(); | |||
| `uvm_info(get_type_name(), $sformatf("//---------------- WRAP SEQUENCE is started -----------------//"), UVM_MEDIUM) | |||
| txn = axi_seq_item::type_id::create("txn"); | |||
| start_item(txn); | |||
| assert(txn.randomize() with {awburst=2'b10;awlen=3;awsize=4};} );//WRAP | |||
| txn.write=1; | |||
| finish_item(txn); | |||
| endtask | |||
| endclass | |||
| class write_sequence extends uvm_sequence#(axi_seq_item); | |||
| `uvm_object_utils(write_sequence) | |||
| axi_seq_item txn; | |||
| function new(string name = "write_sequence"); | |||
| super.new(name); | |||
| endfunction | |||
| virtual task body(); | |||
| `uvm_info(get_type_name(), $sformatf("//---------------- WRITE SEQUENCE is started -----------------//"), UVM_MEDIUM) | |||
| txn = axi_seq_item::type_id::create("txn"); | |||
| start_item(txn); | |||
| assert(txn.randomize() with {foreach(awlen[i]) if(i==awlen+1) wlast==1};} );//for last transfer | |||
| txn.wr_rd=1; | |||
| finish_item(txn); | |||
| endtask | |||
| endclass | |||
| @@ -0,0 +1,93 @@ | |||
| [Yesterday 10:04 am] Mandla Ravali | |||
| class axi_seq_item extends uvm_sequence_item; | |||
| //factory registration for object | |||
| 'uvm_object_utils(axi_seq_item); | |||
| //////write address channel/////////////// | |||
| bit wr_rd; | |||
| bit reset; | |||
| randc logic [31:0] awaddr; | |||
| rand logic [3:0] awlen; | |||
| rand logic [2:0] awsize; | |||
| rand logic [1:0] awburst; | |||
| rand logic [1:0] awlock; | |||
| rand logic [3:0] awcache; | |||
| bit awvalid; | |||
| bit awready; | |||
| bit [1:0] awlock; | |||
| rand logic [2:0] awprot; | |||
| bit [3:0] awid; | |||
| /////////write data channel////////////// | |||
| bit [3:0] wid; | |||
| bit [2:0] wstrb[]; | |||
| logic [7:0] wdata[]; | |||
| bit [1:0] bresp | |||
| bit wvalid; | |||
| bit wready; | |||
| bit wlast; | |||
| bit wstrb; | |||
| //////read address channel ///////////////// | |||
| bit [3:0] arid; | |||
| randc logic [31:0] araddr; | |||
| rand logic [2:0] arsize; | |||
| rand logic [1:0] arburst; | |||
| rand logic [3:0] arlen; | |||
| rand logic [2:0] arprot; | |||
| rand logic [1:0] arlock; | |||
| rand logic [3:0] arcache; | |||
| bit arvalid; | |||
| bit arready; | |||
| ///////////read data channel//////////// | |||
| bit [3:0] rid; | |||
| logic [7:0] rdata; | |||
| bit rresp; | |||
| bit rvalid; | |||
| bit rready; | |||
| bit rlast; | |||
| function new (input string name = "axi_seq_item"); | |||
| super.new(name); | |||
| endfunction | |||
| ////4kb boundary/////////////////// | |||
| constraint awaddr_4k{ awaddr % 4096 <= {(awaddr+(awsize*awlen) % 4096;} | |||
| constraint araddr_4k{ araddr % 4096 <= {(araddr+(arsize*arlen) % 4096;} | |||
| ////last two bits of aligned address should be zero////////// | |||
| constraint ali_w_addr{ awaddr[1:0]==0;} | |||
| constraint ali_r_addr{ araddr[1:0]==0;} | |||
| //constraint burst_type{ awburst==2'b01;arburst==2'b01;}// burst type INCR | |||
| //////id's shoud be same for read and write//////////// | |||
| constraint wr_id{ wid==awid;} | |||
| constraint rd_id{ rid==arid;} | |||
| constraint rd_rid{rid inside {[wid,awid];}} | |||
| //constraint wr_id{ wid inside{[awid]};} | |||
| //constraint rd_id{ rid inside{[arid]};} | |||
| //////increment burst//////////////////////// | |||
| constraint wr_data_size{if(awburst==2'b01) | |||
| (wdata inside{[1:((2**awsize)*16)]});} | |||
| constraint rd_data_size{if(arburst==2'b01) | |||
| (rdata inside{[1:((2**arsize)*16)]});} | |||
| ///// data for wrap burst/////////////////////////////////// | |||
| constraint awdata{ if(awburst==2'b10) | |||
| wdata inside {((2**awsize)*2),((2**awsize)*4),((2**awsize)*8),((2**awsize)*16)};} | |||
| constraint ardata{ if(arburst==2'b10) | |||
| wdata inside {((2**arsize)*2),((2**arsize)*4),((2**arsize)*8),((2**arsize)*16)};} | |||
| endclass | |||
| @@ -0,0 +1,24 @@ | |||
| `include "axi_test_pkg.sv" | |||
| `include "axi_interface.sv" | |||
| module top; | |||
| import uvm_pkg::*; | |||
| import axi_test_pkg::*; | |||
| bit clk; | |||
| always #5 clk= ~clk; | |||
| axi_if axi_if0(clk); | |||
| initial | |||
| begin | |||
| uvm_config_db #(virtual axi_if)::set(null,"*","axi_if",axi_if0); | |||
| run_test("wrap_seq_test"); | |||
| end | |||
| endmodule | |||