GithubHelp home page GithubHelp logo

tilk / digitaljs Goto Github PK

View Code? Open in Web Editor NEW
644.0 19.0 44.0 7.75 MB

Teaching-focused digital circuit simulator

License: BSD 2-Clause "Simplified" License

JavaScript 97.71% CSS 2.29%
simulator circuit-simulator logic-gates logic-circuit-simulator digital-logic

digitaljs's Introduction

  • My name is Marek Materzok and I work at the Computer Science Institute in University of Wrocław, Poland.
  • I'm interested in programming languages, hardware design languages, embedded systems.
  • Contact address: [email protected]

digitaljs's People

Contributors

daniellehuisman avatar dependabot[bot] avatar engineer-of-efficiency avatar ialokim avatar jakubszczerbinski avatar malmeloo avatar mateusz-sz avatar tilk avatar yuyichao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

digitaljs's Issues

Allow customization of subcircuit buttons

Currently, the zoom buttons for subcircuit pop-ups are hardcoded. To customize the user experience, it would be nice to allow providing additional buttons with a callback that should be triggered when the button is clicked. Ideally, the callback would receive some context (such as the circuit object and subcircuit paper) to allow for manipulation.

I'd be happy to make a PR for this, just opening this issue first for discussion. Would this be an acceptable feature?

Layout lock of inspected element with text inputs and desync of representation of its connections

Issue is visible and reproducible e.g. on "ram.sv" simulation upon inspection of element "mem".

ram

Inspecting element "mem" visually locks its position in place. Element becomes unmovable, but attempts seem to move it in the background. After such attempt, moving any other element connected to the affected element refreshes visual representation ot this particular connection in relation to the attempted move offset.

Exact source of the problem has not been identified yet.

Editing a Number should trigger logic

When I enter an input number, the changes do not propagate.
I have to toggle a button to propogate the changes.

Here is a particular circuit that exhibits this behavior.

It is a serial comparator. Starting from the most significant bit. The input on the first stage should just be 2'b11, meaning the two values are the same, before any comparison.
Instead of a constant, I have two buttons to toggle, to make the updates happen.

Here is the code.

module compare(input [1:0] previous,
input a,
input b,
output reg [1:0] result);

wire [1:0] both;
reg [1:0] bitResult;
assign both= {a,b};

always @ (previous,bitResult) begin
case (previous)
2'b10 : result = 2'b10; //A is bigger
2'b01 : result = 2'b01; //B is bigger
2'b11 :
case (both)
2'b10: result = 2'b10;
2'b01: result = 2'b01;
2'b11:
case (both)
2'b10: result = 2'b10;
2'b01: result = 2'b01;
2'b11: result = 2'b11;
2'b00: result = 2'b11;
endcase

          2'b00: result = 2'b11;
       endcase
  2'b00 :  result = 2'b00;
 endcase

end
endmodule

module main (input previous1,
input previous2,
input [3:0]a,
input [3:0]b,
output [1:0] finalResult);
reg [1:0] result0,result1, result2, result3;
compare comp1 ({previous1,previous2},a[3],b[3],result3);
compare comp2 (result3,a[2],b[2],result2);
compare comp3(result2,a[1],b[1],result1);
compare comp4(result1,a[0],b[0],finalResult);

endmodule

Merge different input/output types

If one wants to look at a subcircuit on its own, it is essentially as easy as copying the subcircuits definition to the top level (replacing devices and connectors) in the json file. But due to the (somehow artificial) distinction between Input/Button/NumEntry and Output/Lamp/NumDisplay it gets more difficult if one wants to be able to simulate the circuit on manual inputs.

I would propose to move the logic to differentiate between different in/output types from yosys2digitaljs to digitaljs itself and merge the three in/output types respectively. The corresponding view class could then show different views depending on whether the in/output is inside a subcircuit (Input) or not as well as depending on the bit size (Button vs. NumEntry). This would also be another step towards #2.

Manually positioning connector to avoid weird crossing lines

I have the problem, that in a circuit with a feedback connection (running the output of an dff into an mux and back into the input of the dff) the automatically generated connection path is behind other devices / crosses other lines.

I know that I can manually position the devices using "position":{"x":10,"y":5} but I also need to set a kind of anchor for one connection to prevent the described behavior above.

This is possible ? If not, what are my other options to solve this problem?

Thank you!

Reason why ports are not recognized by jointJS?

For some reason, the ports object of each gate, e.g.​

{
    "ports": {
        "in1": { "id": "in1", "dir": "in", "bits": 3 },
        "in2": { "id": "in2", "dir": "in", "bits": 3 },
    ​​    "out": { "id": "out", "dir": "out", "bits": 3 }
    }
}

for a simple Or gate is not recognized by the native jointJS functions such as getPorts(). Was there any reason why you didn't use the native jointJS functions to add ports (even with own, separated markup)? I think it would have made some things clearer and easier to use if you'd stick to the jointJS API.

Testbench failing

At version 0.6.0, 16 tests out of 691 fail on my machine, all of them related to busgroup and busungroup. With the last changes in 0.6.2, a total of 129 tests fail.

Is that something specific to my local installation? If not, I think it should be fixed soon to be able to detect future bugs.

Sub window should not bind signal listener to the view in parent paper

Haven't found/tested a clean solution yet (and I need to run soon...) so report as an issue for now so that I don't forget...

I tested this with the fsm subwindow but I think this would also affect memory subwindow as well.

The symptom is reproducible with the following source code modified from the fsm example.

module fsm(input clk, rst, a, output b);

  logic [1:0] state;
  
  localparam A = 2'b00;
  localparam B = 2'b01;
  localparam C = 2'b10;
  localparam D = 2'b11;

  always_ff @(posedge clk or posedge rst)
    if (rst) state <= B;
    else casex(state)
      A: state <= C;
      B: state <= D;
      C: if (a) state <= D; else state <= B;
      D: state <= A;
    endcase

  always_comb begin
    b = 1'bx;
    case(state)
      A, D: b = 0;
      B: b = 1;
      C: if (a) b = 1; else b = 0;
    endcase
  end

endmodule

module wrapper(input clk, rst, a, output b);
  fsm fsm_1(clk, rst, a, b);
endmodule
  • Synthesize with the optimization on, fsm into circuit element on (and maybe merge more into fsm for clarity).
  • Open the subcircuit window
  • Open the fsm window
  • Now dragging states around would auto resize the fsm window
  • Close the subcircuit window
  • Now dragging states around in the fsm window will now resize it anymore.

The issue is that the position change listener at

this.listenTo(graph, 'change:position', (elem) => {
is registered on the FSMView, which is destroyed when the subcircuit subwindow is closed and automatically disconnects the listener.

The right solution is to somehow bind this on the paper/div or bind to global circuit and manually remove in the close callback. From the look of it, the memory subwindow has the same issue.

Making this change should also have the benefit of making the display editor function more independent of the view and can make it easier for the user to trigger it in other conditions (e.g. restoring view state).

Decouple subcircuit view from internal logic

Quote by @tilk in #4 :

Currently, displaying popups with subcircuits is handled in the Circuit class; the popup for memories is handled in the view. Ideally, these things should be handled externally. Some users might not want the popups; others might want something different (tabs, side panels, etc.).

I'm not sure what would be considered best practice for such kind of things in Javascript: Some sort of callback function / backbone event that one would need to react to (e.g. inside digitaljs_online)? Or perhaps pass some external function that would be called from within digitaljs on opening subcircuits? Some externally given function that produces and returns a html div where the subcircuit would be rendered into?

Also, should some default handling still remain in the core digitaljs logic such that if e.g. the event is not responded to the subcircuit is still showed in a popup window as done currently?

Change number of bits after gate initialization

As the GateView and the gate's functionality currently seems to be defined once during initialization, I assume there is no way to change the number of (input or output) bits of some gate afterwards. Is that correct?

If so, do you have some idea where and how this functionality could be added? I would like to look into it, as we would like to use your library with this possibility.

ResizeObserver not imported

After commit c698668 using the examples generated by webpack gives the following error:

ReferenceError: ResizeObserver is not defined index.mjs:81

Not sure where ResizeObserver should have been defined or imported?

Make cells themselves aware of celltype

When instantiating a new gate using getCellType and adding it to the circuit, this newly added gate does not contain a value for attributes.celltype as gates loaded from some yosys2digitaljs created json would do. Therefore while saving the circuit into json, these newly added gates do not contain the celltype information at all.

One possible workaround is to always pass the celltype manually as an argument to the constructor while creating the gate, but I think it would make more sense if the celltype would be a default attribute for each gate.
Did you have any reason why you've named the celltypes e.g. $not in the json files and Not when you defined the gates? I've noticed the former is always correctly set into the type parameter even on newly added gates (presumably automatically by jointjs?), but it's value is not considered while saving to json.

If not, I would suggest to keep one common name for the gate's definition and inside the json file (if yosys outputs the types as $not they could be properly renamed already in yosys2digitaljs I guess) so that additionally added gates would automatically "know" their type.
An alternative solution would be to set the celltype argument as a default for each new Gate definition (probably even overwriting some given value) as the celltype should only depend on the instantiated gate.

Request: Customizable port location for multiplexer selection port

Hello,
I think if would be a great addititon let the select port on a multiplexer be customizable. Currently it is always on top, but I think having an option to set the select port either on top or on the bottom can be very useful to avoid clutter in the generated circuit.

System Verilog port input multi-dimensional array

Greetings, I got a .sv module that uses an input port array but it looks like it's not supported

Input e.g.: input signed [BITS-1:0] inp_name [ARRAY_SIZE-1:0]
Result: ERROR: syntax error, unexpected '[', expecting ',' or '=' or ')'

This is a System Verilog input style that synthesises with no issue in other software. From the README section, it is not clear if SystemVerilog is supported, but .sv files are supported. Is this a bug or multi-dimensional arrays are not supported?

In any case, thank you very much for your great work!

Can the schematic layout stuff be used separately from the simulator?

@sifferman complimented the schematic layout that DigitalJS produces in the NetlistSVG GitHub Issue here nturley/netlistsvg#140 and I agree the shared screenshot looks pretty nice!

I was wondering if the schematic layout stuff could potentially be integrated into the sphinxcontrib-hdl-diagrams project? It currently supports both Yosys diagrams and NetlistSVG diagrams.

It looks like DigitalJS is really focused on the simulator side of things rather than the schematic layout generation?

AND OR XOR icons please

Right now your nodes are just boxes.
But if someone has written the code to build an AND gate, an OR gate, an XOR gage, a multiplexer or demultiplexer, it would be awesome if you could display that.

It would also make the designs much more readable.

It would also be perfect for teaching, ask them to build an AND gate, and it gets built.
You could even run the pattern recognition process in the background. As it recognises patterns, update the display.

I really like how your softare only taks a second to run, quartus takes closer to a minute, even for small designs. so I can iterate much faster here.

Lazy-loading for faster UI response time

For circuits as big as the horner example, initial loading takes more than ten seconds (on my machine) leading to a blocked browser tab and a bad user experience without any progress notification.

I think it might be better to first load the top level of the circuit and handle subcircuits loading later (or even in WebWorkers) after the top level is already shown to the user (perhaps also showing some loading progress indicator). Obviously the simulation could not start before all subcircuits have been loaded.

One conceptual change that would be needed for this to work is how subcircuit instances get to know their in/outputs. But I think this should be easy to achieve with a small preprocessing step iterating over all subcircuits and adding some extra IO information to the subcircuit definition. As for each subcircuit type the in/output ports are identical, this might even result in a small performance gain if not every instance of the subcircuit has to check itself for its in/outputs while instantiating.

README Does not reflect actual usage.. Better Documentation on usage?

Good day,..

i have been playing around with this project but i cant seem to get this to work correctly with the info inside the README file ,

// create the simulation object const circuit = new digitaljs.Circuit(input_goes_here);
there is nothing named digitaljs.Circuit
and should be apparently be.
const circuit = new digitaljs.HeadlessCircuit(json)
// display on #paper const paper = circuit.displayOn($('#paper'));
there is nothing called displayOn() ?
// activate real-time simulation circuit.start();
not useable as displayOn is not found..

im i missing something here..?

kind regards.

Rename private functions to start with underscore

My recent work on the gate and wire models introduced some additional methods, some of them are meant to be used from outside of the library (part of the API) while others are just internal helper functions. To distinguish them easier, I would propose to follow naming conventions and rename internal methods to start with the prefix _.

Also, from an esthetic point of view, I would propose to unify method declaration syntax used throughout this project and decide whether to use name: function(argument) {} or name(argument) {}. I don't know if there is a "better" way to declare methods, but I think it would make sense to stick to one of them.

If you were okay with these changes, I would be happy to realize them.

Memory-Device breaks UI when abits < 4 | outdated webbundle

When using a Memory-Device with less than four adress bits (abits) the UI cannot correctly render the memory contents.

Bug producing example code:
{ "devices": { "in": {"type": "Input", "net": "A", "bits": 3}, "out": {"type": "Output", "net": "X", "bits": 4}, "rom": { "type": "Memory", "bits": 4, "abits": 3, "rdports": [ {} ], "wrports": [] } }, "connectors": [ { "from": {"id": "in", "port": "out"}, "to": {"id": "rom", "port": "rd0addr"} }, { "from": {"id": "rom", "port": "rd0data"}, "to": {"id": "out", "port": "in"} } ], "subcircuits": {} }

This reproduces this bug and throws an Uncaught TypeError: Cannot read property 'toString' of undefined error. Instead of showing the memory content in its own window, it gets appended at the end of the current page.

Problems using digitaljs

Hi!

I am trying to use digitaljs, but I am facing problems using the npm module. I am new to Javascript so I might be missing something basic. Here is what I did:

  • created a simple index.html
index.html
<!doctype html>
<html>
  <head>
    <title>Test digitaljs</title>
  </head>
  <body>
      <div name="#paper">
      </div>
  </body>
</html>
  • Created a simple index.js based on the code from README
index.js
// I assume this line is necessary - without it node complains digitaljs is not defined
digitaljs = require('digitaljs')

// create the simulation object
// I know an actual input must go here, but code doesn't reach this point
const circuit = new digitaljs.Circuit(input_goes_here);
// display on #paper
const paper = circuit.displayOn($('#paper'));
// activate real-time simulation
circuit.start();
  • When I run node I get:
$ node index.js
/home/foo/workspace/block_v/workspaces/test/node_modules/digitaljs/src/index.js:3
import 'babel-polyfill';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1063:16)
    at Module._compile (internal/modules/cjs/loader.js:1111:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:996:32)
    at Function.Module._load (internal/modules/cjs/loader.js:896:14)
    at Module.require (internal/modules/cjs/loader.js:1036:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/home/foo/workspace/block_v/workspaces/test/index.js:1:13)
    at Module._compile (internal/modules/cjs/loader.js:1147:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)

Any directions would be appreciated

Add fixed mode

When playing with the digitaljs output, changing some input signals etc. it is often not really necessary to be able at the same time to delete and add wires or move cells or wires around.

I would propose to distinguish the two use cases "rearranging things nicely" and "manipulating and observing signals" in terms of adding a "fixed" mode where the nodes or wires would not be moved around. On the other hand, some sort of "edit" mode where signals are not changing (circuit simulation is stopped) could also be useful.

I guess we could differentiate between three modes: "edit", "simulate" and "both" (which would be equivalent to how it is working now). What do you think about this?

Cannot save simple design due to BigInt

The following simple design cannot be saved due to JSON.stringify() not knowing how to serialize a BigInt.

module counter(input wire clock, output reg [0:0] out);
   initial begin
      out = 1'b0;
   end

   always @(posedge clock) begin
      out <= out + 1'b1;
   end
endmodule

The culprit seems to be the increment. Monkey patching BigInt using GoogleChromeLabs/jsbi#30 (comment) seems to work around the issue and produces a usable json output. A less invasive method by adding a replacement argument to the stringify call is probably better.

I would have tested this locally and submit a PR instead but somehow sass dependency doesn't work on node 17 right now so I couldn't test this...

Move styling from CSS to Javascript

The styles.css consists partly of rules to set colors (and shape) for high or low ports and wires. This is accomplished by adding a specific class to the element inside javascript and then applying the styling inside CSS for this class.

I think it would be easier and more intuitive to set the corresponding styling directly in Javascript, that is, apply it directly to the SVG DOM instead of relying on the CSS browser styling. I'm not sure if one of both has a performance advantage, but at least it would sort things a little bit more clearly to the developer.

Detect and disallow invalid connections in JSON

If the input JSON has a connection between different-sized ports, DigitalJS will happily connect them, with disastrous results. For example, yosys2digitaljs currently generates such a bad JSON for:

module test2(input [1:0] i, output o);
  assign o = i;
endmodule
module test(output o);
  test2 x(0'b1, o);
endmodule

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.