As you can see from the DDS block diagram, which you posted, the structure of DDS block is quite simple. I therefore would model it as a single TDF module containing the accumulator register as a state variable. As input, you will have your frequency control and phase offset control signals. The frequency control signal basically is the value, which you continuously add to the value in your accumulator register to generate a periodic sawtooth signal (due to the overflow of the accumulator). The phase offset control signal gets added to the accumulator register to enable shifting the phase of the sawtooth signal. This sawtooth signal is interpreted as the angle operand of a sine function. The period of the sawtooth signal represents a full revolution on the phase circle, i.e., the 2^L possible sawtooth signal values are evenly mapped to phase angles in the range of 0 rad to 2 pi rad (0° to 360°). To avoid repeated calculations of the sine function, the sine amplitudes for all possible angles are pre-calculated and stored in a look-up table (LUT). The current value of the sawtooth signal is then used as the index into that look-up table to find the corresponding output amplitude.
To implement this in a generic DDS TDF module, I would choose M, L, and K (bit widths) as generic parameters, which can be passed upon DDS module instantiation to the DDS module's constructor. From M and L, you can calculate the value for the modulo operation, which models in software your overflowing of a M-bits-wide and L-bits-wide addition operation. The difference of M and L gives you the shift distance needed to implement your accumulator output quantisation. The sine LUT needs to have 2^L entries. The sine function should be scaled by 2^(k-1)-1 to use the full range of a k bit wide signed output. All these preparatory calculations, you can do in your DDS module's constructor. The processing function then only needs to only implement the two additions and the amplitude look-up based on the current values of the frequency and phase control inputs and the current value stored in the accumulator register.
If you plan to use this kind of module in a model of communication system, you might consider having a look to the Vienna SystemC AMS Building Block Library, which is available for download from systems-ams.org. The latter web site contains also other useful SystemC AMS resources.
Well, you will have to write a test bench, which provides your RC filter with some stimuli for transient simulation or sets up an AC analysis. However, I recommend you to have first a closer look to the fundamental concepts and ideas of SystemC AMS. A good introduction to SystemC AMS is provided by the SystemC AMS extensions User's Guide, which is part of the SystemC AMS extensions 1.0 release. Even though, this discusses only the features available sind SystemC AMS 1.0, it is a good start as SystemC AMS 2.0 and IEEE Std 1666.1 added mainly advanced features related to Dynamic TDF and bug fixes. Also, the SystemC AMS community pages provide some good links to introductory resources to get started with SystemC AMS.
Actually SystemC provided sc_trace(...) functions where you register your signals and variables for tracing. Running the simulation yields a .vcd file which you can open in gtkwave.
You may have a look into https://github.com/Minres/SystemC-Components-Test/blob/master/examples/transaction_recording/scv_tr_recording_example.cpp
In sc_main() you will find sc_trace_file *tf = sc_create_vcd_trace_file("my_db");
sc_trace_file *tf = sc_create_vcd_trace_file("my_db");
This opens the waveform database. At the end you have to call
to properly close the database. 'tf' is a handle to the database, if you follow the code you will see how to trace signals (or variables),
You can look at this example:
Or this one which shows how to add delay in full adder:
Hope it helps.
Ameya Vikram Singh
This has been already discussed before here:
Hope it helps and if you have further questions please feel to ask.
Ameya Vikram Singh