dumpling.Common package
Submodules
dumpling.Common.ElfParser module
- class dumpling.Common.ElfParser.ElfParser(verbose=False)[source]
Bases:
objectA helper class to parse ELF binaries and extract the relevant segments for preloading as well as the start address.
- add_binary(binary: Union[str, PathLike])[source]
Add an additional binary to the ElfParser instance.
All binaries added will be parsed together when parse_binaries() is called.
- Parameters:
binary – A path to the binary to be added to the parser instance.
Returns:
- get_entry()[source]
Return the entry point of the ELF binary (the address where the core should start execution).
- Returns:
The entry point address as an integer.
- Return type:
- parse_binaries(word_width)[source]
Parses the added binaries and returns a dictionary with addr, data pairs.
The word_width determines how many bytes are agregated to a single entry in the returned dictionary. E.g. calling ‘stim_gen.parse_binaries(4)’ will generates a dictionary were each key is a 4-byte aligned address with corresponding 4 bytes of data. The byte ordering is little endian.
- Parameters:
word_width (int) – The width of one word in bytes
- Returns:
Dict[int, int] A dictionary of address data pairs
dumpling.Common.HP93000 module
- class dumpling.Common.HP93000.HP93000VectorReader(stimuli_file_path: Path, pins: Mapping[str, Mapping])[source]
Bases:
objectThe HP93000VectorReader allows parsing of AVC files back to the intermediate representation of vectors in the form of dictionaries.
In order to not exhaust the whole system memory when parsing huge AVC files, the Class provides the self.vectors() generator function that iteratively reads and parses the underlying AVC file while iterating. Additionally the HP93000VectorReader implements the the context manager interface to automatically close the underlying file once all vectors have been consumed.
Examples:
with HP93000VectorReader('my_vectors.avc', my_pin_declarations) as reader: for vector in reader.vectors(): ..do something usefull with the vector...
- Parameters:
stimuli_file_path (Path) – The path to the AVC file to parse
pins (Mapping[str, Mapping]) – The pin declaration that allows the parser to perform the inverse logical to physical pin name mapping (i.e. the same pin declaration that was used to generate the vectors with VectorBuilder
- vectors()[source]
A generator function that yields a single parsed vector at a time.
- Yields:
Mapping – A single vector
- Raises:
StopIteration – Once all vectors have been consumed
- class dumpling.Common.HP93000.HP93000VectorWriter(stimuli_file_path: Path, pins: Mapping[str, Mapping], port: Optional[str] = None, device_cycle_name: str = 'dvc_1', wtb_name: str = 'Standard ATI')[source]
Bases:
objectThis class allows to generate AVC files from Vectors in intermediate (dictionary) representation as generated by the VectorBuilder class.
During initialization, the object is initialized with a pins declaration dictionary (see documentation of the VectorBuilder class) and output AVC file path. Optionally, a port, device_cycle_name and wavetable name can be supplied. In addition to creating the avc output file, a wave table file (.wtb) and a timing format file (.tmf) is generated upon construction of the HP93000VectorWriter instance. These files will have the same base name ( e.g. vectors.tmf and vectors.wtb if stimuli_file_path`==’output.avc’. This allows to directly import the generated vectors for a specific test port given that the `port argument was chosen according to the port name used in the tester setup.
The class implements the context manager interface that automatically closes the underlying avc file. This allows to write vectors to AVC file in batches:
with HP93000VectorWriter('output_vectors.avc', dut_pins) as writer: vectors = ...generate some vectors... writer.write_vectors(vectors) vectors = ...generate some more vectors... writer.write_vectors(vectors) #Append them to the AVC file
- Parameters:
stimuli_file_path (Path) – The path of the output AVC file
pins (Mapping[str, Mapping]) – The pin declaration dictionary (see VectorBuilder docstring)
port (str) – If not None, PORT declaration is added to the header of the AVC file to make it importable as a port specific vector file.
wtb_name – The name of the wavetable to be associated with the AVC pattern file.
- write_vectors(vectors: List[Mapping[str, None]], compress=False)[source]
Append the given vectors to the vector file in AVC format.
This method translates the intermediate vector representation generated by VectorBuilder or HP93000VectorReader to the AVC format that can be imported into the ASIC tester.
The function allows to optionally apply run length compression on the vectors by merging subsequent identical vectors to a single entry with increased ‘repeat’ attribute. This allows to safe vector memory but might make the vectors harder to interpret during debugging.
- Parameters:
vectors (List) – A list of vectors to translate and append to the AVC file.
compress (bool) – If true, apply compression to the vector before writing them to the AVC file.
Returns:
dumpling.Common.Simulation module
- class dumpling.Common.Simulation.CocotbVectorDriver(pins, dut)[source]
Bases:
objectA class to simulate the application of vectors with an RTL simulator.
The class mimics the behavior of the ASIC tester’s wave table. It provides cocotb coroutines that apply the given vectors to a device under test. It addition to the dut handle to which the vectors are applied that constructor also expects the pins declaration corresponding to the vectors according to the format specified in VectorBuilder docstring. There is however one additional key that needs to be provided for each pin:
The CocotbDriver expects the pinlist ‘pins’ to contain a wavefun key for each pin with an associated coroutine function that will be used to apply values to the signal or sample them. This allows to mimick the behavior of the ASIC tester wavetable by arbitrary shifting the time were data is applied or sampled.
Each wavefunction is supposed to have the signature like the following example wavefunction:
async def my_stimuli_appl_fun(signal, value): await cocotb.trigger.Timer('2', units='ns') #Wait 2ns signal <= value
signals is a CocoTB simulation object handle (a signal handle) and value is the pin state character of the pin for the current vector. The example wavefunction from above will advance simulation time by 2ns before applying the value to the signals.
The CocotbVectorDriver will fork the supplied coroutine for each pin supplying the cocotb pin signal handle to ‘signal’ and the value of the current vector to ‘value’ as arguments to the coroutine function. After all wavefunction coroutines have terminated, the driver proceeds with applying the next vectors. It is good practice to have all wavefunctions associated with each pin consume the same amount of simulated time (i.e. the period of the device cycle on the ASIC tester)
The CocotbDriver class contains static helper functions to generate wavefunction coroutines for commonly used wavetable schemes (‘simple_clock_gen_wavefun’, ‘simple_stimuli_appl_wavefun’ and ‘simple_response_acq_wavefun’).
- Parameters:
pins – The pins description dictionary as described in the Docstring of VectorWriter.
dut – The cocotb design under thest simulation handle i.e. the toplevel module where stimuli should be applied to.
See also
CocoTB Documentation: https://docs.cocotb.org/en/stable/
Documentation of the apply_vector method.
- async apply_vector(vector)[source]
Applies a single vector in intermediate representation (dictionary) to the DUT.
This coroutine will print the annotated comment of the vector (if not None or “”) to the simulation log and applies the vector to the DUT (appropriately handling matched_loops, normal loops and the ‘repeat’ value of normal vectors.
- Parameters:
vector – The vector to apply to the DUT
- Returns:
True, if there was a missmatch during application of the vector, False otherwise
- async apply_vectors(vectors)[source]
Apply a list of vectors in intermediate representation to the DUT.
- Parameters:
vectors –
- Returns:
True if all vectors passed (had no missmatches), False otherwise.
- Return type:
- static simple_clock_gen_wavefun(period_ps, duty_cycle=0.5, start_high=False, idle_low=True)[source]
This function returns a coroutine wavefunction for clock application with the given period.
The coroutine will apply a clock to signal if the value is ‘1’. The clock can either be idle-Low or idle-high when value is ‘0’. The start_high parameter decides whether the clock period a rising edge (start_high=’False’) or if the rising edge is applied after (1-duty_cycle)*period_ps
- Parameters:
period_ps – The clock period used by the returned coroutine
duty_cycle – The percentage of ‘period_ps’ the clock remains High
start_high – Whether to start the period with a Rising Edge or with the Falling Edge
idle_low – If signal should remain low when value is ‘0’ or if it should remain high
- Returns:
A coroutine for stimuli application that can be passed to ‘CocotbDriver’ as a wavefunction in the pin dictionary.
- static simple_response_acq_wavefun(acq_delay_ps: float, wave_period_ps: float)[source]
This function returns a coroutine wavefunction that implements a basic waveform acquisition that samples the signal and compares it to the given value ‘acq_delay_s’ before the end of ‘wave_period_s’.
I.e. the signal the value will be assigned to signal after ‘wave_period_ps’ - ‘appl_delay_ps’ pico seconds and the wavefun returns the result of the check
after wave_period_ps has elapsed after its invocation.
- Parameters:
- Returns:
A coroutine for response acquisition that can be passed to ‘CocotbDriver’ as a wavefunction in the pin dictionary.
- static simple_stimuli_appl_wavefun(appl_delay_ps, wave_period_ps)[source]
This function returns a coroutine wavefunction that implements a basic waveform applier that assigns signal the given value the desired skew after the rising clock edge.
- Parameters:
- Returns:
A coroutine for stimuli application that can be passed to ‘CocotbDriver’ as a wavefunction in the pin dictionary.
- async simulate_avc(avc_path: Path)[source]
A Coroutine that parses and iteratively applies all vectors from an AVC file to the device under test.
- Parameters:
avc_path – The path of the AVC files who’s vectors shall be applied to the DUT.
- Returns:
True, if all vectors were applied without any missmatches, False otherwise.
- Return type:
See also
apply_vector
dumpling.Common.VectorBuilder module
- class dumpling.Common.VectorBuilder.VectorBuilder(pins: Mapping[str, Mapping])[source]
Bases:
objectThe VectorRecorder class provides a common interface for stimuli generating classes like the JTagDriver class to dump stimuli in a target independent intermediate representation.
Upon construction, the class expects a declaration of the pins that will be contained in the generated vectors which is a dictionary of pin description of the following form:
{ 'chip_reset': {'name': 'pad_reset_n', 'default': '1', 'type':'input'}, 'trst': {'name': 'pad_jtag_trst', 'default': '1', 'type':'input'}, 'tms': {'name': 'pad_jtag_tms', 'default': '0', 'type':'input'}, 'tck': {'name': 'pad_jtag_tck', 'default': '0', 'type':'input'}, 'tdi': {'name': 'pad_jtag_tdi', 'default': '0', 'type':'input'}, 'tdo': {'name': 'pad_jtag_tdo', 'default': 'X', 'type':'output'} }
The key of the dictionary is the logical name of the pin (e.g.
tck). The logical name of the pin is used by the driver to reference a target pin without knowing the actual name used in the design. The value corresponding to the logical name is another dictionary containing the following keys:- “name”:
The actual name of the pin corresponding to the logical name. This value depends on the module under test.
- “default”:
The default value that should be assigned to the pin if the driver doesn’t assign a different value.
Valid values are ‘0’, ‘1’, ‘X’ and ‘Z’
Once created with such a pin list the vector writer can then be used by the driver to generate stimuli. The VectorRecorder class overrides the __setattr__ and the __getattr__ function so drivers can use the instances of this class according to the following example:
vectors = [] writer.trst = 0 writer.chip_reset = 1 vectors.append(writer.vector()) #Generate 1 vector with writer.chip_reset = 0 writer.tck = 1 vectors.extend(writer.vector()*10) #Release reset and generate 10 vectors with tck=1
For each pin declared in the pin_list when creating the writer, an internal state is maintained, that is initialized with teh ‘default’ value. When calling
self.vectora new vector is generated with using the current state of each pin (i.e. a pin value has to be assigned only if it changes between one vector and another). Each vector is represented int the form of a dictionary. There are three different types of vectors indicated by the ‘type’ entry:- Normal Vectors:
{'type': 'vec', 'vector': <pin_state_map>, 'repeat':int, 'comment':str}
The <pin_state_map> is another dictionary which contains a mapping of each logical pin name supplied in the pin declaration to pin state character, e.g. ‘0’,’1’,’X’ etc. The actual state character used depends on the driver but the three character just mentioned are the most commonly used ones. The repeat value denotes how often the vector should be repeated before the next one is supposed to be applied. A value of 1 denotes that the vector should be applied exactly once. The comment string helps to identify the purpose and context of the current vector. Most drivers automatically anotate the generated vectors with reasonable default comments. How the comments are used depends on the target, consuming the vectors. The AVC vector writer (HP93000VectorWriter class) embeds the comment into the vector string while the CocotbVectorDriver write the to the Log output during simulation.
- Matched Loops:
Matched loops represent the corresponding sequencer capability of the ASIC tester, to apply a list of condition vectors to the DUT in a loop until none of the vector cause a mismatch. If there is a mismatch during condition vector application, the sequencer will apply a second list of ‘idle vectors’ before trying the ‘condition vectors’ once again. This procedure is repeated until the condition vectors all pass or the maximum number of iterations is reached. Matched loops cause all kinds of weird behavior on the ASIC tester and might cause it to no longer be able to reconstruct the timing results of a test. Try to avoid them and don’t nest them. Example:
{'type': 'match_loop', 'cond_vectors': List[Vector], 'idle_vectors': List[Vector], 'retries':int}
A retry count of 1 causes the matched loop to be applied exactly once without any repetitions.
- Loops:
A normal loop allows to repeat a whole sequence of vectors for a configurable amount of time:
{'type': 'loop', 'loop_body': List[Vector], 'repeat': int}
Repeat indicates how often the loop is supposed to be applied with one causing the loop body to be applied exactly once.
- Parameters:
pins – The pin declaration dictionary.
- static compress_vectors(vectors)[source]
Compresses the list of vectors by searching for consecutive identical vectors.
The vectors are merged by summing together the repeat option of the individual vectors. Vectors with identical pin values but different comments are not merged together.
The allows to save vector memory on the ASIC tester and results in smaller AVC files.
- Parameters:
vectors (List[Mapping]) – The list of vectors to compress
- Returns:
The compressed list of vectors
- Return type:
List[Mapping]
- loop(loop_body, loop_repeat_count)[source]
Returns a loop vector with the given loop body and the attribute on how often to repeat the loop body.
- Parameters:
loop_body (List) – The vectors to repeat.
loop_repeat_count – The number of applications of the loop body. 1 -> apply the body exactly once.
- Returns:
A single vector (dictionary) representing the loop construct
- Return type:
Mapping
- matched_loop(condition_vectors: List, idle_vectors: List, retries=5)[source]
Construct a matched loop vector using the given list of condition and idle vectors.
The HP93000 ASIC tester has the limitation that the sequence of condition vectors as well as the idle vectors need to contain an exact multiple of 8 vectors. Use the pad_vectors static method to pad your list of condition and idle vectors with an appropriately chosen padding vector.
Notes
Don’t nest matched loops. Although the CocotbVectorDriver correctly handles it the resulting AVC file cannot be parsed by the ASIC tester.
- Parameters:
condition_vectors – A list of condition vectors with len(condition_vectors)%8 = 0
idle_vectors – A list of idle vectors with len(idle_vectors)%8 = 0
retries – The number of retries where 1 means a single application of the condition vectors with immediate failure on missmatch.
- Returns:
A single vector (dictionary) representing the matched_loop construct
- Return type:
Mapping
- static pad_vectors(input_vectors: List, padding_vector)[source]
Append padding vector to the list of input_vectors until its length is a multiple of 8.
The given padding vector is appended to the end of the sequence until the lenght of the sequence is a multiple of 8.
- Parameters:
input_vectors (List[Mapping]) – The sequence of vectors to pad to a multiple of 8 using the given padding
vector. –
padding_vector (Mapping) – A single vector that should be used for padding. Only ‘Normal Vectors’ are allowed
here. –
- Returns:
The padded sequence of vectors
- Return type:
List[Mapping]
- vector(repeat=1, comment='')[source]
Generate a single vector representing the current state of each pin. The pin values can be altered with the __setattr__ method:
my_vector_builder.clk_i = 1 my_vector_builder.rst_ni = 0 a_vector = my_vector_builder.vector(comment="Enabling clock and asserting reset")
The vector can be annotated with an optional comment and has the option to be attributed with a repeat value that indicates repeated application of the same vector. The ASIC tester actually stores this repeat value in vector memory so applying the same vector for 10’000 cycles with a corresponding repeat value only consumes the memory of a single vector entry in ASIC tester memory.