Tuesday, December 10, 2019

2019 : A year of RISC-V and Open source silicon

Note: This article was originally posted on LinkedIn in December 2019 and was later posted on this blog with a backdated publishing date

I will unfortunately not make it to the RISC-V summit this year, but since everyone will be talking about RISC-V this coming week I thought it would be a good opportunity to highlight some of the work I have done this year within RISC-V and FOSSi (Free and open source silicon) in general. And you are more than welcome to contact me if you are interested in knowing more about any of this work or other things related to RISC-V, FOSSi or Qamcom

SweRVolf

Western Digital made a big splash last year when they announced the release of the open source RISC-V CPU SweRV EH1, currently the fastest 32-bit RISC-V CPU available. Together with Western Digital I have created SwerRVolf, an open source portable and extendible SoC using the SweRV EH1. The intention with this SoC is to allow users interested in SweRV to quickly get started running software or building their own customized SoC using SweRV. The whole project is open source and can be run in a simulator or on supported FPGA targets. On the software side it can be used to run Zephyr OS and has debugging support. The code is available at https://github.com/chipsalliance/Cores-SweRVolf More features will come in 2020 so make sure to check in regularily. The project has also been featured in presentations at the inagural CHIPS Alliance workshop as well as the CHIPS Alliance tools November workshop in Munich. During the latter there was also a tutorial aimed to get people started using the SoC. This workshop is also freely available and I'm happy to do variations on this within your company if you want to get started with a RISC-V SoC.

SERV

In case you're not aware, I have created SERV, likely the world's smallest RISC-V CPU and still cabable of running Zephyr OS. SERV was originally created for the 2018 RISC-V SoftCPU contest, but I have kept working on the core during 2019. In April I submitted a presentation for the RISC-V workshop in Zürich called "Bit by bit - how to fit 8 RISC-V cores on a $38 FPGA board". When there was time to do the actual presentation I had to update the title since further optimizations had allowed me to fit 16 cores on the same board. Work continued after that and in November I was able to fit 53 RISC-V cores on a $30 FPGA board. The SERV CPU is of course open source and available here https://github.com/olofk/serv If you want to learn how to build SERV into your designs and why you should do it, just reach out and I'll get you up to speed.

FuseSoC

FuseSoC is a package manager for IP cores. It is created to manage and describe collections of open source and proprietary cores so that they can be put together to make a SoC. FuseSoC has been around for eight years now, but the past year has seen a lot of improvements and a massive growth of available IP cores (over 500 cores!) to use with FuseSoC. This year it has also been adopted by some major Open source silicon projects such as the manycore OpenPiton project from from Princeton and OpenTitan, the industry collaboration project to create a fully open source Root of Trust device. Even though there are a large number of RISC-V based projects using FuseSoC it is used in many places as well, most notably this year is perhaps the open source POWER implementation called MicroWatt released this summer. If you want help with packaging your RISC-V core to be available for FuseSoC users or if you want to use FuseSoC within your company to manage your IP cores, just let me know. FuseSoC can be found here https://github.com/olofk/fusesoc

Edalize

Closely related to FuseSoC is Edalize, which originally was part of FuseSoC but now a project of its own. Edalize is a build tool abstraction which provides a common interface to the supported EDA tools. It can be used to e.g. target different simulators with a flick of a switch or easily run the same design on FPGA and simulation targets. This year has seen many improvements and support for three new tool flows, which brings up the number of supported tools to 17. Most of this work has been done by contributors, which is a great indicator that it is actively used by many people. See more here https://github.com/olofk/edalize If you're a user or a tool vendor and feel that your favorite tool is missing, just let me know and we can discuss how to add it.

Observer

By combining the flexibility of FuseSoC with the resource efficiency of SERV I created a project called Observer. Observer is a software-programmable sensor aggregation platform for heterogenous sensors, combining the best of HW and SW in an FPGA. It is built on the idea that FPGAs are excellent for communicating with various types of external devices, but many types of data processing are best done in software. By pairing a SERV CPU to each sensor it is possible to combine the speed of RTL with the flexibility of software to easily build a sensor fusion system. The project is still in early stages, but works on a supported FPGA platform already and as a proof of concept it has been shown possible to collect data from over 50 different sensors simultaneously, each with their dedicated RISC-V CPU to handle data. Code can be found here https://github.com/olofk/observer If you want to customize Observer for your particular use case I'm happy to talk more.

Qamcom joins RISC-V Foundation

This year Qamcom joined the RISC-V Foundation. As our first exercise upon joing the foundation, we teamed up with RISC-V veterans SiFive to host the SiFive Tech Symposium in Stockholm in May. At this event we highlighted how we see that RISC-V can benefit many of the areas where we provide expert knowledge, such as AI, automotive, RADAR and 5G. If you are interested in what services Qamcom can provide within these areas and other, feel free to contact me or any of my colleagues or read more about us on https://www.qamcom.se/

Qamcom joins CHIPS Alliance

RISC-V is getting a lot of attention, but an open source ISA is just one of the many challenges we are facing when it comes to innovating chip design. We see an increasing need for custom silicon for many of our clients and partners and there are many keys to unlock to achieve this. CHIPS Alliance is an important consortium with a combination of small and large forward-thinking companies that aims to make open source silicon viable by collaborating on common cores, tools and infrastructure. If you want to be part of the CHIPS Alliance to accelerate chip design, go to https://chipsalliance.org/ to learn more.

Qamcom joins Mentor OpenDoor

Mentor, a Siemens business, has a partner program called OpenDoor. Both Mentor and Qamcom sees the importance of high quality verification of open source silicon and by joining this program, we will ensure that the work we do within open source silicon has first-class support for Mentor's EDA tools to allow new and existing users of these tools to quickly get started using open source IP cores in their products.

FOSSi Foundation

In 2015 I co-founded the FOSSi Foundation with a mission to promote and assist open source silicon in the industry, academia and for hobbyists. FOSSi Foundation consists of many people who work across all levels to acheive these goals but my personal involvement this year has mostly focused on creating events to bring people from industry, academia and hobbyists together under a single roof to exchange experiences. As usual we had ORConf in Europe but we also teamed up with the RISC-V Foundation to create the Week of Open Source Hardware (WOSH) in Zürich conjoined with the RISC-V workshop there. During the event I presented SERV, a poster of FuseSoC and won an award for FuseSoC given by Eurolab4HPC. This was also the year when we did our first conference on US soil. In May we held a new event called Latch-Up in Portland, Oregeon which was a great sucesss. We are already planning for three events next year as well. First up is FOSSiStanbul in Istanbul, Turkey, followed by a new Latch-Up in Cambridge, MA and the usual ORConf some time in the fall. Check out https://fossi-foundation.org/events to see where you should book your tickets.

Apart from events I was also mentor for Google Summer of Code for the fourth year in a row. This year I co-mentored Nancy Chauhan who worked with FOSSi Foundation and did a fantastic job to improve our CI platform at ci.librecores.org

Other stuff

I have had a long and troubling relationship with IP-XACT, as can be seen in my most cited article  . I still stand by my point that we need some sort of standard for describing many of the aspects of IP cores that FuseSoC doesn't care about such as register maps and how to connect cores to each other. I haven't done much work in this area for a long time, but a presentation at Latch-Up by Aliaksei Chapyzhenka on a project called DuH prompted me to resume my efforts and I have now started working on combined IP-XACT/Duh tooling that I hope will be of interest. It's of course open source as well, but I haven't cleaned up enough to release it yet :) If you are an IP-XACT user or interested in tooling in this area, please let me know.

Wow! This turned out far longer than I expected. Seem I did a lot of stuff around RISC-V and Open source silicon in 2019. Let's see what the next decade will bring

Catch up at Latch-Up!

 

 

 

 

 

Tuesday, June 26, 2018

FuseSoC 1.8.2

FuseSoC 1.9 will have an impact so great that people will divide history into the eras before and after it's release. But before that happens, it's time for a less earth-shattering minor release. Allow me to introduce FuseSoC 1.8.2

Backend separation

The biggest feature is also the least visible for most users. A lot of time since the last release was spent on moving stuff around with the ultimate goal of splitting out the backends (the part that create project files and launches EDA tools) to a separate library. This is now complete and the former backend code now lives in a separate library called edalize, which remains part of FuseSoC for now, but will be moved out at some point. The ideas behind this will be a topic for a separate article at some point, but if you're building some Python tool that wants to use the EDA tool wrappers, look for edalize now.

Linter backends

FuseSoC.. sorry, Edalize has gained a new backend for Synopsys SpyGlass which is a powerful linter tool. For a less costly linter, it is now possible also to use the linter mode of Verilator by setting mode to lint-only in the verilator section of the tool options in a target like this

targets:
  lint:
    tools:
      verilator:
        mode: lint-only

CAPI2 changes

The latest core description format has had some minor improvements. The top-level option was originally specified as a list of modules. since there are cases when several top-modules are needed. This however is quite rare, which makes it confusing that it's just a list of one item in most cases. Therefore it can now also be specified as a string. Small improvement, but makes things less annoying. Environment variables are also expanded in file names.

Other changes

Sometimes you really want to ignore a core that's part of a library. By adding a file called FUSESOC_IGNORE to a directory, FuseSoC will ignore that directory and everything below it. There is also a series of tutorials in the works. These are very rough drafts at this point, but I encourage everyone who wants to get started with FuseSoC to take a look through them anyway. They are located here

That's pretty much it. As usual, a number of bugs were fixed but nothing worth taking up more of your precious time. Thank you for reading. See you again in the post FuseSoC 1.9 era

Thursday, March 22, 2018

FuseSoC 1.8.1

With great features come great bugs. FuseSoC 1.8 had a lot of new functionality but it also has some shortcomings. Some of it was intentional. For both the library support and CAPI2 I wanted to push out an early version with the most important functionality, test the waters and add the missing pieces later. (Un)fortunately both these features turned out to be really really good and I came to depend on them immediately. This made it more important to make sure they were useful as I don't want to use the old ways anymore. After some post-release patching I'd say things are in much better shape, so it made sense to do a new release with these things fixed. Therefore I present FuseSoC 1.8.1. It's like 1.8, just a little better.

What's changed then?

Library fixes

The library sections in fusesoc.conf has gained a sync-type flag. This allows users to explictly set what mechanism to use for synchronizing libraries against a remote source (e.g. updating). The only two current values are git, which does a git pull of the library when running fusesoc update, and local, which won't try to synchronize at all. The library sync-type options share code with the core providers, so it should be easy to add other synchronization mechanisms (e.g. rsync, webdav, mercurial) when needed. When adding a new library there is also now a --global flag. If this is present, the library will be added to the user-global fusesoc.conf in $XDG_CONFIG_HOME/fusesoc. Otherwise, a fusesoc.conf in the current workspace directory will be used.

CAPI2 fixes

CAPI2 debuted with support for just a few tools. This was a trade-off to be able to do a quick release. Of course, it soon became apparent that the other tools were needed as well. One other thing that bothered me with CAPI2 was that the tools sections were a hard-coded list in the core class. So to fix both these things at the same  time I did some refactoring and let the backends themselves declare which options they use. FuseSoC will then search for available backends at run time and pick up their available tool options. Voilà, all tools are now supported in CAPI2. This also opens up for more easily adding new tool backends without having to change anything else in the code base.

There are more things missing in CAPI2, but the one that I realized was needed most was the equivalent of the scripts section in CAPI1. I took the opportunity to rearrange things slightly so that I could make this more powerful than in CAPI1. Instead of a list of shell scripts to run, it is now possible to launch arbitrary commands and associate extra files to be exported to the work root and environment variables to be set.

Other fixes

Other noteworthy things that are added to FuseSoC 1.8.1 is a bash completion script that was contributed almost four years ago but never merged. This was polished up by another contributor and is now available in the extras directory of the FuseSoC repo. It is not installed by default, but has to be copied into the appropriate directory (e.g. /etc/bash_completion.d on my system).

Finally, FuseSoC no longer writes a fusesoc.log by default. Writing this logfile on every run has annoyed me for almost six years now, but I never got around to fix it. Thankfully there are other contributors who get things done.

And that's all. Hope you like it!

Monday, February 5, 2018

FuseSoC 1.8

Too tired to write something clever here. Just get it over with. Stuff has changed. Here's what's new

CAPI2

The main feature of FuseSoC 1.8 is the support for a new core description format, CAPI2, to replace the old CAPI1 format. The need for a new format to solve support some use cases has been apparent for a while. Doing some archaeology I found a commit from March 2, 2013 that mentions the next generation format, and yes, after careful evalutation of a few different formats it ended up being based on YAML. Oh well, things take time and there have been other priorities. At least it's here now, or rather, a first experimental version. The CAPI2 support in FuseSoC 1.8 still has many missing features, like documentation and support for IP-XACT and all tools to name a few. There might also be non-compatible changes ahead, but I want to push it out now together with some CAPI2 cores to reach a wider audience.

So what's so good about CAPI2? I'm hoping to find the time to write a separate article with more details some time in the future, but I have written down some of the benefits.

New tool flows

Support for other tool types than simulators and synthesis tools. This includes things like formal verification tools and linters. For linting, I have already made a quick PoC using Verilator in lint mode and there is a Spyglass backend in the works. On the formal verification side, I will start to look into what's need to add support for Yosys-SMTBMC  

Multiple targets

With the support for new flows for a design there is also a need to decide which flow to use. For this, CAPI2 supports multiple targets in a single core file. There are many uses for different targets. A design might have several testbenches that exercises different parts of the design.  These can be specified as different targets using different source files, run time parameters, tool options etc. Some designs have support for targeting multiple FPGA boards. These can also be described as separate targets, with the benefit that they can share all the common parts while freely add target-specific files and options. Targets for linting or formal verification can be separate targets as well.

Conditional expressions

CAPI2 contains a minimal expression parser inspired by the Gentoo ebuild format. An expression can look something like this


flag? (use_if_flag_is_true)
!flag? (use_if_flag_is_false)

This allows including or excluding features depending on which tool is being used or whether the core is at the root of the dependency hierarchy or being used as a dependency for another core. Examples of this can be to enable technology-specific RTL primitives for certain tools, switch between VPI or DPI extensions depending on tool support or use a C++ testbench for verilator while other simulators use a non-synthesisable verilog version. At the time of writing, these flags are defined internally in FuseSoC depending on current tool, target and some other parameters, but it will be possible in the near future for users to define their own flags and set them in the top-level core file or on the command-line.

 Core libraries

FuseSoC already has the ability to define directory paths which contain core files, either by specifying them with the cores_root option in fusesoc.conf, on the command-line with --cores-root= or through the FUSESOC_CORES environment variable. This is all good, but a bit limited. With FuseSoC 1.8 comes support for core libraries. Each library is specified in fusesoc.conf as a separate section. An equivalent of an old config file looking like this


[main]
cores_root = /home/user/.local/share/fusesoc/orpsoc-cores /home/user/cores/fusesoc-cores


will now look like this


[library.orpsoc-cores]

[library.fusesoc-cores]
location = /home/user/cores/fusesoc-cores

So far there isn't much of an improvement over the old style. One thing to notice is that if the location option is missing, it will default to $XDG_DATA_HOME/fusesoc/<library name>

Having separate sections however also allow us to do the following


[library.orpsoc-cores]
sync-uri = https://github.com/openrisc/orpsoc-cores

[library.fusesoc-cores]
location = /home/user/cores/fusesoc-cores
sync-uri = https://github.com/fusesoc/fusesoc-cores
auto-sync = false

sync-uri lets us to specify the remote source of a library. The initial supported remote location are git repositories, but other source such as mercurial, rsync, webdav etc will be support with a sync-type option in the future. The auto-sync option, which defaults to true, controls if the library shall be updated when running fusesoc update.The update command can also take a list of libraries as extra argument to selectively update libraries.

To support library management from the command-line, FuseSoC has now gained a new library subcommand. The only supported library command is currently add, to register a new library, but additional commands for listing and removing libraries will be added in time. To add a remote library, the following commands can be used


fusesoc add library enigma https://github.com/mmicko/enigmaFPGA

The resulting fusesoc.conf will look like this


[library.orpsoc-cores]
sync-uri = https://github.com/openrisc/orpsoc-cores

[library.fusesoc-cores]
location = /home/user/cores/fusesoc-cores
sync-uri = https://github.com/fusesoc/fusesoc-cores
auto-sync = false

[library.enigma]
sync-uri = https://github.com/mmicko/enigmaFPGA 


There are also optional arguments --location and --no-auto-sync to explicitly set the location and auto-sync = false

For adding a directory path as a library, the same command is used, but the sync-uri is treated as a location if FuseSoC detects that it's an existing directory


$ fusesoc library add more_cores ~/other_cores
INFO: Detecting /home/user/other_cores as a local library

will produce


[library.orpsoc-cores]
sync-uri = https://github.com/openrisc/orpsoc-cores

[library.fusesoc-cores]
location = /home/user/cores/fusesoc-cores
sync-uri = https://github.com/fusesoc/fusesoc-cores
auto-sync = false

[library.enigma]
sync-uri = https://github.com/mmicko/enigmaFPGA 

[library.more_cores]
location = /home/user/other_cores

There are more planned featues for core libraries, but this will have to do for today.

Backend features


Most of the tool backends have received fixes or new features. All tools now supports file type = user for passing arbitrary files to the build tree that might be neeeded by the tools. For Xilinx ISE, FuseSoC now supports BMM files as an allowed file type and quoting of verilog string parameters should now work. Isim will shut down properly after simulations, GHDL will receive its arguments in the correct order and XSim supports multiple top-levels. The IceStorm backend now supports verilog defines specified as command-line parameters, has gotten a yosys_synth_options parameters to set extra synthesis options and PCF constraint files are recognized as a file type

Other things

Other things worth mentioning are the new --no-export feature. Before an EDA tool is invoked, FuseSoC has always created a fresh build tree where it places all files and runs the EDA tools to avoid polluting the source directories with files and to not pick up unwanted files that might be lying around in the source trees. This also has the added benefit that the exported build tree is not dependent on FuseSoC and can be archived or sent to non-FuseSoC users if required. I have used that myself to make deliveries of projects to clients. There are however cases where this is not optimal, for example during debugging, when there is a need to make small changes to a file in the source tree without having to recreate the build tree every time. For such use-cases FuseSoC now supports a --no-export option that will reference the original source files instead of copying them to the build tree. For most cases, this should work just as fine, but beware that it might break in some situations, e.g. when multiple cores has an include file with the same name.

Another improvement related to coping files around is a new copyto attribute for files in filesets. It's used like this:


[fileset fs]
files = an/old/file.v[copyto=a/new/name.v]

or with CAPI2, like this

filesets:
  fs:
    files:
      - an/old/file.v: {copyto : a/new/name.v}

This will copy the file to a new location, relative to the work root of the EDA tool and reference this version in the EDA API file. This is quite useful in several situations, for example when a file is required to exist in the working directory. Previously this had to be done with a pre_build_script to copy the file, which also had the disadvantage of being platform-specific. It also makes it less awkward to reference files from the source directory in verilog parameters. For example the top-level of the de0_nano system in orpsoc-cores contain bootrom_file = "../src/de0_nano_0/sw/spi_uimage_loader.vh", which a) assumes source code tree is located in ../src and b) has to be updated on version bumps when the de0_nano_0 name will change. This can now be replaced with bootrom_file = spi_uimage_loader.vh and a copyto = spi_uimage_loader.vh in the .core file. Much better!
 
EDA API - the tool-agnostic file format which is used to pass all information needed by the backends such as the list of files to read and tool options - has seen some changes and will continue to do so in the future. For this reason, it has gained a version field so that external projects which want to read EDA API files will know what to expect in the file. Properly formalizing the EDA API is still a task at hand, but is getting more prioritized now as there are external projects interested in using this format so that they can reuse either the FuseSoC core files and dependency handler or the EDA tool wrappers. This means it's pretty rude to make arbitrary changes to the format without at least informing about it.

There are also some new commands and switches for the FuseSoC 1.8 release. Before CAPI2 you would either build an FPGA image or sim a simulation. Wiht the sight set on new tool types, none of these commands really describe what you do when you run an linter. So there is now a command called run. Going forward, this will be the main command to use when launching EDA tools through FuseSoC. The run command currently has switches for setting the desired target and tool, and can run any of the tree stages setup, build and run. Without any stages being explicitly set it will run them all. The tool can also be derived from the core description in many cases. build and sim will remain as special cases of run for the time being. sim will be the equivalent of run --target=sim and build will evaluate to run --target=sim --setup --build. The build command has also gained --tool and --target switches for overriding the default options. As for new switches, it is now possible to explicitly point out a FuseSoC config file to use with the --config option

That's all folks. Hope you like it. Please try it out and send me patches, bug reports or perfumed letters if you find anything you like or want to see improved.

See you later, Verilator
In a while, Synplify

Wednesday, November 22, 2017

Resetting reset handling

I will make a bold statement. You are probably doing your reset wrong in your RTL code. Yep, that's right. There are of course plenty of ways to resetting things the wrong way. Asynchronous vs synchronous is one example. Active high or active low is another.

But that's not why we're here today. Instead I will talk about a bad coding style that is so prevalent that I feel it needs some mentioning. Consider the following verilog code of a component that is most likely pretty worthless in practice, but will serve well as our example


module rst_all
  (input      clk,
   input      rst,
   input      valid_i,
   input [3:0]      data_i,
   output reg      valid_o,
   output reg [3:0] data_o);

   reg [2:0]  count;
   reg [3:0]  data_r;

   always @(posedge clk) begin
      if (rst) begin
  data_o  <= 4'd0;
  data_r  <= 4'd0;
  valid_o <= 1'b0;
  count   <= 3'd0;
      end else begin
  if (valid_i)
    count <= count + 1;
  data_r  <= data_i;
  data_o  <= data_r + count;
  valid_o <= valid_i;
      end
   end
endmodule


All our registers are being reset, as can be seen in the following screenshot from the elaborated code in Vivado.





Now, as good RTL designers we want to minimize the load on the reset network, so we start looking for things that don't really need to be reset. Both data_o and data_r are unnecessary to reset if we only look at the data when valid_o is asserted. Let's remove them and try again


module rst_bad
  (input clk,
   input     rst,
   input     valid_i,
   input [3:0]     data_i,
   output reg    valid_o,
   output reg [3:0] data_o);

   reg [2:0]  count;
   reg [3:0]  data_r;

   always @(posedge clk) begin
      if (rst) begin
  //data_o  <= 4'd0;
  //data_r  <= 4'd0;
  valid_o <= 1'b0;
  count   <= 3'd0;
      end else begin
  if (valid_i)
    count <= count + 1;
  data_r  <= data_i;
  data_o  <= data_r + count;
  valid_o <= valid_i;
      end
   end
endmodule



Whoa.. what just happened The reset inputs are gone, but we suddenly have two new muxes in the design and clock enable pins on the flip flops. And what's worse, we still have the same load on the reset net. How is this possible?!?! Well, the thing is that we haven't specified what to do with the data_r and data_o signals when rst is low. Therefore, according to verilog rules (the same thing applies to VHDL designs too), we must keep the old value. This is most likely not what we wanted to do. Still, I see this design pattern all the time, and no one is warning about it. What should we do then? One way is to replicate the assignments to data_r and data_o also in the reset section, but that's pretty awkward. The real solution is much simpler, but will probably cause heart attacks among conservative RTL designers.

We put the reset handling at the end of the process. Oh yes, I just did! And no one can stop me! It looks like this by the way


module rst_good
  (input clk,
   input     rst,
   input     valid_i,
   input [3:0]     data_i,
   output reg    valid_o,
   output reg [3:0] data_o);

   reg [2:0]  count;
   reg [3:0]  data_r;

   always @(posedge clk) begin
      begin
  if (valid_i)
    count <= count + 1;
  data_r  <= data_i;
  data_o  <= data_r + count;
  valid_o <= valid_i;

      end
      if (rst) begin
  //data_o  <= 4'd0;
  //data_r  <= 4'd0;
  valid_o <= 1'b0;
  count   <= 3'd0;
      end
   end
endmodule

and the generated design looks like this.



Problem solved!

A few additional notes:
  1. I have put together a FuseSoC core with the source and some notes on how to simulate and build the designs mentioned here in a git repo
  2. This was an example with synchronous resets, but the same thing is true for asynchronous.
  3. I have no idea why Vivado chooses to instantiate the muxes however, as it could just use the CE port directly. Other tools do that. My guess is that CE maybe is always active high, and the mux serves as an inverter.
  4. If you only target FPGA and the reset is just a power-on-reset, you don't need to reset at all. Just provide an init value if you must. Don't be afraid. It works, and will save some load on your reset net.
  5. There are many many more things to say about resets. But we stop here for today

Wednesday, August 30, 2017

Happy sixth birthday FuseSoC

Today FuseSoC is turning six years old. That is probably something like 35 in software years. It has had a colourful past with some breakups and an identity crisis, but has now settled down and realized that it will not change the world in the same way that it used to think. It has spawned a few child projects which are not yet able to handle themselves in the world and still need their loving parent project. Being 35 also means that we can expect a FuseSoC middle-age crisis in a few years where it will try to reinvent itself in a desperate attempt to appear youthful. All in all, it's pretty similar to it's author.

As with most software, there is no birth certificate, but we will use the date of the first commit to the repo of what would become FuseSoC as the birth date. So what really happened on that fateful day that would become forever etched into history as the day when everything changed? According to Wikipedia, it wasn't a happy day overall, but none of those events are really related to FuseSoC.

As so often, we need to go back further in time and take a look at the events leading up to this day. It all started with the OpenRISC Reference Platform System on Chip version 2, or ORPSoCv2. This project was a combination of RTL code for the OpenRISC CPU together with a bunch of peripheral controller cores, drivers, example applications and miles of makefiles to build everything together into FPGA images that could be loaded onto a few select boards for running OpenRISC-based systems. Despite having one of the least sexy names ever, it was widely used by most people who dealt with OpenRISC and seems to still be in use by some people.  But it wasn't without flaws. Due to the tightly integrated nature of the project, everyone who wanted to add support for a new FPGA board or add some extra peripheral driver ended up with their own version of the project, each with their own bugs and features. Fixes were rarely submitted back upstream to the main ORPSoCv2 repo. Also, the RTL code for the CPU and peripheral controllers were copies of other repositories, which quickly started to diverge from their upstream counterparts. Again, none of that code was submitted upstream. There were also other issues with regards to scalability that started to show when more features were added. In short, it was time for something new.

I started sketching out what I would like to see in a successor, and then started implementing ORPSoCv3. Just like ORPSoCv2 this was a system of makefiles calling into other makefiles, but with a major difference. Instead of storing copies of cores, the upstream versions were fetched when they were requested in a SoC to avoid all the code duplication. After some time, I was ready to present my work in progress to the world. At that time I was working for the company that owned and maintained OpenCores. The git hype had already started to sweep through the software landscape and I had been trying to convince my co-workers that we needed to start making OpenCores support git instead of just SVN. I never managed to convince them, but at least I got them to set up a git server where I could put my project as a trial. Except for three or four outdated clones of other OpenRISC-related projects, I had the only git repo at the now defunct git.opencores.org. On August 30 20111 I made the first commit.

The better part of the coming year was spent on writing makefiles calling other makefile until one day I had enough and decided that I will never in my life write another makefile calling other makefiles. It was time to kill my darling. I started a new implementation in Python with the lessons learned and soon got to a state where I wanted to present it to the world. As I only had this one git repo and no real understanding of git work flows, my instinct was to clean out the old repo and just push the new code in. Unfortunately I never figured out how to get rid of the first commit, which resulted in this sequence of commits:




Even after the Python migration, FuseSoC (or ORPSoCv3 really) was still storing a lot of RTL code in the repo. It was a shaky relationship, and in August 2013 there was an inevitable separation of tool and RTL code. The RTL code went into a new project called orpsoc-cores. There wasn't any crying involved an both parties realized that it was best to go separate ways. A day later, the first released version, ORPSoC 3.0 was released.

Life went on, new features were added, bugs were fixed, ORPSoCv3 became older and fatter, but it became more and more evident that ORPSoC really didn't have anything to do with OpenRISC. Everything that was OpenRISC-specific had already moved to the orpsoc-cores repository and ORPSoCv3 was really a dependency manager and build system for any RTL code. It was once again time to cut some ties. As usual, names are harder than code, and I spent some time trying to figure out what to call the thing I had created. One of the main alternatives was SoCify, but it turned out someone else had already used that name. In hindsight, I'm really grateful for that. SoCify as it is a horrible name. The idea of FuseSoC came from the analogy of fusion reactions to build something bigger from a number of smaller cores. The minimalist in me also considered FuSoC, which is also pretty bad and sounds a bit like F*** you SoC. I do like FuseSoC though. In February 2014 the big rename was made, the project was moved to its current location and FuseSoC 1.0 was released.

Since then not much has happened. New features are added. Bugs are fixed, reintroduced and fixed again. FuseSoC is getting older and fatter. I'm really grateful for all help that I have received over the years. According to github, there have been 20 contributors to the code base, but there are also a number of other people who have submitted bugs or contributed to the RTL code in the standard core library. Big thanks to everyone involved.

Birthdays usually involve presents. But what can we give to a project that already has everything? How about a logo and a home page? That's the perfect gift for a six year old and on this big day I can proudly announce the brand new home page (Ssshhh...I have had the domain name since 2014, but don't tell FuseSoC) and the FuseSoC logo.


Happy birthday FuseSoC! I will now leave the word to the millions of users to tell their stories of how FuseSoC has changed their lives.

Monday, August 21, 2017

OSDDI: Director's commentaries

Andrew Back of AB Open and FOSSi Foundation has been working on this great series of interviews called Open Source Digital Design Insights, in which he has been interviewing some of the great minds of the Free and Open Source Silicon movement (+ me). In the fourth episode the turn has come to me. As I watch the video myself, I realize how quickly time moves in the open source silicon world and how many things that have happened since then. I would therefore like to take the opportunity to add some more context as an addendum to the interview.
The interview was made at ORConf 2015, the same day as we publicly announced the Free and Open Source Silicon Foundation. We had been working on this for a year and it was a great feeling to present our ambitions to the world. The first thing that strikes during this interview is that we hadn't yet embraced the Open Source Silicon epithet ourselves and were still referring to our work as Open Source Hardware.
Another major theme that can use some more explanation is to role of the OpenRISC project nowadays. I would believe that most people coming in contact with open source silicon at this time will do so through the RISC-V project. When I started out, the RISC-V project was not yet born and OpenRISC was just about to become a teenager. OpenRISC wasn't the only free ISA around at the time. Most notably there were also free implementations of SPARC (both the LEON and the Sun T1/T2) and Lattice Mico 32 (lm32). OpenRISC was likely the most widely used architecture however and is still used in some critical infrastructure, which I'm unfortunately not allowed to speak freely of. Despite being widely used, the OpenRISC ISA hasn't been without faults, and already in 2011, we started work on a successor to the OpenRISC 1000 ISA, called OpenRISC 2000. Some of the things we wanted to fix was removal of the branch delay slots, better support for wider instruction lengths, instruction compression, more modular instruction set, revised memory model and other things. Unfortunately, we never got around to implement any of that, as we were a small group and there was barely enough manpower to do all the necessary work on or1k. Turns out, we never needed to, because a year or two after that, RISC-V came along and did all those things that we had planned for or2k - and more. In that regard, we see RISC-V as the spiritual successor to OpenRISC and we are happy to pass the dutch to RISC-V for future free thinking ISA development.
So what's the deal with OpenRISC in 2017? Well, it's not seeing as many design starts as it used to do since most new designs are based on RISC-V. My guess is that the ones who make new designs based on OpenRISC do it because they either already have a working OpenRISC environment and have no need to replace that, or because they know that it's a stable code base that has been ASIC-proven numerous times for more than a decade. On the software side we are still pushing to upstream some of the last bits of the toolchains, notably GDB and GCC. There are also some updates and clarifications to the specification, mostly related to the ABI.
I believe that the greatest legacy of OpenRISC will not be the ISA, but the idea and realization of a free and open source silicon ecosystem. A CPU isn't very useful by itself and much of what came out of the OpenRISC project was IP cores, such as peripheral controllers and a lot of support software. For example, the i2c and ethernet drivers for the controllers that came out from the OpenRISC project has been in the Linux kernel since 2006, which is seven years before the OpenRISC CPU support was added to the kernel. Some of the debug infrastructure that originated from OpenRISC is widely used in RISC-V-based designs. The FOSSi Foundation was born from a group of OpenRISC developers who saw the need for a vendor-independent group to foster the open source silicon ecosystem, regardless of which ISA is currently in vogue. ORConf was originally the OpenRISC conference. We have considered renaming it, but we like the name so we just have to find a good backronym (the best proposal is still Olof's Rock'n'roll Conference). Even FuseSoC was born as a tool to make it easier to build OpenRISC-based SoCs, and for the first year or two it was still called ORPSoCv3 (OpenRISC Reference Platform System on Chip version 3)
Enough said about OpenRISC. I think the most amazing aspect of the interview is that I did not mention FuseSoC even once. Nope. Not a single mention of FuseSoC in over 8 minutes! And if you think I look a bit like a zombie sloth on heroin in the interview, that's because I usually spend the months leading up to ORConf as Sonic the Hedgehog on amphetamine, so once everyone is seated and the conference starts, that's when I start to relax. It's a lot of work to organize a conference, but I absolutely love doing it and I hope that you will come to visit and enjoy as well.  And if you haven't seen the other entries in the OSDDI series, please watch them now. They really are insights in the world of open source silicon from some of the most knowledgeable people in the field (+me).