Jump to content

David Black

Members
  • Posts

    690
  • Joined

  • Last visited

  • Days Won

    154

Everything posted by David Black

  1. [WARNING: The following is philisophical] Assembly language programmers felt the same way about high level languages like FORTRAN. Functional programmers (e.g. C) felt the same way about object oriented languages. Schematics were the way of things for many engineers until RTL showed up. Verifying a design by occular inspection waveforms was replaced by self-checking testbenches with some resistance. Verification using directed test was mainstream and constrained random with functional coverage was resisted for many years. The advantages of reuse and scalability of the new techniques has slowly changed many. Engineers and programmers facilitate change, but themselves are some of the most resistant to change when it affects their own world. I think it's inevitable. As complexity increases, we have to find new ways to deal with it, and abstracting upwards is the way of things. One way to deal with change is to decide not to let the new ways master you. Instead read books, take classes and become a master of the new technology. Sadly, many universities have not caught up with modern practices at the undergraduate level.
  2. From our UVM Adopter's class, here is a portion of a Makefile that applies to VCS: UVM_VER = uvm-1.1 UVM_SUB_VER = d UVM_HOME = /apps/uvm VCS = vcs VCS_OPTS = -sverilog +acc +vpi -timescale=1ns/1ns $(EXTRA_VCS_OPTS) .PHONY: clean vcs vcs_debug vcs_std default: # To use with VCS, enter: # make vcs or make vcs_debug # To remove temporary files, enter # make clean vcs: $(VCS) $(VCS_OPTS) -ntb_opts uvm $(INCDIRS) $(SRCS) -R $(EXTRA_VCS_RUNOPTS) vcs_debug: $(VCS) $(VCS_OPTS) -ntb_opts uvm $(INCDIRS) $(SRCS) -R -gui $(EXTRA_VCS_RUNOPTS) vcs_std: $(VCS) $(VCS_OPTS) +acc +vpi $(INCDIRS) +incdir+$(UVM_HOME)/src $(UVM_HOME)/src/uvm.sv $(SRCS) \ $(UVM_HOME)/src/dpi/uvm_dpi.cc -CFLAGS -DVCS -R $(EXTRA_VCS_RUNOPTS) clean: @echo cleaning old simulation files and libraries... @ -$(RM) csrc simv* work *.bak *.log *.vpd transcript \ waves.shm *.wlf mylib lib *.vstf .restart* \ urgReport *.so vc_hdrs.h # EOF
  3. I don't believe anywhere it states that UVM_FATAL is for internal messages vs UVM_ERROR. Instead, I would assert you should use the tag to indicate "Internal". I believe the main idea between the severity's is that: UVM_INFO - informational/debug text to be used sparingly with appropriate verbosity (almost never UVM_NONE) UVM_WARNING - there is possibly an problem here, but not clear cut and must be interpreted UVM_ERROR - definitely an error, but processing may proceed to allow other errors to be seen UVM_FATAL - definitely an error and further simulation will with high probability produce garbage so exit is appropriate here Not all internal errors are any more certainly fatal than others, so I would use things like: if (internal_error1) `uvm_fatal("configuration - internal","Missing required connection to...") if (internal_error2) `uvm_error("option - internal", "Missing configuration value - defaulting") if (design_error) `uvm_error("configuration", "Invalid register configuration may impact data") if (fatal_power) `uvm_fatal("powerup", "Module failed to powerup") That said, you can limit error using the set_report_max_count (or equivalently +UVM_MAX_QUIT_COUNT as you indicated). Another approach would be to use uvm_report::set_report_severity_action_hier(), which has the advantage you can focus it to a particular part of the hierarchy. You can also use a uvm_report_catcher to reclassify messages, but I would use that as a last resort (e.g. when unable to modify the source code due to encryption or legalities). Shameless plug: We discuss all of this and more in the Doulos UVM Adopters class <http://doulos.com/content/training/systemverilog_uvm_adopter.php>.
  4. My favorite Vim plugin for C++ is Clang Complete <http://www.vim.org/scripts/script.php?script_id=3302>. Of course it requires that you install clang++/llvm <http://llvm.org/releases/download.html>. Clang++ is an open-source C++ compiler with much better error messages than GCC. Alternately, you can use the Vim plugin GCCsense <http://www.vim.org/scripts/script.php?script_id=1520>, which depends on ctags. You will need to spend time to learn how to install and use these yourself.
  5. While you can model RTL using SystemC, SystemC is really not intended for this low level of abstraction. SystemC works best at higher levels of abstraction such as TLM and untimed algorithms. RTL capabilities allow SystemC to interface with and co-simulate with Verilog and VHDL simulators. In the extreme, you can create RTL models; however, the simulation performance is abysmal compared to those simulators. Verilog (and SystemVerilog) and VHDL simulators have compilers that are RTL aware and can use that knowledge to improve simulation performance over what a simple C++ compiler can. They have RTL domain specific knowledge to allow this; whereas, SystemC is just a C++ library. For example, knowing RTL one can combine all the RTL blocks sensitive to a clock into a single call across all modules, which reduces context switching considerably. Yes, you can model bus splitters/mergers in SystemC by implementing sc_signal channel adapters, and the syntax will be rough. You will need to implement processes to handle event merging/splitting, which adds to overhead. Simplest solution is to hand large bus around and let endpoint processes deal with the subscripting as dakupoto indicates.
  6. Just use the primitive channel, sc_signal<T>. The sc_signal<T>::write() method uses sc_prim_channel::request_update() to schedule assignments into the update phase of the simulator kernel. Thus: using namespace sc_core; struct FF : sc_module { sc_out<int> a; sc_in<int> b; sc_in<clk1> clk1; SC_HAS_PROCESS(FF); FF(sc_module_name instance_name) { SC_METHOD(FF_method); sensitive << clk1.pos(); } void ff_method(void) { a->write(b->read()); // better than a = b; because it reminds of the odd nature of sc_signal::write() } }; NOTE: I never recommend using 'a = b;' notation, because delta cycle delays are always surprising to programmers. I might be convinced if you agree to name all your signals with _signal suffix (e.g. a_signal = b_signal;).
  7. On Linux, if you use Vim, you can install several nice C++ helper scripts from www.vim.org to get functionality similar to Visual C++ (e.g. name completion). Using The graphical mode (i.e. -g or gvim) yields a pleasant development environment where you can view directories, edit multiple files, compile them and perform quick fixes.
  8. Manikanta's solution assumes temp is public. If not public, you can take the opposite approach and simply call sc_trace from within the module itself. You could even do it conditionally based on run-time command-line arguments: sc_core::sc_trace_file trace_file = 0; //< initialize to indicate not open top::before_end_of_elaboration() { for (int i=1; i<sc_argc(); ++i) { if ( trace_file == 0 && std::string(sc_core::sc_argv()[i]) == "-trace" ) trace_file = sc_core::sc_create_vcd_trace_file("your.vcd"); }//endfor } top::end_of_simulation() { if ( trace_file != 0 ) sc_core::sc_close_trace_file(trace_file); } ... extern sc_core::sc_trace_file trace_file; void dut::end_of_elaboration() { if (trace_file != 0) { sc_core::sc_trace(trace_file, temp,"temp"); } } Of course I am assuming fp is made public as shown, and that you have opened it before end of elaboration:
  9. Nope. It is implemented this way in SystemC for simulation performance (speed) reasons. If that is important to your model, then you should associate a flag with each event. Probably wrap it up in your own custom channel class for safety.
  10. UVM itself knows nothing about clocks. UVM is a transaction level methodology. It is the drivers that deal with clocks and pin-level timing concerns. Each driver is connected to a sequencer (1 to 1 relationship) within an agent. So I have to assume that your sequencers are commented to reflect the fact that their respective drivers deal with the respective clocks. So if you send a transaction to eth_seqr0, then it will use the timing dictated by the driver connected to eth_seqr0 (? possibly eth_drvr0 ?). Your answer most likely lies in the hardware interface, and really has very little to do directly with UVM. Of course it is possible that clock driving information is embedded in the transaction items themselves for interpretation by the drivers; however, I doubt it since that would probably not be the best from a design point of view.
  11. 1. The time delay in b_transport is used to allow temporal decoupling in the models, which speeds up simulation immensely. It is part of the loosely-timed modeling style concept described in IEEE-1666-2011. 2. The instance name parameter of a SystemC module constructor is identical in concept to the UVM factory create string argument. Both are used to maintain an object hierarchy name for use during debug. For more information, I suggest you either take a class in SystemC or read a good book on the topic.
  12. My initial reaction is JDI. Please restate the question. Is the driver code written is assembly or C? Is there an OS presumption?
  13. In your compilation (step 1a) you forgot to add the -g option to get debugging information into the resulting executable. % g++ -ggdb -I. -I$SYSTEMC_HOME/include -L. -L$SYSTEMC_HOME/lib-linux -o out stack_class.cpp -lsystemc -lm
  14. SystemC was never intended for such low-level modeling anyhow. It can be used to model RTL, but SystemC is not the best option. Choosing it because it is "free" doesn't make it the right choice. If you need SPICE level modeling, then use SPICE. If you want System Level Modeling, then SystemC is a decent choice. I use SystemC for modeling -ABOVE- RTL level.
  15. You should be able to use the accessor methods of the tlm_generic_payload to get all the information needed for operator<<.
  16. The source code is available for you to look at. Signals contain basically two variables for the data (current and future data), plus some events used for the mechanics. Their size is not really an issue; however, they are technically primitive channels and they use the request_update() mechanism to create their non-blocking behavior.
  17. If you are just trying to see if the desired matches the actual, you should use peek() to do a back door access and then compare the value with the results of a get(). There is no significant advantage of having mirror() do the check, and as you observed, mirror() does a front door access of the entire register. That is the purpose of mirror() generally. You might also be able tell mirror to do a back door access by specifying .path(UVM_BACKDOOR) I think, but I have not tried this.
  18. A report catcher is ideal for this situation. There is an example in the UVM 1.1 reference manual. Q: Did you put single quotes around the +uvm_set_severity option when passing to the tools? NOTE: If you have wrappers around your tools, this can be quite tricky as some wrappers make passing of special characters such as asterisk (*), question mark (?), etc. difficult indeed.
  19. I observe that the only place in the code where the construct new memItem occurs is in your debug routine. It's no wonder that you crash without it, since the initial array uninitialized ponters. Nowhere do we see the definition of memItem, and nowhere do we see the array properly initialized. Also, I do not see any array bounds checking in the provided code. I would expect numerous problems with this coding approach. Good programmers learn to minimize pointers by relegating them to low-level constructs and using RAII techniques. Good C++ programmers will utilize STL concepts such as std::vector (or std::array) and std::unique_ptr. Consider using: struct memItem { int content; memItem() // Constuctor :content(0) // Proper initialization {} }; std::array<memItem,100> itemArray; # You can now access items in the array with: # memArray.at(i) = newValue; //< set a value # existingValue = memArray.at(i); // get a value #
  20. When dealing with pure combinational circuits, the behavior of SystemC is completely reasonable. Usually with pure combinational signals, timing issues prevent signals from arriving at the same time, so the issues of multiple delta cycles is actually an artifact of modeling in the absence of real timing information. It is also the case with pure combinational signals that re-executing a method would not be a problem other than the slight overhead it incurs. One small issue does remain however... in the current model SystemC model, there is nowhere to identify the final resolved value of a variable as it leaves a timeslot (i.e. after the last delta cycle of a given time). This notion is covered in Verilog with the 'postponed' timing region. Implementation of similar concept is currently under investigation by the SystemC language working group within Accellera. This does not affect most users of SystemC, since the primary use of SystemC is at the architectural level rather than RTL and other low level modeling. This is all carefully spelled out in section 5 (esp. 5.2.1) of the IEEE 1666-2011 standard, which any serious SystemC user should take time to understand. I observe that students at universities are most likely to see this issue because they view SystemC as an inexpensive (i.e. free) RTL/circuit simulator with a low learning curve (ie. C++), which SystemC is not designed for. Verilog or VHDL are more appropriate for those activities. SystemC can suffice if you are willing to put up with these small limitations.
  21. Interesting. I created my own reporting scheme some years back under SystemC with XML output as an alternative. It was part of my revamped report_handler. It should also be noted that transaction recording should offer a similar offering so that reporting and recording can be merged. This could lead to some very powerful debug tools. Of course a carefully thought out XML schema should accompany such a proposal, and perhaps an option to have things like sprint optionally output XML for transactions. As for SQL, I think that could be separated out and left for tools implementations.
  22. I believe 'force' is intended for net types (e.g. wire) and uses the SystemVerilog 'force' statement; whereas, 'deposit' is intended for variables (i.e. var or reg types). Lookup the 'force' and 'release' statements in the SystemVerilog standard for more information.
  23. Dynamic processes have many uses. An interesting example is for those modeling cell phone base station environment. When a cell phone "comes into range", you can launch a process to model the appearance of a cell phone, and have it die when it goes out of range. Another example might be to model hot pluggable USB devices on a USB controller. Admittedly, you could create a pool of static processes for this purpose, but it is not always a natural style. For verification, dynamic processes are frequently useful to do activities related to temporal assertions (i.e. like System Verilog Assertions or PSL). There is an overhead for launching dynamic processes that has to be considered when modeling, so only use when it makes sense. SystemVerilog has the construct: fork/join_none that is the equivalent concept to spawning in SystemC.
  24. Which version of UVM register layer does this tool generate? Or to phrase differently, does this tool generate UVM standard register descriptions (i.e. exactly as called out in the reference)?
×
×
  • Create New...