Is there any plugin that allows automatic tracking of history of all workspace variables?

2 visualizaciones (últimos 30 días)
In RTL simulators (like Questasim, Modelsim, any) and in elecronic circuit simulators (like Cadence virtuoso) it is very easy to setup saving all transitions of all nodes / register values during simulation and them plot them as waveforms.
Has anybody tried to implement something similar for the Matlab workspace?
That is, a plugin that records all transitions of all workspace variables, and stores them as time series (where "time" is just a number in sequence), as a debug tool? Sure it is fairly easy to trace one variable in the code itself, but if you need many, all? Like when you need to inspect bit occupancy of all integers in a complicated loop...
  4 comentarios
Rik
Rik el 18 de Mayo de 2022
I suspect the best way to track variables would be to store every variable as a vector and index the last element when actually using it. That is essentially what you seem to want.
Because dipping into variables runs counter to the general idea of Matlab, I would be surprised if there would be a native solution.
There is another way: if you simply want to track whether a value overflows a certain threshold, you could implement a class that checks every time the value changes whether it is overflowing. That way you have full control over your variables and you can forward all expected operations explicitly. You can use this same class to store itself as a vector if you want.
Denis Chouvaev
Denis Chouvaev el 18 de Mayo de 2022
This last option makes a lot of sense. Could you quote a simple example of a class that monitors a variable?

Iniciar sesión para comentar.

Respuesta aceptada

Rik
Rik el 19 de Mayo de 2022
Below is my initial implementation of what you need. There are a lot of adaptations still to be made. It implements both a vector history storage and a simple scalar storage method.
classdef CappedNumber
%Store a scalar and emit a warning when setting the value to something larger than a threshold.
% Detailed explanation goes here
%
% The implementation below assumes you want obj1=sqrt(obj1);. If you don't want that, you can
% do this instead: obj2=CappedNumber(sqrt(obj1)); (which will refresh the flag and history).
%
% Syntax examples:
%
% % Create variables like this:
% a=CappedNumber(1,10,5)
% % For all functions you use, make sure to create a method that will handle the conversion
% a=a+1
% % You can extract the entire history of the variable like this:
% a.value
%
% % Some things even works for arrays out of the box:
% b=[a+2 a+3;a+4 a+11]
% b(1).flag,b(4).flag
properties
value
threshold
flag=false;
end
properties (Hidden = true)
index=1;
StoreAsVector=false;
init=true;
end
methods
function obj = CappedNumber(v,t,BufferSize)
% Constructor.
if isa(v,'CappedNumber')
oldObject=v;
v=getValue(oldObject);
t=oldObject.threshold;
if obj.StoreAsVector
BufferSize=numel(oldObject.value);
obj = CappedNumber(v,t,BufferSize);
else
obj = CappedNumber(v,t);
end
return
end
if nargin==3
% Store the value in a vector.
obj.value=NaN(1,BufferSize);
obj.index=0;
obj.threshold=t;
obj.StoreAsVector=true;
obj.value=v;
else
obj.threshold=t;
obj.StoreAsVector=false;
obj.value=v;
end
end
function v=getValue(obj)
% NB: this doesn't actually overload the get method.
if numel(obj)>1
error('this function wasn''t implemented for array inputs')
end
v=obj.value(obj.index);
end
function obj = set.value(obj,new_val)
% Overload the set method to emit a warning when the threshold is crossed and store the
% the value in a vector if that is enabled.
if obj.init %#ok<MCSUP>
obj.value=new_val;
obj.init=false; %#ok<MCSUP>
return
end
if obj.StoreAsVector,obj.index=obj.index+1;end %#ok<MCSUP>
if new_val>obj.threshold %#ok<MCSUP>
obj.value(obj.index)=obj.threshold; %#ok<MCSUP>
obj.flag=true; %#ok<MCSUP>
warning('CappedNumber:InvalidValue','threshold crossed')
else
obj.value(obj.index)=new_val; %#ok<MCSUP>
end
end
function disp(obj)
v=zeros(size(obj));
for n=1:numel(v),v(n)=obj(n).value(obj(n).index);end
disp(v)
end
% Implement all function interactions you want to use (there is probably a better way than
% this to get this behavior).
% For common operators, see this doc page:
%https://www.mathworks.com/help/matlab/matlab_oop/implementing-operators-for-your-class.html#br02znk-6
function obj=plus(op1,op2)
% Copy the threshold and the flag properties from the first operand.
if isa(op2,'CappedNumber'),obj=op2;op2=getValue(op2);end
if isa(op1,'CappedNumber'),obj=op1;op1=getValue(op1);end
obj.value=plus(op1,op2);
end
function obj=sqrt(obj)
% This syntax assumes obj1=sqrt(obj1);
% If you don't want that, you can also do
% obj2=CappedNumber(sqrt(obj1));
obj.value=sqrt(getValue(obj));
end
function varargout=min(varargin)
% Copy the threshold and the flag properties from the first operand.
varargout=cell(1,nargout);
error(['the min function has complex behavior and also handles arrays\n'...
'You will need to implement the array behavior.'])
end
end
end
  3 comentarios
Rik
Rik el 19 de Mayo de 2022
You're welcome. You do need to be a bit careful with assigning values, but with the overloading of the operations you're using, you should get most of the way there.
Just be sure to document every design decision you make. I made that explicit in the error message for the min method. You need to make choices about how things work, especially if you intend to use the buffered version. It might make sense to split those two options into separate classes, as that makes the choices uniform.
Daniel
Daniel el 19 de Mayo de 2022
Rik, I like your solution a lot! Clean and simple. I just wanted to make a few extra comments.
  • Scopes: To log and visualize data as you go, have a look at all the scopes that MATLAB has. There are timescope, spectrumAnalyzer, dsp.LogicAnalyzer to name a few. Denis, for the usecase you are mentioning, dsp.LogicAnalyzer comes closest. Just define scope = dsp.LogicAnalyzer; and then put data through the scope by calling scope(data). This requires DSP System Toolbox.
  • Automatic instrumentation: buildInstrumentedMex will build in instrumentation into a function, that keeps track of all variables. This requires Fixed-Point Designer.
  • Fixed-point datatypes: If you use fi() datatypes, then you can turn on logging via P = fipref; P.LoggingMode = 'On'. Now, if you define a = fi(7,0,4,1); and calculate a(:)=a+1, then you get an immediate warning: 'Warning: 1 overflow(s) occurred in the fi assignment operation'. It also keeps track of the number of overflows/underflows that have occured. This requires Fixed-Point Designer.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Logical en Help Center y File Exchange.

Productos


Versión

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by