├── UVM_AHB_SRAMC_CONTROL ├── RTL │ ├── RA1SH.v │ ├── sram_bist.v │ ├── sram_core.v │ ├── sramc_top.v │ ├── ahb_slave_if.v │ └── sram_bist_8kx8.v ├── hsize16.png ├── hsize8.png ├── hszie32.png ├── bankn_csn.png ├── TB │ └── tb_sramc_top.sv ├── ahb_wr_rd_ctr.jpg ├── ahb_sramc_control_frame.png ├── UVM │ ├── read_sramc_sequencer.sv │ ├── write_sramc_sequencer.sv │ ├── my_transaction.sv │ ├── my_virtual_sequencer.sv │ ├── read_sramc_transaction.sv │ ├── define.sv │ ├── read_sramc_seq.sv │ ├── write_sramc_seq.sv │ ├── read_sramc_agent.sv │ ├── write_sramc_agent.sv │ ├── base_test.sv │ ├── my_model.sv │ ├── read_sramc_monitor.sv │ ├── my_if.sv │ ├── write_sramc_monitor.sv │ ├── my_env.sv │ ├── my_case1.sv │ ├── my_case0.sv │ ├── my_case2.sv │ ├── my_scoreboard.sv │ ├── read_sramc_driver.sv │ ├── write_sramc_driver.sv │ └── tb_top.sv └── UVM testbench topology.md └── README.md /UVM_AHB_SRAMC_CONTROL/RTL/RA1SH.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/RTL/RA1SH.v -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/hsize16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/hsize16.png -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/hsize8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/hsize8.png -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/hszie32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/hszie32.png -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/bankn_csn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/bankn_csn.png -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/RTL/sram_bist.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/RTL/sram_bist.v -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/RTL/sram_core.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/RTL/sram_core.v -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/RTL/sramc_top.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/RTL/sramc_top.v -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/RTL/ahb_slave_if.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/RTL/ahb_slave_if.v -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/TB/tb_sramc_top.sv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/TB/tb_sramc_top.sv -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/ahb_wr_rd_ctr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/ahb_wr_rd_ctr.jpg -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/RTL/sram_bist_8kx8.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/RTL/sram_bist_8kx8.v -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/ahb_sramc_control_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wbbbbbb123/UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design/HEAD/UVM_AHB_SRAMC_CONTROL/ahb_sramc_control_frame.png -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/read_sramc_sequencer.sv: -------------------------------------------------------------------------------- 1 | `ifndef READ_SRAMC_SEQUENCER__SV 2 | `define READ_SRAMC_SEQUENCER__SV 3 | 4 | class read_sramc_sequencer extends uvm_sequencer #(read_sramc_transaction); 5 | 6 | function new(string name = "read_sramc_sequencer", uvm_component parent); 7 | super.new(name, parent); 8 | endfunction 9 | 10 | `uvm_component_utils(read_sramc_sequencer) 11 | endclass 12 | 13 | `endif -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/write_sramc_sequencer.sv: -------------------------------------------------------------------------------- 1 | `ifndef WRITE_SRAMC_SEQUENCER__SV 2 | `define WRITE_SRAMC_SEQUENCER__SV 3 | 4 | class write_sramc_sequencer extends uvm_sequencer #(my_transaction); 5 | 6 | function new(string name = "write_sramc_sequencer", uvm_component parent); 7 | super.new(name, parent); 8 | endfunction 9 | 10 | `uvm_component_utils(write_sramc_sequencer) 11 | endclass 12 | 13 | `endif 14 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_transaction.sv: -------------------------------------------------------------------------------- 1 | `include "define.sv" 2 | `ifndef MY_TRANSACTION__SV 3 | `define MY_TRANSACTION__SV 4 | 5 | class my_transaction extends uvm_sequence_item; 6 | 7 | rand bit[`DSIZE-1:0] data; 8 | 9 | 10 | `uvm_object_utils_begin(my_transaction) 11 | `uvm_field_int(data, UVM_ALL_ON) 12 | `uvm_object_utils_end 13 | 14 | 15 | function new(string name = "my_transaction"); 16 | super.new(); 17 | endfunction 18 | 19 | endclass 20 | `endif -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_virtual_sequencer.sv: -------------------------------------------------------------------------------- 1 | `ifndef MY_VIRTUAL_SEQUENCER__SV 2 | `define MY_VIRTUAL_SEQUENCER__SV 3 | 4 | class my_virtual_sequencer extends uvm_sequencer; 5 | //Declaration. 6 | write_sramc_sequencer m_wr_seqr; 7 | read_sramc_sequencer m_rd_seqr; 8 | 9 | function new(string name = "my_virtual_sequencer", uvm_component parent); 10 | super.new(name, parent); 11 | endfunction 12 | 13 | `uvm_component_utils(my_virtual_sequencer) 14 | endclass 15 | 16 | `endif -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/read_sramc_transaction.sv: -------------------------------------------------------------------------------- 1 | `ifndef READ_SRAMC_TRANSACTION__SV 2 | `define READ_SRAMC_TRANSACTION__SV 3 | 4 | class read_sramc_transaction extends uvm_sequence_item; 5 | 6 | rand bit[`DSIZE-1:0] data; 7 | 8 | `uvm_object_utils_begin(read_sramc_transaction) 9 | `uvm_field_int(data, UVM_ALL_ON) 10 | `uvm_object_utils_end 11 | 12 | function new(string name = "read_sramc_transaction"); 13 | super.new(); 14 | endfunction 15 | 16 | endclass 17 | `endif 18 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/define.sv: -------------------------------------------------------------------------------- 1 | 2 | `define DSIZE 16 //data_size 8bit/16bit/32bit 3 | `define DATA_DEPTH 2**15 //data_size=8bit-->DATA_DEPTH=2**16 data_size=16bit-->DATA_DEPTH=2**15 data_size=32bit-->DATA_DEPTH=2**14 4 | `define HCLK_PERIOD 50 //write clk 200ns 5 | `define START_ADDR 324 6 | /////////////////////AHB CTR//////////////////////// 7 | //h_size 8 | `define SIZE8 3'b000 //00:8bit、01:16bit、10:32bit 9 | `define SIZE16 3'b001 10 | `define SIZE32 3'b010 11 | //htrans 12 | `define NOTRANS 2'b00 //是否传输 13 | `define TRANS 2'b10 14 | //hwrite 15 | `define WR_EN 1'b1 16 | `define RD_EN 1'b0 17 | //hsel 18 | `define SEL 1'b1 19 | `define NOSEL 1'b0 20 | //hburst 21 | `define BURST 3'd0 22 | `define BURST_EN 3'd1 23 | //hready 24 | `define READY 1'b1 25 | `define NOREADY 1'b0 26 | 27 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/read_sramc_seq.sv: -------------------------------------------------------------------------------- 1 | `ifndef READ_SRAMC_SEQ_SV 2 | `define READ_SRAMC_SEQ_SV 3 | 4 | class read_sramc_seq extends uvm_sequence #(read_sramc_transaction); 5 | 6 | function new(string name= "read_sramc_seq"); 7 | super.new(name); 8 | endfunction 9 | 10 | extern virtual task body(); 11 | extern virtual task pre_body(); 12 | extern virtual task post_body(); 13 | 14 | `uvm_object_utils(read_sramc_seq) 15 | endclass 16 | 17 | task read_sramc_seq::body(); 18 | read_sramc_transaction rd_trans; 19 | `uvm_do(rd_trans) 20 | //`uvm_info("read_fifo_seq", "Get one transaction", UVM_MEDIUM) 21 | 22 | endtask 23 | 24 | task read_sramc_seq::pre_body(); 25 | if(starting_phase != null) begin 26 | starting_phase.raise_objection(this); 27 | end 28 | endtask 29 | 30 | task read_sramc_seq::post_body(); 31 | if(starting_phase != null) begin 32 | starting_phase.drop_objection(this); 33 | end 34 | endtask 35 | `endif 36 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/write_sramc_seq.sv: -------------------------------------------------------------------------------- 1 | `ifndef WRITE_SRAMC_SEQ_SV 2 | `define WRITE_SRAMC_SEQ_SV 3 | 4 | class write_sramc_seq extends uvm_sequence #(my_transaction); 5 | 6 | function new(string name= "write_sramc_seq"); 7 | super.new(name); 8 | endfunction 9 | 10 | extern virtual task body(); 11 | extern virtual task pre_body(); 12 | extern virtual task post_body(); 13 | 14 | `uvm_object_utils(write_sramc_seq) 15 | endclass 16 | 17 | task write_sramc_seq::body(); 18 | my_transaction my_trans; 19 | `uvm_do(my_trans) 20 | //`uvm_info("write_fifo_seq", "send one transaction", UVM_MEDIUM) 21 | 22 | endtask 23 | 24 | task write_sramc_seq::pre_body(); 25 | // if(starting_phase != null) begin 26 | // starting_phase.raise_objection(this); 27 | // end 28 | endtask 29 | 30 | task write_sramc_seq::post_body(); 31 | // if(starting_phase != null) begin 32 | // starting_phase.drop_objection(this); 33 | // end 34 | endtask 35 | `endif 36 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/read_sramc_agent.sv: -------------------------------------------------------------------------------- 1 | `ifndef READ_SRAMC_AGENT__SV 2 | `define READ_SRAMC_AGENT__SV 3 | 4 | class read_sramc_agent extends uvm_agent ; 5 | read_sramc_sequencer sqr; 6 | read_sramc_monitor mon; 7 | read_sramc_driver drv; 8 | 9 | uvm_analysis_port #(my_transaction) ap; 10 | 11 | function new(string name="read_sramc_agent", uvm_component parent); 12 | super.new(name, parent); 13 | endfunction 14 | 15 | extern virtual function void build_phase(uvm_phase phase); 16 | extern virtual function void connect_phase(uvm_phase phase); 17 | 18 | `uvm_component_utils(read_sramc_agent) 19 | endclass 20 | 21 | 22 | function void read_sramc_agent::build_phase(uvm_phase phase); 23 | super.build_phase(phase); 24 | sqr = read_sramc_sequencer::type_id::create("sqr", this); 25 | mon = read_sramc_monitor::type_id::create("mon", this); 26 | drv = read_sramc_driver::type_id::create("drv", this); 27 | endfunction 28 | 29 | function void read_sramc_agent::connect_phase(uvm_phase phase); 30 | super.connect_phase(phase); 31 | drv.seq_item_port.connect(sqr.seq_item_export); 32 | ap = mon.ap; 33 | endfunction 34 | 35 | `endif 36 | 37 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/write_sramc_agent.sv: -------------------------------------------------------------------------------- 1 | `ifndef WRITE_SRAMC_AGENT__SV 2 | `define WRITE_SRAMC_AGENT__SV 3 | 4 | class write_sramc_agent extends uvm_agent ; 5 | write_sramc_sequencer sqr; 6 | write_sramc_driver drv; 7 | write_sramc_monitor mon; 8 | 9 | uvm_analysis_port #(my_transaction) ap; 10 | 11 | function new(string name, uvm_component parent); 12 | super.new(name, parent); 13 | endfunction 14 | 15 | extern virtual function void build_phase(uvm_phase phase); 16 | extern virtual function void connect_phase(uvm_phase phase); 17 | 18 | `uvm_component_utils(write_sramc_agent) 19 | endclass 20 | 21 | 22 | function void write_sramc_agent::build_phase(uvm_phase phase); 23 | super.build_phase(phase); 24 | sqr = write_sramc_sequencer::type_id::create("sqr", this); 25 | drv = write_sramc_driver::type_id::create("drv", this); 26 | mon = write_sramc_monitor::type_id::create("mon", this); 27 | endfunction 28 | 29 | function void write_sramc_agent::connect_phase(uvm_phase phase); 30 | super.connect_phase(phase); 31 | drv.seq_item_port.connect(sqr.seq_item_export); 32 | ap = mon.ap; 33 | endfunction 34 | 35 | `endif 36 | 37 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/base_test.sv: -------------------------------------------------------------------------------- 1 | `ifndef BASE_TEST__SV 2 | `define BASE_TEST__SV 3 | 4 | class base_test extends uvm_test; 5 | 6 | my_env env; 7 | 8 | function new(string name = "base_test", uvm_component parent = null); 9 | super.new(name,parent); 10 | endfunction 11 | 12 | extern virtual function void build_phase(uvm_phase phase); 13 | extern virtual function void report_phase(uvm_phase phase); 14 | `uvm_component_utils(base_test) 15 | endclass 16 | 17 | 18 | function void base_test::build_phase(uvm_phase phase); 19 | super.build_phase(phase); 20 | env = my_env::type_id::create("env", this); 21 | uvm_top.set_timeout(1000000ns,0); 22 | endfunction 23 | 24 | function void base_test::report_phase(uvm_phase phase); 25 | uvm_report_server server; 26 | int err_num; 27 | super.report_phase(phase); 28 | 29 | server = get_report_server(); 30 | err_num = server.get_severity_count(UVM_ERROR); 31 | 32 | if (err_num != 0) begin 33 | $display("TEST CASE FAILED"); 34 | end 35 | else begin 36 | $display("TEST CASE PASSED"); 37 | end 38 | //`uvm_info("base_test:report", $sformatf("coverage:%p",$get_coverage), UVM_MEDIUM) 39 | endfunction 40 | 41 | `endif 42 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_model.sv: -------------------------------------------------------------------------------- 1 | `ifndef MY_MODEL__SV 2 | `define MY_MODEL__SV 3 | 4 | class my_model extends uvm_component; 5 | 6 | uvm_blocking_get_port #(my_transaction) port; 7 | uvm_analysis_port #(my_transaction) ap; 8 | 9 | extern function new(string name, uvm_component parent); 10 | extern function void build_phase(uvm_phase phase); 11 | extern virtual task main_phase(uvm_phase phase); 12 | 13 | `uvm_component_utils(my_model) 14 | endclass 15 | 16 | function my_model::new(string name, uvm_component parent); 17 | super.new(name, parent); 18 | endfunction 19 | 20 | function void my_model::build_phase(uvm_phase phase); 21 | super.build_phase(phase); 22 | port = new("port", this); 23 | ap = new("ap", this); 24 | endfunction 25 | 26 | task my_model::main_phase(uvm_phase phase); 27 | my_transaction tr; 28 | my_transaction new_tr; 29 | super.main_phase(phase); 30 | while(1) begin 31 | port.get(tr); 32 | //`uvm_info("my_model", $sformatf("write_data_noseq data:%0d",tr.data), UVM_LOW); 33 | new_tr = new("new_tr"); 34 | new_tr.copy(tr); 35 | //`uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW) 36 | //new_tr.print(); 37 | ap.write(new_tr); 38 | end 39 | endtask 40 | `endif 41 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/read_sramc_monitor.sv: -------------------------------------------------------------------------------- 1 | `ifndef READ_SRAMC_MONITOR__SV 2 | `define READ_SRAMC_MONITOR__SV 3 | class read_sramc_monitor extends uvm_monitor; 4 | 5 | virtual my_if rd_if; 6 | 7 | uvm_analysis_port #(my_transaction) ap; 8 | 9 | `uvm_component_utils(read_sramc_monitor) 10 | function new(string name = "read_sramc_monitor", uvm_component parent = null); 11 | super.new(name, parent); 12 | endfunction 13 | 14 | virtual function void build_phase(uvm_phase phase); 15 | super.build_phase(phase); 16 | if(!uvm_config_db#(virtual my_if)::get(this, "", "rd_if", rd_if)) 17 | `uvm_fatal("read_sramc_monitor", "virtual interface must be set for rd_if!!!") 18 | ap = new("ap", this); 19 | endfunction 20 | 21 | extern task main_phase(uvm_phase phase); 22 | extern task collect_one_pkt(my_transaction tr); 23 | endclass 24 | 25 | task read_sramc_monitor::main_phase(uvm_phase phase); 26 | my_transaction tr; 27 | while(1) begin 28 | tr = new("tr"); 29 | collect_one_pkt(tr); 30 | //`uvm_info("read_sramc_monitor", $sformatf("read_data_seq data:%0d",tr.data), UVM_LOW); 31 | ap.write(tr); 32 | end 33 | endtask 34 | 35 | task read_sramc_monitor::collect_one_pkt(my_transaction tr); 36 | 37 | while(1) begin 38 | @(posedge rd_if.hclk); 39 | if(~rd_if.hwrite&rd_if.hsel) 40 | break; 41 | end 42 | @(posedge rd_if.hclk); 43 | tr.data = rd_if.hrdata;//读数据应该在读指令发出后的下一个时钟沿读,这里用延时代替 44 | 45 | endtask 46 | 47 | 48 | `endif 49 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_if.sv: -------------------------------------------------------------------------------- 1 | `include "define.sv" 2 | `ifndef MY_IF__SV 3 | `define MY_IF__SV 4 | interface my_if(input hclk,input hresetn); 5 | logic sram_clk ; //sram时钟信号 6 | logic hsel ; //slave选择信号 7 | logic hwrite ; //读/写命令(控制信号) 8 | logic hready ; //由mater发给slave(状态信号),高:有效;低,无效 9 | logic [1:0] htrans ; //指示命令是否有效、是否连续传输(控制信号) 10 | logic [2:0] hsize ; //传输总线的有效数据位(控制信号) 11 | logic [2:0] hburst ; // 12 | logic [31:0] haddr ; //32位系统总线地址信号 13 | logic [31:0] hwdata ; //写数据总线信号 14 | logic hready_resp; //output hready_out(状态信号),slave输出给master,表明slave是否OK 15 | logic [1:0] hresp ; //output hrdata信号(状态信号),表明传输是否OK,00:OKAY,01:ERROR 16 | logic [`DSIZE:0] hrdata ; //output 读数据总线信号 17 | 18 | assign sram_clk = ~hclk; 19 | 20 | 21 | // clocking c_wr @(posedge hclk);//写时钟 22 | 23 | // output hsel ; 24 | // output hwrite ; 25 | // output hready ; 26 | // output htrans ; 27 | // output hsize ; 28 | // output hburst ; 29 | // output haddr ; 30 | // output hwdata ; 31 | 32 | // endclocking 33 | 34 | // clocking c_rd @(posedge hclk);//读时钟 35 | 36 | // output hsel ; 37 | // output hwrite ; 38 | // output hready ; 39 | // output htrans ; 40 | // output hsize ; 41 | // output hburst ; 42 | // output haddr ; 43 | // input hrdata ; 44 | 45 | // endclocking 46 | 47 | 48 | endinterface 49 | `endif //ASYNCF_IF__SV 50 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/write_sramc_monitor.sv: -------------------------------------------------------------------------------- 1 | `ifndef WRITE_SRAMC_MONITOR__SV 2 | `define WRITE_SRAMC_MONITOR__SV 3 | class write_sramc_monitor extends uvm_monitor; 4 | 5 | virtual my_if wr_if; 6 | 7 | uvm_analysis_port #(my_transaction) ap; 8 | 9 | `uvm_component_utils(write_sramc_monitor) 10 | function new(string name = "write_sramc_monitor", uvm_component parent = null); 11 | super.new(name, parent); 12 | endfunction 13 | 14 | virtual function void build_phase(uvm_phase phase); 15 | super.build_phase(phase); 16 | if(!uvm_config_db#(virtual my_if)::get(this, "", "wr_if", wr_if)) 17 | `uvm_fatal("write_sramc_monitor", "virtual interface must be set for wr_if!!!") 18 | ap = new("ap", this); 19 | endfunction 20 | 21 | extern task main_phase(uvm_phase phase); 22 | extern task collect_one_pkt(my_transaction tr); 23 | endclass 24 | 25 | task write_sramc_monitor::main_phase(uvm_phase phase); 26 | my_transaction tr; 27 | while(1) begin 28 | tr = new("tr"); 29 | collect_one_pkt(tr); 30 | //`uvm_info("write_sramc_monitor", $sformatf("write_data_seq data:%0d",tr.data), UVM_LOW); 31 | ap.write(tr); 32 | end 33 | endtask 34 | 35 | task write_sramc_monitor::collect_one_pkt(my_transaction tr); 36 | 37 | while(1) begin 38 | @(posedge wr_if.hclk); 39 | if(wr_if.hwrite&wr_if.hsel) 40 | break; 41 | end 42 | 43 | //`uvm_info("write_sramc_monitor", "begin to collect one pkt", UVM_MEDIUM); 44 | @(posedge wr_if.hclk); 45 | tr.data = wr_if.hwdata; 46 | 47 | //`uvm_info("write_sramc_monitor", "end collect one pkt", UVM_MEDIUM); 48 | endtask 49 | 50 | 51 | `endif 52 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_env.sv: -------------------------------------------------------------------------------- 1 | `ifndef MY_ENV__SV 2 | `define MY_ENV__SV 3 | 4 | class my_env extends uvm_env; 5 | 6 | write_sramc_agent i_agt; 7 | read_sramc_agent o_agt; 8 | my_model mdl ; 9 | my_scoreboard scb ; 10 | my_virtual_sequencer m_vseqr; 11 | 12 | uvm_tlm_analysis_fifo #(my_transaction) agt_scb_fifo; 13 | uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo; 14 | uvm_tlm_analysis_fifo #(my_transaction) mdl_scb_fifo; 15 | 16 | function new(string name = "my_env", uvm_component parent); 17 | super.new(name, parent); 18 | endfunction 19 | 20 | virtual function void build_phase(uvm_phase phase); 21 | super.build_phase(phase); 22 | i_agt = write_sramc_agent::type_id::create("i_agt", this); 23 | o_agt = read_sramc_agent::type_id::create("o_agt", this); 24 | mdl = my_model::type_id::create("mdl", this); 25 | scb = my_scoreboard::type_id::create("scb", this); 26 | m_vseqr= my_virtual_sequencer::type_id::create("m_vseqr", this); 27 | agt_scb_fifo = new("agt_scb_fifo", this); 28 | agt_mdl_fifo = new("agt_mdl_fifo", this); 29 | mdl_scb_fifo = new("mdl_scb_fifo", this); 30 | 31 | endfunction 32 | 33 | extern virtual function void connect_phase(uvm_phase phase); 34 | 35 | `uvm_component_utils(my_env) 36 | endclass 37 | 38 | function void my_env::connect_phase(uvm_phase phase); 39 | super.connect_phase(phase); 40 | i_agt.ap.connect(agt_mdl_fifo.analysis_export); 41 | mdl.port.connect(agt_mdl_fifo.blocking_get_export); 42 | mdl.ap.connect(mdl_scb_fifo.analysis_export); 43 | scb.exp_port.connect(mdl_scb_fifo.blocking_get_export); 44 | o_agt.ap.connect(agt_scb_fifo.analysis_export); 45 | scb.act_port.connect(agt_scb_fifo.blocking_get_export); 46 | //Connect the seqr. 47 | m_vseqr.m_wr_seqr = i_agt.sqr; 48 | m_vseqr.m_rd_seqr = o_agt.sqr; 49 | endfunction 50 | 51 | `endif -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_case1.sv: -------------------------------------------------------------------------------- 1 | `include "define.sv" 2 | `ifndef MY_CASE1__SV 3 | `define MY_CASE1__SV 4 | 5 | class my_case1_sequence extends uvm_sequence; 6 | 7 | `uvm_object_utils(my_case1_sequence) 8 | `uvm_declare_p_sequencer(my_virtual_sequencer) 9 | 10 | function new(string name= "my_virtual_sequencer"); 11 | super.new(name); 12 | endfunction 13 | 14 | extern virtual task body(); 15 | extern virtual task pre_body(); 16 | extern virtual task post_body(); 17 | 18 | endclass 19 | 20 | task my_case1_sequence::body(); 21 | write_sramc_seq wr_seq; 22 | read_sramc_seq rd_seq; 23 | repeat (19) begin 24 | `uvm_do_on(wr_seq,p_sequencer.m_wr_seqr) 25 | end 26 | repeat (19) begin 27 | `uvm_do_on(rd_seq,p_sequencer.m_rd_seqr) 28 | end 29 | #(2*(`HCLK_PERIOD)); 30 | `uvm_info("my_case1", "body finished", UVM_MEDIUM) 31 | endtask 32 | 33 | task my_case1_sequence::pre_body(); 34 | if(starting_phase != null) begin 35 | starting_phase.raise_objection(this); 36 | end 37 | endtask 38 | 39 | task my_case1_sequence::post_body(); 40 | `uvm_info("my_case1", "Entering post_body", UVM_MEDIUM) 41 | if(starting_phase != null) begin 42 | `uvm_info("my_case1", "starting_pase is drop", UVM_MEDIUM) 43 | starting_phase.drop_objection(this); 44 | end 45 | endtask 46 | 47 | 48 | class my_case1 extends base_test; 49 | 50 | function new(string name = "my_case1", uvm_component parent = null); 51 | super.new(name,parent); 52 | endfunction 53 | extern virtual function void build_phase(uvm_phase phase); 54 | `uvm_component_utils(my_case1) 55 | endclass 56 | 57 | 58 | function void my_case1::build_phase(uvm_phase phase); 59 | super.build_phase(phase); 60 | 61 | uvm_config_db#(uvm_object_wrapper)::set(this, 62 | "env.m_vseqr.main_phase", 63 | "default_sequence", 64 | my_case1_sequence::type_id::get()); 65 | endfunction 66 | 67 | `endif 68 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_case0.sv: -------------------------------------------------------------------------------- 1 | `include "define.sv" 2 | `ifndef MY_CASE0__SV 3 | `define MY_CASE0__SV 4 | class my_case0_sequence extends uvm_sequence; 5 | 6 | `uvm_object_utils(my_case0_sequence) 7 | `uvm_declare_p_sequencer(my_virtual_sequencer) 8 | 9 | function new(string name= "my_case0_sequence"); 10 | super.new(name); 11 | endfunction 12 | 13 | extern virtual task body(); 14 | extern virtual task pre_body(); 15 | extern virtual task post_body(); 16 | 17 | endclass 18 | 19 | task my_case0_sequence::body(); 20 | write_sramc_seq wr_seq; 21 | read_sramc_seq rd_seq; 22 | //direct_read_during_write 23 | repeat (16) begin 24 | `uvm_do_on(wr_seq,p_sequencer.m_wr_seqr) 25 | `uvm_do_on(rd_seq,p_sequencer.m_rd_seqr) 26 | end 27 | #(2*(`HCLK_PERIOD));//读指令需要一个周期,读数据需要一个周期,所以延迟两个周期 28 | `uvm_info("my_case0", "body finished", UVM_MEDIUM) 29 | endtask 30 | 31 | task my_case0_sequence::pre_body(); 32 | if(starting_phase != null) begin 33 | starting_phase.raise_objection(this); 34 | end 35 | endtask 36 | 37 | task my_case0_sequence::post_body(); 38 | //`uvm_info("my_case0", "Entering post_body", UVM_MEDIUM) 39 | if(starting_phase != null) begin 40 | //`uvm_info("my_case0", "starting_pase is drop", UVM_MEDIUM) 41 | starting_phase.drop_objection(this); 42 | end 43 | endtask 44 | 45 | 46 | 47 | class my_case0 extends base_test; 48 | 49 | function new(string name = "my_case0", uvm_component parent = null); 50 | super.new(name,parent); 51 | endfunction 52 | extern virtual function void build_phase(uvm_phase phase); 53 | extern task main_phase(uvm_phase phase); 54 | `uvm_component_utils(my_case0) 55 | endclass 56 | 57 | 58 | function void my_case0::build_phase(uvm_phase phase); 59 | super.build_phase(phase); 60 | 61 | uvm_config_db#(uvm_object_wrapper)::set(this, 62 | "env.m_vseqr.main_phase", 63 | "default_sequence", 64 | my_case0_sequence::type_id::get()); 65 | endfunction 66 | task my_case0::main_phase(uvm_phase phase); 67 | 68 | super.main_phase(phase); 69 | uvm_top.print_topology(); 70 | endtask 71 | `endif -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_case2.sv: -------------------------------------------------------------------------------- 1 | `include "define.sv" 2 | `ifndef MY_CASE2__SV 3 | `define MY_CASE2__SV 4 | 5 | class my_case2_sequence extends uvm_sequence; 6 | 7 | `uvm_object_utils(my_case2_sequence) 8 | `uvm_declare_p_sequencer(my_virtual_sequencer) 9 | 10 | function new(string name= "my_case2_sequence"); 11 | super.new(name); 12 | endfunction 13 | 14 | extern virtual task body(); 15 | extern virtual task pre_body(); 16 | extern virtual task post_body(); 17 | 18 | endclass 19 | 20 | task my_case2_sequence::body(); 21 | write_sramc_seq wr_seq; 22 | read_sramc_seq rd_seq; 23 | //write full 24 | repeat (2000) begin 25 | `uvm_do_on(wr_seq,p_sequencer.m_wr_seqr) 26 | end 27 | //read empty 28 | repeat (2000) begin 29 | `uvm_do_on(rd_seq,p_sequencer.m_rd_seqr) 30 | end 31 | #(2*(`HCLK_PERIOD));; 32 | `uvm_info("my_case2", "body finished", UVM_MEDIUM) 33 | endtask 34 | 35 | task my_case2_sequence::pre_body(); 36 | if(starting_phase != null) begin 37 | starting_phase.raise_objection(this); 38 | end 39 | endtask 40 | 41 | task my_case2_sequence::post_body(); 42 | `uvm_info("my_case2", "Entering post_body", UVM_MEDIUM) 43 | if(starting_phase != null) begin 44 | `uvm_info("my_case2", "starting_pase is drop", UVM_MEDIUM) 45 | starting_phase.drop_objection(this); 46 | end 47 | endtask 48 | 49 | 50 | class my_case2 extends base_test; 51 | 52 | function new(string name = "my_case2", uvm_component parent = null); 53 | super.new(name,parent); 54 | endfunction 55 | extern virtual function void build_phase(uvm_phase phase); 56 | extern task main_phase(uvm_phase phase); 57 | `uvm_component_utils(my_case2) 58 | endclass 59 | 60 | 61 | function void my_case2::build_phase(uvm_phase phase); 62 | super.build_phase(phase); 63 | 64 | uvm_config_db#(uvm_object_wrapper)::set(this, 65 | "env.m_vseqr.main_phase", 66 | "default_sequence", 67 | my_case2_sequence::type_id::get()); 68 | endfunction 69 | task my_case2::main_phase(uvm_phase phase); 70 | 71 | super.main_phase(phase); 72 | uvm_top.print_topology(); 73 | endtask 74 | `endif -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/my_scoreboard.sv: -------------------------------------------------------------------------------- 1 | `ifndef MY_SCOREBOARD__SV 2 | `define MY_SCOREBOARD__SV 3 | class my_scoreboard extends uvm_scoreboard; 4 | my_transaction expect_queue[$]; 5 | uvm_blocking_get_port #(my_transaction) exp_port; 6 | uvm_blocking_get_port #(my_transaction) act_port; 7 | `uvm_component_utils(my_scoreboard) 8 | 9 | extern function new(string name, uvm_component parent = null); 10 | extern virtual function void build_phase(uvm_phase phase); 11 | extern virtual task main_phase(uvm_phase phase); 12 | endclass 13 | 14 | function my_scoreboard::new(string name, uvm_component parent = null); 15 | super.new(name, parent); 16 | endfunction 17 | 18 | function void my_scoreboard::build_phase(uvm_phase phase); 19 | super.build_phase(phase); 20 | exp_port = new("exp_port", this); 21 | act_port = new("act_port", this); 22 | endfunction 23 | 24 | task my_scoreboard::main_phase(uvm_phase phase); 25 | my_transaction get_expect, get_actual, tmp_tran; 26 | bit result; 27 | 28 | super.main_phase(phase); 29 | fork 30 | while (1) begin 31 | exp_port.get(get_expect); 32 | expect_queue.push_back(get_expect); 33 | end 34 | while (1) begin 35 | act_port.get(get_actual); 36 | if(expect_queue.size() > 0) begin 37 | tmp_tran = expect_queue.pop_front(); 38 | 39 | //result = (get_actual.data==tmp_tran.data)?1'b1:1'b0; 40 | 41 | result = get_actual.compare(tmp_tran); 42 | if(result) begin 43 | `uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW); 44 | $display("the expect pkt is"); 45 | tmp_tran.print(); 46 | $display("the actual pkt is"); 47 | get_actual.print(); 48 | end 49 | else begin 50 | `uvm_error("my_scoreboard", "Compare FAILED"); 51 | $display("the expect pkt is"); 52 | tmp_tran.print(); 53 | $display("the actual pkt is"); 54 | get_actual.print(); 55 | end 56 | end 57 | else begin 58 | `uvm_error("my_scoreboard", "Received from DUT, while Expect Queue is empty"); 59 | $display("the unexpected pkt is"); 60 | get_actual.print(); 61 | end 62 | end 63 | join 64 | endtask 65 | `endif 66 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/read_sramc_driver.sv: -------------------------------------------------------------------------------- 1 | `ifndef READ_SRAMC_DRIVER__SV 2 | `define READ_SRAMC_DRIVER__SV 3 | class read_sramc_driver extends uvm_driver#(read_sramc_transaction); 4 | 5 | virtual my_if rd_if; 6 | int i=`START_ADDR; 7 | 8 | `uvm_component_utils(read_sramc_driver) 9 | function new(string name = "read_sramc_driver", uvm_component parent = null); 10 | super.new(name, parent); 11 | endfunction 12 | 13 | virtual function void build_phase(uvm_phase phase); 14 | super.build_phase(phase); 15 | if(!uvm_config_db#(virtual my_if)::get(this, "", "rd_if", rd_if)) 16 | `uvm_fatal("read_sramc_driver", "virtual interface must be set for rd_if!!!") 17 | endfunction 18 | extern task reset_phase(uvm_phase phase); 19 | extern task main_phase(uvm_phase phase); 20 | extern task ahb_init(); 21 | extern task read_data(read_sramc_transaction tr); 22 | //extern task read_data_noseq(read_sramc_transaction tr); 23 | 24 | extern task drive_one_pkt(read_sramc_transaction tr); 25 | extern task drive_nothing(); 26 | endclass 27 | 28 | task read_sramc_driver::reset_phase(uvm_phase phase);//init 29 | super.reset_phase(phase); 30 | rd_if.hsel <= `NOSEL ;//NOSEL:未中该slave、SEL:选中该slave 31 | rd_if.hwrite <= `WR_EN ;//WR_EN:写 RD_EN:读 32 | rd_if.htrans <= `TRANS ;//10or11 enable transmit 33 | rd_if.hsize <= `SIZE16 ;//SIZE8:8bit、SIZE16:16bit、SIZE32:32bit 34 | rd_if.hburst <= `BURST ; 35 | rd_if.hready <= `READY ; 36 | rd_if.haddr <= 32'd0 ; 37 | endtask 38 | 39 | 40 | task read_sramc_driver::main_phase(uvm_phase phase); 41 | super.main_phase(phase); 42 | while(!rd_if.hresetn) 43 | @(posedge rd_if.hclk); 44 | fork 45 | while(1) begin 46 | seq_item_port.get_next_item(req); 47 | drive_one_pkt(req); 48 | i++; 49 | seq_item_port.item_done(); 50 | end 51 | join 52 | 53 | endtask 54 | 55 | task read_sramc_driver::ahb_init(); 56 | rd_if.hsel <= `NOSEL ;//未中该slave 57 | endtask 58 | 59 | task read_sramc_driver::read_data(read_sramc_transaction tr);//连续读 60 | @(posedge rd_if.sram_clk); 61 | rd_if.hsel <= `SEL ;//选中该slave 62 | rd_if.hwrite <= `RD_EN ;//读 63 | rd_if.haddr <= i; 64 | @(posedge rd_if.sram_clk); 65 | rd_if.hsel <= `NOSEL ;//未选中该slave 66 | endtask 67 | 68 | // task read_sramc_driver::read_data_noseq(read_sramc_transaction tr); 69 | // @(posedge rd_if.hclk); 70 | // rd_if.hsel <= `SEL ;//选中该slave 71 | // rd_if.hwrite <= `RD_EN ;//读 72 | // rd_if.haddr <= i; 73 | // @(posedge rd_if.hclk); 74 | // ahb_init(); 75 | // endtask 76 | 77 | 78 | task read_sramc_driver::drive_one_pkt(read_sramc_transaction tr); 79 | //`uvm_info("read_sramc_driver", "begin to drive one pkt", UVM_LOW); 80 | //$display("read addr is %0d",i); 81 | while(!rd_if.hresetn) 82 | @(posedge rd_if.hclk); 83 | while(1)begin 84 | if(((`TRANS)==2'b10)|((`TRANS)==2'b11))begin//transmit enable 85 | //read_data_seq(tr); 86 | read_data(tr); 87 | break; 88 | end 89 | else 90 | ahb_init(); 91 | end 92 | //`uvm_info("read_sramc_driver", "end to drive one pkt", UVM_LOW); 93 | endtask 94 | 95 | 96 | 97 | 98 | `endif 99 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/write_sramc_driver.sv: -------------------------------------------------------------------------------- 1 | `include "define.sv" 2 | `ifndef WRITE_SRAMC_DRIVER__SV 3 | `define WRITE_SRAMC_DRIVER__SV 4 | class write_sramc_driver extends uvm_driver#(my_transaction); 5 | 6 | virtual my_if wr_if; 7 | int i=`START_ADDR; 8 | //logic no_tr = 1'b0; 9 | 10 | `uvm_component_utils(write_sramc_driver) 11 | function new(string name = "write_sramc_driver", uvm_component parent = null); 12 | super.new(name, parent); 13 | endfunction 14 | 15 | virtual function void build_phase(uvm_phase phase); 16 | super.build_phase(phase); 17 | if(!uvm_config_db#(virtual my_if)::get(this, "", "wr_if", wr_if)) 18 | `uvm_fatal("write_sramc_driver", "virtual interface must be set for my_if!!!") 19 | endfunction 20 | 21 | extern task reset_phase(uvm_phase phase); 22 | 23 | extern task main_phase(uvm_phase phase); 24 | extern task ahb_init(); 25 | extern task write_data(my_transaction tr); 26 | //extern task write_data_noseq(my_transaction tr); 27 | 28 | extern task drive_one_pkt(my_transaction tr); 29 | extern task drive_nothing(); 30 | endclass 31 | 32 | task write_sramc_driver::reset_phase(uvm_phase phase);//init 33 | super.reset_phase(phase); 34 | wr_if.hsel <= `NOSEL ;//NOSEL:未中该slave、SEL:选中该slave 35 | wr_if.hwrite <= `WR_EN ;//WR_EN:写、RD_EN:读 36 | wr_if.htrans <= `TRANS ;//TRANS/NOTRANS eanble/disable transmit 37 | wr_if.hsize <= `SIZE16 ;//SIZE8:8bit、SIZE16:16bit、SIZE32:32bit 38 | wr_if.hburst <= `BURST ;//BURST 39 | wr_if.hready <= `READY ;//READY or NOREADY 40 | wr_if.haddr <= 32'd0; 41 | wr_if.hwdata <= 32'd0; 42 | endtask 43 | 44 | 45 | task write_sramc_driver::main_phase(uvm_phase phase); 46 | super.main_phase(phase); 47 | while(!wr_if.hresetn) 48 | @(posedge wr_if.hclk); 49 | fork 50 | while(1) begin 51 | seq_item_port.get_next_item(req); 52 | drive_one_pkt(req); 53 | i++; 54 | seq_item_port.item_done(); 55 | end 56 | join 57 | endtask 58 | 59 | task write_sramc_driver::ahb_init(); 60 | wr_if.hsel <= `NOSEL ;//未中该slave 61 | endtask 62 | 63 | task write_sramc_driver::write_data(my_transaction tr); 64 | @(posedge wr_if.hclk); 65 | wr_if.hsel <= `SEL ;//未中该slave 66 | wr_if.hwrite <= `WR_EN ;//写 67 | wr_if.haddr <= i; 68 | @(posedge wr_if.hclk); 69 | wr_if.hwdata <= tr.data;//[`DSIZE-1:0] 70 | 71 | endtask 72 | 73 | 74 | // task write_sramc_driver::write_data_noseq(my_transaction tr); 75 | // //#(tr.delay); 76 | // @(posedge wr_if.hclk); 77 | // wr_if.hsel <= `SEL ;//选中该slave 78 | // wr_if.hwrite <= `WR_EN ;//写 79 | // wr_if.haddr <= i; 80 | // wr_if.hwdata <= tr.data;//[`DSIZE-1:0] 81 | // //`uvm_info("write_sramc_driver", $sformatf("write_data_noseq data:%0d",tr.data), UVM_LOW); 82 | // @(posedge wr_if.hclk); 83 | // //wr_if.hwdata <= tr.data;//[`DSIZE-1:0] 84 | // //@(posedge wr_if.hclk); 85 | // ahb_init(); 86 | 87 | // endtask 88 | 89 | task write_sramc_driver::drive_one_pkt(my_transaction tr); 90 | //`uvm_info("write_sramc_driver", "begin to drive one pkt", UVM_LOW); 91 | 92 | while(!wr_if.hresetn) 93 | @(posedge wr_if.hclk); 94 | while(1) begin 95 | if(((`TRANS)==2'b10)|((`TRANS)==2'b11))begin 96 | //write_data_seq(tr); 97 | write_data(tr); 98 | break; 99 | end 100 | else 101 | ahb_init(); 102 | end 103 | 104 | //`uvm_info("write_sramc_driver", "end drive one pkt", UVM_LOW); 105 | 106 | endtask 107 | 108 | 109 | 110 | `endif 111 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM testbench topology.md: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------ 2 | Name Type Size Value 3 | 4 | uvm_test_top my_case2 - @457 5 | env my_env - @473 6 | agt_mdl_fifo uvm_tlm_analysis_fifo #(T) - @693 7 | analysis_export uvm_analysis_imp - @737 8 | get_ap uvm_analysis_port - @728 9 | get_peek_export uvm_get_peek_imp - @710 10 | put_ap uvm_analysis_port - @719 11 | put_export uvm_put_imp - @701 12 | agt_scb_fifo uvm_tlm_analysis_fifo #(T) - @640 13 | analysis_export uvm_analysis_imp - @684 14 | get_ap uvm_analysis_port - @675 15 | get_peek_export uvm_get_peek_imp - @657 16 | put_ap uvm_analysis_port - @666 17 | put_export uvm_put_imp - @648 18 | i_agt write_sramc_agent - @485 19 | drv write_sramc_driver - @926 20 | rsp_port uvm_analysis_port - @943 21 | seq_item_port uvm_seq_item_pull_port - @934 22 | mon write_sramc_monitor - @952 23 | ap uvm_analysis_port - @962 24 | sqr write_sramc_sequencer - @803 25 | rsp_export uvm_analysis_export - @811 26 | seq_item_export uvm_seq_item_pull_imp - @917 27 | arbitration_queue array 0 - 28 | lock_queue array 0 - 29 | num_last_reqs integral 32 'd1 30 | num_last_rsps integral 32 'd1 31 | m_vseqr my_virtual_sequencer - @517 32 | rsp_export uvm_analysis_export - @525 33 | seq_item_export uvm_seq_item_pull_imp - @631 34 | arbitration_queue array 0 - 35 | lock_queue array 0 - 36 | num_last_reqs integral 32 'd1 37 | num_last_rsps integral 32 'd1 38 | mdl my_model - @501 39 | ap uvm_analysis_port - @990 40 | port uvm_blocking_get_port - @981 41 | mdl_scb_fifo uvm_tlm_analysis_fifo #(T) - @746 42 | analysis_export uvm_analysis_imp - @790 43 | get_ap uvm_analysis_port - @781 44 | get_peek_export uvm_get_peek_imp - @763 45 | put_ap uvm_analysis_port - @772 46 | put_export uvm_put_imp - @754 47 | o_agt read_sramc_agent - @493 48 | drv read_sramc_driver - @1134 49 | rsp_port uvm_analysis_port - @1151 50 | seq_item_port uvm_seq_item_pull_port - @1142 51 | mon read_sramc_monitor - @1126 52 | ap uvm_analysis_port - @1162 53 | sqr read_sramc_sequencer - @1003 54 | rsp_export uvm_analysis_export - @1011 55 | seq_item_export uvm_seq_item_pull_imp - @1117 56 | arbitration_queue array 0 - 57 | lock_queue array 0 - 58 | num_last_reqs integral 32 'd1 59 | num_last_rsps integral 32 'd1 60 | scb my_scoreboard - @509 61 | act_port uvm_blocking_get_port - @1185 62 | exp_port uvm_blocking_get_port - @1176 63 | ------------------------------------------------------------------ 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UVM-based-AHB-bus-SRAM-controller-design-verification-platform-design 2 | 3 | ## ahb_sramc_control_architecture 4 | 5 | ![ahb_sramc_control_architecture](https://user-images.githubusercontent.com/71707557/184055306-04816a4b-d1ee-4d11-9e7d-ba9e5cb4407a.png) 6 | 7 | 8 | UVM testbench topology 9 | ------------------------------------------------------------------ 10 | Name Type Size Value 11 | 12 | uvm_test_top my_case1 - @457 13 | env my_env - @473 14 | agt_mdl_fifo uvm_tlm_analysis_fifo #(T) - @693 15 | analysis_export uvm_analysis_imp - @737 16 | get_ap uvm_analysis_port - @728 17 | get_peek_export uvm_get_peek_imp - @710 18 | put_ap uvm_analysis_port - @719 19 | put_export uvm_put_imp - @701 20 | agt_scb_fifo uvm_tlm_analysis_fifo #(T) - @640 21 | analysis_export uvm_analysis_imp - @684 22 | get_ap uvm_analysis_port - @675 23 | get_peek_export uvm_get_peek_imp - @657 24 | put_ap uvm_analysis_port - @666 25 | put_export uvm_put_imp - @648 26 | i_agt write_sramc_agent - @485 27 | drv write_sramc_driver - @926 28 | rsp_port uvm_analysis_port - @943 29 | seq_item_port uvm_seq_item_pull_port - @934 30 | mon write_sramc_monitor - @952 31 | ap uvm_analysis_port - @962 32 | sqr write_sramc_sequencer - @803 33 | rsp_export uvm_analysis_export - @811 34 | seq_item_export uvm_seq_item_pull_imp - @917 35 | arbitration_queue array 0 - 36 | lock_queue array 0 - 37 | num_last_reqs integral 32 'd1 38 | num_last_rsps integral 32 'd1 39 | m_vseqr my_virtual_sequencer - @517 40 | rsp_export uvm_analysis_export - @525 41 | seq_item_export uvm_seq_item_pull_imp - @631 42 | arbitration_queue array 0 - 43 | lock_queue array 0 - 44 | num_last_reqs integral 32 'd1 45 | num_last_rsps integral 32 'd1 46 | mdl my_model - @501 47 | ap uvm_analysis_port - @990 48 | port uvm_blocking_get_port - @981 49 | mdl_scb_fifo uvm_tlm_analysis_fifo #(T) - @746 50 | analysis_export uvm_analysis_imp - @790 51 | get_ap uvm_analysis_port - @781 52 | get_peek_export uvm_get_peek_imp - @763 53 | put_ap uvm_analysis_port - @772 54 | put_export uvm_put_imp - @754 55 | o_agt read_sramc_agent - @493 56 | drv read_sramc_driver - @1134 57 | rsp_port uvm_analysis_port - @1151 58 | seq_item_port uvm_seq_item_pull_port - @1142 59 | mon read_sramc_monitor - @1126 60 | ap uvm_analysis_port - @1162 61 | sqr read_sramc_sequencer - @1003 62 | rsp_export uvm_analysis_export - @1011 63 | seq_item_export uvm_seq_item_pull_imp - @1117 64 | arbitration_queue array 0 - 65 | lock_queue array 0 - 66 | num_last_reqs integral 32 'd1 67 | num_last_rsps integral 32 'd1 68 | scb my_scoreboard - @509 69 | act_port uvm_blocking_get_port - @1185 70 | exp_port uvm_blocking_get_port - @1176 71 | ------------------------------------------------------------------ 72 | 73 | You can also view this project on the EDA playground at the address:https://www.edaplayground.com/x/dbgS 74 | -------------------------------------------------------------------------------- /UVM_AHB_SRAMC_CONTROL/UVM/tb_top.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns/1ps 2 | //`include "uvm_macros.svh" 3 | // import uvm_pkg::*; 4 | `include "define.sv" 5 | `include "my_if.sv" 6 | `include "my_transaction.sv" 7 | `include "read_sramc_transaction.sv" 8 | `include "write_sramc_sequencer.sv" 9 | `include "read_sramc_sequencer.sv" 10 | `include "write_sramc_seq.sv" 11 | `include "read_sramc_seq.sv" 12 | `include "my_virtual_sequencer.sv" 13 | `include "write_sramc_driver.sv" 14 | `include "read_sramc_driver.sv" 15 | `include "write_sramc_monitor.sv" 16 | `include "read_sramc_monitor.sv" 17 | `include "write_sramc_agent.sv" 18 | `include "read_sramc_agent.sv" 19 | `include "my_model.sv" 20 | `include "my_scoreboard.sv" 21 | `include "my_env.sv" 22 | `include "base_test.sv" 23 | `include "my_case0.sv" 24 | `include "my_case1.sv" 25 | `include "my_case2.sv" 26 | 27 | module top_tb; 28 | 29 | reg hclk; 30 | reg hresetn; 31 | 32 | 33 | my_if vif(hclk, hresetn); 34 | 35 | 36 | 37 | sramc_top u_sramc_top( 38 | .hclk (hclk ), 39 | .sram_clk (vif.sram_clk ), 40 | .hresetn (hresetn ),//给DUT 41 | .hsel (vif.hsel ),//给DUT 42 | .hwrite (vif.hwrite ),//给DUT 43 | .htrans (vif.htrans ),//给DUT 44 | .hsize (vif.hsize ),//给DUT 45 | .hready (vif.hready ),//给DUT 46 | .hburst (3'b0), //无用 burst没用的话就接0,在tr里面激励产生什么都关系不大了 47 | .haddr (vif.haddr ),//给DUT 48 | .hwdata (vif.hwdata ),//给DUT 49 | .hrdata (vif.hrdata ),//给DUT 50 | .dft_en (1'b0), //不测 dft不测,写成0 51 | .bist_en (1'b0), //不测 52 | .hready_resp (vif.hready_resp ), 53 | .hresp (vif.hresp ), 54 | .bist_done ( ), //不测 55 | .bist_fail ( ) //不测 56 | ); 57 | 58 | initial begin 59 | hclk = 0; 60 | forever begin 61 | #(`HCLK_PERIOD/2); 62 | hclk = ~hclk; 63 | end 64 | end 65 | 66 | initial begin 67 | hresetn = 1'b0; 68 | #101; 69 | hresetn = 1'b1; 70 | end 71 | 72 | initial begin 73 | run_test("my_case0"); 74 | end 75 | 76 | initial begin 77 | uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.drv", "wr_if", vif); 78 | uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.mon", "wr_if", vif); 79 | uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.o_agt.drv", "rd_if", vif); 80 | uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.o_agt.mon", "rd_if", vif); 81 | end 82 | 83 | initial begin 84 | $dumpfile("top_tb.vcd"); 85 | $dumpvars; 86 | end 87 | 88 | endmodule 89 | 90 | 91 | 92 | 93 | // /*/////////////////////// 94 | // TESTBENCH 95 | // *//////////////////////// 96 | // `timescale 1ns/1ps 97 | // `define START_ADDR 8192//32bit:0~2*8192-1、16bit:0~4*8192-1、8bit:0~8*8192-1 98 | // `define DATA_SIZE 16 99 | // `define IS_SEQ 1 //1:SEQ write、read 0:NOSEQ write、read(STL中两种都一样) 100 | 101 | 102 | // class random_data; 103 | // rand bit [`DATA_SIZE-1:0] data; 104 | // rand bit [`DATA_SIZE-1:0] delay; 105 | // constraint c_delay{ 106 | // delay <=50; 107 | // } 108 | // endclass 109 | 110 | // module tb_sramc_top(); 111 | 112 | // //interface define 113 | // reg hclk ;//产生时钟信号 114 | // wire sram_clk ;//hclk 的反向,与hclk属于同一个时钟沿 115 | // reg hresetn ;//复位 116 | // reg hsel ;//选中该slave 117 | // reg hwrite ;//读写模式0:读、1:写 118 | // reg [1:0] htrans ;//传输是否有效00:空闲、01:忙、10:非连续、11:连续 119 | // reg [2:0] hsize ;//有效传输位00:8bit、01:16bit、10:32bit 120 | // reg hready ;// master -> slave,一般接常高 121 | // reg [31:0] haddr ;//本次命令访问的地址 122 | // reg [31:0] hwdata ;// 写数据 123 | // wire [31:0] hrdata ;// 从sram读出的数据 124 | // wire hready_resp;// slave -> master,看 slave 是否ready 125 | // wire [1:0] hresp ;// hresp 也只会返回0,即ok状态。 126 | 127 | // reg [`DATA_SIZE-1:0] rdata ;//读出数据 128 | // reg r_data_en; 129 | // static int wr_iter = 0 ; 130 | // static int rd_iter = 0 ; 131 | 132 | 133 | // always #10 hclk = ~hclk; 134 | // assign sram_clk = ~hclk; 135 | 136 | // random_data rm_data; 137 | 138 | 139 | // initial begin 140 | // hclk =1; 141 | // hresetn = 0; 142 | // #200 143 | // hresetn = 1; 144 | // end 145 | 146 | // initial begin:process 147 | // rm_data = new(); 148 | // direct_write_during_read(16'd8); 149 | // #200; 150 | // loop_wr_rd_data(16'd18); 151 | 152 | // $finish; 153 | // end 154 | 155 | // task ahb_init(); 156 | // hsel = 1'b0 ;//未中该slave 157 | // hwrite = 1'b1 ;//写 158 | // htrans = `IS_SEQ?2'b11:2'b10; 159 | // hsize = (`DATA_SIZE==32)?2'b10:((`DATA_SIZE==16)?2'b01:((`DATA_SIZE==8)?2'b00:2'b10));//00:8bit、01:16bit、10:32bit、11:32bit 160 | // hready = 1'b1; 161 | // haddr = 32'd0; 162 | // hwdata = 32'd0; 163 | // rdata = 32'd0; 164 | // r_data_en = 1'b0; 165 | // wait(hresetn); 166 | // repeat(3)@(posedge sram_clk); 167 | // endtask 168 | 169 | // task write_data; 170 | // input [15:0] wr_nums; 171 | // begin 172 | // repeat(wr_nums)begin 173 | // @(posedge hclk); 174 | // rm_data.randomize(); 175 | // hsel = 1'b1 ;//选中该slave 176 | // hwrite = 1'b1 ;//写 177 | // haddr = `START_ADDR + wr_iter; 178 | // wr_iter = wr_iter +1; 179 | // @(posedge hclk); 180 | // hwdata = rm_data.data; 181 | // hsel = 1; 182 | // end 183 | // end 184 | // endtask 185 | 186 | // task read_data; 187 | // input [15:0] rd_nums; 188 | // begin 189 | // repeat(rd_nums)begin 190 | // @(posedge sram_clk); 191 | // hsel = 1'b1 ;//选中该slave 192 | // hwrite = 1'b0;//read 193 | // haddr = `START_ADDR + rd_iter;//bank1 cs0 194 | // rd_iter = rd_iter +1; 195 | // @(posedge sram_clk); 196 | // hsel = 1'b0 ; 197 | // //@(posedge hclk); 198 | // rdata <= hrdata[`DATA_SIZE-1:0]; 199 | // end 200 | // end 201 | // endtask 202 | 203 | // task direct_write_during_read; 204 | // input [15:0] wr_nums;//读写次数 205 | // begin 206 | // ahb_init(); 207 | // repeat(wr_nums)begin 208 | // write_data(1); 209 | // read_data(1); 210 | // end 211 | // @(posedge sram_clk); 212 | // @(posedge hclk); 213 | // ahb_init(); 214 | // #200; 215 | // end 216 | // endtask 217 | 218 | // task loop_wr_rd_data; 219 | // input [15:0] wr_nums; 220 | // begin 221 | // ahb_init(); 222 | // write_data(wr_nums); 223 | // #rm_data.delay; 224 | // read_data(wr_nums); 225 | // @(posedge sram_clk); 226 | // @(posedge hclk); 227 | // ahb_init(); 228 | // #200; 229 | // end 230 | // endtask 231 | 232 | // sramc_top u_sramc_top( 233 | // .hclk (hclk ), //input 234 | // .sram_clk (sram_clk ), //input 235 | // .hresetn (hresetn ), //input 236 | // .hsel (hsel ), //input 237 | // .hwrite (hwrite ), //input 238 | // .htrans (htrans ), //input [1:0] 239 | // .hsize (hsize ), //input [2:0] 240 | // .hready (hready ), //input 241 | // .haddr (haddr ), //input [31:0] 242 | // .hwdata (hwdata ), //input [31:0] 243 | // .hrdata (hrdata ), //output [31:0] 244 | // .hready_resp (hready_resp), //output 245 | // .hresp (hresp ), //output [1:0] 246 | 247 | // .hburst (3'b0), //burst没用的话就接0,在tr里面激励产生什么都关系不大了 248 | // .dft_en (1'b0), //不测 dft不测,写成0 249 | // .bist_en (1'b0), //不测 250 | // .bist_done ( ), //不测 251 | // .bist_fail ( ) //不测 252 | // ); 253 | 254 | // endmodule 255 | --------------------------------------------------------------------------------