Public
Edited
Dec 24, 2023
Insert cell
Insert cell
wdWrapper({
config: {
skin:'default',marks:true,fit2pane: 1,wrapSvgInImg: 0,
},
head: { tick: 0, text:
['tspan',{style:'font-size:28px'}, 'Example of Plugins Usage',
['tspan',{dy:32, x:0, style:'font-size:16px'},
'Core Plugins: parseTrig & parseAsync [source: wavedrom.plugins.js]', ],
['tspan',{dy:24, x:0, style:'font-size:16px'},
'Custom Plugins: customParse(\'example\', {...}) [source: example.custom.wavedrom.plugin.js]', ],
]
},
signal: [
{name: 'clkp', wave: 'p..........'}, // Lane 0
{},
wd_.parseTrig({
name: "sinB", phase: 0,
wave: [ 'sin', { f: 1 , repeat : 3, amp: 1 } ]
}), // Lane 2
{},
wd_.parseTrig({
name: "sinC", phase: 0,
wave: [ 'sin', { f: 0.5 , repeat : 3, amp: 1 } ]
}), // Lane 4
{},
{name: 'pll_en', wave: '0.1.........0...'}, // Lane 6
{},
{name: 'pll_out', wave: 'x..<.>'},
// Lane 8 needs 3 overlays - low freq sin, better freq sin, x
{},
{name: 'pll_lock', wave: '0......1.....0..'}, // Lane 10
{},
{name: 'data-digital', wave: 'h.l...h.l.'}, // Lane 12
{},
wd_.parseTrig({
name: "PSK-analog", phase: 0,
wave: [ 'sin', { f: 1 , repeat : 2, amp: 1 } ]
}),
// Lane 14 needs 3 overlays
{},
wd_.customParse('example', {
key: 'Dummy \'signal\' object, doesnt matter what is here for the example'
}),
{},
wd_.parseAsync({name: 'async-test', wave: [ 'async',
{ seq: '0z1z1', cTimes: [0.2,2.1,3,5,7.3,8.2], rTime: 0.2, fTime: 0.2, sharpz: false }
]}),
{},
wd_.parseTrig({
phase: -3.5,
wave: [ 'sin', { f: 0.75 , repeat : 2, amp: 1 } ],
overlayOnLane: 8 // pll not locked
}),
wd_.parseTrig({
phase: -6.175,
wave: [ 'sin', { f: 1.25 , repeat : 9, amp: 1 } ],
overlayOnLane: 8 // pll locked
}),
{phase: -13.375, wave: 'x..', overlayOnLane: 8}, // pll not enabled
wd_.parseTrig({
phase: -2,
wave: [ 'sin', { f: 1 , repeat : 4, phi: 180 } ],
overlayOnLane: 14 // data = h
}),
wd_.parseTrig({
phase: -6,
wave: [ 'sin', { f: 1 , repeat : 2, phi: 0 } ],
overlayOnLane: 14 // data = l
}),
wd_.parseTrig({
phase: -8,
wave: [ 'sin', { f: 1 , repeat : 2, phi: 180 } ],
overlayOnLane: 14 // data = h
}),
]
}
, 0)
Insert cell
wdWrapper = (() => {
wavedrom.waveSkin = window.WaveSkin ;
return (obj,i) => {
const actSVG = wavedrom.onml.stringify(wavedrom.renderAny(i, obj, wavedrom.waveSkin));
const parser = new DOMParser();
const actSVGForImg = parser.parseFromString(actSVG,'image/svg+xml').firstChild;
let ser = new XMLSerializer();
let imgt = document.createElement('img');
const svgAsImgString = encodeURIComponent(ser.serializeToString(actSVGForImg));
imgt.src = `data:image/svg+xml;utf8,${svgAsImgString}` ;
imgt.style = 'width:100%;height:100%;' ;
return imgt ;
}
})();
Insert cell
wd = (() => {
wavedrom.waveSkin = window.WaveSkin ;
return (obj,i) => html`${wavedrom.onml.stringify(wavedrom.renderAny(i, obj, wavedrom.waveSkin))}`
})();
Insert cell
wd_.customParse('example',{})
Insert cell
temp = {
// START contents of example.custom.wavedrom.plugin.js
const examplePlugin = {

name: 'example',
exec: function(sig) {
sig['wave'] = [];
sig['wave'].push( 'tl',
{
coords: [0,0.5],
text: ('This is an example of a custom plugin output! Eg. field of Plugin class : nativePWAttrList : ' + wd_.nativePWAttrList.join(':')),
tlStyle: 'text-anchor:start'
} );
return sig ;
}

};

wd_.register(examplePlugin);
// END contents of example.custom.wavedrom.plugin.js
return wd_ ;
}
Insert cell
wd_ = {
// START contents of the file wavedrom.plugins.js
class WaveDromPlugins {

static sinTable ;
static cosTable ;
static nativePWAttrList ;
static plugins ;

constructor() {
this.sinTable = [...Array(Math.ceil(2*Math.PI*1000)).keys()].map( x => Math.sin(x/1000) );
this.cosTable = [...Array(Math.ceil(2*Math.PI*1000)).keys()].map( x => Math.cos(x/1000) );
this.nativePWAttrList = ['d','pwStyle','pwClass'] ;
this.plugins = {};
}

parseTrig (sig) {

let tphase = sig.phase || 0 ;
let tspec = JSON.parse(JSON.stringify(sig.wave)) ; // wave to mod
sig.wave = [] ;
let dspec = tspec[1] ;
let nodspec = (typeof dspec === 'undefined') ;
let dspecamp = (nodspec || (typeof dspec.amp === 'undefined')) ? 1 : dspec.amp ;
let dspecf = (nodspec || (typeof dspec.f === 'undefined') || (dspec.f == 0)) ? 1 : dspec.f ;
let dspecphi = (nodspec || (typeof dspec.phi === 'undefined')) ? 0 : dspec.phi ;
let drepeat = (nodspec || (typeof dspec.repeat === 'undefined')) ? 1 : dspec.repeat ;
let pathArr = [] ;
for (let rn = 0; rn < drepeat; rn++) {
for (let i = 0; i < (1/dspecf); i += 0.001) {
let tblIdx = parseInt((2000 * Math.PI * i * dspecf) + (dspecphi * 1000 * Math.PI * dspecf / 180))
% parseInt(2000 * Math.PI) ;
let scaledVal = (tspec[0] === "sin") ? this.sinTable[tblIdx] :
(tspec[0] === "cos") ? this.cosTable[tblIdx] : 0 ;
// scaledVal is between -1 and +1, but pw coords pre-scaling should be between 0 and 1
// first shift the value to be between -0.5 and 0.5 and then apply the amplitude factor
scaledVal /= 2.00 ;
scaledVal *= dspecamp ;
// shift to center around y = 0.5
scaledVal += 0.5 ;
if ((rn == 0) && (i == 0)) {
pathArr.push('M');
}
pathArr.push((rn / dspecf) + i - tphase);
pathArr.push(scaledVal);
}
}
let pwObj = { 'd' : pathArr };
Object.keys(dspec).forEach( (pwAttr) => {
if (this.nativePWAttrList.includes(pwAttr)) {
pwObj[pwAttr] = dspec[pwAttr];
}
} );
sig.wave = [ 'pw', pwObj ] ;
return sig ;
} // end parseTrig

parseAsync (sig) {

let tspec = JSON.parse(JSON.stringify(sig.wave)) ; // wave to mod
sig.wave = [] ;
if (tspec[0] !== 'async') {
return [];
}
let dspec = tspec[1] ;
let nodspec = (typeof dspec === 'undefined') ;
let dspecSeq = (nodspec || (typeof dspec.seq === 'undefined')) ? '0' : dspec.seq ;
let dspecCTimes = (nodspec || (typeof dspec.cTimes === 'undefined')) ? [0] : dspec.cTimes ;
let dspecRT = (nodspec || (typeof dspec.rTime === 'undefined')) ? 0 : dspec.rTime ;
let dspecFT = (nodspec || (typeof dspec.fTime === 'undefined')) ? 0 : dspec.fTime ;
let dspecSharpZ = (nodspec || (typeof dspec.sharpz === 'undefined')) ? false : dspec.sharpz ;
let pathArr = [] ;
let seqIdx = 0 ;
pathArr.push('M');
let xpos = dspecCTimes[seqIdx];
let ypos = (dspecSeq[seqIdx] === '0') ? 0 : (dspecSeq[seqIdx] === '1') ? 1 :
(dspecSeq[seqIdx] === 'z') ? 0.5 : 0 ;
pathArr.push(xpos);
pathArr.push(ypos);
let prevSig = dspecSeq[seqIdx] ;
for (seqIdx = 1; seqIdx < dspecSeq.length; seqIdx++) {
let nxtSig = dspecSeq[seqIdx];
let nxtCTime = dspecCTimes[seqIdx];
// draw line up to the ctime as x pos, y pos will be from prevSig
pathArr.push('L', nxtCTime, ypos); // 'L' not strictly necessary, but for readability
// nxtXPos will depend on rise or fall time
let nxtXPos = nxtCTime + dspecRT; // assume rise time
let cpX = nxtCTime + (0.4 * dspecRT) ;
ypos = (nxtSig === '0') ? 0 : (nxtSig === '1') ? 1 : (nxtSig === 'z') ? 0.5 : 0;
if (prevSig == '1') { // we need to change to fall time
nxtXPos = nxtCTime + dspecFT;
cpX = nxtCTime + (0.4 * dspecFT) ;
}
if ((nxtSig !== 'z') || (dspecSharpZ === true)) {
pathArr.push('L', nxtXPos, ypos);
} else { // Not a straight transition, but We will need a slow rise or fall
pathArr.push('Q', cpX, ypos, nxtXPos, ypos);
}
prevSig = nxtSig ;
}
// Handle the last dspecCTimes
pathArr.push('H',dspecCTimes[seqIdx]);
let pwObj = { 'd' : pathArr };
Object.keys(dspec).forEach( (pwAttr) => {
if (this.nativePWAttrList.includes(pwAttr)) {
pwObj[pwAttr] = dspec[pwAttr];
}
} );
sig.wave = [ 'pw', pwObj ] ;
return sig ;
} // end parseAsync


register (plugin) {
const {name, exec} = plugin ;
this.plugins[name] = exec ;
}

customParse (parseFunc, sig) {
const func = this.plugins[parseFunc];
return func(sig);
}

}
let wd_ ;
try {
wd_ = new WaveDromPlugins();
}
catch(err) { console.log("Unable to load WaveDromPlugins... " + err); }
// END contents of wavedrom.plugins.js
return wd_ ;
}
Insert cell
wavedrom = (await require(await FileAttachment("wavedrom.unpkg.min.js").url()));
Insert cell
(await require(await FileAttachment("default.js").url())).catch ( () => {} );
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more