Giter Site home page Giter Site logo

steffenreith / j1sc Goto Github PK

View Code? Open in Web Editor NEW
77.0 12.0 7.0 18.59 MB

A reimplementation of a tiny stack CPU

License: BSD 3-Clause "New" or "Revised" License

VHDL 8.01% Makefile 0.06% Forth 27.59% Scala 36.71% Shell 0.65% Python 12.56% Verilog 5.54% Pascal 0.07% Tcl 0.94% C 7.87% PureBasic 0.01%
fpga spinalhdl forth cpu vhdl verilog hdl j1-cpu

j1sc's Introduction

J1Sc - A simple reimplementation of the J1 CPU in Scala using Spinal HDL

How to build J1Sc and Swapforth

To build the J1Sc, you need first to create the VDHL / Verilog sources. The implementation is written by using Spinal HDL (https://github.com/SpinalHDL/SpinalHDL). Hence these sources are generated by a Scala program (Spinal HDL is a compelling Scala library that can be used to generate VHDL and Verilog code.

  • Install OpenJDK 8

  • Install a running Scala system and sbt

  • Clone the latest version of Spinal HDL (at least version 1.4.1) (see https://github.com/SpinalHDL/SpinalHDL)

  • Setup Spinal HDL (see http://spinalhdl.github.io/SpinalDoc/spinal_getting_started/)

  • Install gforth (e.g. sudo apt-get install gforth)

  • Change directory to the new clone of SpinalHDL and run sbt publish-local inside

  • Clone J1Sc (use git clone --recurse-submodules https://github.com/SteffenReith/J1Sc.git)

  • Change directory to J1Sc

  • Run cd toolchain/forth && make && cd ../.. to build the forth core system

  • Build, load and install the tty0tty kernel module

A FORTH Shell/Terminal for J1Sc

Manfred Mahlow offers an excellent terminal for embedded FORTH systems, which supports linux on x86 and Raspberry/Raspbian. Besides 430CamelForth , 430eForth , 4e4th, AmForth, anyForth , Mecrisp , Mecrisp-Stellaris , noForth and STM8 eForth it also supports the J1Sc with Swapforth now (thank you Manfred!). This solution gives a much higher comfort than the original Python-based terminals from Swapforth. Hence, it is (strongly) suggested to use e4thcom instead the provided python-scripts. The python scripts are not very comfortable (you have been warned!) and reconnecting to your J1Sc doesn't work (at least for me).

Download the latest e4thcom (https://wiki.forth-ev.de/doku.php/en:projects:e4thcom) and install it according to the documentation (copy it to the installation directory) the e4thcom-plugin swapforth-j1sc.efc from support/e4thcom/. Version 0.8.2 works out of the box, because it has the swapforth-plugin in the distribution. Therefore, you don't have to copy swapforth-j1sc.efc!

Start enjoying e4thcom by the following command-line by e4thcom -d ttyUSB1 -b B115200 -t swapforth-j1sc. In case anything does not work, please check for the correct transmission rate (B115200 for the Nexys4 and B38400 for the simulation) and the serial device (e.g. /dev/tnt0 for the simulation). Make sure that the PATH-variable is set correctly and your J1Sc instance is connected to /dev/ttyUSB1 or modify the command-line accordingly to your situation.

The descriptions below show how to work with J1Sc without e4thcom. I give you advise not to do so because the shell scripts bin/confsX are unflexible and uncomfortable. Be warned!

Supported prototyping boards

J1Sc for a Digilent Nexys4 and Nexys4DDR board

  • We will build the J1Sc variant J1Nexys4X (either using the VHDL or the Verilog version) by sbt run (select the Nexys4X configuration to be generated). The generated files can be found in gen/src/vhdl/J1Nexys4X.vhd and gen/src/verilog/J1Nexys4X.v. You need Board_<BOARDNAME>.vhd and PLL.vhd in src/main/vhdl/arch or the corresponding Verilog versions in src/main/verilog/arch as toplevel for synthesis. A Xilinx Vivado project file J1Sc.xpr for the VHDL version can be found in vprj/vhdl/J1Sc and the Verilog version is in vprj/verilog/J1Sc. Note that J1Sc runs fine with a 100Mhz clock on a Nexys4 DDR from Digilent. Constraint files for the Nexys4 DDR can be found in /src/main/xilinx/nexys4ddr the corresponding files for the Nexys4 can be found in /src/main/xilinx/nexys4.

  • Next build J1Nexys4X (see gen/src/vhdl or gen/src/verilog) which is the J1Sc variant used fo Neys4X boards. Send the .bit file to your FPGA/board (use either src/main/vhdl/arch/Nexys4DDR/BoardNexys4DDR.vhd or src/main/verilog/arch/Nexys4DDR/BoardNexys4DDR.v as toplevel module)

  • cd toolchain/forth

  • Become root or set the permissions of your serial devices properly and run bin/confsX, where X is the number of the used serial port. Hence X is 0 if /dev/ttyUSB0 should be used.

  • Press the reset button (default is the "CPU reset" button on the Nexys4 DDR). You should see something like: Contacting... established Loaded 142 words

  • Type #include swapforth.fs to load the complete FORTH system

  • Turn the leds on by $ffff leds!

  • Use the first RBG led by 5 10 10 rgbled!

  • Have fun with a working FORTH system

J1Sc for the icoBoard

At the moment only one hardware configuration is supported

  • icoBoard Version 1.1
  • icoUSBaseboard: FTDI Interfacebasis (first FTDI interface for programming the FPGA)
  • Pmod USBUART (second FTDI interface for serial connection)
  • Pmod 8LD (simply eight leds)

Attach the icoUSBBaseBoard to the icoBoard and connect the Pmods as shown here. Hence use PMod P1 for the leds and the upper row (!) of PMod P3 for the UART.

Clone and install the latest version of

Now change to the cloned directory of J1Sc

  • Build J1Ico by using the sbt build system. Type sbt icoProg to generate a Verilog version of J1Sc for your IcoBoard, synthesize it, do a place & route and to download the bit-file finally.

  • Become root or set the permissions of your serial devices properly and run bin/confsX, where X is the number of the used serial port. Hence X is 0 if /dev/ttyUSB0 should be used.

  • Press the reset button (the button S1 near the PMod P2 is used by default). You should see something like: Contacting... established Loaded 142 words

  • Type #include swapforth.fs to load the complete FORTH system

  • Turn the leds on by $ff leds!

  • Have fun with a running FORTH system on your icoBoard!

At the moment, the tools can provide an implementation that is able to run at 40 MHz. This constraint will be checked during the sbt build. Hence stay tuned and read the log-files.

In principle, it is possible to use the IcoBoard together with a Raspberry PI to run J1Sc. In the case you do this, please send me (EMail: [email protected]) the needed steps, because I don´t have/use this configuration.

IcoBoard

J1Sc for the iCEBoard

J1Sc has some preliminary support for the iCEBreaker FPGA board (see https://github.com/icebreaker-fpga). At the moment the UART, buttons, and LEDs can be used but it has not corresponded forth words for easily using them.

Clone and install the latest version of

Now change to the cloned directory of J1Sc and connect your board by USB

  • Build J1Ice by using the sbt build system. Type sbt iceProg to generate a Verilog version of J1Sc for your iCEBreaker board, synthesize it, do a place & route and to download the bit-file finally.

  • Become root or set the permissions of your serial devices properly and run bin/confsX, where X is the number of the used serial port. Hence X is 0 if /dev/ttyUSB0 should be used.

  • Press the reset button (the button S1 near the PMod P2 is used by default). You should see something like: Contacting... established Loaded 142 words

  • Type #include swapforth.fs to load the complete FORTH system

  • Have fun with a running FORTH system on your iCEBoard!

At the moment, the tools can provide an implementation that can run at 18 MHz. This constraint will be checked during the sbt build. Hence stay tuned and read the log-files.

A Gatelevel simulation of J1Sc

The latest versions for SpinalHDL (you need at least version 1.1.2) offer a complete gate-level simulation of the generated designs. In the background, SpinalHDL uses Verilator as a simulation framework and hide all the C++ stuff by another Scala library called SpinalSim. Moreover, to connect the simulation to the host, a virtual null-modem cable is used. Hence

  • Clone and install the latest version of Verilator from http://git.veripool.org/git/verilator

  • Clone and install the latest version of tty0tty from https://github.com/SteffenReith/tty0tty.git. Load the kernel module by insmod tty0tty.ko. To make the installation permanent, install the kernel module according to your distribution (for Ubuntu 16.04.3 LTS cp tty0tty.ko /lib/modules/`uname -r`/kernel/drivers/misc and depmod -a). Alternatively you can update the tty0tty submodule by git submodule update --init --recursive. You can install the kernel-module by running scripts/installTTY. You have to set the permission of /dev/tnt0 and /dev/tnt1 such that they are user read- and writeable. You can set the permissions of ´/dev/tnt0´ and ´/dev/tnt1´ by udev after every reboot automatically. For this see the udev-rule 55-tty-tnt.rules in the directory doc/udev, modify it to your needs (e.g. the dialout group) and copy it e.g. to /etc/udev/rules.d.

  • Go to your cloned J1Sc copy and type cd toolchain/forth

  • start a terminal by bin/confhost

  • open another shell window go to your copy of J1Sc and type sbt test:run to compile and run the simulation. If everything went well a small gui with some LEDs and a reset button will occur (maybe you have to resize the window).

  • Press the reset button. You should see something like: Contacting... established Loaded 142 words in your terminal window.

  • Type #include swapforth.fs to load the complete FORTH system

  • Turn the simulated LEDs on by $ff leds!

  • Have fun with a running FORTH on the simulated J1Sc!

Preliminary JTAG support

J1Sc offeres a simple and very restricted JTAG support at a very early stage. At the moment you can reset, stop and continue the CPU by corresponding JTAG-commands. Moreover, you can upload a memory-dump to the internal RAM. The corresponding scripts can be found in support/openocd/bin. All variants of J1Sc (including the gate-level simulation!) support this JTAG interface. Note that you need a special variant of OpenOCD for this. So clone and build

For the physical connection, I use a simple FT232H board from adafruit as shown below (I found it accidentally in my grab bag). Remember any similar FT232H adapter should work (please send email if you use another adapter) too.

JTAG Adapter

In support/openocd/bin you will find some primitive OpenOCD scripts for programming, resetting, resuming and stalling your J1Sc:

progJ1, resetJ1, resumeJ1 and stallJ1

For the gatelevel simulation of J1Sc use

progJ1Sim, resetJ1Sim, resumeJ1Sim and stallJ1Sim

Wiring a JTAG-adapter to a Nexys4DDR

JTAG signal FT232H pin Constraint PMod
TCK D0 H16 JB10
TDI D1 G13 JB9
TDO D2 F13 JB8
TMS D3 E16 JB1

Nexys4DDRJtag

The JTAG-implementation is at a very early state. Hence, I suggest that you don't rely on a correct function! This will be fixed in the future. Note that the JTAG-support is tested on a Nexys4DDR (and the simulation) only, but in principle, it should work for the IcoBoard and the iCEBreaker too! In the case that you use the JTAG on the IcoBoard or the Icebreaker: Please send an email and the needed patches!

j1sc's People

Contributors

steffenreith 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

Watchers

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

j1sc's Issues

Introduction

First thank you for creating this repository.

I plan on using this to generate many core Forth processors.
You can read more about my plans here.
https://forth.pythonlinks.info

Probably initially as an audio synthesizer. There are a bunch of us interested in audio synthesis on the pico-ice discord server.

You may have seen my SVFIG talk on "A review of Forth Soft Core Processors"

https://www.youtube.com/watch?v=qgmrZoJyHUw

More recently I did the same talk at the Stockholm FPGA conference. Here are the updated slides.
https://pythonlinks.info/presentations/StockholmConference.pdf

It turns out that the Mecrisp Forth interpreter is 200 times smaller than the Python interpreter. Wow.

I recently bought the Pico-Ice and the Upduino FPGA boards. I released an echo server for the Pico-Ice.
https://forth.pythonlinks.info/pico-ice-echo-server

Then I got Mecrisp Forth running on the Pico-Ice. But it took up
way too many resources.
ICESTORM_LC: 2604/ 5280 49%

Hard to buld a many core, when half the luts are already used.

But there is a more important reason to switch to this software stack. If you look at the Mecrisp source code, it support some 12 boards, and 28 different options in the verilog files. Really hard to mange that complexity in pure Verilog. Much better to do it in a high level language.

I took a look at MyHDL, did not like it. They generate the code, but throw out hierarchy information at simulation time, making debugging harder. Amaranth did not resonate with me either. I took one look at SpinalHDL, and everything looks very reasonable, even fantastic. I can refer to something in another branch of the hierarchy without having to manage wires up and down the stack. Awesome.

Not only I think so. The VexRiscV which won the first prize at the RISC-V Summit softCore contest, was also written in SpinalHDL

https://tomverbeure.github.io/rtl/2018/12/06/The-VexRiscV-CPU-A-New-Way-To-Design.html

Also I think it is much better to start with a tiny core, and only add in the stuff that I need.

As for issues, I wish that there were a newer release of this software, and I wish that more Electrical Engineers were aware of the advantages of high level languages, and were using this software, instead of sticking to Verilog and VHDL. Oh well.

Wish me luck.

Bump Java, and Scala versions.

I tried installing JDK 8, but could not find it on the web. They redirect to JDK version 21. So I installed that. I hope it all works.

A simple starting Point

So I flashed a blinky onto my pico-ice board using SpinalHDL and apio. Hurrah. Now I am trying to synthesize the J1SC for the Pico-Ice board. Oh boy, it is quite tricky. There is a lot of stuff in there.

What Mecrisp did is to creae a directory skeletalstructure which just had the core parts in it. It was easy to get it up and running, and then one could add things back in one at a time.

Your code has LED arrays, button arrays, a uart led, a pwm led, interrupts, bridges, a clock lock, and who knows what else.

It takes a while to read all of the code, figure out what they all do, and figure out how to turn them off.

The problem is that it is lots of changes, and then at the end of the day, when everything is not working, I will not know what I broke. The ideal is to make it easy to get the first version working on an FPGA.

As a software developer, I would always make lots of changes and then debug it. As an FPGA developer, they repeatedly instruct us to make one change at a time, get it to work, and then make the next change.

I am not asking that you do anything, I am just recording what might make life easier for those who follow in my footsteps.

Documenting the Files

There are many files in J1Sc/src/main/scala defining the circuit. This documentation is an overview of what those files do. For simplicity I deleted the .scala from the file names.

J1: This is the highest level of the J1, defining interfaces to the outside.
J1Core: Defines signals towards the inner part of the J1.

INNER WORLD

J1Stack: Basic stack definitions and logic.

J1RStack: Return stack definition and logic, all in one place.

J1DStack: Data stack definition and logic.

J1Decoder: Decides the instruction. Just decides if it is a literal, call, jump,
conditional jump or instruction.

MainMemory: Defines the main memory assuming multiple smaller blocks (???)

J1PC: Program counter

Timer: Sets alarms

J1Alu: Does the basic operations (Words).

J1Bus: I think that there are multiple busses, but I am not yet sure. One for the LEDs, one for the GPIO, PWM, LEDs, and SSD.
J1BusSlaveFactory:

OUTER WORLD

DBPinArray: debounced Pin array. Input Pins, Debounced Pins, a timer, and some kind of bus.

GPIO: Define the GPIOs. Assumes that we are using PMODs.

LEDArray: A register of LED values which you can read and write to. Why does in mention PWM?

InterruptCtrl: Defines the interrupts. I did not fully understand this part.

PWM: Pulse Width Modulation is for control of motors. The width has to be a power of 2.

SSD: For driving a Solid State Drive.

JTAG FOR SINGLE STEP DEBUGGING

J1Jtag:
J1JtagData:
SingleStepUnit:

Board Definitions

Here is where you customize things.

J1Config: Configure IRQ, JTAG. Timer, Instruction set and the J1 itself. Includes instruction set tests.
CoreConfig.: Configure UART, LEDs, PWM, and GPIO for various boards.

*J1Ice.**: Define a J1 for the Ice Board. J1Ico Define a J1 for the Ico board.

J1Nexys4X: Define a J1 for the Nexys4X board.

If you like this I can create a pull request.

Simulation on M1 Mac

@SteffenReith, you said that you are developing the devel branch on the Mac M1. Which means that you have the simulator running on the M1 Mac.

I did not find any instructions on how to do that. It just said load some drivers for Linux.

So how do I get the simulation working on the M1 Mac?

In my news, I did manage to create a much simplified PicoIce.scala board using the devel branch. It compiles but does not run. But I am getting more familiar with all of these libraries.

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.