mortbopet / vsrtl Goto Github PK
View Code? Open in Web Editor NEWVisual Simulation of Register Transfer Logic
License: MIT License
Visual Simulation of Register Transfer Logic
License: MIT License
An obvious data structure would be to contain the place & route result in a matrix, with items within the matrix being pointers to either ComponentGraphics or Ports (which are associated with wires). However, such a data structure does not scale well.
CURRENT_SOURCE_DIR should not be included in the include paths of files.
External include path should be started from External/
Currently, Various colors as well as the grid size is set as compiler definitions. These should be moved to application-wide settings through QSettings.
Currently, Component::verifyComponent throws std::runtime_error's when an issue in the circuit is found.
This task should:
Qt 5.12.1 Windows MinGW 7.3.0 64bit Need to add #include <QAction>
in vsrtl_netlist.cpp
or, the compiler will complain as:
...\VSRTL\graphics\vsrtl_netlist.cpp:17:68: error: invalid use of incomplete type 'class
QAction'
QAction* expandAct = new QAction(expandIcon, "Expand All", this);
A ComponentGraphic should be able to query a Place & Route singleton with the components subcomponents. This will then return a to-be-determined representation form of the component placements and signal routings, which may then be set by the ComponentGraphic.
This singleton may contain different place & route algorithms, and may be configured by a settings dialogue.
Ie. Multiplexers should have their select port to be at either the top- or bottom of the component.
Base classes of ports and registers are a remnant of the templated design of components. These base classes should be removed with their subclass into a single class.
With a Place and Route run finished, the PlaceRoute object will return a data structure which designates how the subcomponents of a component should be layed out, and how the signals should be drawn. This data structure should be interpreted and drawn.
Depends on #16
A unit test for testing the "undo" feature of a vsrtl::Design should be added. The test should verify that:
It should be possible to expand all components in the design;
Currently, the entire Netlist/Register model is updated when the circuit is clocked - this is not scaleable.
model::data() should fetch values directly from their connected ports instead of this data being set during model initialization. Furthermore, a port emitting its updated signal should be connected to the specific treeItem (and QModelIndex) to update that specific index. This should allow us to completely remove the updateNetlistData() methods.
End goal is to remove the NetlistModelBase::invalidate() calls made in Netlist::reloadNetist()
Currently, Component::propagateComponents always executes changed.emit() upon each propagation cycle. This signal is used to identify the GUI whether to update the drawing of the component.
This signal should only be changed when any output ports of the component is modified.
Todo: Investigate whether more logic is required for correctly updating the component graphics when the component is expanded/collapsed.
Adding new unit tests to address some of the lesser covered parts of the source code would be a great way to familiarize oneself with the project.
To view unit test ideas which has been filed as issues, go to the Issues tab and filter for the "Test" label.
For the current status of the tests' code coverage, refer to:
https://codecov.io/gh/mortbopet/VSRTL
VCD waveforms are a common tool for analyzing simulations of digital circuits.
The implementation should be on a vsrtl::widget level, wherein it should connect to the Gallant::Signal members available in components and ports. These signals are emitted when ports and components change value - exactly what is required for the VCD file format.
Writing a VCD writer should be (fairly) simple - however, the file format should be used to its advantage, wherein all signals and components are nested within their respective parents, as the file format allows.
Resources:
https://en.wikipedia.org/wiki/Value_change_dump
https://github.com/wohali/vcd_parsealyze
#7 should be resolved before this.
With #40 , it should be possible to partition the graph into subgraphs with no dependencies. These subgraphs are then valid to be executed in a separate thread.
This task would initialize a QThreadPool and the logic for assigning subgraph propagation to threads.
Based on the circuit being simulated, this may induce some load balancing issues, but as long as the number of subgraphs is somewhat greater than the number of executing threads, assigning the subgraph propagations to the QThreadPool, the threadpool will handle the scheduling for maximum operation overlap.
Related to #9
Currently, clocking the circuit is bound by the QEventLoop, limiting the circuit to be clocked at ~5ms intervals at a minimum. If faster simulations are desired, the circuit should be moved to a separate thread from the GUI thread, using a faster clock triggering mechanism than what QTimer (and the Qt event loop) may provide.
Discussion:
In larger systems, viewing all circuit elements may provide excess information.
Create a model solely for the displaying of registers. Columns may be:
(LHS -> RHS)
Component tree with leaf nodes being register names | Register Value | Register Size |
If at the future a register-enable input is added to registers, there may be a colored icon indicating whether this is set.
Currently, the graphics view and netlist view have to manually synchronize selections. This is error prone and tedious to expand. A shared selection model should be implemented, to centralize selection state and state change behaviour.
A breadth-first-search based algorithm should be implemented, wherein objects are placed based on their depth in the graph. Root node(s) should be the output port(s) of a component.
Currently, VSRTL draws objects with smooth edges, and uses colors. There should be a selection to choose different draw styles; ie. a draw style with sharp, thin edges, more closely mimicking schematics.
It is annoying and verbose to type eg.:
INPUTPORT_W(acc, 32);
...
return acc.value<VSRTL_VT_S>() == 0;
Comparison with integer literals is fairly safe, and should be implemented as an operator, so we can do:
return acc == 0;
Currently, NetlistItem contains logich assume that specific values are placed in certain columns (such as the decorationRole in NetlistItem::data).
Likewise, the models retreive their column count from the itemData variable in NetlistItem's.
itemData should be removed, given that all data is kept in the NetlistData struct, and NetlistItems should be made fully independent from their models. The only "link" to the model should be the QModelIndex index variable, which will come of importance for #25 .
Having undo/redo functionality is a perfect companion for the graphical visualization component of vsrtl, which will aid in its use as a testing as well as teaching tool. This will also set the simulator apart from many other
The obvious implementation is to only have undo/redo affect registers and other memory elements, given that the combinational parts of the circuit may be derived from the state of constants and registers.
While the aforementioned implementation only requires a single value to be stored pr. register, this may still have a significant memory impact in large circuits, and as such should be toggleable in a Settings dialog.
Expand/collapse components control should consist of:
(When selecting a component)
The menu should present itself as a context menu as well as tools in the toolbar. The menu should be focus-aware, and remove options when netlist has focus/when no components are selected.
A prefix for filenames should not be needed when include directories are configured correctly. However, include guards should include the name of the project to avoid conflicts.
Remove "vsrtl_" prefix from all files, and ensure that include guards are "VSRTL_" prefixed.
This may be facilitated by moving the getParent() and getName() methods of ports, components, to the Base component
Currently, the entire graph is explored for each clock cycle, to ensure correctness.
However, this exploration in terms of properly sequencing the propagation operations is only required once.
This task should
Relates to: #9
It should be possible to specify some decorative text to be drawn in the center of a component.
This could be useful for ie. an adder, drawing a '+' in the center.
Possibly this could also be done with some function which may change the text drawn inside a component based on the state of the component (ie. a comparator could have different comparison signs based on the requested comparison type).
Currently, the entire circuit is visited by the register propagation algorithm each time the circuit is clocked. This is redundant, given that the register propagation algorithm may push components on to a stack in the order of which the algorithm deems that components may be propagated in a correct order.
Component::propagateComponent() as well as Port::propagate() should be rewritten in such a way as to traverse the graph, but also push $this onto a stack (owned by the Design) when it is allowed to propagate itself. In this way, this stack may be traversed in the order of which the elements was added, to allow for clocking the circuit in O(c+p) where c = number of components and p = number of ports.
To have compile-time bit-width checking, propagation functions should be typed with a width paramter
for instance
std::function<VSRTL_VT_U()> m_propagationFunction;
would be transformed to
template<unsigned int W>
std::function<VSRTL_VT_U<W>()> m_propagationFunction;
This issue is intended for tracking a discussion on suggestions for features which improve the visualization of a circuit during simulation.
To reproduce:
Place source & sink ports far away from each other, and click on the sink port. It does not repaint as being select, even though it selected.
Reason:
the source port is out of view, and thus does not get repainted, even though it gets selected by clicking the sink port - implicitely calling update() on the source port, which should trigger a repaint.
Solution should be to:
Extract m_pen setting logic from paint() method, such that pen changes can propagate between ports & wires without relying on paint() being called on intermediate ports and wires.
Unit test(s) should be added to assure the functionality of the vsrtl::core logic gates. Unit test should involve both logic gates of width 1 (boolean), as well as logic gates with wider inputs.
Between clock events, the state of the circuit should be modified, as in, register output values.
This task consists of:
for future algorithms regarding place and route, these will require investigating the current state of the scene, to identify whether certain items or paths collide.
In these cases, the components within the view should provide accurate collision detection feedback, by returning proper Shape's - whether this is a QRect or a PainterPath.
Currently, travis CI compiles and runs on linux and OSX.
Windows-based continuous integration should be enabled, possibly through appveyor or Travis' experimental windows environment.
An initial implementation of a place & route algorithm is to be implemented. within the PlaceRoute
Resources:
Depends on #14
It should be possible to store and load a file for specifying the configuration of the graphical view.
Serialized data should include:
Serialization of wires will come in a later stage, when place/route is fully implemented.
Serialization should be facilitated by a common library, such as:
The graphical component should be able to display the names of enum values to the user. To create the enum => string association, we may use a library such as:
https://github.com/Neargye/magic_enum
Needed for interpreting a std::vector<ComponentGraphic*> as an implicit netlist
Many places, unimplemented or unreachable states are marked by Q_ASSERT(false). Most of these should be replaced with Q_UNREACHABLE(), which is more fitting for the task.
Continuous integration should be set up as soon as possible, to allow for continous unit testing of pull requests and newly pushed patches.
Compilers to enable:
OSX:
Linux:
Windows:
A unit test for testing the "restart" feature of a vsrtl::Design should be added. The unit test should verify that the circuit is set to its initial state after restarting, and that it is not possible to "undo-clock" the circuit. The test should verify that the circuit, once clocked after a restart, shows expected values.
When selecting a component in the graphics view, the corresponding signals contained within that component should be highlighted in the netlist.
Similarly, when selecting a signal in the netlist, this signal shall be highlighted in the graphical view.
The vsrtl::Memory object should be seen as a base class for all components implementing some form of memory (whether this is to model ram, rom, ...).
The memory component should provide different policies for handling invalid memory accesses (RAZ/WI or other policies).
Subclasses of memory shall during construction specify the regions available within the component.
interface to the memory could be:
template<int width>
class Memory : public Component {
public:
Port* address = nullptr;
Port* readEnable = nullptr;
Port* writeEnable = nullptr;
Port* dataRead = nullptr;
Port* dataValid = nullptr;
// Externally modify value at addr, size in bytes
void externalWrite(VSRTL_VT_U addr, VSRTL_VT_U data, int size){
static_assert(sizeof(data) <= size);
}
// This function would verify that the memory blob which is written to is
// appropriately sized. Also, add handling for writing to contiguous but separate
// blobs
void externalWrite(VSRTL_VT_U addr, VSRTL_VT_U dataPtr, int size);
// Externally modify value at addr, size in bytes
VSRTL_VT_U externalRead(VSRTL_VT_U addr, data, int size){
static_assert(sizeof(data) <= size);
}
private:
enum class readErrorPolicy{ RAZ, RDEADBEEF, ... };
enum class writeErrorPolicy{ WI } ;
}
template<int width>
class ROM : public Memory {
public:
Rom(Component* parent) : Memory<width>(parent){
readEnable = createPort(this, width);
dataRead = createPort(this, width);
dataValid = createPort(this, width);
// writeEnable is not instantiated, Read-only memory
}
}
This issue is related to removing some of the initial hardcoding, and moving it to a settings widget.
The settings should be implemented through QSettings.
Drawing:
simulator
Depends on #4
With CI enabled, unit tets should be enabled for each commit and PR.
QTest should be utilized for testing vsrtl_graphics library.
Todo: Determine whether QTest or Catch should be used for unit testing vsrtl_core. Catch is relevant, given that vsrtl_core is designed to be independant on Qt, and as such, its testing suite should be aswell.
The bounding rect of PortGraphics is misaligned, resulting in an unintuitive selection area.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.