Show HN: A 16-bit Forth machine written in VHDL
github.com
github.com
It makes your port maps super simple (and can change them by editing just one file) and each entity consists of just two processes: one to update the entity's state on clock and the other to generate the combinatorial logic using procedural, not dataflow, programming. When you use procedural, you can step through it with a debugger just like with SW! Makes debugging much easier. Also, using records for the port maps makes the ModelSim waveform viewer much easier to use.
You can see an example of it in a MIPS subset I wrote. [1] Any file with a _r.vhd or _p.vhd suffix is written in the two process style. I'd suggest looking at the ALU and I-cache, they are probably the simplest and cleanest entities.
I like your use of numeric_std. =) I'm surprised by how few times I've seen it used.
[0]: http://www.gaisler.com/doc/vhdl2proc.pdf
[1]:https://github.com/jevinskie/mips--/tree/master/project4/sou...
Everything I've read these days says to use numeric_std (I've read the reasons why, and it makes sense), so I just never even bothered using the std_logic_*signed libraries. I'll check out your MIPS project; I'm intending my next project to be a fully pipelined RISC machine :-)
I ask because this seems like one avenue to create a full stack open source/hardware machine whose security can be vetted by the community. I wonder if by 2020 we might be running your core on handsets.
On a related note, I wish I could run a USB stick that runs a ROM-BIOS burned into an FPGA stick. Is that possible today?
But if it is possible to obfuscate a program, I think it should be possible to create something on an FPGA that is secure and private.
Maybe you have any links with a good further reading on that topic?
Well, in theory it must not, because it could detect "oh, this looks exactly like one of popular Ethernet cores, so I'll bug onto those pins and have networking", but this seems like a hard task. Or, well, it could be that every pin is hooked and a secret block awaits a specifically crafted code (somehow like port knocking), but I'm not sure this is a feasible approach.
[1] http://www.latticesemi.com/en/Products/DevelopmentBoardsAndK... [2] http://www.altera.com/b/nios-bemicro-evaluation-kit.html
Honestly, I wrote this just to scratch an itch. I've always loved the elegance of Forth, and having stumbled upon (http://users.ece.cmu.edu/~koopman/stack_computers/index.html) that, I decided to create my own, with the goal of having single-cycle execution of all non-control-flow operations. Having said that, one could easily take it, and probably fairly quickly implement the Forth interpreter and use it in a classroom if they desired. I guess the explicit goal was an embedded node, but it's fairly flexible.
The softcore is pretty small, takes up roughly a tenth of a small cheap (by fpga standards) dev board. There are bigger, and smaller, soft cores.
To compare, you could be running benchmarks on about ten simultaneous systems vs one FPGA if you insist on "one chip" vs "one chip" comparisons so obviously the fpga is ten times faster than it appears. The advantage a FPGA provides is really smart custom peripherals. So if for whatever reason you need to do lots of floating point divides in your app, or perhaps in your benchmark, you stick 100 hardware FP dividers on the chip and suddenly your division benchmark absolutely smokes the ARM which I believe has only one hardware FP division unit (or was it two?)
-- arithmetic
alu_results.add_result <= std_logic_vector( signed( nos ) + signed( tos ) );
alu_results.sub_result <= std_logic_vector( signed( nos ) - signed( tos ) );
This logic can be done with one adder instead of two. In two's complement, invert the 2nd operand and assert the carry in.