Jump to content

Martin Barnasconi

Members
  • Posts

    89
  • Joined

  • Last visited

  • Days Won

    18

Posts posted by Martin Barnasconi

  1. It bascially means you have an error in your ELN circuit topology and the equation system cannot be calculated. This could mean a couple of things:

    • you have capacitors in parallel and not defined the initial charge as undefined
    • you have inductors in series and not defined the initial flux as undefined
    • you have two voltage sources in parallel with different voltages
    • you have two current sources in series with different currents
    • you have some short-circuits

    The message says that the error is near component c02 (I expect a capacitor?). So I expect you need to define sca_util::SCA_UNDEFINED for q0 (for ELN primitive sca_eln::sca_c) or phi0 (for ELN primitive sca_eln::sca_l)

  2. You cannot trace SystemC-AMS signals using the SystemC (sc_trace*) methods, because SystemC is not aware of the additional types introduced in SystemC-AMS. Therefore you need to use the sca_trace* methods. These SystemC-AMS trace methods also support SystemC build-in types.

     

    Furthermore, your sc_main does not contain any module instantiatons. Also the use of ports in sc_main is not correct. You need to use signals (e.g. sca_signal<bool> mysig) to interconnect instantiate blocks with signals

     

    Again, please read the SystemC AMS user guide more carefully before you start coding. For tracing usage read section 6.2.

  3. There are some things missing or incorrect in your setup, and that is the reason why you do not see any signals:

    • Use sc_main instead of main
    • You need to instantate the SystemC and/or SystemC-AMS (TDF) modules in your sc_main. You need at least a signal generator (stimuli) and the ADC. You also need to bind them together via a signal of type sca_tdf::sca_signal<double>. This means you also need to instantiate an object of this signal type.
    • You need to enable tracing in sc_main, by opening a trace file using e.g. sca_util::sca_create_tabular_trace_file(...)  and assigning signals or ports to be traced using sca_util::sca_trace(...).
    • I recommend the use of a time limited simulation by specifying the end-time. Example for 1ms simulation: sc_start(1.0, sc_core::SC_MS);

    Please have a look into the SystemC AMS user's guide, which is part of the SystemC AMS standard download, section 2.6.3 which shows an example of the sc_main and instantiation of various modules, signals and tracing mechnism.

  4. This forum is related to SystemC-AMS, not Verilog-AMS. SystemC-AMS is used to model complex heterogeneous systems at an abstract level. Verilog-AMS is often used to model AMS blocks and circuits at the implementation level.

     

    To answer your general questions

     

    1) No. AMS modeling can be used to describe analog and/or digital behaviour, it is just a matter of abstraction. AMS modeling languages support different levels of abstraction. Low abstraction level relates to conservative behaviour, by solving Kirchhoff's voltage and current laws. Signal flow modeling approaches is an abstraction towards a non-conservative description, single quantity (voltage or current, not both) but still continuous in time. Further abstraction can be realized to data flow modeling approaches (discrete-time) or alternatively discrete-event modeling, or even transaction level.

    SystemC-AMS allows you to model at different levels of abstraction, depending on the analog functionality or behaviour you would like to capture.

    This is not only for analog subsystems, but also for digital subsystems. For example SystemC-AMS is very efficient to model Digital Signal Processing functions like FIR filters or IQ modulators/demodulators.

     

    2) For sure, AMS modeling can be used to create AMS testbenches. Also here, it is just a matter of selecting the right abstraction level for the blocks in your testbench (stimuli, checkers, etc). Special care is always necessary at the boundary between 2 abstraction levels. This means there is not always the need to connect an analog stimuli to an analog input of the DUT, but you need to take care of the semantic difference and conversion if you cross such abstraction boundary. Often you need converter ports, modules or other interface elements in between to make the conversion from one domain (abstraction) to the other.

    This is not only relevant for the interface between testbench and DUT, but also on-chip from analog subsystem A to digital subsystem B, where the abstraction level is thus different.

  5. The TDF converter ports sca_tdf::sca_de::sca_in<T> or shorter version sca_tdf::sc_in<T> are normally used in TDF modules (of class sca_tdf::sca_module) where you connect to the SystemC discrete event domain. In your case, you correctly create a regular SystemC module (of class sc_module), in which you instantiate ELN primitive modules.

     

    If you want to connect such model to the SystemC discrete event domain, you should use the regular SC port of type sc_core::sc_in<T>. In order to have the voltage source to access discrete event signals, you need to select the component sca_eln::sca_de::sca_vsource or shorter version sca_eln::sca_de_vsource.

     

    Also note that this is a regular SystemC module, so use the normal constructor or macro (SC_CTOR) and not SCA_CTOR.

     

    Anohter good coding style is only to use capitals for the macro and defines, not in port and modules names, etc.

  6. Your input signal created by module lpf_tb is not a valid SystemC AMS module. It seems you created a regular SystemC module following discrete event semantics, but you need to create a module following timed data flow (TDF) semantics. Please check the SystemC AMS users guide, section 2.3.1 to create a TDF module.

    Alternativelty, you can replace the voltage source and sink converter elements the LPF module by a voltage source driven by a discrete-event input signal called sca_de_vsource and the sink by sca_de_sink.

    Also note that you need to specify at least one timestep to the TDF or ELN cluster. You can do this via the main function, for example L1.set_timestep(1.0, sc_core::SC_MS)

  7. A DAC is basically bits in, and analog value (represented as a double) out. Depending on the data type you use as the input, bit-by-bit (bool, or sc_logic) or a bit vector (sc_bv or as a sc_uinit), you need to take these bits, make a bit vector of your favourite size, and make an double value from this.

    You might need a multi-rate input port (sca_tdf::sca_de::sca_in if you connect to a plain SystemC digital model or sca_tdf::sca_in when your DAC input is connected to another TDF model). In a for-loop you can grab the individual bits and create the bit vector, and you can use the to_double method, which is supported by most SystemC data types, to write the double value to a TDF output port.

  8. The whitepaper was published long before the release of the SystemC AMS 2.0 LRM, so therefore there were some changes in the API. You will find the updated whitepaper in Annex A2 of the AMS 2.0 standard, which includes the updated language constructs. Here you can read that the member functions allow_dynamic_tdf() and disallow_dynamic_tdf() are replaced by does_attribute_changes() and does_no_attribute_changes(). The defintion of these methods are explained in the sections with the corresponding name.

  9. I'm not familiar with this COSIDE library component, but it looks like your are facing a classical time step and rate inconsistency problem when different and incompatible time steps are defined in a single TDF cluster.

     

    My advice is to read section 2.1.3 of the users guide (Time step assignment and propagation) and in particular the paragraph Consistency of time step assignment and propagation. Here you will see that you can have different time steps due to the rate setting. Please check carefully the time steps and rates defined in the methods set_attributes() of your TDF modules, and see if this is consistent with the formula given in the user guide: module time step = input port time step · input port rate = output port time step · output port rate

     

    If changing the port time step is not possible (either by a parameter or changing the value in the method set_timestep(...) ), only then I would advice to apply the SystemC AMS 2.0 features. In this case, you basically split the TDF cluster in 2 independent TDF clusters, each having its own time step. Note that the complexity changes in this case, because you need to introduce dedicated decoupling ports.

     

    But I expect you can resolve the issue easily by checking the consistency of time steps and rates.

  10. Section 2.3.2 in the SystemC AMS user's guide explains the effect you see:

     

    Although the TDF model of computation processes the samples at discrete time steps, the equations of these embedded functions will be solved by considering the input samples as continuous-time signals.

     

    This means that your input signal is *not* considered as discrete (sample-and-hold) values, but it will interpolate. This means that between t=3 and t=4 the area is 0.5, which counts up to the integrated value of  3.5.

     

    So if you really want to integrate discrete (digital) signals, I recommend to write this in plain SystemC using discrete-event semantics.

     

    (Note: If you ask me, Matlab/Simulink are not a good reference for comparison, because the execution semantics and models of computations are non-standard.)

  11. 1) A TDF cluster (in this case formed by modules A, B and C) runs dependently from any other part in the system. This other part can be another (not connected) TDF cluster or any other SystemC module which is executed following discrete-event semantics. Looking from an analog perspective on the matter, this is correct: the analog part is "always active" (assuming there is supply voltage - often we do not model this in system level models). As such, there is no dependency between the TDF cluster(s) and SystemC modules, and the execution order is then implementation defined. In the end, you define that both the TDF cluster as well as the SystemC modules need to be active each 10ms, and this will happen. If you would look at the results in a waveform viewer, you will not notice the difference, because you are not interested which samples are written to the screen (or file) first, as long as the samples appear at the right place in time.

     

    2) Here you touch on one of the fundamental differences between SystemC AMS TDF modules using data flow semantics, and regular SystemC modules which work under a discrete-event regime. Due to the evaluate/update mechanism in the SystemC kernel, is it simply not possible using SystemC modules to write a value and read the value in the same simulation cycle. When using SystemC AMS TDF models, they will form a TDF cluster which defines the execution order, and this cluster can be computed prior to simulation. This means the signal values in the whole cluster are computed and thus known for each time step. In a pure SystemC topology however, there does not exists such dependency graph, and therefore the signal values through the system only propagate after each evaluate/update cycle. This effect is part of the discrete-event semantics and cannot be altered.

  12. @Steven: I expect it will be a matter of months to have the first (draft) material available. But again, it is the working group that decides on the schedule. Not sure if this will be LRM or proof-of-concept or both.

     

    @Hans: UVM-SystemC is being developed and tested by end-user companies and system houses (of which only some are member in Accellera). Accellera supports the development of a multi-language verification standard, simply because UVM is available in different language flavors. UVM in SystemC/C++ is just one of them.

  13. I recommend to use the conversion as explained in this thread:

    http://forums.accellera.org/topic/1637-type-casting-floating-point-nos/

     

    note that the code of Philipp was untested and it contains some minor errors. Below the working code:

      double val = ...
    
      sc_dt::scfx_ieee_double id(val); // convert to IEEE 754 bitfield
    
      bool               sgn = id.negative();
      sc_dt::sc_uint<11> exp = id.exponent();
      sc_dt::sc_uint<52> mnt = ( sc_dt::uint64( id.mantissa1() ) << 20 ) | id.mantissa0();
    
      // concatenate parts to bitvector
      sc_dt::sc_uint<64> bits;
      bits = ( sgn, exp, mnt );
    
    
  14. The SystemC AMS TDF model of computation follows the well known data flow semantics, which means that the module is activated (i.e. the SystemC AMS processing() callback is called) as soon as the samples are available at the input port(s). After this computation, the results are immediately available at the TDF output ports (assuming you write to output ports).

    This means the SystemC AMS modules simply compute the signal as soon as TDF samples come in, and pass them after performing some signal processing to the output.

     

    In SystemC AMS 2.0 we introduced the concept of "Dynamic TDF" which allows additional activation of the TDF module's processing() method as soon as discrete-events come in via the converter input ports (sca_tdf::sca_de::sca_in or sca_tdf::sc_in), but this concept should only be used to make reactive systems. I advice *not* to apply this in combination with your coordinator module.

     

    Unfortunately your example of module A and B is incomplete (e.g. are module A and B connected?) to give good guidance. But the use of this coordinator module really sounds like overhead to the system simulation, as it is only meant to synchronize the execution of module A and B. Guess this is an artificial module to drive simulation only? This type of modules should be avoided. Architecture design in SystemC and SystemC AMS should represent the system by modules which are really available in the system.

    Instead, you could implement this example using SystemC AMS only, where module A has a fixed time step of 10ms, and module B a time step of 20ms. You can connect them via a port with a rate of 2, which means module A is called twice, before module B is called. This gives you the right execution schedule. Furthermore, by following this approach, you basically skip the native SystemC discrete event semantics, and simulation even gets much more efficient.

  15. One of the unique features of SystemC-AMS is the propagation of the time-step properties, as documented in the user guide section 2.1.3. I expect you have already seen this section.

    This means it is not mandatory to specify the time step for each TDF module, but only specify this at one place in the TDF cluster (this is the computed execution schedule of the set of connected TDF modules). The most common place is to do this in the test bench, for example as the input source of the system.

     

    Of course you can assign time steps to each TDF module, but then it is very important to get it consistent in the entire TDF cluster. In a single-rate system this is rather easy, but as soon as you start with multi-rate systems, the execution (firing) of each TDF module and its TDF port time steps could differ. Therefore I would advice to rely on the time step propagation approach, because it will match TDF module time step and port time steps.

     

    This story also explains that (especially in multi-rate systems) that the time step is not something global, but something that belongs to a TDF module and port. That's why TDF modules and ports have the set_timestep methods, and we did not define this time step definition as global simulator function. As such, one can argue the time step properties belong to the TDF module, and thus can be included in the parameter object which is passed as constructor argument.

  16. Although I do not understand well your application (perhaps you can explain a bit more), here some things which might help.

     

    The SystemC AMS TDF modules are tiggered -or fired according to the synchronous data flow terminology-  if all samples are available at its input ports. In such case, the processing() method is called. You can add a simple data member counting the number of firings of this processing() method, As the time step is known, you should then know when to perform the additional calculations on your array.

    Alternatively, you can use the get_time() method to ask for the time in a TDF module (note: you should not use the sc_time_stamp(), as the SystemC time might differ from the SystemC AMS TDF time in a TDF module), and compare it with previous stored time (also using a data member) and take action if the time difference is what you expect.

     

    Note that the whole idea of SystemC AMS is to keep the number of digital discrete events (handled by the SystemC kernal) for signal-level interfaces as low as possible, and therefore time handled in the SystemC AMS kernel. Actually, the time in TDF models is annotated, based on the static schedule which can be calculated prior to simulation, and thus the number of discrete events processed by the SystemC kernel is kept as low as possible. So I would not introduce additional (SystemC) modules to generate additional events; instead, it is adviced to calculate the number of firings or time in a TDF module.

  17. It seems your starting point is Verilog-A or Verilog-AMS, because the ddt keyword is defined in this langauge. Note that Verilog-A/MS do not offer electrical primitives as part of the language defintion, so you should create your own. The ddt keyword is invented to create equations to model inductors or capacitors. But for the SystemC AMS extensions, you do not need to do all this; you can simply instantiate an inductor or capacitor.

     

    So the lession is: do not blindly map Verilog-A/MS concepts on SystemC AMS.

     

    Instead, explore if and how to abstract the analog functionality, perferably to a signal flow (LSF) or data flow (TDF) model of computation. Remember: SystemC AMS is a system-level language. If this is not possible, I expect you are dealing with electrical signals or conservative behaviour, and you should be able to directly use the predefined electrical primitives to model your analog subsystem.

  18. I propose to take one step back, and before diving into the technical challenges of your request, just briefly explain to us why would you like to embed SystemC-AMS in Verilog-AMS?

     

    For me this sounds a bit strange, as I expect you might need to embed a more refined or detailed models (e.g. in Verilog-AMS) into a System-level model (e.g. SystemC-AMS) and not the other way round. Furthermore, as SystemC AMS supports conservative and signal flow modeling, I could argue there is no need at all to use Verilog-AMS. So why not stick to SystemC and SystemC-AMS?

     

    When you use Incisive, you can do a SystemC-on-top design. SystemC on top gives you much more flexibility and power than Verilog on top, for example you can easily include C/C++ functions, use the concept of interfaces, transaction-level modeling, and all these essential features you need to create a good system-level testbench or virtual prototype for/of your system.

    I would recommed reading the manual how to use ncsc_run or irun to do SystemC on top.

     

    If you then want to include SystemC-AMS, just compile this library together with the build-in SystemC library of Incisive. This is feasible as the SystemC-AMS PoC fully relies on the SystemC standard API, which is supported and implemented by most EDA vendors. For example, you put  all SystemC-AMS source files in a fileset (.f) and pass it in one go to irun. 

     

    After this preparation you can make your design, and make the connections as suggested by Torsten, by using the TDF converter ports of type sca_tdf::sca_de::sca_in<T> or sca_tdf::sca_de::sca_out<T> to connect to a SystemC sc_in<T> or sc_out<T>.

     

    Such approach saves you from the big hassle to deal with multiple languages, and above all from the ugly and inefficient $bitstoreal and $realtobits.

     

    Just my 2 ct ;-)

×
×
  • Create New...