CircuitOnline/public/js/testBench.js

547 lines
17 KiB
JavaScript

function TB_Input(x, y, scope = globalScope, dir = "RIGHT", identifier, testData) {
CircuitElement.call(this, x, y, scope, dir, 1);
// this.setDimensions(60,20);
// this.xSize=10;
// this.plotValues = [];
// this.inp1 = new Node(0, 0, 0, this);
// this.inp1 = new Node(100, 100, 0, this);
this.setIdentifier (identifier|| "Test1");
this.testData=testData || {"inputs":[],"outputs":[],"n":0}
this.clockInp = new Node(0,20, 0,this,1);
this.outputs = []
this.running = false;
this.iteration=0;
this.setup();
}
TB_Input.prototype = Object.create(CircuitElement.prototype);
TB_Input.prototype.constructor = TB_Input;
TB_Input.prototype.tooltipText = "Test Bench Input Selected";
TB_Input.prototype.centerElement = true;
TB_Input.prototype.helplink = "https://docs.circuitverse.org/#/testbench";
TB_Input.prototype.dblclick=function(){
this.testData=JSON.parse(prompt("Enter TestBench Json"));
this.setup();
}
TB_Input.prototype.setDimensions=function() {
this.leftDimensionX = 0;
this.rightDimensionX = 120;
this.upDimensionY = 0;
this.downDimensionY = 40 + this.testData.inputs.length * 20;
}
TB_Input.prototype.setup=function(){
this.iteration = 0;
this.running = false;
this.nodeList.clean(this.clockInp);
this.deleteNodes();
this.nodeList = []
this.nodeList.push(this.clockInp);
this.testData = this.testData || { "inputs": [], "outputs": [], "n": 0 };
// this.clockInp = new Node(0,20, 0,this,1);
this.setDimensions();
this.prevClockState = 0;
this.outputs = [];
for(var i = 0; i < this.testData.inputs.length; i++ ){
this.outputs.push(new Node(this.rightDimensionX, 30+i*20, 1, this, bitWidth = this.testData.inputs[i].bitWidth,label=this.testData.inputs[i].label));
}
for(var i =0; i<this.scope.TB_Output.length;i++){
if(this.scope.TB_Output[i].identifier == this.identifier)
this.scope.TB_Output[i].setup();
}
}
TB_Input.prototype.toggleState=function(){
this.running=!this.running;
this.prevClockState=0;
}
TB_Input.prototype.resetIterations=function(){
this.iteration=0;
this.prevClockState=0;
}
TB_Input.prototype.resolve=function(){
if(this.clockInp.value != this.prevClockState){
this.prevClockState = this.clockInp.value;
if(this.clockInp.value == 1 && this.running){
if(this.iteration<this.testData.n){
this.iteration++;
}
else{
this.running = false;
}
}
}
if(this.running && this.iteration)
for(var i=0;i<this.testData.inputs.length;i++){
console.log(this.testData.inputs[i].values[this.iteration-1]);
this.outputs[i].value = parseInt(this.testData.inputs[i].values[this.iteration-1],2);
simulationArea.simulationQueue.add(this.outputs[i]);
}
}
TB_Input.prototype.setPlotValue = function() {
var time = plotArea.stopWatch.ElapsedMilliseconds;
if (this.plotValues.length && this.plotValues[this.plotValues.length - 1][0] == time)
this.plotValues.pop();
if (this.plotValues.length == 0) {
this.plotValues.push([time, this.inp1.value]);
return;
}
if (this.plotValues[this.plotValues.length - 1][1] == this.inp1.value)
return;
else
this.plotValues.push([time, this.inp1.value]);
}
TB_Input.prototype.customSave = function() {
var data = {
constructorParamaters: [this.direction, this.identifier, this.testData],
nodes: {
outputs: this.outputs.map(findNode),
clockInp: findNode(this.clockInp)
},
}
return data;
}
TB_Input.prototype.setIdentifier = function(id = "") {
if (id.length == 0 || id==this.identifier) return;
for(var i =0; i<this.scope.TB_Output.length;i++){
this.scope.TB_Output[i].checkPairing();
}
for(var i =0; i<this.scope.TB_Output.length;i++){
if(this.scope.TB_Output[i].identifier == this.identifier)
this.scope.TB_Output[i].identifier = id;
}
this.identifier = id;
this.checkPaired();
}
TB_Input.prototype.checkPaired=function(){
for(var i =0; i<this.scope.TB_Output.length;i++){
if(this.scope.TB_Output[i].identifier == this.identifier)
this.scope.TB_Output[i].checkPairing();
}
}
TB_Input.prototype.delete = function () {
CircuitElement.prototype.delete.call(this)
this.checkPaired();
}
TB_Input.prototype.mutableProperties = {
"identifier": {
name: "TestBench Name:",
type: "text",
maxlength: "10",
func: "setIdentifier",
},
"iteration": {
name: "Reset Iterations",
type: "button",
func: "resetIterations",
},
"toggleState": {
name: "Toggle State",
type: "button",
func: "toggleState",
},
}
TB_Input.prototype.customDraw = function() {
ctx = simulationArea.context;
ctx.beginPath();
ctx.strokeStyle = "grey";
ctx.fillStyle = "#fcfcfc";
ctx.lineWidth = correctWidth(1);
var xx = this.x;
var yy = this.y;
var xRotate=0;
var yRotate=0;
if(this.direction=="LEFT") {
xRotate=0;
yRotate=0;
}else if(this.direction=="RIGHT") {
xRotate=120-this.xSize;
yRotate=0;
}else if(this.direction=="UP") {
xRotate=60-this.xSize/2;
yRotate=-20;
}else{
xRotate=60-this.xSize/2;
yRotate=20;
}
// rect2(ctx, -120+xRotate+this.xSize, -20+yRotate, 120-this.xSize, 40, xx, yy, "RIGHT");
// if ((this.hover && !simulationArea.shiftDown) || simulationArea.lastSelected == this || simulationArea.multipleObjectSelections.contains(this))
// ctx.fillStyle = "rgba(255, 255, 32,0.8)";
// ctx.fill();
// ctx.stroke();
//
// ctx.font = "14px Georgia";
// this.xOff = ctx.measureText(this.identifier).width;
// ctx.beginPath();
// rect2(ctx, -105+xRotate+this.xSize, -11+yRotate,this.xOff + 10, 23, xx, yy, "RIGHT");
// ctx.fillStyle = "#eee"
// ctx.strokeStyle = "#ccc";
// ctx.fill();
// ctx.stroke();
//
ctx.beginPath();
ctx.textAlign = "center";
ctx.fillStyle = "black";
fillText(ctx, this.identifier + " [INPUT]", xx + this.rightDimensionX/ 2 , yy + 14 , 10);
fillText(ctx, ["Not Running","Running"][+this.running], xx + this.rightDimensionX/ 2 , yy + 14 + 10 + 20*this.testData.inputs.length, 10);
fillText(ctx, "Case: "+(this.iteration), xx + this.rightDimensionX/ 2 , yy + 14 + 20 + 20*this.testData.inputs.length, 10);
// fillText(ctx, "Case: "+this.iteration, xx , yy + 20+14, 10);
ctx.fill();
ctx.font = "30px Georgia";
ctx.textAlign = "right";
ctx.fillStyle = "blue";
ctx.beginPath();
for(var i=0;i<this.testData.inputs.length;i++){
// ctx.beginPath();
fillText(ctx, this.testData.inputs[i].label , this.rightDimensionX - 5 + xx , 30+i*20 + yy+4, 10);
}
ctx.fill();
if(this.running && this.iteration){
ctx.font = "30px Georgia";
ctx.textAlign = "left";
ctx.fillStyle = "blue";
ctx.beginPath();
for(var i=0;i<this.testData.inputs.length;i++){
fillText(ctx, this.testData.inputs[i].values[this.iteration-1] , 5 + xx , 30+i*20 + yy+4, 10);
}
ctx.fill();
}
//
//
// ctx.font = "30px Georgia";
// ctx.textAlign = "center";
// ctx.fillStyle = ["blue", "red"][+(this.inp1.value == undefined)];
// if (this.inp1.value !== undefined)
// fillText(ctx, this.inp1.value.toString(16), xx - 23 + xRotate, yy + 8 + yRotate, 25);
// else
// fillText(ctx, "x", xx - 23 + xRotate, yy + 8 + yRotate, 25);
// ctx.fill();
ctx.beginPath();
ctx.strokeStyle = ("rgba(0,0,0,1)");
ctx.lineWidth = correctWidth(3);
var xx = this.x;
var yy = this.y;
// rect(ctx, xx - 20, yy - 20, 40, 40);
moveTo(ctx, 0, 15, xx, yy, this.direction);
lineTo(ctx, 5, 20, xx, yy, this.direction);
lineTo(ctx, 0, 25, xx, yy, this.direction);
ctx.stroke();
}
function TB_Output(x, y, scope = globalScope, dir = "RIGHT", identifier) {
CircuitElement.call(this, x, y, scope, dir, 1);
// this.setDimensions(60,20);
// this.xSize=10;
// this.plotValues = [];
// this.inp1 = new Node(0, 0, 0, this);
// this.inp1 = new Node(100, 100, 0, this);
this.setIdentifier (identifier|| "Test1");
this.inputs = []
this.testBenchInput = undefined;
this.setup();
}
TB_Output.prototype = Object.create(CircuitElement.prototype);
TB_Output.prototype.constructor = TB_Output;
TB_Output.prototype.tooltipText = "Test Bench Output Selected";
TB_Output.prototype.helplink = "https://docs.circuitverse.org/#/testbench";
TB_Output.prototype.centerElement = true;
// TB_Output.prototype.dblclick=function(){
// this.testData=JSON.parse(prompt("Enter TestBench Json"));
// this.setup();
// }
TB_Output.prototype.setDimensions=function() {
this.leftDimensionX = 0;
this.rightDimensionX = 160;
this.upDimensionY = 0;
this.downDimensionY = 40;
if(this.testBenchInput)
this.downDimensionY = 40 + this.testBenchInput.testData.outputs.length * 20;
}
TB_Output.prototype.setup = function(){
// this.iteration = 0;
// this.running = false;
// this.nodeList.clean(this.clockInp);
this.deleteNodes();
this.nodeList = []
this.inputs = [];
this.testBenchInput = undefined;
for(var i=0;i<this.scope.TB_Input.length;i++){
if(this.scope.TB_Input[i].identifier == this.identifier) {
this.testBenchInput = this.scope.TB_Input[i];
break;
}
}
this.setDimensions();
if(this.testBenchInput){
for(var i = 0; i < this.testBenchInput.testData.outputs.length; i++ ){
this.inputs.push(new Node(0, 30+i*20, NODE_INPUT, this, bitWidth = this.testBenchInput.testData.outputs[i].bitWidth,label=this.testBenchInput.testData.outputs[i].label));
}
}
}
// TB_Output.prototype.toggleState=function(){
// this.running=!this.running;
// this.prevClockState=0;
// }
// TB_Output.prototype.resetIterations=function(){
// this.iteration=0;
// this.prevClockState=0;
// }
// TB_Output.prototype.resolve=function(){
// if(this.clockInp.value != this.prevClockState){
// this.prevClockState = this.clockInp.value;
// if(this.clockInp.value == 1 && this.running){
// if(this.iteration<this.testData.n){
// this.iteration++;
// }
// else{
// this.running = false;
// }
// }
// }
// if(this.running && this.iteration)
// for(var i=0;i<this.testData.inputs.length;i++){
// console.log(this.testData.inputs[i].values[this.iteration-1]);
// this.outputs[i].value = parseInt(this.testData.inputs[i].values[this.iteration-1],2);
// simulationArea.simulationQueue.add(this.outputs[i]);
// }
//
// }
// TB_Output.prototype.setPlotValue = function() {
// var time = plotArea.stopWatch.ElapsedMilliseconds;
// if (this.plotValues.length && this.plotValues[this.plotValues.length - 1][0] == time)
// this.plotValues.pop();
//
// if (this.plotValues.length == 0) {
// this.plotValues.push([time, this.inp1.value]);
// return;
// }
//
// if (this.plotValues[this.plotValues.length - 1][1] == this.inp1.value)
// return;
// else
// this.plotValues.push([time, this.inp1.value]);
// }
TB_Output.prototype.customSave = function() {
var data = {
constructorParamaters: [this.direction, this.identifier],
nodes: {
inputs: this.inputs.map(findNode),
},
}
return data;
}
TB_Output.prototype.setIdentifier = function(id = "") {
if (id.length == 0 || id==this.identifier) return;
this.identifier = id;
this.setup();
}
TB_Output.prototype.checkPairing = function(id = "") {
if(this.testBenchInput){
if(this.testBenchInput.deleted || this.testBenchInput.identifier!=this.identifier){
this.setup();
}
}
else {
this.setup();
}
}
TB_Output.prototype.mutableProperties = {
"identifier": {
name: "TestBench Name:",
type: "text",
maxlength: "10",
func: "setIdentifier",
},
}
TB_Output.prototype.customDraw = function() {
ctx = simulationArea.context;
ctx.beginPath();
ctx.strokeStyle = "grey";
ctx.fillStyle = "#fcfcfc";
ctx.lineWidth = correctWidth(1);
var xx = this.x;
var yy = this.y;
var xRotate=0;
var yRotate=0;
if(this.direction=="LEFT") {
xRotate=0;
yRotate=0;
}else if(this.direction=="RIGHT") {
xRotate=120-this.xSize;
yRotate=0;
}else if(this.direction=="UP") {
xRotate=60-this.xSize/2;
yRotate=-20;
}else{
xRotate=60-this.xSize/2;
yRotate=20;
}
// rect2(ctx, -120+xRotate+this.xSize, -20+yRotate, 120-this.xSize, 40, xx, yy, "RIGHT");
// if ((this.hover && !simulationArea.shiftDown) || simulationArea.lastSelected == this || simulationArea.multipleObjectSelections.contains(this))
// ctx.fillStyle = "rgba(255, 255, 32,0.8)";
// ctx.fill();
// ctx.stroke();
//
// ctx.font = "14px Georgia";
// this.xOff = ctx.measureText(this.identifier).width;
// ctx.beginPath();
// rect2(ctx, -105+xRotate+this.xSize, -11+yRotate,this.xOff + 10, 23, xx, yy, "RIGHT");
// ctx.fillStyle = "#eee"
// ctx.strokeStyle = "#ccc";
// ctx.fill();
// ctx.stroke();
//
ctx.beginPath();
ctx.textAlign = "center";
ctx.fillStyle = "black";
fillText(ctx, this.identifier + " [OUTPUT]", xx + this.rightDimensionX/ 2 , yy + 14 , 10);
// fillText(ctx, ["Not Running","Running"][+this.running], xx + this.rightDimensionX/ 2 , yy + 14 + 10 + 20*this.testData.inputs.length, 10);
// fillText(ctx, "Case: "+(this.iteration), xx + this.rightDimensionX/ 2 , yy + 14 + 20 + 20*this.testData.inputs.length, 10);
fillText(ctx, ["Unpaired","Paired"][ +(this.testBenchInput!=undefined)], xx + this.rightDimensionX/ 2 , yy + this.downDimensionY - 5, 10);
ctx.fill();
if(this.testBenchInput){
ctx.beginPath();
ctx.font = "30px Georgia";
ctx.textAlign = "left";
ctx.fillStyle = "blue";
for(var i=0;i<this.testBenchInput.testData.outputs.length;i++){
// ctx.beginPath();
fillText(ctx, this.testBenchInput.testData.outputs[i].label , 5 + xx , 30+i*20 + yy+4, 10);
}
ctx.fill();
if(this.testBenchInput.running && this.testBenchInput.iteration){
ctx.beginPath();
ctx.font = "30px Georgia";
ctx.textAlign = "right";
ctx.fillStyle = "blue";
ctx.beginPath();
for(var i=0;i<this.testBenchInput.testData.outputs.length;i++){
fillText(ctx, this.testBenchInput.testData.outputs[i].values[this.testBenchInput.iteration-1] , xx +this.rightDimensionX-5 , 30+i*20 + yy+4, 10);
}
ctx.fill();
}
if(this.testBenchInput.running && this.testBenchInput.iteration){
ctx.beginPath();
ctx.font = "30px Georgia";
ctx.textAlign = "center";
ctx.fillStyle = "blue";
for(var i=0;i<this.testBenchInput.testData.outputs.length;i++){
if(this.inputs[i].value!=undefined){
ctx.beginPath();
if(this.testBenchInput.testData.outputs[i].values[this.testBenchInput.iteration-1]=="x"||parseInt(this.testBenchInput.testData.outputs[i].values[this.testBenchInput.iteration-1],2)==this.inputs[i].value)
ctx.fillStyle="green"
else
ctx.fillStyle="red"
fillText(ctx, dec2bin(this.inputs[i].value,this.inputs[i].bitWidth) , xx +this.rightDimensionX/2 , 30+i*20 + yy+4, 10);
ctx.fill();
}
else{
ctx.beginPath();
if(this.testBenchInput.testData.outputs[i].values[this.testBenchInput.iteration-1]=="x")
ctx.fillStyle="green"
else
ctx.fillStyle="red"
fillText(ctx, "X" , xx +this.rightDimensionX/2 , 30+i*20 + yy+4, 10);
ctx.fill();
}
}
}
}
//
//
// ctx.font = "30px Georgia";
// ctx.textAlign = "center";
// ctx.fillStyle = ["blue", "red"][+(this.inp1.value == undefined)];
// if (this.inp1.value !== undefined)
// fillText(ctx, this.inp1.value.toString(16), xx - 23 + xRotate, yy + 8 + yRotate, 25);
// else
// fillText(ctx, "x", xx - 23 + xRotate, yy + 8 + yRotate, 25);
// ctx.fill();
}