diff options
Diffstat (limited to 'IBISBridge.m')
| -rw-r--r-- | IBISBridge.m | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/IBISBridge.m b/IBISBridge.m new file mode 100644 index 0000000..637dbbe --- /dev/null +++ b/IBISBridge.m @@ -0,0 +1,215 @@ +classdef (StrictDefaults) IBISBridge < serdes.SerdesAbstractSystemObject & TriggeredComponent + % IBISBridge IBIS Bridge + % obj = IBISBridge returns a System Object, obj, that recombines the + % demuxed samples into their original sequence. Due to the ADC + % operation, the resulting waveform contains the same voltage + % throughout each unit interval or symbol duration. + % + % IBISBridge methods: + % step - Recombines the demuxed signals into a single signal as + % required by the IBIS-AMI standard. The clock times are also + % processed and prepared for IBIS-AMI model generation. + % + % IBISBridge methods: + % DemuxWidth - Width of the output signal + % SymbolTime - Symbol time of system + % SampleInterval - Uniform time step of the system + + % Copyright 2021-2024 The MathWorks, Inc. + + %#codegen + + properties (Nontunable) + + %Demux Width + DemuxWidth = 32; + end + properties (Hidden, SetAccess=private) + + %Bridge properties + MuxCounter % Multiplexor counter + SampleCounter % Output clock counter + SamplesPerHalfSymbol % Output clock half period, samples + ClockOutInternal % Output clock + ClockTimesInternal % Output clock times + WaveOutInternal % Wave out internal + SamplesElapsed = 0; % Samples Elapsed + OutputBuffer + end + properties(Hidden) + %Property required by abstract class but unused + NumberOfClocks = 1; + end + properties (SetAccess = immutable, Nontunable, Hidden) + IsLinear = true; + IsTimeInvariant = true; + end + properties (Nontunable,Hidden) + %Input Waveform Type + % Set the input wave type as one of 'Sample' | 'Impulse' | + % 'Waveform'. The default is 'Sample'. + WaveType = 'Sample'; + end + properties(Hidden, Constant) + WaveTypeSet = matlab.system.StringSet({'Sample','Impulse','Waveform'}); + end + + methods + % Constructor + function obj = IBISBridge(varargin) + % Support name-value pair arguments when constructing object + obj.BlockName = 'IBISBridge'; + setProperties(obj,nargin,varargin{:}) + end + end + methods (Hidden) + % The below methods, getAMIParameters, getAMIInputNames and + % getAMIOutputNames are for use only within the serdesDesigner App + % and will not influence the AMI parameters in Simulink whatsoever. + function amiParameters = getAMIParameters(~) + amiParameters = {}; + end + function names = getAMIInputNames(~) + names = {}; + end + function names = getAMIOutputNames(~) + names = {}; + end + end + methods (Access = protected, Hidden) + function val = isSample(obj) + val = strcmpi(obj.WaveType,'Sample'); + end + end + methods(Access = protected) + %% Common functions + function setupImpl(obj) + setupClock(obj); + + % Initialize properties + obj.MuxCounter = 1; + obj.SampleCounter = 0; + SamplesPerSymbol = round(obj.SymbolTime/obj.SampleInterval); + obj.SamplesPerHalfSymbol = round(SamplesPerSymbol / 2); + obj.SamplesElapsed = 0; + obj.OutputBuffer = zeros(obj.DemuxWidth,1); + + % Initialize outputs to zero + obj.WaveOutInternal = 0; + obj.ClockOutInternal = 0; + obj.ClockTimesInternal = 0; + end + + function validateInputsImpl(~,waveIn) + validateattributes(waveIn,{'numeric'},{'finite'},'','waveIn'); + end + + function [WaveOut,ClockOut,Time] = stepImpl(obj,SampleIn,varargin) + if nargin==3 + ClockIn = varargin{1}; + else + ClockIn = 0; + end + + if isSample(obj) + % Triggered clock step + ClockStep(obj,ClockIn) + % Calculate Clock Time + SimTime = obj.SamplesElapsed*obj.SampleInterval; + clock_times = SimTime - obj.SymbolTime/2; + if clock_times < 0 + clock_times = 0; + end + % Buffer incoming frame upon its transition + if SampleIn ~= obj.OutputBuffer + obj.OutputBuffer = SampleIn; + % Force output position to beginning of frame + obj.MuxCounter = 1; + end + % Update waveform output on the rising edge of any ADC clock(s) + if any(obj.ClockRisingFlag) + obj.WaveOutInternal = obj.OutputBuffer(obj.MuxCounter); + if obj.MuxCounter < obj.DemuxWidth + obj.MuxCounter = obj.MuxCounter + 1; + end + % On rising clock edge, set output clock to 0 (edge sample location) + obj.ClockOutInternal = 0; + % Reset output clock counter + obj.SampleCounter = 0; + end + % Update output clock counter + obj.SampleCounter = obj.SampleCounter + 1; + % After half a UI, set output clock to 1 (data sample location) and update clock + % times output with current time. Use previous ClockOutInternal to prevent executing + % more than once per clock period. + if obj.SampleCounter > obj.SamplesPerHalfSymbol && obj.ClockOutInternal == 0 + obj.ClockOutInternal = 1; + obj.ClockTimesInternal = clock_times; + end + else + obj.WaveOutInternal = SampleIn; + end + %Increment count + obj.SamplesElapsed = obj.SamplesElapsed + 1; + % Assign outputs + WaveOut = obj.WaveOutInternal; + ClockOut = obj.ClockOutInternal; + Time = obj.ClockTimesInternal; + end + function [sz_1,sz_2,sz_3] = getOutputSizeImpl(~) + % Return size for each output port + sz_1 = [1 1]; + sz_2 = [1 1]; + sz_3 = [1 1]; + end + function [c1,c2,c3] = isOutputFixedSizeImpl(~) + c1 = true; + c2 = true; + c3 = true; + end + function [dt1,dt2,dt3] = getOutputDataTypeImpl(obj) + dt1 = propagatedInputDataType(obj,1); + dt2 = propagatedInputDataType(obj,2); + dt3 = "double"; + end + function [c1,c2,c3] = isOutputComplexImpl(~) + c1 = false; + c2 = false; + c3 = false; + end + function resetImpl(~) + % Initialize / reset discrete-state properties + end + + %% Simulink functions + function icon = getIconImpl(~) + % Define icon for System block + icon = "IBIS\nBridge"; + end + function [name1,name2] = getInputNamesImpl(~) + name1 = 'Samples'; + name2 = 'Clock'; + end + function [name1,name2,name3] = getOutputNamesImpl(~) + name1 = 'Wave'; + name2 = 'Clock'; + name3 = 'Time'; + end + function num = getNumInputsImpl(obj) + if isSample(obj) + num = 2; + else + num = 1; + end + end + end + methods(Static, Access=protected) + function group = getPropertyGroupsImpl(~) + % Define property section(s) for System block dialog + group = matlab.system.display.SectionGroup(... + 'Title','Main',... + 'PropertyList',{'DemuxWidth',... + 'SymbolTime','SampleInterval'}); + end + end +end
\ No newline at end of file |
