A C-like hardware description language (HDL) adding high level synthesis(HLS)-like automatic pipelining as a language construct/compiler feature.

Overview

pipelinec_color

██████╗ ██╗██████╗ ███████╗██╗     ██╗███╗   ██╗███████╗ ██████╗
██╔══██╗██║██╔══██╗██╔════╝██║     ██║████╗  ██║██╔════╝██╔════╝
██████╔╝██║██████╔╝█████╗  ██║     ██║██╔██╗ ██║█████╗  ██║     
██╔═══╝ ██║██╔═══╝ ██╔══╝  ██║     ██║██║╚██╗██║██╔══╝  ██║     
██║     ██║██║     ███████╗███████╗██║██║ ╚████║███████╗╚██████╗
╚═╝     ╚═╝╚═╝     ╚══════╝╚══════╝╚═╝╚═╝  ╚═══╝╚══════╝ ╚═════╝

Please feel free to message - very happy to make PipelineC work for you! Always looking for help as well. -Julian

Getting Started

Get started by reading the wiki.

What is PipelineC?

A C-like(1) hardware description language (HDL)(2) adding high level synthesis(HLS)-like automatic pipelining(3) as a language construct/compiler feature.

  1. Not actually regular C. But mostly compileable by gcc for doing basic functional verification/'simulation'. This is for convenience as a familiar bare minimum language prototype, not as an ideal end goal. Reach out to help develop something more complex together!
  2. Can reasonably replace Verilog/VHDL. Compiler produces synthesizable and human readable+debuggable VHDL. Hooks exist for inserting raw VHDL / existing IP / black boxes.
  3. If a computation can be written as a pure function without side effects (i.e. no global/static variables) then it will be autopipelined. Conceptually similar to technologies like Intel's variable latency Hyper-Pipelining and Xilinx's retiming options. Sharing some of the compiler driven pipelining design goals of Google's XLS Project and the DFiantHDL language as well.

What is PipelineC not?

  • High level synthesis of arbitrary C code with a global memory model / threads / etc.
  • Meta-programming hardware-generator (ex. uses C type system and preprocessor).

Core Features/Benefits

An easy to understand hardware description language with a powerful autopipelining compiler and growing set of real life hardware design inspired features.

  • Familiar C syntax that eliminates many HDL quirks that beginners (and experts) can fall victim to (ex. blocking/nonblocking assignments, reasoning about the sequential ordering of combinatorial logic).
  • Simulate your code in seconds, debug with printf's (tool imports human readable+debuggable VHDL into Modelsim - can also imagine custom C based simulation is within reach as well)
  • Helpful timing feedback derived from synthesis tool reports to help identify critical path logic that cannot be automatically pipelined - especially helpful for those new to digital logic design.
  • Integrates with software side C easily; helpful built in code generation. (ex. for un/packing structs from de/serialized byte arrays when moving data from host<->FPGA).
  • A full hardware description language replacement. Can start by cloning existing VHDL/Verilog designs or including raw VHDL - not forced to use entire language at all times.
  • Globally visible point-to-point wires, multi-rate/width clock domain crossings, inferred clock enable nested FSMs, are just some of the growing list of composability features inspired by real life hardware design requirements/tasks.
  • Automatic pipelining as a feature of the compiler. Basic use of the tool can be to generate single pipelines to drop into existing designs elsewhere. Eliminate the practice of pipelining logic by hand = not portable (relies on operating frequency and part).

Fundamental design elements are state machines/stateful elements(registers, rams, etc), auto-pipelined stateless pure functions, and interconnects (wires,cdc,async fifos,etc).

By isolating complex logic into autopipelineable functions, and only writing literal clock by clock hardware description when absolutely necessary, PipelineC designs do not need to be rewritten for each new target device / operating frequency. The hope is to build shared, high performance, device agnostic, hardware designs described in a familiar and powerfully composable C language look.

For software folks I want writing PipelineC to feel like solving a programming puzzle in C, not a whole new paradigm of programming languages. The rules of the puzzle hide/imply hardware concepts. For hardware folks I want PipelineC to be a better hardware description language (it is my language of choice as an FPGA engineer :) ).

Comments
  • OSS, GDHL, PYRTL

    OSS, GDHL, PYRTL

    Hi, I have a little problem with running PYRTL. When I source oss cad suite, pipelineC forces me to specify part and I can't go with PYRTL flow.

    But if I run pipelineC without oss, pipelineC runs PYRTL flow but then GHDL is not detected and it fails to run ;o

    any ideas? quick fixes?

    opened by bartokon 17
  • Allow global variables to be directly used (not as wires) to communicate between functions

    Allow global variables to be directly used (not as wires) to communicate between functions

    As @suarezvictor has pointed out - wouldnt it be nice to not have to specify WIRE for things - and have the tool do it all? :smirk:

    Currently global variables are identical in functionality to static local variables. They are associated with a single function only. Even though global variables are in the global scope, they cannot be directly used by multiple functions. Global variables are locked to a single function right now.

    Currently WIRE's are the work around for this. A global variable is declared but special WIRE/clock crossing functions are used to make clear where writes to the global vs reads to global are occurring.

    Why is it needed to know when writes and reads occur? Well lets get into why this issue has few layers to it...

    enhancement 
    opened by JulianKemmerer 12
  • const variables

    const variables

    for variables declared as const, never generate registers for the pipeline (just wires) This will ease the job of the synth tool and be easier than tracking if the variables changes (and makes syntax and purpose of functions more clear)

    enhancement help wanted 
    opened by suarezvictor 12
  • add script to parse and estimate delays of unary and binary operations

    add script to parse and estimate delays of unary and binary operations

    I wrote a model of FPGA delays. It works by parsing the logs at ./path_delay_cache/vivado/xc7a35ticsg324-1l/syn For each entry it calculates the timing depending on the type of operation and bit widths involved, and RMS error overall, dumping the results

    Example on the current database: Count: 339 , minimum delay (ns): 1.117 , RMS error (ns): 0.41

    The function is called like this: estimate_int_timing("XOR", [16, 16])

    returns None if estimation is not available. NOTE: only integer support

    TODO: calculate coefficients automatically from the database, and generate the samples by calling the synth project for various kind of operations and bit sizes

    enhancement 
    opened by suarezvictor 11
  • Provide alternative flows for OSS integration

    Provide alternative flows for OSS integration

    In the Setup instructions, the open source synthesis integration instructions call for the user to manually specify the paths for Yosys and NextPNR. This is really sub-optimal, and can make user patches more annoying to review and/or merge.

    A more flexible solution would be to allow more options that can leverage industry-standard flows such as environment variables, i.e. $YOSYS_PATH, $NEXTPNR_PATH, etc.

    opened by ted-xie 8
  • Vitis import example

    Vitis import example

    These scripts are used to generate Vitis hls IP's that transfer data to/from pipelineC generated IP. Streaming interfaces are used as communication channel. PipelineC ip is packaged as .XO and connected with Vitis at linking stage.

    opened by bartokon 7
  • Allow operator overloading

    Allow operator overloading

    Since operator overloading is easily supported for compile as regular C++ it seems like a reasonable idea to make possible for user types now in plain-C PipelineC. Thanks for the push @suarezvictor!

    Maybe?

    typedef struct ....my_struct_t;
    #pragma OVERLOAD * my_struct_t my_mul_op
    my_struct_t my_mul_op(my_struct_t lhs, my_struct_t rhs)
    {
    ...
    }
    

    Or does this feature wait for PipelineC++ rewritten with clang tools etc?

    enhancement 
    opened by JulianKemmerer 7
  • Add 'always a wire' clock crossings

    Add 'always a wire' clock crossings

    Current clock crossings take into account clock ratios to buffer and/or require fifos if the clock domains are not the same.

    Create a way of declaring a wire-always clock domain crossing (always a wire, not just when same clock domain - for all domain crossings).

    enhancement 
    opened by JulianKemmerer 6
  • Support user produced 'internal' clock signals

    Support user produced 'internal' clock signals

    Ex. If user instantiated a PLL inside the design (instead of typically outside top level). Or if user did the slow clock via counters thing to produce internal slow changing 'clock' signal.

    enhancement 
    opened by JulianKemmerer 6
  • Auto remove output directory

    Auto remove output directory

    Copy pasting the snippet of docs explaining the current situation:

    https://github.com/JulianKemmerer/PipelineC/wiki/Running-the-Tool

    If the tool is stopped while running, upon next start it attempts to restart where it left off. Good for large designs / long synthesis sweeps. But bad for other yet-to-be-resolved reasons: Stopping the tool after code parsing completes means the code will not be parsed again - delete your_file.c.parsed from within SYN_OUTPUT_DIRECTORY directories if code is modified after parsing. Stopping the tool during synthesis creates a failing synthesis run log - delete that log file from it's SYN_OUTPUT_DIRECTORY before trying again. If all else fails, try removing the SYN_OUTPUT_DIRECTORY before running the tool as a sanity check. Ex.rm -r ~/pipelinec_syn_output/*; ./src/pipelinec

    Want a way to auto remove this directory (or continue using it correctly) as needed

    opened by JulianKemmerer 6
  • Easier bit slicing syntax

    Easier bit slicing syntax

    As opposed to fancier C++ style syntax for bit slicing, ex bits<5,2>(x) as suggested from https://github.com/JulianKemmerer/PipelineC/discussions/32 (trying to replace current bit manip syntax...)

    Do something that is immediately parseable by pycparser and also overloadable by full C++ software compilers (as evidenced by other C++ HLS tools using syntax like below):

    uint32_t x;
    ...
    uint1_t b = x[3]; // Fourth bit of x(31 downto 0)
    uint16_t y = x(15, 0); // (15 downto 0) 16b slice of x
    

    Thanks @Quarky93 !

    enhancement 
    opened by JulianKemmerer 5
  • Default zero initialized arrays can generate broken VHDL syntax when indexed by constants

    Default zero initialized arrays can generate broken VHDL syntax when indexed by constants

    Code like so:

    #include "intN_t.h"
    #include "uintN_t.h"
    
    #pragma MAIN test
    uint32_t test()
    {
      uint32_t a_const_array[3];
      // Dummy logic to use array...
      int32_t i;
      uint32_t sum;
      for(i=0;i<3;i+=1){
        sum += a_const_array[i];
      }
      return sum;
    }
    

    With a_const_array default initialized to zeros produces incorrect VHDL syntax when used in the array dereferenced like a_const_array[i]

    VAR_FOR_main_c_l112_c3_32e3_ITER_0_CONST_REF_RD_uint32_t_uint32_t_3_0_d41d_main_c_l114_c12_2cd5_return_output := (others => to_unsigned(0, 32))(0);
    

    Work around: Init each element

    uint32_t a_const_array[3] = {0, 0, 0};
    

    produces vhdl assignments of individual u32s

    VAR_FOR_main_c_l113_c3_149c_ITER_0_BIN_OP_PLUS_main_c_l114_c5_0eb6_left := to_unsigned(0, 32);
         VAR_a_const_array_0_main_c_l109_c12_ca56_0 := resize(to_unsigned(0, 1), 32);
    

    Likely to do with how null array isnt same constant as a literal zeros that would be each array element....

    bug 
    opened by JulianKemmerer 0
  • Global variables of compound types cannot be driven from multiple main functions

    Global variables of compound types cannot be driven from multiple main functions

    Ex. global wire 'point': This makes it so you cant drive point.x from one main function, and point.y from another - both drive the entire wire, not just pieces.

    enhancement 
    opened by JulianKemmerer 0
  • Raw VHDL interface should be bits per stage not slices

    Raw VHDL interface should be bits per stage not slices

    Currently for basic things like adders ex. 32 bits is divided by the slices specified [0.5] = slice into two pieces = two 16b stages

    First this is annoying because [0.499] is the same slicing (etc w/ close FP values) but still gets a different file, file name etc, blegh

    Also its important to know how many bits per stage as being used. As in https://github.com/JulianKemmerer/PipelineC/issues/46 and https://github.com/JulianKemmerer/PipelineC/issues/48 and https://github.com/JulianKemmerer/PipelineC/issues/45 we want to know what hardware is produced by the synthesis tool - some bits per stage implement better than others, etc.

    enhancement 
    opened by JulianKemmerer 1
  • FIFO_FWFT implementation causes output to pause unexpectedly long after flow control assertion

    FIFO_FWFT implementation causes output to pause unexpectedly long after flow control assertion

    The FIFO_FWFT implementation is correct in its use of valid+ready handshake signaling clock by clock.

    However because of the weird way that the implementation uses its 2 cycle latency BRAM, asserting flow control ready=0 one cycle later causes 2 cycles of pause/valid=0 output data in a way that typical streams of data/FIFOs do not do...

    Fix this because it can be a corner case folks get stuck on if not strictly following handshake signals...

    enhancement 
    opened by JulianKemmerer 2
  • Allowing global variables to be marked as top level clock inputs

    Allowing global variables to be marked as top level clock inputs

    Related to allowing global variables to be top level inputs or outputs https://github.com/JulianKemmerer/PipelineC/issues/123

    Allow special clock enable and reset signals marked this way too maybe?

    Otherwise, work around like in the graphics repo work - simply using a MAIN top level input port ex. pixel(uint1_t clock) that renders a pixel_clock input wire and marking it with the CLK_MHZ pragma as a clock doesnt work for all tools:

    During internal runs of the tool all inputs have registers so timing paths are all sync. In this case the input clock is registered using itself as a clock and weird things happen...

    At least apparently for some tools like Quartus, which, similar to https://github.com/JulianKemmerer/PipelineC/issues/137, seem unable to use get_nets for the internal net name that isn't registered as the source of the clock for create_clock in the timing constraints. The internal clock net is also connected as an output port. Quartus can apply a clock to this output port with get_ports - but the clock constraint does not reach the interior of the design - internal registers,etc that are using the internal 'copy' of the clock wire are all still unconstrained/not reached by the output port create clock constraint.

    Vivado however is able to define a proper internal clock net usingcreate_clock with get_nets on the intended top level clock signal (and seems to ignore preceding funny clock input register business).

    enhancement 
    opened by JulianKemmerer 0
A example project's description is a high-level overview of why you’re doing a project.

A example project's description is a high-level overview of why you’re doing a project.

Nikita Matyukhin 12 Mar 23, 2022
Hotpile: High Order Turing Machine Language Compiler

Hotpile: High Order Turing Machine Language Compiler Build and Run Requirements: Python 3.6+, bison, flex, and GCC installed. Needs to be run under UN

Jiang Weihao 4 Dec 29, 2021
a simple functional programming language compiler written in python

Functional Programming Language A compiler for my small functional language. Written in python with SLY lexer/parser generator library. Requirements p

Ashkan Laei 3 Nov 5, 2021
A complex language with high level programming and moderate syntax.

zsq a complex language with high level programming and moderate syntax.

an aspirin 6 Jun 25, 2022
Pydesy package description (EN)

Pydesy package description (EN) Last version: 0.0.2 Geodetic library, which includes the following tasks: 1. Calculation of theodolite traverse (tachy

null 1 Feb 3, 2022
The most widely used Python to C compiler

Welcome to Cython! Cython is a language that makes writing C extensions for Python as easy as Python itself. Cython is based on Pyrex, but supports mo

null 7.6k Jan 3, 2023
Reactjs web app written entirely in python, using transcrypt compiler.

Reactjs web app written entirely in python, using transcrypt compiler.

Dan Shai 22 Nov 27, 2022
A small C compiler written in Python for learning purposes

A small C compiler written in Python. Generates x64 Intel-format assembly, which is then assembled and linked by nasm and ld.

Scattered Thoughts 3 Oct 22, 2021
Pulse sequence builder and compiler for q1asm

q1pulse Pulse sequence builder and compiler for q1asm. q1pulse is a simple library to compile pulse sequence to q1asm, the assembly language of Qblox

Sander de Snoo 3 Dec 14, 2022
MatroSka Mod Compiler for ts4scripts

MMC Current Version: 0.2 MatroSka Mod Compiler for .ts4script files Requirements Have Python 3.7 installed and set as default. Running from Source pip

MatroSka 1 Dec 13, 2021
This is a small compiler to demonstrate how compilers work.

This is a small compiler to demonstrate how compilers work. It compiles our own dialect to C, while being written in Python.

Md. Tonoy Akando 2 Jul 19, 2022
A simple BrainF**k compiler written in Python

bf-comp A simple BrainF**k compiler written in Python. What else were you looking for?

null 1 Jan 9, 2022
🎉 🎉 PyComp - Java Code compiler written in python.

?? ?? PyComp Java Code compiler written in python. This is yet another compiler meant for babcock students project which was created using pure python

Alumona Benaiah 5 Nov 30, 2022
Compiler Final Project - Lisp Interpreter

Compiler Final Project - Lisp Interpreter

null 2 Jan 23, 2022
Feature engineering library that helps you keep track of feature dependencies, documentation and schema

Feature engineering library that helps you keep track of feature dependencies, documentation and schema

null 28 May 31, 2022
Retrying is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simplify the task of adding retry behavior to just about anything.

Retrying Retrying is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simplify the task of adding retry behavior to just

Ray Holder 1.9k Dec 29, 2022
Repo created for the purpose of adding any kind of programs and projects

Programs and Project Repository A repository for adding programs and projects of any kind starting from beginners level to expert ones Contributing to

Unicorn Dev Community 3 Nov 2, 2022
New multi tool im making adding features currently

Emera Multi Tool New multi tool im making adding features currently Current List of Planned Features - Linkvertise Bypasser - Discord Auto Bump - Gith

Lamp 3 Dec 3, 2021
Starscape is a Blender add-on for adding stars to the background of a scene.

Starscape Starscape is a Blender add-on for adding stars to the background of a scene. Features The add-on provides the following features: Procedural

Marco Rossini 5 Jun 24, 2022