Jump to content

Search the Community

Showing results for tags 'test'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Accellera Systems Initiative
    • Information
    • Announcements
    • In the News
  • SystemC
    • SystemC Language
    • SystemC AMS (Analog/Mixed-Signal)
    • SystemC TLM (Transaction-level Modeling)
    • SystemC Verification (UVM-SystemC, SCV)
    • SystemC CCI Public Review
  • UVM (Universal Verification Methodology)
    • Methodology and BCL Forum
    • UVM SystemVerilog Discussions
    • Simulator Specific Issues
    • UVM Commercial Announcements
    • UVM 1.2 Public Review
  • Portable Stimulus
    • Portable Stimulus Discussion
  • IP-XACT
    • IP-XACT Discussion
  • IEEE 1735/IP Encryption
    • IEEE 1735/IP Encryption Discussion
  • OCP (Open Core Protocol)
  • UCIS (Unified Coverage Interoperability Standard)
  • Commercial Announcements
    • Announcements

Categories

  • SystemC
  • UVM
  • UCIS
  • IEEE 1735/IP Encryption

Calendars

  • Community Calendar

Found 2 results

  1. Hi Guys, I have a simple framework for an IP level testbench, written using UVM-SC libraries. The intent is to be able to pump basic AHB write/read request to the DUT(in System C) using this BFM. I have created all basic components, snippet for which are pasted below. I have an ahb_sequencer, which is just an extension oh uvm_sequencer with specific ahb_transaction type. In ahb_driver run_phase is as under: void run_phase(uvm::uvm_phase phase) { REQ req, rsp; for(;;) { UVM_INFO(this->get_name(), "run_phase Entered", UVM_LOW); this->seq_item_port->get_next_item(req); rsp.set_id_info(req); this->seq_item_port->item_done(); this->seq_item_port->put_response(rsp); } } In ahb_env, driver and seqr are connected and sequences are started. class ahb_basic_env : public uvm::uvm_env { public: ahb_driver<ahb_transaction>* ahb_driver_inst; ahb_sequencer<ahb_transaction>* ahb_sequencer_inst; ahb_basic_write_sequence* ahb_wr_seq[NUM_SEQS]; UVM_COMPONENT_UTILS(ahb_basic_env); ahb_basic_env( uvm::uvm_component_name name) : uvm::uvm_env(name) { std::cout << sc_core::sc_time_stamp() << ": constructor " << name << std::endl; } void build_phase(uvm::uvm_phase& phase) { std::cout << sc_core::sc_time_stamp() << ": build_phase " << name() << std::endl; uvm::uvm_env::build_phase(phase); UVM_INFO(this->get_name(), " is ACTIVE", UVM_LOW); ahb_sequencer_inst = ahb_sequencer<ahb_transaction>::type_id::create("ahb_sequencer_inst",this); assert(ahb_sequencer_inst); ahb_driver_inst = ahb_driver<ahb_transaction>::type_id::create("ahb_driver_inst",this); assert(ahb_driver_inst); for (int i = 0; i < NUM_SEQS; i++) { std::ostringstream str; str << "ahb_basic_write_sequence" << i; ahb_wr_seq = new ahb_basic_write_sequence(str.str()); } } void connect_phase(uvm::uvm_phase& phase) { std::cout << sc_core::sc_time_stamp() << ": connect_phase " << name() << std::endl; uvm::uvm_component::connect_phase(phase); ahb_driver_inst->seq_item_port(ahb_sequencer_inst->seq_item_export); } void run_phase(uvm::uvm_phase& phase) { phase.raise_objection(this); std::cout << sc_core::sc_time_stamp() << ": run_phase Entered " << name() << std::endl; SC_FORK sc_core::sc_spawn(sc_bind(&ahb_basic_env::start_sequence, this, 0)), sc_core::sc_spawn(sc_bind(&ahb_basic_env::start_sequence, this, 1)), SC_JOIN std::cout << sc_core::sc_time_stamp() << ": run_phase Exited " << name() << std::endl; phase.drop_objection(this); } void start_sequence(int n) { ahb_wr_seq[n]->start(ahb_sequencer_inst, NULL); } }; The sequence uses wait_for_grant() and start_item() calls to initiate the transaction: class ahb_basic_write_sequence : public uvm::uvm_sequence<ahb_transaction,ahb_transaction> { public: ahb_basic_write_sequence( const std::string& name = "ahb_basic_write_sequence") : uvm::uvm_sequence< ahb_transaction,ahb_transaction > ( name ) { std::cout << sc_core::sc_time_stamp() << ": constructor " << name << std::endl; } UVM_OBJECT_UTILS(ahb_basic_write_sequence); void pre_body() { // raise objection if started as a root sequence if(this->starting_phase != NULL) this->starting_phase->raise_objection(this); } void body() { ahb_transaction* req_pkt; ahb_transaction* rsp; unsigned transaction_numb; UVM_INFO(this->get_name(), "Starting sequence ahb_basic_write_sequence", uvm::UVM_INFO); transaction_numb = 10; for(unsigned int i = 0; i < transaction_numb; i++) { req_pkt = new ahb_transaction(); rsp = new ahb_transaction(); UVM_INFO(this->get_name(), "Sending transaction from sequence ahb_basic_write_sequence", uvm::UVM_INFO); req_pkt->haddr = 0x100000 + 4*i; req_pkt->hwrite = 1; //req_pkt->hwrite = ahbConfig::WRITE_XACT; req_pkt->htrans = 2; //req_pkt->htrans = ahbConfig::HTRANS_NONSEQ; req_pkt->hwdata = (sc_uint<32>)(0xAAAABBBB + 4*i); req_pkt->hsize = ahbConfig::HSIZE_WORD; this->wait_for_grant(); UVM_INFO(this->get_name(), "Calling send_request from sequence ahb_basic_write_sequence", uvm::UVM_INFO); this->send_request(req_pkt); UVM_INFO(this->get_name(), "Getting response from sequence ahb_basic_write_sequence", uvm::UVM_INFO); this->get_response(rsp); } UVM_INFO(this->get_name(), "Finishing sequence", uvm::UVM_INFO); } void post_body() { // drop objection if started as a root sequence if(this->starting_phase != NULL) this->starting_phase->drop_objection(this); } }; But when i run the code, it gets stuck at wait_for_grant() call and also I don't see the run_phase prints from the driver class. The output looks something like this: Starting SC tests ... Running AHB tests 0 sIn dut UVM_INFO @ 0 s: reporter [RNTST] Running test ... 0 s: build_phase tb UVM_INFO ahb_basic_env.h(65) @ 0 s: tb [tb] is ACTIVE 0 s: constructor ahb_sequencer_inst 0 s: constructor ahb_driver_inst 0 s: constructor ahb_basic_write_sequence0 0 s: constructor ahb_basic_write_sequence1 UVM_INFO ahb_driver.h(53) @ 0 s: reporter [ahb_driver_inst] build_phase Entered 0 s: connect_phase tb Info: (I804) /IEEE_Std_1666/deprecated: all waits except wait() and wait(N) are deprecated for SC_CTHREAD, use an SC_THREAD instead 0 s: run_phase Entered tb UVM_INFO ahb_basic_write_sequence.h(66) @ 0 s: reporter [ahb_basic_write_sequence0] Starting sequence ahb_basic_write_sequence UVM_INFO ahb_basic_write_sequence.h(76) @ 0 s: reporter [ahb_basic_write_sequence0] Sending transaction from sequence ahb_basic_write_sequence UVM_INFO ahb_basic_write_sequence.h(66) @ 0 s: reporter [ahb_basic_write_sequence1] Starting sequence ahb_basic_write_sequence UVM_INFO ahb_basic_write_sequence.h(76) @ 0 s: reporter [ahb_basic_write_sequence1] Sending transaction from sequence ahb_basic_write_sequence Any idea why is this happening? wait_for_grant() should unblock when driver takes the request right? Not sure why isnt the driver getting the request. Appreciate your help here! TIA PS: Attached the files for reference. Akhila ahb_basic_write_sequence.h ahb_basic_env.h ahb_driver.h ahb_sequencer.h
  2. I am learning UVM. So far I was able to create the following environment for my DUT. Agents with monitors, drivers and sequences for all of the input-output interfaces from my DUT. A top level UVM env. Sequences to send valid data to DUT. I yet to implement scoreboard. I'm having some trouble to understand how to handle scenarios like following: For one of my tb->dut interfaces, TB needs to wait for an event (or transaction) from DUT. Once it receives the transaction from DUT, TB needs to send back a response. What is the best way to implement this? How can I monitor DUT transaction from sequence? I assume I need to wait for an event or something similar which will tell me that DUT has a new valid output in its interface. My agents have monitors which will monitor any new output signals from DUT. So, do I need to somehow bring this data from agent's monitor to my test/sequence class? I know that monitor has an analysis port and it can be used to send received data to scoreboard for checking. So, do I need to use the same port to read DUT output data, create valid response and send it to DUT? Thanks!
×