コミットを比較

...

共通のコミットはありません。 'master' と 'main' の履歴はすべて異なっています。
master ... main

10個のファイルの変更665行の追加2行の削除
分割表示
  1. +0
    -2
      README.md
  2. +40
    -0
      axi_env.sv
  3. +108
    -0
      axi_m_monitor.sv
  4. +50
    -0
      axi_master_agent.sv
  5. +109
    -0
      axi_s_monitor.sv
  6. +83
    -0
      driver.sv
  7. +0
    -0
      mango
  8. +45
    -0
      seq.sv
  9. +102
    -0
      seq_item.sv
  10. +128
    -0
      wrap_intf.sv

+ 0
- 2
README.md ファイルの表示

@@ -1,2 +0,0 @@
# aswini_axi


+ 40
- 0
axi_env.sv ファイルの表示

@@ -0,0 +1,40 @@
class axi_env extends uvm_env;
`uvm_component_utils(axi_env)
// Components
axi_master master;
axi_slave slave;
axi_scoreboard scb;
env_config env_cfg;
//
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction //new()
// Function: build_phase
extern function void build_phase(uvm_phase phase);
// Function: connect_phase
extern function void connect_phase(uvm_phase phase);
endclass //axi_env extends uvm_env
function void axi_env::build_phase(uvm_phase phase);
/* note: Do not call super.build_phase() from any class that is extended from an UVM base class! */
/* For more information see UVM Cookbook v1800.2 p.503 */
//super.build_phase(phase);
master = axi_master::type_id::create("master", this);
slave = axi_slave::type_id::create("slave", this);
scb = axi_scoreboard::type_id::create("scb", this);
endfunction: build_phase
function void axi_env::connect_phase(uvm_phase phase);
super.connect_phase(phase);
master.ap.connect(scb.m_ap_imp);
slave.ap.connect(scb.s_ap_imp);
endfunction: connect_phase

+ 108
- 0
axi_m_monitor.sv ファイルの表示

@@ -0,0 +1,108 @@
class axi_m_monitor extends uvm_monitor;
`uvm_component_utils(axi_m_monitor)
// Components
uvm_analysis_port#(axi_transaction#(D_WIDTH, A_WIDTH)) ap;
virtual axi_intf#(.D_WIDTH(D_WIDTH), .A_WIDTH(A_WIDTH)).SMON vif;
// variables
axi_transaction#(D_WIDTH, A_WIDTH) w_trans, r_trans;
bit w_done, r_done;
int b_size;
// Methods
extern task run_mon(uvm_phase phase);
extern task write_monitor();
extern task read_monitor();
function new(string name, uvm_component parent);
super.new(name, parent);
w_done = 1;
r_done = 1;
endfunction //new()
// Function: build_phase
extern function void build_phase(uvm_phase phase);
// Function: run_phase
extern task run_phase(uvm_phase phase);
endclass //axi_m_monitor extends uvm_monitor
function void axi_m_monitor::build_phase(uvm_phase phase);
ap = new("ap", this);
endfunction: build_phase
task axi_m_monitor::run_phase(uvm_phase phase);
forever begin
run_mon(phase);
@(vif.mon_cb);
end
endtask: run_phase
task axi_m_monitor::run_mon(uvm_phase phase);
fork
if(w_done) begin
phase.raise_objection(this);
w_done = 0;
write_monitor();
w_done = 1;
phase.drop_objection(this);
end
if(r_done) begin
phase.raise_objection(this);
r_done = 0;
read_monitor();
r_done = 1;
phase.drop_objection(this);
end
join_none
endtask: run_mon
task axi_m_monitor::write_monitor();
if(vif.mon_cb.AWVALID && vif.mon_cb.AWREADY) begin
w_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("w_trans");
w_trans.addr = vif.mon_cb.AWADDR;
w_trans.id = vif.mon_cb.AWID;
w_trans.b_size = vif.mon_cb.AWSIZE;
w_trans.b_len = vif.mon_cb.AWLEN;
w_trans.b_type = B_TYPE'(vif.mon_cb.AWBURST);
w_trans.data = new [w_trans.b_len+1];
for (int i=0; i<w_trans.b_len+1; i++) begin
@(vif.mon_cb);
wait(vif.mon_cb.WVALID && vif.mon_cb.WREADY);
w_trans.data[i] = new [D_WIDTH/8];
for (int j=0; j<D_WIDTH/8; j++) begin
w_trans.data[i][j] = vif.mon_cb.WDATA[8*j+:8];
end
end
wait(vif.mon_cb.BVALID);
w_trans.b_resp = vif.mon_cb.BRESP;
ap.write(w_trans);
`uvm_info("MMON", $sformatf("WTRANS %s", w_trans.convert2string()), UVM_HIGH)
end
endtask: write_monitor
task axi_m_monitor::read_monitor();
if(vif.mon_cb.ARVALID && vif.mon_cb.ARREADY) begin
r_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("r_trans");
r_trans.addr = vif.mon_cb.ARADDR;
r_trans.id = vif.mon_cb.ARID;
r_trans.b_size = vif.mon_cb.ARSIZE;
r_trans.b_len = vif.mon_cb.ARLEN;
r_trans.b_type = B_TYPE'(vif.mon_cb.ARBURST);
r_trans.data = new [r_trans.b_len+1];
r_trans.r_resp = new [r_trans.b_len+1];
for (int i=0; i<r_trans.b_len+1; i++) begin
@(vif.mon_cb);
wait(vif.mon_cb.RVALID && vif.mon_cb.RREADY);
r_trans.data[i] = new [D_WIDTH/8];
for (int j=0; j<D_WIDTH/8; j++) begin
r_trans.data[i][j] = vif.mon_cb.RDATA[8*j+:8];
end
r_trans.r_resp[i] = vif.mon_cb.RRESP;
end
ap.write(r_trans);
`uvm_info("MMON", $sformatf("RTRANS %s", r_trans.convert2string()), UVM_HIGH)
end
endtask: read_monitor

+ 50
- 0
axi_master_agent.sv ファイルの表示

@@ -0,0 +1,50 @@
class axi_master extends uvm_agent;
`uvm_component_utils(axi_master)
// Components
uvm_sequencer#(axi_transaction#(D_WIDTH, A_WIDTH)) w_seqr;
uvm_sequencer#(axi_transaction#(D_WIDTH, A_WIDTH)) r_seqr;
axi_m_driver drv;
axi_m_monitor mon;
uvm_analysis_port#(axi_transaction#(D_WIDTH, A_WIDTH)) ap;
// Variables
env_config env_cfg;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction //new()
// Function: build_phase
extern function void build_phase(uvm_phase phase);
// Function: connect_phase
extern function void connect_phase(uvm_phase phase);
endclass //axi_master extends uvm_agent
function void axi_master::build_phase(uvm_phase phase);
env_cfg = new("env_cfg");
assert (uvm_config_db#(env_config)::get(this, "", "config", env_cfg)) begin
`uvm_info(get_name(), "vif has been found in ConfigDB.", UVM_LOW)
end else `uvm_fatal(get_name(), "vif cannot be found in ConfigDB!")
drv = axi_m_driver::type_id::create("drv", this);
mon = axi_m_monitor::type_id::create("mon", this);
w_seqr = uvm_sequencer#(axi_transaction#(D_WIDTH, A_WIDTH))::type_id::create("w_seqr", this);
r_seqr = uvm_sequencer#(axi_transaction#(D_WIDTH, A_WIDTH))::type_id::create("r_seqr", this);
drv.vif = env_cfg.intf;
mon.vif = env_cfg.intf;
ap = new("ap", this);
endfunction: build_phase
function void axi_master::connect_phase(uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(w_seqr.seq_item_export);
drv.seq_item_port2.connect(r_seqr.seq_item_export);
mon.ap.connect(ap);
endfunction: connect_phase

+ 109
- 0
axi_s_monitor.sv ファイルの表示

@@ -0,0 +1,109 @@
class axi_s_monitor extends uvm_monitor;
`uvm_component_utils(axi_s_monitor)
// Components
uvm_analysis_port#(axi_transaction#(D_WIDTH, A_WIDTH)) ap;
virtual axi_intf#(.D_WIDTH(D_WIDTH), .A_WIDTH(A_WIDTH)).SMON vif;
// variables
axi_transaction#(D_WIDTH, A_WIDTH) w_trans, r_trans;
bit w_done, r_done;
int b_size;
// Methods
extern task run_mon(uvm_phase phase);
extern task write_monitor();
extern task read_monitor();
function new(string name, uvm_component parent);
super.new(name, parent);
w_done = 1;
r_done = 1;
endfunction //new()
// Function: build_phase
extern function void build_phase(uvm_phase phase);
// Function: run_phase
extern task run_phase(uvm_phase phase);
endclass //axi_s_monitor extends uvm_monitor
function void axi_s_monitor::build_phase(uvm_phase phase);
ap = new("ap", this);
endfunction: build_phase
task axi_s_monitor::run_phase(uvm_phase phase);
forever begin
run_mon(phase);
@(vif.mon_cb);
end
endtask: run_phase
task axi_s_monitor::run_mon(uvm_phase phase);
fork
if(w_done) begin
phase.raise_objection(this);
w_done = 0;
write_monitor();
w_done = 1;
phase.drop_objection(this);
end
if(r_done) begin
phase.raise_objection(this);
r_done = 0;
read_monitor();
r_done = 1;
phase.drop_objection(this);
end
join_none
endtask: run_mon
task axi_s_monitor::write_monitor();
if(vif.mon_cb.AWVALID && vif.mon_cb.AWREADY) begin
w_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("w_trans");
w_trans.addr = vif.mon_cb.AWADDR;
w_trans.id = vif.mon_cb.AWID;
w_trans.b_size = vif.mon_cb.AWSIZE;
w_trans.b_len = vif.mon_cb.AWLEN;
w_trans.b_type = B_TYPE'(vif.mon_cb.AWBURST);
w_trans.data = new [w_trans.b_len+1];
for (int i=0; i<w_trans.b_len+1; i++) begin
@(vif.mon_cb);
wait(vif.mon_cb.WVALID && vif.mon_cb.WREADY);
w_trans.data[i] = new [D_WIDTH/8];
for (int j=0; j<D_WIDTH/8; j++) begin
w_trans.data[i][j] = vif.mon_cb.WDATA[8*j+:8];
end
end
wait(vif.mon_cb.BVALID);
w_trans.b_resp = vif.mon_cb.BRESP;
ap.write(w_trans);
`uvm_info("SMON", $sformatf("WTRANS %s", w_trans.convert2string()), UVM_HIGH)
end
endtask: write_monitor
task axi_s_monitor::read_monitor();
if(vif.mon_cb.ARVALID && vif.mon_cb.ARREADY) begin
r_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("r_trans");
r_trans.addr = vif.mon_cb.ARADDR;
r_trans.id = vif.mon_cb.ARID;
r_trans.b_size = vif.mon_cb.ARSIZE;
r_trans.b_len = vif.mon_cb.ARLEN;
r_trans.b_type = B_TYPE'(vif.mon_cb.ARBURST);
r_trans.data = new [r_trans.b_len+1];
r_trans.r_resp = new [r_trans.b_len+1];
for (int i=0; i<r_trans.b_len+1; i++) begin
@(vif.mon_cb);
wait(vif.mon_cb.RVALID && vif.mon_cb.RREADY);
r_trans.data[i] = new [D_WIDTH/8];
for (int j=0; j<D_WIDTH/8; j++) begin
r_trans.data[i][j] = vif.mon_cb.RDATA[8*j+:8];
end
r_trans.r_resp[i] = vif.mon_cb.RRESP;
end
ap.write(r_trans);
`uvm_info("SMON", $sformatf("RTRANS %s", r_trans.convert2string()), UVM_HIGH)
end
endtask: read_monitor

+ 83
- 0
driver.sv ファイルの表示

@@ -0,0 +1,83 @@
class driver extends uvm_driver #(wrap_txn);
`uvm_component_utils(driver)
virtual axi_if vif;
wrap_txn txn;
function new(string name ="driver",uvm_component parent);
suoer.new(name,parent);
endfunction

function void build_phase(uvm_phase phase);
super.build_phase(phase);
txn = wrap_txn::type_id::create("txn",this);
if(!uvm_config_db #(axi_if)::get(this,"","vif",vif))
`uvm_error("build phase","driver virtual interface failed")
endfunction

task run_phase(uvm_phase phase);
forever
begin
seq_item_port.get_next_item(txn);
drive_logic(txn);
seq_item_port.item_done();
end
endtask

task drve_logic(wrap_txn txn);
begin
`uvm_info("AXI_DRIVER",$sformatf("driver started"),UVM_LOW);
@(vif.drv_cb);
vif.arst<=1;
@(vif.drv_cb);
vif.arst<=0;
if(wr_rd <= 1)
begin
vif.awid <= txn.awid;
vif.awaddr<= txn.awaddr;
vif.awburst <= txn.awburst;
vif.awsize <= txn.awsize;
vif.awlen <= txn.awlen;
vif.awlock <= txn.awlen;
vif.awprot <= txn.awprot;
vif.awcache<= txn.awcache;
vif.awvalid <= 1;
wait(vif.drv_cb.awready == 1);
vif.awvalid <= 0;
@(vif.drv_cb);
for(int i =1;i<=vif.awlen+1;i++)
begin
vif.wid <= txn.wid;
vif.wdata<= txn.wdata.pop_front();
vif.wstrb <= txn.wstrb;
vif.awvalid <= 1;
if(i == vif.awlen+1)
vif.wlast <= txn.wlast;
else
vif.wlast <= 0;
wait(vif.wready == 1);
vif.wvalid <= 0;
end
@(vif.drv_cb);
vif.bid <= txn.bid;
vif.bresp <= txn.bresp;
vif.bvalid <= 1;
wait(vif.bready == 1);
vif.bvalid <= 0;
end
else
begin
vif.arid <= txn.arid;
vif.araddr<= txn.araddr;
vif.arburst <= txn.arburst;
vif.arsize <= txn.arsize;
vif.arlen <= txn.arlen;
vif.arlock <= txn.arlen;
vif.arprot <= txn.arprot;
vif.arcache<= txn.arcache;
vif.arvalid <= 1;
wait(vif.drv_cb.arready == 1);
vif.arvalid <= 0;
@(vif.drv_cb);
end
end
endtask


+ 0
- 0
mango ファイルの表示


+ 45
- 0
seq.sv ファイルの表示

@@ -0,0 +1,45 @@
class wr_seq extends uvm_sequence #(wrap_txn);
`uvm_object_utils(wr_seq)
wrap_txn txn;
function new(string name = "wr_seq");
super.new(name);
endfunction

task body();
txn=wrap_txn::type_id::create("txn");
start_item(txn);
assert(txn.randomize() with {wr_rd == 1;});
finish_item(txn);
endtask

endclass

class rd_seq extends uvm_sequence #(wrap_txn);
`uvm_object_utils(rd_seq)
wrap_txn txn;
function new(string name = "rd_seq");
super.new(name);
endfunction

task body();
txn=wrap_txn::type_id::create("txn");
start_item(txn);
assert(txn.randomize() with {wr_rd ==0;});
finish_item(txn);
endtask
endclass

class seq extends uvm_sequence#(wrap_txn);
`uvm_object_utils(seq)
wr_seq w_s;
rd_seq r_s;
function new(string name = "seq");
super.new(name);
endfunction
task body();
`uvm_do(w_s);
`uvm_do(r_s);
endtask
endclass


+ 102
- 0
seq_item.sv ファイルの表示

@@ -0,0 +1,102 @@
class wrap_txn extends uvm_sequence_item;
function new(string name ="wrap_txn");
super.new(name)
endfunction
rand bit wr_rd;
//write address channel
rand logic[31:0]awaddr;
rand bit[3:0]awid;
rand logic[3:0]awlen;
rand logic[2:0]awsize;
rand logic[1:0]awburst;
rand logic[3:0]awcache;
rand logic[2:0]awprot;
rand logic[1:0]awlock;
logic awvalid;'
logic awready;
'
//write data channel
rand bit[3:0]wid;
logic[3:0]wstrb;
rand logic[31:0]wdata[$];
logic wlast;
logic wvalid;
logic wready;
//write response channel
rand bit[3:0]bid;
logic[1:0]bresp;
logic bvalid;
logic bready;
//read address channel
rand logic[31:0]araddr;
rand bit[3:0]arid;
rand logic[3:0]arlen;
rand logic[2:0]arsize;
rand logic[1:0]arburst;
rand logic[3:0]arcache;
rand logic[2:0]arprot;
rand logic[1:0]arlock;
logic arvalid;
logic arready;
//read data channel
rand bit[3:0]rid;
logic[31:0]rdata[$];
logic rlast;
logic[1:0]rresp;
logic rvalid;
logic rready;
constraint write_id {awid == wid; wid == bid;}
constraint read_id {arid == rid;}
constraint wr_data {wdata.size()==awlen+1;}
constraint write_unalign {awaddr%(2**awsize)!=0;}
constraint wrap {awburst ==2'b10; arburst ==2'b10;}
constraint read_unalign {araddr%(2**arsize)!=0;}
function void post_randomize();
if(wr_rd = 1)
begin
for(int i=1;i<=(2**awsize);i++)
wstrb[i] = 1;
end
endfunction
`uvm_object_param_utils_begin(wrap_txn)
`uvm_field_int(wr_rd,UVM_ALL_ON)
`uvm_field_int(awaddr,UVM_ALL_ON)
`uvm_field_int(awid,UVM_ALL_ON)
`uvm_field_int(awlen,UVM_ALL_ON)
`uvm_field_int(awsize,UVM_ALL_ON)
`uvm_field_int(awburst,UVM_ALL_ON)
`uvm_field_int(awcache,UVM_ALL_ON)
`uvm_field_int(awprot,UVM_ALL_ON)
`uvm_field_int(awlock,UVM_ALL_ON)
`uvm_field_int(awvalid,UVM_ALL_ON)
`uvm_field_int(awready,UVM_ALL_ON)
`uvm_field_int(wid,UVM_ALL_ON)
`uvm_field_queue_int(wdata,UVM_ALL_ON)
`uvm_field_int(wstrb,UVM_ALL_ON)
`uvm_field_int(wlast,UVM_ALL_ON)
`uvm_field_int(wvalid,UVM_ALL_ON)
`uvm_field_int(wready,UVM_ALL_ON)
`uvm_field_int(bid,UVM_ALL_ON)
`uvm_field_int(bresp,UVM_ALL_ON)
`uvm_field_int(araddr,UVM_ALL_ON)
`uvm_field_int(arid,UVM_ALL_ON)
`uvm_field_int(arlen,UVM_ALL_ON)
`uvm_field_int(arsize,UVM_ALL_ON)
`uvm_field_int(arburst,UVM_ALL_ON)
`uvm_field_int(arcache,UVM_ALL_ON)
`uvm_field_int(arprot,UVM_ALL_ON)
`uvm_field_int(arlock,UVM_ALL_ON)
`uvm_field_int(arvalid,UVM_ALL_ON)
`uvm_field_int(arready,UVM_ALL_ON)
`uvm_field_int(rid,UVM_ALL_ON)
`uvm_field_queue_int(rdata,UVM_ALL_ON)
`uvm_field_int(rlast,UVM_ALL_ON)
`uvm_field_int(rresp,UVM_ALL_ON)
`uvm_field_int(rvalid,UVM_ALL_ON)
`uvm_field_int(rready,UVM_ALL_ON)
`uvm_object_utils_end
endclass

+ 128
- 0
wrap_intf.sv ファイルの表示

@@ -0,0 +1,128 @@
interface axi_if(input bit aclk,arst);
//write address channel
logic[31:0]awaddr;
bit[3:0]awid;
logic[3:0]awlen;
logic[2:0]awsize;
logic[1:0]awburst;
logic[3:0]awcache;
logic[2:0]awprot;
logic[1:0]awlock;
logic awvalid;'
logic awready;
//write data channel
bit[3:0]wid;
logic[3:0]wstrb;
logic[31:0]wdata[$];
logic wlast;
logic wvalid;
logic wready;
//write response channel
bit[3:0]bid;
logic[1:0]bresp;
logic bvalid;
logic bready;
//read address channel
logic[31:0]araddr;
bit[3:0]arid;
logic[3:0]arlen;
logic[2:0]arsize;
logic[1:0]arburst;
logic[3:0]arcache;
logic[2:0]arprot;
logic[1:0]arlock;
logic arvalid;
logic arready;
//read data channel
bit[3:0]rid;
logic[31:0]rdata[$];
logic rlast;
logic[1:0]rresp;
logic rvalid;
logic rready;
clocking drv_cb @(posedge aclk);
default input #1 output #0;
output awid; //write address channel
output awaddr;
output awlen;
output awsize;
output awburst;
output awprot;
output awcache;
output awlock;
output awvalid;
input awready;
output wid; //write data channel
output wdata;
output wstrb;
output wlast;
output wvalid;
input wready; //write response channel
input bid;
input bresp;
input bvalid;
output bready;
output arid; //read address channel
output araddr;
output arlen;
output arsize;
output arburst;
output arprot;
output arcache;
output arlock;
output arvalid;
input arready;
input rid; //read response channel
input rdata;
input rresp;
input rlast;
input rvalid;
output rready;
endclocking
clocking mon_cb @(posedge clk);
default input #1 output #0;
input awid; //write address channel
input awaddr;
input awlen;
input awsize;
input awburst;
input awprot;
input awcache;
input awlock;
input awvalid;
input awready;
input wid; //write data channel
input wdata;
input wstrb;
input wlast;
input wvalid;
input wready; //write response channel
input bid;
input bresp;
input bvalid;
input bready;
input arid; //read address channel
input araddr;
input arlen;
input arsize;
input arburst;
input arprot;
input arcache;
input arlock;
input arvalid;
input arready;
input rid; //read data channel
input rdata;
input rresp;
input rlast;
input rvalid;
input rready;
endclocking
modport drv_mod(clocking drv_cb,arst);
modport mon_mod(clocking mon_cb,arst);
endinterface

読み込み中…
キャンセル
保存