I've been spending the past few hours reading up on and playing with Icarus, commonly known as Icarus Verilog, which is an open source Verilog compiler/simulator package much like GHDL is for VHDL. There are some differences: Icarus is written in C++ instead of Ada, and it compiles to an intermediate language called VPP which is then executed/simulated by a standalone utility, 'vpp'.
Good design throughout, but the really nice part is new: Icarus/VPP now supports VHDL-to-VPP compilation! The VHDL support isn't finished yet, but I am going to try to leverage what is there and see if I can replace GHDL with Icarus for use with Controlix, as the primary compiler, because it would make porting Controlix to bare-metal hardware easier. The reason for this is that porting the 'vpp' utility would be all that would be needed and it is also C++ code, much easier to statically link than Ada.... read more
Most system level languages use some kind of macro language along with the core compiler, to enable variables in the build environment to be passed to the compiler, basic logic (in many cases) to be handled before compilation, and many other seemingly minor but very necessary uses. Controlix currently has none of that, and as a result a simple thing I was needing today (Passing a build date string to a shell 'Version' command) is basically impossible.... read more
The document describing the hierarchy of the Controlix virtual machine layers/sectors has been completely reworked and debugged. I think I've finally gotten it straight now, at least to a rough-grained degree. The first two layers are defined, which I think is enough to start working with in terms of actual VHDL code generation.
One major area left to define is the design of the assembly language parsed by the VM. It will need to reflect the core nature of the VHDL language, so I'll need to spend some time boning up on the IEEE STD documents that define the VHDL abstraction....... read more
More new stuff regarding the type system. It appears that one must make use of UML types in addition to the SysML types I was previously solely focused on, because the UML typeset is necessary for modeling actual code. This brings me closer to my goal of being able to do away with the 'legacy' (ADA-holdover) VHDL types and move to a completely bit-serializable type system for Controlix, which should end up being much more synthesizable.... read more
After a few weeks of downtime for me, it is time to start working on Controlix again. This time I need to discuss an attempt to properly virtualize an aspect of the VHDL language - the type system, variables and signals.
First of all, we need to discuss what NOT to do, and that IMHO is to use much if any of the ADA-holdover standard types provided by VHDL. What is needed is to use the fundamental standard types 'bit' and 'bit_vector' as the basis upon which to construct another type system.... read more
So far, the design of the controls which make up the body of Controlix have been somewhat ad-hoc and limited to emulating networking hardware and a simple ASCII-based packeting motif. A more all-encompassing approach for the long term would be to specify and encourage the use of a more abstract set of forms which can encapsulate any software and hardware motif in systems as a whole. The logical choice here is the SysML systems modeling language, which is designed to model generic systems in an abstract sense. SysML defines a set of prototype form elements which are used to model systems in general.... read more
TCP/IP version 4 specifies a network addressing scheme which uses a four-octet address for each node on the network, and in Controlix each control presents to the system a network physical-port analogy which provides the control with an IPv4 address that it can use to interact with the rest of the system. When an IP address is used in Controlix by a control, it can therefore categorize that control in one of four ways:... read more
...is in. The native networking code in network_.c now spawns a thread to run the socket listener code and buffers input data from the socket into a FIFO which tcp_receive() can now read one byte of data at a time from, instead of blocking the whole control on native listen() (oops! |->). Much more hardware-ish in design now, especially on the VHDL side. Also new is an additional signal on the network_port which represents a status register for the network port device. It currently holds one significant bit, which represents a FIFO_EMPTY condition - when this bit is set, the network_port won't signal receive_message and the caller can properly wait in a loop without blocking. I haven't yet implemented a FIFO_FULL status bit, but I will - that will enable muxing of network message sends, a necessary feature for things like switching and routing of messages.
New stuff today:
Today's work involved refactoring the console support code to support retargeting. I had previously done some basic retargeting work at the VHDL level, but I want to keep the VHDL code as abstract and generic as possible, so the retargeting stuff has to move down to the native level. The console functions are now simple getc()/putc() generic functions, and everything involving switching between (for example) the Ncurses and libc (and someday raw text-buffer/IO port) console targets will be done in native code and will be selected at compile time based on the overall system target.... read more
Bad news, with a silver lining: both libvirt and lxc on Linux are currently unuseable disasters. I have never seen systems software designed that badly - both packages consist of huge, unweildy libraries which, instead of talking to the underlying OS as system libraries should, instead wrap system() calls to command-line utilities! This isn't portable, doesn't work at all for embedded systems which might not have a POSIX shell or execution environment, doesn't allow for static linking, and too many other problems to mention them all here. I spoke with the liblxc development folks and they showed me some of the C headers they are working on for a "real" (i.e. properly designed) LXC library, but it isn't even close to done being designed, let alone implemented.... read more
Currently, all patches in Controlix are configured and designed to run as "controls". This is why we call it "Controlix". What are controls, though? Simply put, controls are regularized patches. Features of controls:
I had to switch my development system back to Gentoo (Calculate Linux) from Debian. I used to run Debian 6, but it didn't come with a current (read: non-buggy) version of libvirt. Unfortunately, Debian 7 doesn't contain a package for ghdl, so I was pretty much out of luck. I've been happy in the past with Gentoo and variants, so I decided to give Calculate a shot, and after a long day of fiddling I have it installed, its kernel configured properly for lxc and libvirt, and all of my Controlix development environment up and running. The libvirt bug is gone, and although I had a similar wierd crash-on-init bug with Ncurses pop up, I was able to switch back to the old libc-based console I/O routines. Everything is now building and running without errors, yay! All fixes have been committed.
The previously-mentioned networking support code has been written and committed. Libvirt is used on the native side to allocate a LXC virtual network interface with a private IP and MAC address for each control, and each control runs as a separate process inside it's own LXC container. An ultra-simple TCP interface (send(destination_address, message) and recieve(source_address)) is used by a common network interface control which is instantiated inside each "standard" control and delivers messages to in- and out-message strings in the containing parent control for further processing. Presto! Controlix now has a client-server process management and IPC system.... read more
OK, so now I am working on the ability of controls written in VHDL to access services from "parent" controls. This is what will pass for a generic system call type interface. Here goes: Each control which wants to make use of a parent control's services will need to port itself into a system-wide ethernet bus and then make a DHCP request, which will provide an IP address within a subnet managed by the parent control. A messaging port on a gateway managed by the parent control will allow the child control(s) to communicate service requests to the parent, or even route the service requests further upstream to a parent network for handling, depending on the type of service requested.... read more
The native console I/O has been switched over to use ncurses. I did this because I was having too much trouble with raw mode on the standard Linux console, and ncurses appears to have fixed that problem nicely.
I have just committed a new pointer.vhdl file, which contains both VHDL and native methods for reading and writing 32- and 64-bit native pointers, as well as the necessary VHDL types to go with them. These will be needed for bus access when it comes time to make Controlix boot on bare-metal hardware....
Due to the need for non-blocking reading of characters from stdio (so the main loop in controlix.vhdl which precesses the master system clock can run at maximum speed), I have created a non-blocking getchar() and a native-code kbhit() function to go with it. This stuff has been used in a new non-blocking gets(), and the code in shell.vhdl has in turn been made polled and the polling update called from the main loop in controlix.vhdl.... read more
My first shell command |->. Now I need to make some more commands....
It turns out that there was no GHDL empty-string bug - null-length strings are not legal in VHDL! I can't comment on why the VHDL creators implemented something this bizarre, (it may be a holdover from ADA, which VHDL came from) but I have decided to work around it for now by terminating all strings with an ASCII 25(decimal) character, which specifies "end of medium" and isn't commonly used anymore. Wierd, but it seems to be working - I have converted the strlib_* routines as well as libc_gets() to use the new marker and it looks like it is OK now.... read more
More new stuff:
shell.vhdl parameter tokenization is lot more generic and flexible now. Still some bugs, and needs breaking out into its own parseargs-style module.
More new string-handling routines, strcpy() and strtok() specifically.
All strings are explicitly null-terminated now, to work around the limits of the VHDL string type.
Moved the lib/libc/ directory contents back up to lib/. The reason for this is that subdirs should only contain sub-interface implementations ("targets"), not the top-level target-using wrapper code. lib/printk/ will need to be reorganized similarly eventually.... read more
There is a lot of new code that has been committed over the last couple of days:
A good way to work with a Controlix system control remotely would be a "control board", mimicking an industrial process control console and consisting of the following features:
In a VHDL-based mixed hardware/software system such as Controlix, it is necessary to get used to the idea that the software side, even when running on top of a software emulation layer such as POSIX, must also run synchronously using an external clock provided by either software such as GTKWave, a simple POSIX timer daemon of some sort, or a hardware-provided pulse from a custom device driver or bare interrupt handler/distributor. Device drivers will need to run using polling mode or an emulated equivalent which uses some sort of I/O buffer FIFO - my current thinking is that Controlix itself will not expose interrupt or any other sort of async notification abstraction.... read more
In VHDL coding, it is normal to use a library of VHDL modules which are abstractly linked together - the VHPIDIRECT external calling interface is supposed to be used only as a bridge to native code. I was using VHPIDIRECT for everything |-/. That should now be fixed - all of the VHDL module linking is now properly done using the compiler.
There is still VHPIDIRECT external calling in the libc wrapper interface modules, and much more of that will still be needed as the amount of native code grows over time. Now, however, the VHDL code itself should in principle be synthesizable using tools like Altera's Quartus or Xilinx's ISE....