https://github.com/liatemplates/digisim
Template for using SimcirJS to simulate circuits in LiaScript
https://github.com/liatemplates/digisim
circuit liascript liascript-template simulation
Last synced: 5 months ago
JSON representation
Template for using SimcirJS to simulate circuits in LiaScript
- Host: GitHub
- URL: https://github.com/liatemplates/digisim
- Owner: LiaTemplates
- Created: 2020-03-20T13:29:24.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2020-08-05T18:27:12.000Z (over 5 years ago)
- Last Synced: 2025-10-11T13:32:02.129Z (5 months ago)
- Topics: circuit, liascript, liascript-template, simulation
- Language: JavaScript
- Homepage: https://liascript.github.io/course/?https://raw.githubusercontent.com/LiaTemplates/DigiSim/master/README.md
- Size: 52.7 KB
- Stars: 0
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# DigiSim for LiaScript
Implementation of DigitalJs for Liascript
[DigitalJS Source](https://github.com/tilk/digitaljs)
## `@DigiSim.evalJson`
Put the JSON of your circuit into Markdown ticks and put the makro `@DigiSim.evalJson` at the first line of your markdown and the circuit will be evaluated and shown.
``` json @DigiSim.evalJson
{
"devices": {
"dev0": {
"label": "s",
"position": {
"x": 0,
"y": 20
},
"celltype": "$button",
"propagation": 0
},
"dev1": {
"label": "r",
"position": {
"x": 155,
"y": 75
},
"celltype": "$button",
"propagation": 0
},
"dev2": {
"label": "q",
"position": {
"x": 480,
"y": 55
},
"celltype": "$lamp",
"propagation": 1
},
"dev3": {
"label": "nq",
"position": {
"x": 325,
"y": 0
},
"celltype": "$lamp",
"propagation": 1
},
"dev6": {
"label": "$or$_input.sv:7$1",
"position": {
"x": 310,
"y": 50
},
"celltype": "$nor",
"propagation": 1,
"bits": 1
},
"dev7": {
"label": "$or$_input.sv:8$3",
"position": {
"x": 140,
"y": 15
},
"celltype": "$nor",
"propagation": 1,
"bits": 1
}
},
"connectors": [
{
"from": {
"id": "dev0",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in1"
},
"name": "s",
"vertices": []
},
{
"from": {
"id": "dev1",
"port": "out"
},
"to": {
"id": "dev6",
"port": "in1"
},
"name": "r",
"vertices": []
},
{
"from": {
"id": "dev6",
"port": "out"
},
"to": {
"id": "dev2",
"port": "in"
},
"name": "q",
"vertices": []
},
{
"from": {
"id": "dev6",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in2"
},
"name": "q",
"vertices": []
},
{
"from": {
"id": "dev7",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in"
},
"name": "nq",
"vertices": []
},
{
"from": {
"id": "dev7",
"port": "out"
},
"to": {
"id": "dev6",
"port": "in2"
},
"name": "nq",
"vertices": []
}
],
"subcircuits": {}
}
```
To get the JSON of a circuit you have to visite the website if
[Yosys2digitaljs](https://digitaljs.tilk.eu/) and put the
[Verilog](https://en.wikipedia.org/wiki/Verilog) representation of the circuit
in the text field on the website. Afterwards you have to click the save button
near the timer in the upper right corner and save the JSON on your computer. The
simply copy the JSON from the file into the LiaScript Document.
You can also write the JSON by hand. A document of the JSON format will also be
included in this documentation.
### Multiple Circuits
It is also possible to put multiple circuits on the same site of your LiaScript
document as shown below.
`D-Latch`
``` json @DigiSim.evalJson
{
"devices": {
"dev0": {
"label": "d",
"position": {
"x": 0,
"y": 32.5
},
"celltype": "$button",
"propagation": 0
},
"dev1": {
"label": "e",
"position": {
"x": 0,
"y": 82.5
},
"celltype": "$button",
"propagation": 0
},
"dev2": {
"label": "q",
"position": {
"x": 660,
"y": 65
},
"celltype": "$lamp",
"propagation": 1
},
"dev3": {
"label": "nq",
"position": {
"x": 660,
"y": 10
},
"celltype": "$lamp",
"propagation": 1
},
"dev4": {
"position": {
"x": 275,
"y": 95
},
"celltype": "$and",
"propagation": 1,
"bits": 1
},
"dev5": {
"position": {
"x": 290,
"y": -5
},
"celltype": "$and",
"propagation": 1,
"bits": 1
},
"dev7": {
"position": {
"x": 95,
"y": 105
},
"celltype": "$not",
"propagation": 1,
"bits": 1
},
"dev9": {
"position": {
"x": 450,
"y": 5
},
"celltype": "$nor",
"propagation": 1,
"bits": 1
},
"dev10": {
"position": {
"x": 440,
"y": 105
},
"celltype": "$nor",
"propagation": 1,
"bits": 1
}
},
"connectors": [
{
"from": {
"id": "dev0",
"port": "out"
},
"to": {
"id": "dev5",
"port": "in2"
},
"name": "d",
"vertices": []
},
{
"from": {
"id": "dev0",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in"
},
"name": "d",
"vertices": []
},
{
"from": {
"id": "dev1",
"port": "out"
},
"to": {
"id": "dev4",
"port": "in1"
},
"name": "e",
"vertices": []
},
{
"from": {
"id": "dev1",
"port": "out"
},
"to": {
"id": "dev5",
"port": "in1"
},
"name": "e",
"vertices": []
},
{
"from": {
"id": "dev10",
"port": "out"
},
"to": {
"id": "dev2",
"port": "in"
},
"name": "q",
"vertices": []
},
{
"from": {
"id": "dev10",
"port": "out"
},
"to": {
"id": "dev9",
"port": "in2"
},
"name": "q",
"vertices": []
},
{
"from": {
"id": "dev9",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in"
},
"name": "nq",
"vertices": []
},
{
"from": {
"id": "dev9",
"port": "out"
},
"to": {
"id": "dev10",
"port": "in2"
},
"name": "nq",
"vertices": []
},
{
"from": {
"id": "dev7",
"port": "out"
},
"to": {
"id": "dev4",
"port": "in2"
},
"name": "nd",
"vertices": []
},
{
"from": {
"id": "dev4",
"port": "out"
},
"to": {
"id": "dev10",
"port": "in1"
},
"name": "r",
"vertices": []
},
{
"from": {
"id": "dev5",
"port": "out"
},
"to": {
"id": "dev9",
"port": "in1"
},
"name": "s",
"vertices": []
}
],
"subcircuits": {}
}
```
`Priority encoder`
``` json @DigiSim.evalJson
{
"devices": {
"dev0": {
"label": "y",
"position": {
"x": 901.09375,
"y": 191.5
},
"celltype": "$numdisplay",
"propagation": 0,
"numbase": "hex",
"bits": 2
},
"dev1": {
"label": "valid",
"position": {
"x": 903.109375,
"y": 241.5
},
"celltype": "$lamp",
"propagation": 1
},
"dev2": {
"label": "a",
"position": {
"x": 0,
"y": 120.5
},
"celltype": "$numentry",
"propagation": 0,
"numbase": "hex",
"bits": 4
},
"dev3": {
"label": "$procmux$3",
"position": {
"x": 603.609375,
"y": 187.5
},
"celltype": "$pmux",
"propagation": 1,
"bits": {
"in": 3,
"sel": 4
}
},
"dev4": {
"label": "$procmux$4_CMP0",
"position": {
"x": 303.5625,
"y": 0
},
"celltype": "$eq",
"propagation": 1,
"bits": {
"in1": 4,
"in2": 1
},
"signed": {
"in1": false,
"in2": false
}
},
"dev5": {
"label": "$procmux$5_CMP0",
"position": {
"x": 303.5625,
"y": 60
},
"celltype": "$eq",
"propagation": 1,
"bits": {
"in1": 3,
"in2": 1
},
"signed": {
"in1": false,
"in2": false
}
},
"dev6": {
"label": "$procmux$6_CMP0",
"position": {
"x": 303.5625,
"y": 145.5
},
"celltype": "$eq",
"propagation": 1,
"bits": {
"in1": 2,
"in2": 1
},
"signed": {
"in1": false,
"in2": false
}
},
"dev7": {
"position": {
"x": 459.5859375,
"y": 99.5
},
"celltype": "$busgroup",
"propagation": 0,
"groups": [
1,
1,
1,
1
]
},
"dev8": {
"position": {
"x": 453.5625,
"y": 49.5
},
"celltype": "$constant",
"propagation": 0,
"numbase": "hex",
"constant": "000"
},
"dev9": {
"position": {
"x": 453.5625,
"y": 191.5
},
"celltype": "$constant",
"propagation": 0,
"numbase": "hex",
"constant": "111"
},
"dev10": {
"position": {
"x": 453.5625,
"y": 241.5
},
"celltype": "$constant",
"propagation": 0,
"numbase": "hex",
"constant": "101"
},
"dev11": {
"position": {
"x": 453.5625,
"y": 291.5
},
"celltype": "$constant",
"propagation": 0,
"numbase": "hex",
"constant": "011"
},
"dev12": {
"position": {
"x": 453.5625,
"y": 341.5
},
"celltype": "$constant",
"propagation": 0,
"numbase": "hex",
"constant": "001"
},
"dev13": {
"position": {
"x": 160.8125,
"y": 65
},
"celltype": "$constant",
"propagation": 0,
"numbase": "hex",
"constant": "1"
},
"dev14": {
"position": {
"x": 753.609375,
"y": 194.5
},
"celltype": "$busslice",
"propagation": 0,
"slice": {
"first": 1,
"count": 2,
"total": 3
}
},
"dev15": {
"position": {
"x": 758.34375,
"y": 244.5
},
"celltype": "$busslice",
"propagation": 0,
"slice": {
"first": 0,
"count": 1,
"total": 3
}
},
"dev16": {
"position": {
"x": 156.078125,
"y": 119.5
},
"celltype": "$busslice",
"propagation": 0,
"slice": {
"first": 1,
"count": 3,
"total": 4
}
},
"dev17": {
"position": {
"x": 156.078125,
"y": 163.5
},
"celltype": "$busslice",
"propagation": 0,
"slice": {
"first": 2,
"count": 2,
"total": 4
}
},
"dev18": {
"position": {
"x": 309.5546875,
"y": 205.5
},
"celltype": "$busslice",
"propagation": 0,
"slice": {
"first": 3,
"count": 1,
"total": 4
}
}
},
"connectors": [
{
"from": {
"id": "dev14",
"port": "out"
},
"to": {
"id": "dev0",
"port": "in"
},
"name": "y",
"vertices": []
},
{
"from": {
"id": "dev15",
"port": "out"
},
"to": {
"id": "dev1",
"port": "in"
},
"name": "valid",
"vertices": []
},
{
"from": {
"id": "dev2",
"port": "out"
},
"to": {
"id": "dev4",
"port": "in1"
},
"name": "a",
"vertices": []
},
{
"from": {
"id": "dev2",
"port": "out"
},
"to": {
"id": "dev16",
"port": "in"
},
"name": "a",
"vertices": []
},
{
"from": {
"id": "dev2",
"port": "out"
},
"to": {
"id": "dev17",
"port": "in"
},
"name": "a",
"vertices": []
},
{
"from": {
"id": "dev2",
"port": "out"
},
"to": {
"id": "dev18",
"port": "in"
},
"name": "a",
"vertices": []
},
{
"from": {
"id": "dev8",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in0"
},
"vertices": []
},
{
"from": {
"id": "dev7",
"port": "out"
},
"to": {
"id": "dev3",
"port": "sel"
},
"vertices": []
},
{
"from": {
"id": "dev3",
"port": "out"
},
"to": {
"id": "dev14",
"port": "in"
},
"vertices": []
},
{
"from": {
"id": "dev3",
"port": "out"
},
"to": {
"id": "dev15",
"port": "in"
},
"vertices": []
},
{
"from": {
"id": "dev9",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in1"
},
"vertices": []
},
{
"from": {
"id": "dev10",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in2"
},
"vertices": []
},
{
"from": {
"id": "dev11",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in3"
},
"vertices": []
},
{
"from": {
"id": "dev12",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in4"
},
"vertices": []
},
{
"from": {
"id": "dev13",
"port": "out"
},
"to": {
"id": "dev4",
"port": "in2"
},
"vertices": []
},
{
"from": {
"id": "dev13",
"port": "out"
},
"to": {
"id": "dev5",
"port": "in2"
},
"vertices": []
},
{
"from": {
"id": "dev13",
"port": "out"
},
"to": {
"id": "dev6",
"port": "in2"
},
"vertices": []
},
{
"from": {
"id": "dev4",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in3"
},
"vertices": []
},
{
"from": {
"id": "dev16",
"port": "out"
},
"to": {
"id": "dev5",
"port": "in1"
},
"vertices": []
},
{
"from": {
"id": "dev5",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in2"
},
"vertices": []
},
{
"from": {
"id": "dev17",
"port": "out"
},
"to": {
"id": "dev6",
"port": "in1"
},
"vertices": []
},
{
"from": {
"id": "dev6",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in1"
},
"vertices": []
},
{
"from": {
"id": "dev18",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in0"
},
"vertices": []
}
],
"subcircuits": {}
}
```
## `@DigiSim.runJson`
``` json
{
"devices": {
"dev0": {
"label": "s",
"position": {
"x": 0,
"y": 20
},
"celltype": "$button",
"propagation": 0
},
"dev1": {
"label": "r",
"position": {
"x": 155,
"y": 75
},
"celltype": "$button",
"propagation": 0
},
"dev2": {
"label": "q",
"position": {
"x": 480,
"y": 55
},
"celltype": "$lamp",
"propagation": 1
},
"dev3": {
"label": "nq",
"position": {
"x": 325,
"y": 0
},
"celltype": "$lamp",
"propagation": 1
},
"dev6": {
"label": "$or$_input.sv:7$1",
"position": {
"x": 310,
"y": 50
},
"celltype": "$nor",
"propagation": 1,
"bits": 1
},
"dev7": {
"label": "$or$_input.sv:8$3",
"position": {
"x": 140,
"y": 15
},
"celltype": "$nor",
"propagation": 1,
"bits": 1
}
},
"connectors": [
{
"from": {
"id": "dev0",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in1"
},
"name": "s",
"vertices": []
},
{
"from": {
"id": "dev1",
"port": "out"
},
"to": {
"id": "dev6",
"port": "in1"
},
"name": "r",
"vertices": []
},
{
"from": {
"id": "dev6",
"port": "out"
},
"to": {
"id": "dev2",
"port": "in"
},
"name": "q",
"vertices": []
},
{
"from": {
"id": "dev6",
"port": "out"
},
"to": {
"id": "dev7",
"port": "in2"
},
"name": "q",
"vertices": []
},
{
"from": {
"id": "dev7",
"port": "out"
},
"to": {
"id": "dev3",
"port": "in"
},
"name": "nq",
"vertices": []
},
{
"from": {
"id": "dev7",
"port": "out"
},
"to": {
"id": "dev6",
"port": "in2"
},
"name": "nq",
"vertices": []
}
],
"subcircuits": {}
}
```
@DigiSim.runJson
## `@DigiSim.insertCircuit(name)`
Using the `@onload`-macro you cant predefine circuits which can later be inserted into the document with the `@DigiSim.insertCircuit(name)` macro by giving the name of the circuit.
@DigiSim.insertCircuit(sr_latch)
## `@DigiSim.eval`
You can also use a pseudo RTL code to define your circuit as demostrated below.
__Don't__ use the `finalizeJSON(name)` function in the code, or your circuit will not be shown!
``` js
// Init components
AND(["and1", "and2"], ["and3"], "AND1");
OR(["or1", "or2"], ["or3"], "OR1");
XOR(["xor1", "xor2"], ["xor3"], "XOR1");
Button("btn1", "BUTTON1");
Button("btn2", "BUTTON2");
Button("btn3", "BUTTON3");
Button("btn4", "BUTTON4");
Lamp("lmp1", "LAMP1");
// IO IN
wire("btn1", "and1");
wire("btn2", "and2");
wire("btn3", "or1");
wire("btn4", "or2");
// AND, OR -> XOR
wire("and3", "xor1");
wire("or3", "xor2");
// IO OUT
wire("xor3", "lmp1", "Main Output");
```
``` js @DigiSim.eval
// Init components
AND(["and1", "and2"], ["and3"], "AND1");
OR(["or1", "or2"], ["or3"], "OR1");
XOR(["xor1", "xor2"], ["xor3"], "XOR1");
Button("btn1", "BUTTON1");
Button("btn2", "BUTTON2");
Button("btn3", "BUTTON3");
Button("btn4", "BUTTON4");
Lamp("lmp1", "LAMP1");
// IO IN
wire("btn1", "and1");
wire("btn2", "and2");
wire("btn3", "or1");
wire("btn4", "or2");
// AND, OR -> XOR
wire("and3", "xor1");
wire("or3", "xor2");
// IO OUT
wire("xor3", "lmp1", "Main Output");
```
# Js Docs
To create a circuit you have to call some functions to create components for your circuit and then you can connect them with the `wire(outpurname, inputname, label)` function.
To save your circuit you must call the `finalizeJSON(name)` function, which saves a json representation of your circuit and resests the global state so that you can create the next circuit.
Example:
``` js
@onload
Button("btn1", "");
Button("btn2", "");
Button("btn3", "");
Button("btn4", "");
AND(["and1", "and2"], ["and3"], "AND1");
OR(["or1", "or2"], ["or3"], "OR1");
XOR(["xor1", "xor2"], ["xor3"], "XOR1");
Lamp("lmp1", "Main Output");
wire("btn1", "and1", "");
wire("btn2", "and2", "");
wire("btn3", "or1", "");
wire("btn4", "or2", "");
wire("and3", "xor1", "");
wire("or3", "xor2", "");
wire("xor3", "lmp1", "");
finalizeJSON("ex1");
@end
```
If you use the `@DigiSim.eval`-macro you dont have to use the `finalizeJSON(name)` to save your circuit! If you use it in the code it will not display your circuit!
## Simple Logic Gates
You can simply use this functions to create logic gates in your circuits.
`inputs`: Array of strings with the name of your inputs. `type: [String]`
`outputs`: Array of strings with the name of your outputs. `type: [String]`
`label`: Name that will be displayed next to the component. `type: String`
`bits`: Size of your data bus in bits. `type: Int`
`pos`: Position of the circuit. `type: {x: Int, y: Int}`
All of these parameters are the same for the upcoming functions.
If the parameter is called `input` instead of `inputs` it is not an array of strings but a single string. The same apllies to `output` and `outputs`.
``` js
AND(inputs, outputs, label, bits=1, pos=undefined);
NAND(inputs, outputs, label, bits=1, pos=undefined);
OR(inputs, outputs, label, bits=1, pos=undefined);
NOR(inputs, outputs, label, bits=1, pos=undefined);
XOR(inputs, outputs, label, bits=1, pos=undefined);
XNOR(inputs, outputs, label, bits=1, pos=undefined);
NOT(inputs, outputs, label, bits=1, pos=undefined);
```
## Reducing Gates
These gates take a bus of the given bit size and reduce its size to 1 bit.
``` js
ReducingAND(input, output, label, bits, pos=undefined)
ReducingNAND(input, output, label, bits, pos=undefined)
ReducingOR(input, output, label, bits, pos=undefined)
ReducingNOR(input, output, label, bits, pos=undefined)
ReducingXOR(input, output, label, bits, pos=undefined)
ReducingXNOR(input, output, label, bits, pos=undefined) // does currently not work properly and produces a reducing xor gate
```
## IO
Components that can handle input/output operations.
`bitsIn/bitsOut`: Determines the bus size only of the input/output of the component. `type: Int`
`base`: Base of the number system the should be used `possible values: "hex", "bin", "oct"`
`value`: Numeric value that is constantly output by the component. `type: Int`
``` js
Button(output, label, pos=undefined)
Lamp(input, label, pos=undefined)
NumberInput(output, label, bitsOut, base, pos=undefined)
NumberOutput(input, label, bitsIn, base, pos=undefined)
NumberConstant(output, label, value, pos=undefined)
```
## Unary Operations
Unary operations that can be performed on numbers.
`signed`: Determines wheter the numbers are signed or unsigned. `type: Boolean`
```js
Negator(input, output, label, bitsIn, bitsOut, signed, pos=undefined)
```
## Binary Operations
Binary operations that can be performed on numbers.
``` js
Add(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
Subtract(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
Multiply(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
Divide(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
Modulo(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
Pow(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
```
## Comparison Operations
Comparison operations that can be performed on numbers.
``` js
Equals(inputs, output, label, bitsIn, signed, pos=undefined)
NotEquals(inputs, output, label, bitsIn, signed, pos=undefined)
LessThan(inputs, output, label, bitsIn, signed, pos=undefined)
LessThanOrEqual(inputs, output, label, bitsIn, signed, pos=undefined)
GreaterThan(inputs, output, label, bitsIn, signed, pos=undefined)
GreaterThanOrEqual(inputs, output, label, bitsIn, signed, pos=undefined)
```
## Shift Operations
Shift operations that can be performed on numbers.
``` js
ShiftLeft(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
ShiftRight(inputs, output, label, bitsIn, bitsOut, signed, pos=undefined)
```
## Multiplexer
`bitsSel`: Determines the bus size of the select input. `type: Int`
`Number of inputs: 2 ^ bitSel`
``` js
Multiplexer(inputs, selInput, output, label, bitsIn, bitsSel, pos=undefined)
```