The Synflow framework is a framework for digital hardware development made by system engineers for system engineers. You can download the framework on our website or contact us to access the source code. We provide you documentation, tutorials and contents to quickly get on your way to building anything you want. We also regularly release new versions that include updates, new features, community contributions and bug fixes.

So what is a FPGA?

FPGAs are SoCs composed of programmable logic + DSP slices + RAMs + ALUs (doing things like multiply-accumulates). The cheapest FPGAs can do hundreds of operations simultaneously. For instance, you can have lots of small "cores" running in parallel, for a fraction of the power that would be required to do the same with a CPU or a GPU. More details here.

And what is the Cx language?

Cx is a new language intended to make the development of applications and systems for FPGA easy, fun, and fast. It uses a C-like "curly" syntax and supports most C control structures (if, for, while). It support common types (char, int, long, etc.) as well as bit-accurate types (which are required to design optimized hardware). The language has first-class support for parallel tasks and networks of tasks. Take a look at the roadmap for a glimpse of the features we'd like to implement.


unsigned int mk_crc(int size, unsigned char *contents) {
  // This code computes the CRC of a n-byte frame
  unsigned int crc = 0xFFFFFFFF;
  for (int i = 0; i < size; i++) {
    crc = compute_crc(crc, contents[i]);
  return crc;
task CrcComputer {
  // This code computes the CRC of a n-byte frame
  in sync u8 din; out uint crc;
  void loop() {
    u32 crc_i = compute_crc(0xFFFF_FFFF,;
    while (din.available) {
      crc_i = compute_crc(crc_i,;


Why a new language?

Because the semiconductor industry has been using the same old languages (VHDL and Verilog) for decades, but these languages haven't evolved much. Verilog is too low-level and has a poor type system; VHDL is a bit higher level but features a very strict type system and is quite verbose. The complexity and quirks of both languages make it needlessly difficult to design hardware for newcomers, and make hardware design much slower than it could be with a better language. See below an example of HDL code.

The Electronic Design Automation (EDA) industry has recognized this to some extent. Some vendors propose High-Level Synthesis (HLS) that claims to transform software into efficient hardware. The problem is that you have to respect many rules to make sure that your C/C++ code can be synthesized, and in fact for anything but a small class of designs, your code looks nothing like regular C/C++ code.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

library std;
use std.textio.all;

library work;
use work.Helper_functions.all;

entity PhyMIIMI is
  port (
    clock : in std_logic;
    reset_n : in std_logic;
    readTransaction : in std_logic;
    readTransaction_send : in std_logic;
    mdi : in std_logic;
    phyAddr : in std_logic_vector(4 downto 0);
    regAddr : in std_logic_vector(4 downto 0);
    din : in std_logic_vector(15 downto 0);
    mdo : out std_logic;
    mdoEn : out std_logic;
    writeDone : out std_logic;
    writeDone_send : out std_logic;
    dout : out std_logic_vector(15 downto 0);
    dout_send : out std_logic);
end PhyMIIMI;

architecture rtl_PhyMIIMI of PhyMIIMI is

  constant LENGTH_PRE : unsigned(5 downto 0) := "100000";
  constant LENGTH_DATA : unsigned(5 downto 0) := "010000";
  signal doRead : std_logic;
  signal regad : unsigned(4 downto 0);
  signal phyad : unsigned(4 downto 0);
  signal data : unsigned(15 downto 0);
  signal i : unsigned(5 downto 0);

  type FSM_type is (s_start, s_send_st, s_send_st_1, s_send_op, s_send_op_1, s_send_phyad, s_issueRead, s_issueRead_1, s_issueRead_2, s_issueRead_3, s_issueRead_4);
  signal FSM : FSM_type;


  PhyMIIMI_execute : process (reset_n, clock) is
    variable local_data_4 : unsigned(15 downto 0);
    if reset_n = '0' then
      doRead <= '0';
      regad <= "00000";
      phyad <= "00000";
      data <= x"0000";
      i <= "000000";
      mdo <= '0';
      mdoEn <= '0';
      writeDone <= '0';
      writeDone_send <= '0';
      dout <= (others => '0');
      dout_send <= '0';
      FSM    <= s_start;
    elsif rising_edge(clock) then
      writeDone_send <= '0';
      dout_send <= '0';
      case FSM is
        when s_start =>
          if to_boolean(readTransaction_send and '1') then
            -- Body of start_a (line 63)
            doRead <= readTransaction;
            phyad <= unsigned(phyAddr);
            regad <= unsigned(regAddr);
            data <= unsigned(din);
            i <= "000000";
            FSM <= s_send_st;
          end if;
        when s_send_st =>
          if to_boolean(to_std_logic((i < LENGTH_PRE))) then
            -- Body of send_st_a (line 72)
            mdoEn <= '1';
            mdo <= '1';
            i <= resize((resize(i, 7) + "0000001"), 6);
            FSM <= s_send_st;
          elsif to_boolean(not (to_std_logic((i < LENGTH_PRE)))) then
            -- Body of send_st_b (line 78)
            mdo <= '0';
            FSM <= s_send_st_1;
          end if;
        when s_send_st_1 =>
          if to_boolean('1') then
            -- Body of send_st_1_a (line 79)
            mdo <= '1';
            FSM <= s_send_op;
          end if;
        when s_send_op =>
          if to_boolean('1') then
            -- Body of send_op_a (line 84)
            mdo <= doRead;
            FSM <= s_send_op_1;
          end if;
        when s_send_op_1 =>
          if to_boolean('1') then
            -- Body of send_op_1_a (line 85)
            mdo <= not (doRead);
            i <= "000000";
            FSM <= s_send_phyad;
          end if;
        when s_send_phyad =>
          if to_boolean(to_std_logic((i < "000101"))) then
            -- Body of send_phyad_a (line 91)
            mdo <= to_std_logic(((phyad and "10000") /= "00000"));
            phyad <= resize(shift_left(resize(phyad, 6), 1), 5);
            i <= resize((resize(i, 7) + "0000001"), 6);
            FSM <= s_send_phyad;
          elsif to_boolean(not (to_std_logic((i < "000101")))) then
            -- Body of send_phyad_b (line 98)
            mdo <= to_std_logic(((regad and "10000") /= "00000"));
            i <= "000000";
            FSM <= s_issueRead;
          end if;
        when s_issueRead =>
          if to_boolean(to_std_logic((i < "000100"))) then
            -- Body of issueRead_a (line 100)
            mdo <= to_std_logic(((resize(shift_left(resize(regad, 6), 1), 5) and "10000") /= "00000"));
            regad <= resize(shift_left(resize(regad, 6), 1), 5);
            i <= resize((resize(i, 7) + "0000001"), 6);
            FSM <= s_issueRead;
          elsif to_boolean((not (to_std_logic((i < "000100"))) and doRead)) then
            -- Body of issueRead_b (line 106)
            mdoEn <= '0';
            FSM <= s_issueRead_1;
          elsif to_boolean((not (to_std_logic((i < "000100"))) and not (doRead))) then
            -- Body of issueRead_c (line 108)
            mdo <= '1';
            FSM <= s_issueRead_3;
          end if;
        when s_issueRead_1 =>
          if to_boolean('1') then
            -- Body of issueRead_1_a (line 106)
            data <= x"0000";
            i <= "000000";
            FSM <= s_issueRead_2;
          end if;
        when s_issueRead_2 =>
          if to_boolean(to_std_logic((i < LENGTH_DATA))) then
            -- Body of issueRead_2_a (line 106)
            if (to_boolean(mdi)) then
              local_data_4 := (resize(shift_left(resize(data, 17), 1), 16) or x"0001");
              local_data_4 := (resize(shift_left(resize(data, 17), 1), 16) and x"fffe");
            end if;
            data <= local_data_4;
            i <= resize((resize(i, 7) + "0000001"), 6);
            FSM <= s_issueRead_2;
          elsif to_boolean(not (to_std_logic((i < LENGTH_DATA)))) then
            -- Body of issueRead_2_b (line 106)
            dout <= std_logic_vector(data);
            dout_send <= '1';
            FSM <= s_start;
          end if;
        when s_issueRead_3 =>
          if to_boolean('1') then
            -- Body of issueRead_3_a (line 108)
            mdo <= '0';
            i <= "000000";
            FSM <= s_issueRead_4;
          end if;
        when s_issueRead_4 =>
          if to_boolean(to_std_logic((i < LENGTH_DATA))) then
            -- Body of issueRead_4_a (line 108)
            mdo <= to_std_logic(((data and x"8000") /= x"0000"));
            data <= resize(shift_left(resize(data, 17), 1), 16);
            i <= resize((resize(i, 7) + "0000001"), 6);
            FSM <= s_issueRead_4;
          elsif to_boolean(not (to_std_logic((i < LENGTH_DATA)))) then
            -- Body of issueRead_4_b (line 108)
            mdoEn <= '0';
            writeDone <= '1';
            writeDone_send <= '1';
            FSM <= s_start;
          end if;
      end case;
    end if;
  end process PhyMIIMI_execute;

end architecture rtl_PhyMIIMI;

Using the framework

How do I get started with hardware development?

Start by downloading our framework. Then follow our online course.

How do I compile a project?

Actually, projects are built automatically every time it is necessary. You never need to manually build a project. However, if for some reason you suspect that there is a bug in the compiler, you might want to clean a project by using the Project > Clean... in the main menu.

How do I generate (VHDL/Verilog) code?

You need to enable code generation in your language of choice for each project. To do that, right-click on a project, and go to Project > Properties. Select your language(s). Once enabled, code generation is automatic: VHDL (or Verilog) code is automatically generated whenever a source file (or files) changes.

How do I simulate my design?

The new version of the framework includes a simulator. We also plan to have a debugger in future releases.

There are also several commercial simulators with advanced debugging capabilities and many other features, but if you know that in all likelihood you already use one of these.

How do I write a state machine?

That's the beauty of Cx: you never need to write an FSM (Finite State Machine), it is generated for you by the compiler. If you need to see what FSM corresponds to your code, take a look at the "FSM view" located at the right of the IDE.

How do I write a pipeline?

At the moment, you write it the same way you would with traditional languages, with one task for each pipeline stage. For simpler pipelines, we recommend you use inner tasks, as they make it much faster to describe this kind of behavior. In the future we might introduce automated pipelining for simple loop-and-array code (for typical DSP code).


What is the Marketplace?

The Marketplace provides usable content and code to create applications faster. You can buy code from the marketplace or sell your code on the marketplace.

What can I do with content I obtain from the Marketplace

You can use the code for learning, experimenting, prototyping, and ship it in your own products.

Can I sell or sublicense Marketplace content?

You are not allowed to sell or sublicense Marketplace content to other developers for use in their products.

What forms of payment are accepted for Marketplace transactions?

We accept Paypal as well as credit and debit cards bearing the VISA, MasterCard logo. You will receive receipts for all transactions via email.

How can I sell my own creations in the Marketplace?

You need to submit your code and we will push your content on the marketplace.

Creating and releasing products

What kinds of products can I release?

You can release any product that is allowed by law, with the exception of safety-critical control systems (more details on the EULA). You can release hardware applications, accelerators and systems for the IoT, automotive, aerospace and defence, smarthome, smartcity, multimedia, and more.

However you cannot release the source code of the frameword or modifications to it.

What do I need to do when releasing a product?

You must notify our team when you ship your product by email or using the contact page.

What royalties are due to Synflow, and when?

You must pay to Synflow 5% of all gross revenue after the first $100 per project per calendar quarter, regardless of what company collects the revenue. Along with the payment, you must send a royalty report on a per-product basis.

Why is our business royalty-based?

Our aim is to provide a user-friendly framework, advanced contents, development boards and millions of lines of code that enables developers to achieve more than they would otherwise be able to. To do so, we need you to be successful and when you are, we also succeed. A royalty-based business is the most fair because you pay only when you are successful.

What if my project requires custom licensing terms?

If you require terms that reduce or eliminate the 5% royalty in exchange for an upfront fee, or if you need custom legal terms or dedicated support to help your team reduce risk or achieve specific goals, contact us.

Source code

What modifications can I make to the source code?

You can extend it, modify it, and integrate it with other software or libraries. However you cannot combine the source code with code covered by a “Copyleft” license agreement which would directly or indirectly require Synflow to be governed by terms other than the EULA (e.g. GPL, LGPL, Creative Commons Attribution-ShareAlike License).

Can I copy and paste the code into my own project?

If you use any line of code in your product, then your entire product is governed by the EULA, and royalties are due.


I have another question, can you add it to this list?

Maybe, this FAQ is not exhaustive, so let us know your question and we'll consider adding it.