
The Cx programming language: digital hardware design for developers - jclis
http://cx-lang.org/
======
scott_s
Advice to the authors: don't stress syntax, but _semantics_. People here are
getting caught up on the notion that "this syntax is not too different from
Verilog/VHDL". But that's not the point; it's not what you say, but _what that
means_. You have created a programming model that software people can
understand intuitively, but also easily maps to hardware.

People may get hung up on this because the example on your page is so simple.
The equivalent VHDL and Verilog is also relatively simple. A simple example is
good, and a comparison is good, but just presenting the differences is not
enough. Stress what someone coding in Cx _does not have to think about_. In
other words, what are the abstractions in Cx?

Consider what the equivalent page for C versus assembly would look like for a
function that computes some simple arithmetic. Some people may say, "Oh, sure,
the assembly has a few more lines because you need to push and pop parameters
from the stack, but that's no big deal." And it's not - for one function.
What's the big deal is that there are entire concepts - saving existing
registers, pushing parameters onto the stack, register management - that C
programmers don't need to think about. (Most of the time.)

The code you link to elsewhere in this thread hints to me that there are
indeed significant abstractions behind Cx, that make it more than just an
alternative syntax to Verilog and VHDL. See:
[https://github.com/synflow/sha-256/blob/master/SHA256/src/co...](https://github.com/synflow/sha-256/blob/master/SHA256/src/com/synflow/sha256/SHA256.cx)

~~~
MootWoop
That's a very good point. In fact the main difference in semantics is that Cx
code is structured. Sure in VHDL/Verilog you have functions and if statements
and loops. But they can only be used to describe combinational logic. There is
a chasm between synchronous logic (everything in a big switch/case) and
combinational statements.

Cx supports functions, if and loops for both combinational and synchronous
logic. You can have a function that spans over two cycles. You can give
parameters to this kind of function just like in software, except that in the
end this is all inlined and the state machine is flattened.

The language encourages a higher level of abstraction where you think in terms
of blocking reads and data availability rather than "is my signal true". The
best is that this can be extended just by changing the port signature, for
example to provide rendez-vous style communications (we call it "sync ack" but
they're not implemented yet), whereas in HDL you'd have to write a lot of
boilerplate code.

Another property is that there is no synthesizable subset in Cx. As far as I
know, this is very rare in languages for hardware design, but the language is
entirely synthesizable. You never have to think about synthesis versus
simulation. Exactly like in software, nobody ever wonders if they can write
code that won't run on the processor :-)

And for the example you mention, this is another interesting feature of the
language. Because we support sequential loop constructs etc. you can actually
write code that works and synthesizes pretty easily, albeit it is slow. And
then you can produce a derived version that is optimized :-)

~~~
gothenburg
"Another property is that there is no synthesizable subset in Cx. As far as I
know, this is very rare in languages for hardware design, but the language is
entirely synthesizable. You never have to think about synthesis versus
simulation. Exactly like in software, nobody ever wonders if they can write
code that won't run on the processor :-)"

This is scary. I want the tool to tell me "I can't synthesize this" because
when it does, it might infer characteristics of the design that I might not
want.

Do you have some kind of paper or detailed explanation about this part?

Sometimes a bad design is not bad because it's badly written, it's bad because
it's not complying with some timing constraints or because the synthesis tool
decided to infer some crazy system from the code the designer wrote.

~~~
scott_s
Is it any scarier than having wildly inefficient software code? (Think a naive
traversal of large matrices that thrashes the cache.)

That's a workflow where optimization requires knowing the internals and how
they interact, but you can ignore such things if you just want correctness. At
least in software, that model works well, because the performance of most of
the code we write doesn't matter - even in applications where performance is a
concern.

~~~
mng2
I wouldn't call it 'scary', myself, but it doesn't strike me as a particularly
useful feature. In software, a single slow subroutine can simply take up more
cycles. But in hardware, a slow path becomes your critical path, and you have
a hard clock cycle requirement. (Sure, you can use multi-cycle paths and/or
change clock speed, but those generally have to be adjusted
manually/physically, and not all design situations will have that
flexibility.)

------
scott_wilson46
I can't help but feel that the VHDL that was written is a bit overly verbose.
You could probably write something like:

    
    
      i_sm: process(clk, reset)
      begin
        if (reset) then
          state <= DATA_BITS;
        elsif (clk'event and clk = '1') then
          case (state)
            when DATA_BITS => 
              if (data_valid = '1') then
                if (count < 8) then
                  count <= count + 1;
                else
                  state <= STOP_BIT;
                  count <= 0; 
                end if;
              end if;
            when STOP_BITS => 
              if (data_valid = '1') then
                if (count < num_stop_bits) then
                  count <= count + 1;
                else
                  state <= DATA_BITS;
                  count <= 0;
                end if; 
              end if;
           end case
        end if;
      end process i_sm;
    

which is not too dis-similar from the Cx example (I've missed a few things out
like port/signal declerations, just wanted to show the guts of the code). The
thing I like about VHDL/Verilog is that its easy to tell the exact port names,
what the clk is, the name and type of reset, etc which is useful information
for putting the block in the context of an overall system.

~~~
nsiret
Hi Scott, I'm a co-founder of Synflow. You're right, the VHDL on our website
is a bit overly verbose. I will update the website with the right version of
the code that day.

And I also agree on your point. This is why we added properties to the
language ([http://cx-lang.org/documentation/properties](http://cx-
lang.org/documentation/properties)) so one can either use the (implicit)
default names and types for the clk, reset, etc. or explicit/tweek things for
more complex systems.

~~~
scott_wilson46
Actually another thing I am curious about is how asynchronous clock domains
are handled Usually this is something thats quite tricky to model in a HLS
tool. Also, how about simulating the interactions between the domains?

~~~
nsiret
That's a good point Scott. Asynchronous clock domains are indeed complex and
it took us time to manage them efficiently. When you need to connect different
clock domains with Cx/ngDesign you have to synchronize the various tasks with
specific components (e.g. SynchronizerMux) [http://cx-
lang.org/documentation/instantiation/stdlib](http://cx-
lang.org/documentation/instantiation/stdlib). Simulating the interactions
between the domains is not yet supported by our simulator. We will develop
this feature when people will request it. And you know, we're a startup so we
still have plenty of R&D to do :-)

~~~
scott_wilson46
I think if you can crack the modelling and simulation of asynchronous clock
domains then I suspect you will have something that the other HLS solutions
don't have at the moment that would be an incredibly useful feature. Design
with async clocks is difficult and I have seen loads of bugs with these
interfaces (including bugs found in the field for chips that were release many
years previously).

------
csirac2
It's been 10 years since I did much FPGA dev, but at the time I had a lot of
fun in Celoxica Handel-C. Sadly I could never quite synthesize my project to
the size I could achieve with Verilog. I seem to recall having the Virtex-II
datasheets next to me when coding Verliog, not so much with the Handel-C so
perhaps I never quite got the hang of driving the language optimally for the
target device at hand...

My question is, to a layman like me - does Cx bring something to the table
that other C-like HDLs missed?

Edit: I Also very much enjoyed a scheme-like HDL called confluence... Seems it
fizzled out. Have any alternative HDLs stuck?

~~~
daphreak
I don't know if MyHDL([http://www.myhdl.org/](http://www.myhdl.org/)) really
stuck but I've used it a few times for some smaller things. What I really
liked about it was how fast I could simulate while iterating on a design, and
the fact that I could use Python unittest for testing.

I will definitely be taking Cx for a spin. Not wasting time with
clock/reset/fsm boilerplate will make development faster. If I can get my
hands on a trial of their cycle accurate simulator and can automate my test
suites I'd be thrilled.

~~~
scott_wilson46
If you are interested in using python for unit testing there is also Cocotb
which is a python based library for running verilog and vhdl simulations. It
interfaces to the simulator and allows you to stimulate your design directly
from python:

[https://github.com/potentialventures/cocotb](https://github.com/potentialventures/cocotb)

~~~
daphreak
Very interesting. Will definitely look into this.

All of our tests right now are implemented as VHDL/Verilog testbenches. We
automate building and running in ISim with a simple Python tool which
generates xunit output. It works but its slow and kind of painful to manage
testcases.

------
txomon
I would love to use this instead of VHDL, I have been searching for an
alternative to those such verbose languages for a long time, but wasn't able
to find any.

Where can I download a compiler? How may I start using it? I haven't found any
reference of low level that could help me to understand what is the output of
the compilers.

~~~
MootWoop
Good point, we need to make this clearer I think. We (Synflow) have a compiler
and IDE that you can download from
[https://www.synflow.com](https://www.synflow.com) The compiler and IDE are
open source, and the compiler generates VHDL code. We also have additional
(proprietary) features that include a Verilog code generator, a C-based
simulator, and exporters to third-party tools.

------
chillingeffect
This is interesting, but if you really want to get user traction, look deeper
into how the industry uses HDLs.

For example, one of the most common use cases is scaling code from year-to-
year, e.g. the video card market. This means that in 2012, your code works
with 16 bits, then 2013, 32, then 2014, 64-bit etc. And you need to keep
updating your code to do this, having not touched it for just about six months
- perfect time to be kind of familiar but not enough. This is currently
handled by integrating perl-like syntax into the HDL. Then it gets "pre-
processed" into the proper values in place. It sounds clumsy , but it may be
how the machine you're using to read this was made.

A second important use case is integrating writing test code with the source
code. As the register, path widths, number of cycles, etc., change, the
verification cases have to track. If you could find a way to simplify that,
companies would pay a LOT for it.

Another major problem becomes "ifdef-hell" in which sometimes dozens of
hierarchical #ifdefs are used to compile and configure HDL code. it's
maddening, hence the pre-processor approach.

So, in summary, it's not the clumsy syntax of HDLs that slows progress, it's
the ecosystem in which the HDLs are used.

~~~
MootWoop
Really? Aren't they using VHDL generics/Verilog parameters?

Cx supports specialization of entities with this kind of semantics, so you
give an instance parameters and the compiler generates specialized code (so
there's no more need for Perl scripts thankfully ^^). Right now you can't
enable or disable things, but this is something that would be excellent:
modify the hierarchy, add or remove ports, all depending on which flags the
entity was instantiated with.

As I explained in another comment a few minutes ago, we're not so much about
syntax as we're about better semantics and higher level description (I agree
this isn't very clear on the website). Your remark about the ecosystem is
perfectly right, and this is what makes EDA a tough market.

I don't know enough about verification to comment. I know SystemVerilog is
very powerful but very complex, I've read about UVM and stuff, some people use
SystemC. I wonder how they even manage to get hardware validated!

------
niklasni1
Hard to tell from the site if the language is proprietary or if it's just the
IDE they're flogging.

I have to say "what this needs is another proprietary component in the
toolchain" is not something I've ever thought when working with FPGAs. Quite
the contrary.

~~~
MootWoop
Hi I'm a co-founder of Synflow and author of the website. Sorry if this is not
clear about what is open source or not.

To answer your question the language, compiler, and IDE are open source:
[https://github.com/synflow/ngDesign](https://github.com/synflow/ngDesign)
We're using Xtext to develop the language. The open source version includes
everything you need to design with Cx and then generate VHDL code. We also
have a proprietary version that adds a Verilog code generator, exporters to
third-party tools, and a C-based simulator.

I agree that a lot of tools for FPGAs are much too proprietary, hopefully
we're contributing to changing that. I wish we could make it all open source
but we also have to make a living :-)

------
gothenburg
I fail to understand what kind of advantage this language brings to the table
compared to the existing solutions.

You touched the subject of the awkward syntax of VHDL. But what about the
syntax of Verilog? The syntax seems to be very similar to Verilog.

And besides of the syntax, what are the other features that this language
brings that we can't find anywhere else?

And why do you claim that this is oriented "for developers"? Who are these
"developers"? Software guys?

~~~
MootWoop
Don't worry, you're not the first to find that this looks similar to Verilog.
I have commented about the syntax aspect on EETimes: see
[http://www.eetimes.com/author.asp?section_id=36&doc_id=13252...](http://www.eetimes.com/author.asp?section_id=36&doc_id=1325215#singlefullmsg_333799)

It's more than the syntax though, it's about having a language for hardware
design that most developers (yes software developers) will be able to read,
understand, and write. For all sorts of purposes, from playing with FPGAs to
designing devices for the IoT. And I think this is something pretty unique :-)

~~~
gothenburg
What I really wanted was a better explanation of Cx's advantages other than
"The syntax is similar to C".

And I'm not sure if you fully understand the difference between a programming
language and a hardware description language. Yes, HDL's syntax might be
awkward sometimes (whether it's Verilog or VHDL) but I think you are tackling
the wrong problems with the wrong way.

Taking the example you gave:

always @(negedge reset_n or posedge clock) begin

    
    
      if (~reset_n) begin
    
        count <= 4'b0;
    
        FSM <= init;
    
      end else begin
    
        case (FSM)
    
          init: begin
    
            if (count != 4'h8) begin
    
              count <= count + 1;
    
              FSM <= init;
    
            end else
    
              FSM <= next_state;
    
         end
    
       next_state: // blah
    
      end
      
     end
    

end

Can you point exactly what do you think it's wrong with this syntax? And don't
compare it with a while() cycle in C, because this is a totally different
thing. I'm not saying that this is the perfect way of doing things but there
are good reasons why Verilog ended up this way.

I'm really scared with this whole "Hardware design for software developers"
thing. Hardware design is very complex and if you aren't careful with what you
write, you might end with problems like: CDC, synthesis tools mistaking flip-
flops with latches, problems with the insertion of scan chain, and so on.

And by the way, where do you define your clocks in Cx?

~~~
nsiret
In short, I would say.

(Main) advantages: \- The Cx syntax is a lot easier to learn/debug than VHDL
and Verilog (and SystemVerilog, and SystemC) \- Cx is easier to use for making
more complex systems (it's a structured language with Control structures,
Subroutines, blocks, etc). \- Being easier to use, Cx allows you to write
programs faster. Generally these programs are also easier to debug and easier
to maintain. Furthermore, it's easier to manage large, complex programs in Cx.
\- When you do need to have a really low level of abstraction, you can use
VHDL/Verilog and call it in Cx

We are here to help people doing better hardware, and to open it to a majority
of engineers so I don't think that fully understanding the difference (...)
really matters.

Nothing is wrong with the syntax however it's too tedious and complex. In this
simple example it's ok but the more larger the FSM the more complexity to
handle.

How is this a different thing? The init is the same as a loop (n = 0; n < 5;
n++) in software ... It's just more complex to write. I would rather say that
you can do the same in C using a switch case statement... but who will code C
that way today?

Yes it is complex and error probing, and that is precisely why it is our duty
to make it more simple. Handling and preventing the problems is the job of the
compiler so hardware makers can focus on what's matter not on these kinds of
complexities.

Clocks (and resets) can be either implicit or explicit. By default you only
have one clock and reset, and if you need more you can explicit them -
[http://cx-lang.org/documentation/properties](http://cx-
lang.org/documentation/properties)

------
eps
In the example, shouldn't it be checking that stop bits are ones?

Does _available()_ extract and discard the bit if one's available? Or does it
act a flag that's reset upon reading? Why doesn't loop() extract stop bits
then?

I mean, this is clearly aimed at a technical audience with embedded
background, so the code should really match the specs, even if it's just an
illustartive example :)

~~~
MootWoop
Hi I'm the person who wrote this example. In fact you don't need to check that
stop bits are ones because one is the default: when nothing is being written
on the line, it is high all the time. This is why it's just a matter of
convention (number of stop bits) rather than a specific pattern.

EDIT: available checks that data is available on a port. If the test is true,
then you can read from the port; if you don't read from the port, this is
equivalent to an implicit read and data is discarded.

~~~
kw71
Hi. I think this UART can be made better. A typical hardware UART receiver is
clocked at a multiple of the signalling rate (16x is common) and the pin is
sampled according to the clock. During the middle of the bit period, marks on
the bus affect a counter whose value is compared to a constant, the result of
which indicates whether the majority of samples indicate a mark or a space.
The result of this goes into the receive shift register. The samples from the
beginning and the end of the bit period are discarded.

This mechanism allows for timing differences between either end, and some
immunity to electrical noise.

Also, sampling and validating the stop bit(s) will reveal framing errors.

~~~
MootWoop
Thank you for your insight and suggestions! This example is really a toy
implementation to show what the Cx language looks like, so it is not really
suited for a robust hardware core. With this example I put the emphasis on how
easy it is to understand what the Cx code does, and UART is a good use case
because it is small enough.

------
runeks
This looks pretty cool.

Would love to see a toy example of a double-SHA256 engine. Would be kind of
cool if people could build their own Bitcoin mining ASIC, crowd fund it, and
give everyone access to cheap Bitcoin mining ASICs.

~~~
bpg_92
This needs to become a thing!!! I guess I will give Cx a chance.

~~~
MootWoop
We hope so too :) If somehow Cx doesn't live up to its promises and what you
expect from it, please let us know! We're still improving it based on the
feedback we get. Thanks!

------
Quanticles
The VHDL defines a reset and reset conditions, actually uses a clock, and many
other things that the Cx code is leaving out.

~~~
MootWoop
Exactly! Isn't that a breeze? Reset and clock are implicit by default, but you
can always override them (change name, set reset synchronous, etc.)

~~~
kw71
Very cool, I was wondering where the clock was.

