Author Topic: Good intros to FPGAs?  (Read 10075 times)

0 Members and 1 Guest are viewing this topic.

Online pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3704
  • Country: nl
Re: Good intros to FPGAs?
« Reply #50 on: July 04, 2022, 09:00:11 am »
Or is this some bizarre pile on from a bunch of people who don't actually use or write HDL?

I can only speak for myself, but I'm in the process of learning HDL. I have not yet run into a situation where I needed a "for loop" construction and your example with the priority encoder helped in seeing a use for it. Can't directly think of a setup where the "for loop" has to do a variable number of iterations, like you pointed out to be possible, but assume they will exist.

As this thread is about "intros to FPGAs" I think the whole "for loop" discussion is a bit to advanced and so you are on the mark with your S/N ratio remark earlier.

For me good to know the "for loop" exists and what it can do. The pointer to the nandland.com website is very useful. :-+

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Good intros to FPGAs?
« Reply #51 on: July 04, 2022, 04:02:38 pm »
The 'for loop' discussion brings out 2 points:  HDL doesn't work like C and, generally, HDL for loops are used to replicate logic.

Suppose you had a component that implemented a 1 bit full adder with Carry In, A, B as inputs and Y, Carry Out as outputs.  Nothing special, just a neat 1 bit adder.

You would use a 'for' loop to connect 16 of these adders in series to create a 16 bit full adder

You can follow along here but the 'for' loop is on page 13 (there are previous incantations, I think this is the cleanest):

http://osorio.wait4.org/SSC0113/AULA02/eecs_317_adder.pdf

It is an elegant way of avoiding having to write out 'n' lines of code to describe the interconnects.  But you could!  It might be a great exercise to unroll the loop on page 13 line 8.  In fact, I highly recommend it.  It will put the 'for loop' to bed.

The first line to get synthesized looks like:
Code: [Select]
full_adder PORT MAP (t(0), a(0), b(0), S(0), t(1));

This kind of 'for' loop is used all the time but it is important to realize that it is unrolled during synthesis. It is not executed as logic.

The take-away from all of this is the HDL isn't C and shutting off the application code mindset is going to be very important.  You need to think in terms of gates and flops.  Gates and flops...  You could actually write your VHDL at the gate and flop level.  It would be verbose and cumbersome but it could be done.  The HDL allows us to take a step up and think in terms of components.

You not only need to think about the value of a signal, you need to think about when, exactly, it changes.  You need to keep quite a few signals in mind as you write the code because it's going to matter when they change relative to some other chunk of code which relies on them.  When do the signals get updated?


« Last Edit: July 04, 2022, 04:12:59 pm by rstofer »
 
The following users thanked this post: agehall

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19500
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Good intros to FPGAs?
« Reply #52 on: July 04, 2022, 04:38:04 pm »
This kind of 'for' loop is used all the time but it is important to realize that it is unrolled during synthesis. It is not executed as logic.

The take-away from all of this is the HDL isn't C and shutting off the application code mindset is going to be very important.  You need to think in terms of gates and flops.  Gates and flops...  You could actually write your VHDL at the gate and flop level.  It would be verbose and cumbersome but it could be done.  The HDL allows us to take a step up and think in terms of components.

Precisely.

It is useful, and often necessary, to write your code at the gate level - particularly if you expand "gate" to include IP supplied by the device manufacturer.

The benefits are that you can instantiate well-designed components that can't easily be defined in HDLs. Examples include specific IO blocks e.g. SERDES or DRAM interfaces, clock tiles with specific properties, clock distribution strategies, signals that cross clock domains. By "wiring together" such blocks in an HDL, you get the benefit of predictable performance that is not subject to the whim of the synthesis and placement tools. That can be vital as you push the capabilities of the FPGAs in terms of speed and performance.

Note those benefits are the same as the benefits for wiring ICs together :)
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline laugensalm

  • Regular Contributor
  • *
  • Posts: 105
  • Country: ch
Re: Good intros to FPGAs?
« Reply #53 on: July 04, 2022, 08:01:21 pm »
The whole loop argument would be pretty much void, if generator statements for hardware elements are semantically separated from flow of control (which needs to be run in order to synthesize), somewhat following the C preprocessor analogon brought up earlier.
Yes, VHDL has the `generate` keyword, but you can still write funky code using functions and variables where the synthesis path becomes obscure and non-explicit. It also makes synthesis support of the usual set of language constructs explode in complexity, some may argue that those V*-Languages were never designed with synthesis in mind and that you'll be left with writing non-portable code for specific tools anyhow. Unfortunately, that's what can make development in V* very tedious and why they were avoided for a large project here in the first place.

As a software minded person, I tend to waste less time with language peculiarities when inference paths/design rules are under control and things are spelled out in a simple and as explicit-as-possible manner. Like for example, Python code for a bit flip logic:

Code: [Select]
    @sensitivity.generator
    def wireup():
        for i in range(8):
            j = 7 - i
            yield [ z[i] <= s[j] ]

The above code is run for transfer to RTL and the list in `yield` contains the statements that directly infer to RTL (logic), in this case a simple assignment. There's more aspects to it: Verification can be done in-situ, plus translation style is determined by the caller instead of pragma-style decoration/configuration options/ifdef mess.
Nevertheless, V* is eventually used for transfer and possibly for primitive (gate) level verification. So even when using simplified Python or other flashy HDL approaches, being able to debug V* is pretty mandatory when it comes to the engineering part, i.e. moving from the dry dock of the simulation world towards a real hardware project, like having to write a crt0.s when starting bare metal as a C coder.

The discussion seems to have gotten off track - to wrap this up and to not scare the TO any further: there's pretty much two approaches, either starting out with a specific hardware and some refdesign to hack on in whatever language, or the dry dock abstracted approach without the requirement to buy any hardware, focusing on the actual modeling, simulation and verification. I guess it's pretty much of personal preference which gives more 'instant gratification', some just like seeing those LEDs blink. Both approaches worked for us, but most important thing is to be able to debug (tools, knowledge) in order to be effective and avoid frustrations. And to stay with the event driven way of thinking before moving on the HLS concepts.


 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Good intros to FPGAs?
« Reply #54 on: July 04, 2022, 09:20:47 pm »
A badly thought out view is that iteration that loops provides in programming splits into two types - iterative processing and iterating over data. Loops in HDL are great for iterating over data, but not so good for iterative processing.

I wouldn't want to use a loop to calculate Fibonacci numbers based on an input value, but I would use a loop to add two large sets of numbers together.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: Someone

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Good intros to FPGAs?
« Reply #55 on: July 04, 2022, 11:00:51 pm »
The take-away from all of this is the HDL isn't C and shutting off the application code mindset is going to be very important.  You need to think in terms of gates and flops.  Gates and flops...  You could actually write your VHDL at the gate and flop level.  It would be verbose and cumbersome but it could be done.  The HDL allows us to take a step up and think in terms of components.

You not only need to think about the value of a signal, you need to think about when, exactly, it changes.  You need to keep quite a few signals in mind as you write the code because it's going to matter when they change relative to some other chunk of code which relies on them.  When do the signals get updated?
No. That is the path straight to a world of pain. People who do this tend to write obfustigated, unmaintainable HDL code. If you are going to work on more complex projects, you'll get stuck quickly because thinking in gates & flipflops is equal to writing a C program using inline assembler. I've come across lots of VHDL code where 10 to 15 lines could be replaced by 3 lines at most. The best way to becoming an effective FPGA developer is to use a HDL and all it's features (like functions, records, etc) to the fullest extend to describe a problem and let the synthesizer deal with it. 99% of the logic in most designs doesn't even need to be fast. Optimise the 1% that doesn't meet timing requirements.

For example: I never infer instantiate memory; I create an array but I do read the synthesis manual to understand how the synthesizer deals with the memory. But in the end it is the synthesizer that will choose to use memory blocks or flipflops to create the actual memory in logic.

All this leads to highly flexible and re-usable code that is also easy to understand and maintain.

Edit: typo
« Last Edit: July 05, 2022, 07:56:56 am by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14472
  • Country: fr
Re: Good intros to FPGAs?
« Reply #56 on: July 04, 2022, 11:37:55 pm »
Memories can be tricky. Sure the simplest ones are a no-brainer, but as soon as you wanna make the tools infer true dual-port stuff, make sure its gets into EBR rather than distributed memory, and most of all, as soon as you wanna implement some kind of "byte enable" (that's the one I had the most trouble with trying to use pure HDL, with most vendors), things can get problematic fast, and that's where you'll end up instantiating a vendor primitive/IP.
 

Offline Someone

  • Super Contributor
  • ***
  • Posts: 4531
  • Country: au
    • send complaints here
Re: Good intros to FPGAs?
« Reply #57 on: July 05, 2022, 12:08:21 am »
The first line to get synthesized looks like:
Code: [Select]
full_adder PORT MAP (t(0), a(0), b(0), S(0), t(1));
This kind of 'for' loop is used all the time but it is important to realize that it is unrolled during synthesis. It is not executed as logic.
It actually depends on the synthesiser, some internal intermediary might be an unrolling of that loop but it's never explicit or required. Funnily enough that example is one where using a loop to build hand crafted adders is often less resource efficient than just adding higher level signed/unsigned vectors with that hard to understand."+" operator :P Synthesis can pull out larger optimised structures with higher level code. While the optimisation of logic is usually impressive, trying to infer larger functions from logic usually fails. Writing out a gate level adder rarely maps to the hard adder resources.

Synthesis is not standardised, its tool/device/vendor specific. People trying to say it will do anything specific are living in dreamland. The tools take the HDL standard and implement what was described, they don't use inspectable things like loop unrolling, and even if they did (in some specific circumstances) by the time the logic optimisation ran over it the result would be unrecognisable.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19500
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Good intros to FPGAs?
« Reply #58 on: July 05, 2022, 12:19:24 am »
Memories can be tricky. Sure the simplest ones are a no-brainer, but as soon as you wanna make the tools infer true dual-port stuff, make sure its gets into EBR rather than distributed memory, and most of all, as soon as you wanna implement some kind of "byte enable" (that's the one I had the most trouble with trying to use pure HDL, with most vendors), things can get problematic fast, and that's where you'll end up instantiating a vendor primitive/IP.

Precisely.

And with other components such as queues crossing clock domains, specialised IO blocks, and complex vendor supplied IP functional components.

A good engineer uses what the tool manufacturers provide, rather than taking a long time to reinvent an elliptical wheel.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Good intros to FPGAs?
« Reply #59 on: July 05, 2022, 01:05:39 am »
Precisely.

It is useful, and often necessary, to write your code at the gate level - particularly if you expand "gate" to include IP supplied by the device manufacturer.

While using components is useful, I have not found it necessary to use gate level coding... ever.  Typically, instantiation is used for very special cases, or modularity in the design.  Virtually never gates or anything at the TTL MSI level or below. 

Things like counters, adders, and registers are a single line of code for the declaration and very few lines of code for the RTL description.  I've never used components for those.


Quote
The benefits are that you can instantiate well-designed components that can't easily be defined in HDLs. Examples include specific IO blocks e.g. SERDES or DRAM interfaces, clock tiles with specific properties, clock distribution strategies, signals that cross clock domains. By "wiring together" such blocks in an HDL, you get the benefit of predictable performance that is not subject to the whim of the synthesis and placement tools. That can be vital as you push the capabilities of the FPGAs in terms of speed and performance.

I don't know that speed is actually the issue.  You literally can't infer special purpose blocks in the HDL typically.  Clock multiplexers are a good example.  I've never seen an HDL inference that would work in place of an instantiation.  SERDES is just one of those blocks of logic that can't be inferred, no?


Quote
Note those benefits are the same as the benefits for wiring ICs together :)

As opposed to writing HDL and using programmable logic?
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Good intros to FPGAs?
« Reply #60 on: July 05, 2022, 01:09:11 am »
For example: I never infer memory; I create an array but I do read the synthesis manual to understand how the synthesizer deals with the memory. But in the end it is the synthesizer that will choose to use memory blocks or flipflops to create the actual memory in logic.

All this leads to highly flexible and re-usable code that is also easy to understand and maintain.

I think you meant you *always* infer memory and never instantiate it.  Is that right? 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Good intros to FPGAs?
« Reply #61 on: July 05, 2022, 01:14:07 am »
Memories can be tricky. Sure the simplest ones are a no-brainer, but as soon as you wanna make the tools infer true dual-port stuff, make sure its gets into EBR rather than distributed memory, and most of all, as soon as you wanna implement some kind of "byte enable" (that's the one I had the most trouble with trying to use pure HDL, with most vendors), things can get problematic fast, and that's where you'll end up instantiating a vendor primitive/IP.

My preference would be to infer everything I can, but memory can be tricky.  You have to tailor it to the synthesis engine and the target, so in the end, it is not nearly as flexible as you might want.  Even with inference, I've had to have different code for different families of parts.

Instantiation can be a real PITA.  Has anyone tried to work with the Gowin documentation for their libraries?  It is a pretty ugly combination of different types of diagrams, some showing all the bits and bobs in the chip to allow flexibility and other diagrams seem to be tailored to specific modes, but good luck tying any of it to the library components. 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Good intros to FPGAs?
« Reply #62 on: July 05, 2022, 07:56:25 am »
For example: I never infer memory; I create an array but I do read the synthesis manual to understand how the synthesizer deals with the memory. But in the end it is the synthesizer that will choose to use memory blocks or flipflops to create the actual memory in logic.

All this leads to highly flexible and re-usable code that is also easy to understand and maintain.

I think you meant you *always* infer memory and never instantiate it.  Is that right?
You are right. I'll change it.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Good intros to FPGAs?
« Reply #63 on: July 05, 2022, 08:24:02 am »
Memories can be tricky. Sure the simplest ones are a no-brainer, but as soon as you wanna make the tools infer true dual-port stuff, make sure its gets into EBR rather than distributed memory, and most of all, as soon as you wanna implement some kind of "byte enable" (that's the one I had the most trouble with trying to use pure HDL, with most vendors), things can get problematic fast, and that's where you'll end up instantiating a vendor primitive/IP.

Precisely.

And with other components such as queues crossing clock domains, specialised IO blocks, and complex vendor supplied IP functional components.

A good engineer uses what the tool manufacturers provide, rather than taking a long time to reinvent an elliptical wheel.
The problem is that manufacturers tend to provide tools that are dumbed down or don't offer maximum flexibility. In reality instantiation is mostly a remnant of the time where programmable logic was defined using schematic entry.

Specific to the memory example: try to design a truly generic FIFO. If you infer memory, the synthesizer can choose the optimum type of memory depending on the depth of the FIFO. This means you never have to bother with choosing between FIFOs depending on what kind of programmable logic you are using. However, to make such a design succefully you have to understand how the synthesizer deals with infering memory so you can write the HDL in a way it does what you want.

In general: it is well worth spending time on reading the synthesis manual. It makes your workflow much more efficient compared to instantiating all kinds of vendor specific blocks because that also requires to understand those blocks fully. Another example: many FPGAs have DSP blocks. Usually these aren't the easiest to instantiate. Inferring these is much easier because you can simply write: a = b*c +d in HDL which on top of everything is also much easier to understand for someone else looking at the code.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
Re: Good intros to FPGAs?
« Reply #64 on: July 05, 2022, 08:48:28 am »
.
« Last Edit: August 19, 2022, 05:41:39 pm by emece67 »
 
The following users thanked this post: nctnico, Someone, Bassman59

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19500
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Good intros to FPGAs?
« Reply #65 on: July 05, 2022, 09:24:57 am »
Precisely.

It is useful, and often necessary, to write your code at the gate level - particularly if you expand "gate" to include IP supplied by the device manufacturer.

While using components is useful, I have not found it necessary to use gate level coding... ever.  Typically, instantiation is used for very special cases, or modularity in the design.  Virtually never gates or anything at the TTL MSI level or below. 

Things like counters, adders, and registers are a single line of code for the declaration and very few lines of code for the RTL description.  I've never used components for those.

Agreed. That's why I didn't use those as examples, and why I explicitly expanded "gate" to include arbitrarily complex functional blocks.

Quote
Quote
The benefits are that you can instantiate well-designed components that can't easily be defined in HDLs. Examples include specific IO blocks e.g. SERDES or DRAM interfaces, clock tiles with specific properties, clock distribution strategies, signals that cross clock domains. By "wiring together" such blocks in an HDL, you get the benefit of predictable performance that is not subject to the whim of the synthesis and placement tools. That can be vital as you push the capabilities of the FPGAs in terms of speed and performance.

I don't know that speed is actually the issue. 

Speed is usually an issue. Poorly constrained implementations lead to "trivial" changes drastically changing the maximum speed.

In some cases I've had to resort to manually nailing down blocks so that the placement can give remotely useful results.

I always consider floorplanning when starting a design. It goes with the territory of defining clock domains before starting implementation.

"Thinking in procedural languages" when designing software systems leads to fragile distributed/networked software applications. People ignore that their design could fail because of a computer you didn't know existed and which is under the control of another company.

Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.

Quote
You literally can't infer special purpose blocks in the HDL typically.  Clock multiplexers are a good example.  I've never seen an HDL inference that would work in place of an instantiation.  SERDES is just one of those blocks of logic that can't be inferred, no?

Yes, as I said.

They have to be instantiated, and that doesn't fit well into the mentality of using a procedural language.

Quote
Quote
Note those benefits are the same as the benefits for wiring ICs together :)

As opposed to writing HDL and using programmable logic?

I was discussing principle. Using pre-existing blocks, whether IPs or ICs, is conceptually very similar. The size/complexity hidden within the blocks changes over time, but the principle remains unchanged.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Good intros to FPGAs?
« Reply #66 on: July 05, 2022, 11:36:50 am »
Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.
No, what you write only applies to people that do not take the timing relationships into account. But that is a competence issue, not a problem that comes from using a higher level language.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19500
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Good intros to FPGAs?
« Reply #67 on: July 05, 2022, 11:54:50 am »
Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.
No, what you write only applies to people that do not take the timing relationships into account. But that is a competence issue, not a problem that comes from using a higher level language.

Strawman argument. In this context, that specific incompetence stems from using the tool inappropriately, i.e. thinking you can "write like C" in an HDL.

Remember that's the OP's starting point: thinking that experience creating arduino/C applications might be relevant to FPGA/HDL applications.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: Sal Ammoniac, Bassman59

Offline laugensalm

  • Regular Contributor
  • *
  • Posts: 105
  • Country: ch
Re: Good intros to FPGAs?
« Reply #68 on: July 05, 2022, 12:09:03 pm »
For some time ago I think that all those hype on HLS tools, MyHDL, Migen and others came bacause people do not really understand (or believe on) the true capabilities of VHDL, SystemVerilog and modern synthesis tools. I also in doubt that the astounding results of SpinalHDL cannot be mimmicked with modern VHDL/SV. Many still think that traditional HDLs are just a textual means to describe netlists, instead of a textual means to describe behavior, structure and information flow, and at different levels of abstraction.

Believe me, those *working* on the innards of those HDL generator languages understand the architectural details and flaws of Verilog and VHDL very well. One good read on the simple integer arithmetics pitfalls: https://www.jandecaluwe.com/hdldesign/counting.html.
When having to write architecture-agnostic code that needs to verify for ASIC silicon as well, verification of authored VHDL or Verilog95 code proves highly ineffective compared to modern approaches.

And even if the languages would be improved, take for example VHDL2019: No FPGA tool maintainer is actually expecting to ever integrate support for it. So, real world looks like this: We're still stuck with a subset of VHDL93 for most tools, no OO, no user defined data types that would allow to specify inference behaviour. Same hassle for the full SystemVerilog language set.

With primitive-connection-based versus behaviour-based HDL authoring: first will always synthesize for a specific architecture (but isn't portable). Second will not necessarily infer as wanted or be understood at all by various synthesis tools (let aside non-portable attribute decorations). So one is eventually left with iterating through a mixture of both approaches in order to keep code portable. For large projects, this is a real maintenance nightmare and a lot of copy-paste engineering. Yes, when the V*-languages were conceived, engineers didn't really make use of OOP, nor did they have a concept of functional programming (which makes transpilation/translation a lot less expensive).

This is something where functional and OO approaches for transpilation to V* or direct RTL are way less costly, be it Scala or Python based. Nevertheless, even if a full verification chain is present for HDL X -> result, one might have to be able to read V*, because Tools just make mistakes and the only 'copper standards' available in this domain are for those two V* (Let aside integration of external code/blackbox primitives)

 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: Good intros to FPGAs?
« Reply #69 on: July 05, 2022, 12:10:50 pm »
Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.
No, what you write only applies to people that do not take the timing relationships into account. But that is a competence issue, not a problem that comes from using a higher level language.

Strawman argument. In this context, that specific incompetence stems from using the tool inappropriately, i.e. thinking you can "write like C" in an HDL.
It is not a strawman argument. You can actually 'write like C' using HDL (sequential versus parallel aside) but just like in C you have a finite amount of resources to complete a task in time. One of the problems is that people think that 'in time' means that only the fastest solution suffices but that isn't true. That isn't what 'in time' means. Remember that optimisation before figuring out whether or not you actually need optimisation, is a waste of effort and money.
« Last Edit: July 05, 2022, 01:28:05 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19500
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Good intros to FPGAs?
« Reply #70 on: July 05, 2022, 01:30:25 pm »
Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.
No, what you write only applies to people that do not take the timing relationships into account. But that is a competence issue, not a problem that comes from using a higher level language.

Strawman argument. In this context, that specific incompetence stems from using the tool inappropriately, i.e. thinking you can "write like C" in an HDL.
It is not a strawman argument. You can actually 'write like C' using HDL (sequential versus parallel aside) but just like in C you have a finite amount of resources to complete a task in time. One of the problems is that people think that 'in time' means the fastest solution but that isn't true. That isn't what 'in time' means. Remember that optimisation before figuring out whether or not you actually need optimisation, is a waste of effort and money.

Sure all the languages are Turing complete (just like the C++ preprocessor language!), and you can write Fortran in any language. Speed is irrelevant to that. I'm sure you've seen such idiocies as well.

You can also use a bicycle to cross the USA or go over the Alps, but that doesn't make it a good idea. (Unless you are Dervla Murphy going to India in 1963, as per "Full Tilt" :) )
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Good intros to FPGAs?
« Reply #71 on: July 05, 2022, 03:07:51 pm »
I don't know that speed is actually the issue. 

Speed is usually an issue. Poorly constrained implementations lead to "trivial" changes drastically changing the maximum speed.

I don't find the tools to be the problem with speed.  Speed problems usually come from either poorly written code, meaning it expands into large logic, or and overly crowded chip that prevents good placement and efficient routing.


Quote
In some cases I've had to resort to manually nailing down blocks so that the placement can give remotely useful results.

I always consider floorplanning when starting a design. It goes with the territory of defining clock domains before starting implementation.

I'm not sure what that means.  Floorplanning is something you do to constrain placement.  It has no meaning before you have a design.  If your designs are so difficult to meet timing, that you have to plan the placement before you do the design, then you are in the 1% of designs that are pushing the chips to their limits. 

I don't normally have designs like that.


Quote
"Thinking in procedural languages" when designing software systems leads to fragile distributed/networked software applications. People ignore that their design could fail because of a computer you didn't know existed and which is under the control of another company.

Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.

I think you are carrying that water too far and your bucket has a leak. 


Quote
Quote
You literally can't infer special purpose blocks in the HDL typically.  Clock multiplexers are a good example.  I've never seen an HDL inference that would work in place of an instantiation.  SERDES is just one of those blocks of logic that can't be inferred, no?

Yes, as I said.

They have to be instantiated, and that doesn't fit well into the mentality of using a procedural language.

Whatever that means.  My point is there are times when instantiation is required. Otherwise, I use inference which works just fine.  I typically have some idea of what logic and in particular, registers will be inferred.  It's not my goal to dominate the tool and use inference as a substitute for instantiation, meaning, controlling the inference so tightly that I get exactly what I want.  The point is to let the tool do the walking!


Quote
Quote
Quote
Note those benefits are the same as the benefits for wiring ICs together :)

As opposed to writing HDL and using programmable logic?

I was discussing principle. Using pre-existing blocks, whether IPs or ICs, is conceptually very similar. The size/complexity hidden within the blocks changes over time, but the principle remains unchanged.

So you are talking modularity?  Yes, but even with that, my designs use most modules exactly once.  It's more a way of decomposing the design to give it structure and an means of testing units rather than the whole.  Instantiation is seldom about component reuse because most components don't get reused.  Pretty not much like wiring ICs together where you use the same ICs over and over.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19500
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Good intros to FPGAs?
« Reply #72 on: July 05, 2022, 04:11:30 pm »
I don't know that speed is actually the issue. 

Speed is usually an issue. Poorly constrained implementations lead to "trivial" changes drastically changing the maximum speed.

I don't find the tools to be the problem with speed.  Speed problems usually come from either poorly written code, meaning it expands into large logic, or and overly crowded chip that prevents good placement and efficient routing.

You misunderstand. I've seen a design with, IIRC, around 40% occupancy, mostly datapath with a relatively small amount of control logic. A trivial change in the control logic caused a factor of 4 change in the maximum clock rate. Nailing down the data path reduced the clock rate change to essentially zero.

Go figure.

Quote
Quote
In some cases I've had to resort to manually nailing down blocks so that the placement can give remotely useful results.

I always consider floorplanning when starting a design. It goes with the territory of defining clock domains before starting implementation.

I'm not sure what that means.  Floorplanning is something you do to constrain placement.  It has no meaning before you have a design.  If your designs are so difficult to meet timing, that you have to plan the placement before you do the design, then you are in the 1% of designs that are pushing the chips to their limits. 

I disagree. Perhaps my designs are pushing the limits harder than yours.

Quote
I don't normally have designs like that.


Quote
"Thinking in procedural languages" when designing software systems leads to fragile distributed/networked software applications. People ignore that their design could fail because of a computer you didn't know existed and which is under the control of another company.

Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.

I think you are carrying that water too far and your bucket has a leak. 

Unhelpful analogy which gives no insight. I've seen the effects I've described.

Quote
Quote
Quote
You literally can't infer special purpose blocks in the HDL typically.  Clock multiplexers are a good example.  I've never seen an HDL inference that would work in place of an instantiation.  SERDES is just one of those blocks of logic that can't be inferred, no?

Yes, as I said.

They have to be instantiated, and that doesn't fit well into the mentality of using a procedural language.

Whatever that means.  My point is there are times when instantiation is required. Otherwise, I use inference which works just fine.  I typically have some idea of what logic and in particular, registers will be inferred.  It's not my goal to dominate the tool and use inference as a substitute for instantiation, meaning, controlling the inference so tightly that I get exactly what I want.  The point is to let the tool do the walking!

I have no idea what you mean by "dominate the tool".

Inference and instantiation are orthogonal. You can (and do) have inference with and without instantiation.

Software programmers, particularly when using C and higher optimisation levels, often have to look at the asm code to see if there are any "unexpected" effects (that's why the Linux kernel uses -O2 not -O3). Similarly it is often beneficial (and sometimes necessary) to look at what the synthesis and placement has done with your design.

Quote
Quote
Quote
Quote
Note those benefits are the same as the benefits for wiring ICs together :)

As opposed to writing HDL and using programmable logic?

I was discussing principle. Using pre-existing blocks, whether IPs or ICs, is conceptually very similar. The size/complexity hidden within the blocks changes over time, but the principle remains unchanged.

So you are talking modularity?  Yes, but even with that, my designs use most modules exactly once.  It's more a way of decomposing the design to give it structure and an means of testing units rather than the whole.  Instantiation is seldom about component reuse because most components don't get reused.  Pretty not much like wiring ICs together where you use the same ICs over and over.

We are discussing several effects, in this case modularity.

Whatever the modularity, whether or not you are instantiating one or more instances of a component is irrelevant.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2218
  • Country: pr
Re: Good intros to FPGAs?
« Reply #73 on: July 05, 2022, 05:36:13 pm »
I don't know that speed is actually the issue. 

Speed is usually an issue. Poorly constrained implementations lead to "trivial" changes drastically changing the maximum speed.

I don't find the tools to be the problem with speed.  Speed problems usually come from either poorly written code, meaning it expands into large logic, or and overly crowded chip that prevents good placement and efficient routing.

You misunderstand. I've seen a design with, IIRC, around 40% occupancy, mostly datapath with a relatively small amount of control logic. A trivial change in the control logic caused a factor of 4 change in the maximum clock rate. Nailing down the data path reduced the clock rate change to essentially zero.

What does "nailing down the data path" mean exactly? 

Do you understand what caused the change in clock rate?


Quote
Go figure.

Quote
Quote
In some cases I've had to resort to manually nailing down blocks so that the placement can give remotely useful results.

I always consider floorplanning when starting a design. It goes with the territory of defining clock domains before starting implementation.

I'm not sure what that means.  Floorplanning is something you do to constrain placement.  It has no meaning before you have a design.  If your designs are so difficult to meet timing, that you have to plan the placement before you do the design, then you are in the 1% of designs that are pushing the chips to their limits. 

I disagree. Perhaps my designs are pushing the limits harder than yours.

Ok, so you have more designs in the 1% then.


Quote
Quote
I don't normally have designs like that.


Quote
"Thinking in procedural languages" when designing software systems leads to fragile distributed/networked software applications. People ignore that their design could fail because of a computer you didn't know existed and which is under the control of another company.

Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.

I think you are carrying that water too far and your bucket has a leak. 

Unhelpful analogy which gives no insight. I've seen the effects I've described.

Ok, then can you provide some examples of "thinking in procedural languages"?  I've never seen anyone code an entire design in sequential code such as processes, although that's perfectly reasonable too.  I don't know of any designs that can't be done in sequential code.  So I'm thinking I not following what you mean by the term above.


Quote
Quote
Quote
Quote
You literally can't infer special purpose blocks in the HDL typically.  Clock multiplexers are a good example.  I've never seen an HDL inference that would work in place of an instantiation.  SERDES is just one of those blocks of logic that can't be inferred, no?

Yes, as I said.

They have to be instantiated, and that doesn't fit well into the mentality of using a procedural language.

Whatever that means.  My point is there are times when instantiation is required. Otherwise, I use inference which works just fine.  I typically have some idea of what logic and in particular, registers will be inferred.  It's not my goal to dominate the tool and use inference as a substitute for instantiation, meaning, controlling the inference so tightly that I get exactly what I want.  The point is to let the tool do the walking!

I have no idea what you mean by "dominate the tool".

Inference and instantiation are orthogonal. You can (and do) have inference with and without instantiation.

Software programmers, particularly when using C and higher optimisation levels, often have to look at the asm code to see if there are any "unexpected" effects (that's why the Linux kernel uses -O2 not -O3). Similarly it is often beneficial (and sometimes necessary) to look at what the synthesis and placement has done with your design.

I've not seen software people dig into the asm code routinely unless they HAD a problem to solve.  No one codes in C caring about the asm, mostly, because it is hard to understand after the tool is done optimizing it.  Often it is much more efficient than what is hand coded. 

I look at the synthesis result on small blocks that I wish to optimize or when learning to use a new tool.  If this is done routinely, like with writing C code, it becomes very time wasting.  I use the same coding styles over and over, so once I've learned a tool, I don't need to keep looking over my shoulder to check that the result is effective. 

Here's an analogy.  I got a kayak and proceeded to kayak for some weeks or even months before learning from others.  I found I was gripping the paddle too tightly, trying to control every aspect of its motion.  I learned that the paddle finds its own center and a relaxed grip is much less tiring.  I code that way as well, relaxed, using the style that works for the tool I'm using.  I don't need to keep checking it unless there's a problem.

Like with the kayak paddle, if you are getting poor results, you probably have a poor style for that tool.  Rather than fix things with instantiation (gripping the paddle tightly) it is better to learn how to code properly for the tool (a relaxed grip with an understanding of how the paddle should be used).  I find it much less tiring to work with the tools, rather than to beat them into submission with excessive use of instantiation. 


Quote
Quote
Quote
Quote
Quote
Note those benefits are the same as the benefits for wiring ICs together :)

As opposed to writing HDL and using programmable logic?

I was discussing principle. Using pre-existing blocks, whether IPs or ICs, is conceptually very similar. The size/complexity hidden within the blocks changes over time, but the principle remains unchanged.

So you are talking modularity?  Yes, but even with that, my designs use most modules exactly once.  It's more a way of decomposing the design to give it structure and an means of testing units rather than the whole.  Instantiation is seldom about component reuse because most components don't get reused.  Pretty not much like wiring ICs together where you use the same ICs over and over.

We are discussing several effects, in this case modularity.

Whatever the modularity, whether or not you are instantiating one or more instances of a component is irrelevant.

I'm not sure what you are discussing.  Modularity in HDL is done with instantiation mostly.  Some people use procedures, but I find that limiting. 

Modularity is to facilitate understanding the design, as well as testing and decision hiding.  I don't use it to control layout, mostly because I seldom need to control layout.  Controlling layout to achieve timing, is under the heading of optimization which is to be avoided if possible.  I certainly don't do it routinely. 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 
The following users thanked this post: nctnico

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 19500
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Good intros to FPGAs?
« Reply #74 on: July 05, 2022, 06:27:27 pm »
I don't know that speed is actually the issue. 

Speed is usually an issue. Poorly constrained implementations lead to "trivial" changes drastically changing the maximum speed.

I don't find the tools to be the problem with speed.  Speed problems usually come from either poorly written code, meaning it expands into large logic, or and overly crowded chip that prevents good placement and efficient routing.

You misunderstand. I've seen a design with, IIRC, around 40% occupancy, mostly datapath with a relatively small amount of control logic. A trivial change in the control logic caused a factor of 4 change in the maximum clock rate. Nailing down the data path reduced the clock rate change to essentially zero.

What does "nailing down the data path" mean exactly? 

Do you understand what caused the change in clock rate?

Placing individual LUTs in the datapath. And it was an exceedingly simple and regular datapath.

The tools placed the datapath "suboptimally", for reasons best known to itself. That meant the control path timing changed radically, with consequent timing changes.

Quote
Quote
Go figure.

Quote
Quote
In some cases I've had to resort to manually nailing down blocks so that the placement can give remotely useful results.

I always consider floorplanning when starting a design. It goes with the territory of defining clock domains before starting implementation.

I'm not sure what that means.  Floorplanning is something you do to constrain placement.  It has no meaning before you have a design.  If your designs are so difficult to meet timing, that you have to plan the placement before you do the design, then you are in the 1% of designs that are pushing the chips to their limits. 

I disagree. Perhaps my designs are pushing the limits harder than yours.

Ok, so you have more designs in the 1% then.

Who knows whether it is 1%, 5%, 10%, 50%. And who cares.

Any engineer will choose the smallest slowest cheapest part for their design; anything else is wasteful.

Quote
Quote
Quote
I don't normally have designs like that.


Quote
"Thinking in procedural languages" when designing software systems leads to fragile distributed/networked software applications. People ignore that their design could fail because of a computer you didn't know existed and which is under the control of another company.

Thinking in procedural languages when designing FPGAs leads to fragile hardware implementations where I/O has multiple different clocks. People that ignore that their design could fail due to metastability problems even in plesiochronous systems where the clock rates are nominally the same.

I think you are carrying that water too far and your bucket has a leak. 

Unhelpful analogy which gives no insight. I've seen the effects I've described.

Ok, then can you provide some examples of "thinking in procedural languages"?  I've never seen anyone code an entire design in sequential code such as processes, although that's perfectly reasonable too.  I don't know of any designs that can't be done in sequential code.  So I'm thinking I not following what you mean by the term above.

See earlier posts in this thread. More generally, use duckduckgo.

Quote
Quote
Quote
Quote
Quote
You literally can't infer special purpose blocks in the HDL typically.  Clock multiplexers are a good example.  I've never seen an HDL inference that would work in place of an instantiation.  SERDES is just one of those blocks of logic that can't be inferred, no?

Yes, as I said.

They have to be instantiated, and that doesn't fit well into the mentality of using a procedural language.

Whatever that means.  My point is there are times when instantiation is required. Otherwise, I use inference which works just fine.  I typically have some idea of what logic and in particular, registers will be inferred.  It's not my goal to dominate the tool and use inference as a substitute for instantiation, meaning, controlling the inference so tightly that I get exactly what I want.  The point is to let the tool do the walking!

I have no idea what you mean by "dominate the tool".

Inference and instantiation are orthogonal. You can (and do) have inference with and without instantiation.

Software programmers, particularly when using C and higher optimisation levels, often have to look at the asm code to see if there are any "unexpected" effects (that's why the Linux kernel uses -O2 not -O3). Similarly it is often beneficial (and sometimes necessary) to look at what the synthesis and placement has done with your design.

I've not seen software people dig into the asm code routinely unless they HAD a problem to solve.  No one codes in C caring about the asm, mostly, because it is hard to understand after the tool is done optimizing it.  Often it is much more efficient than what is hand coded. 

The combination of the C compiler optimiser, the C language specification, and programmer knowledge combine to cause "surprises". That's why LinusT doesn't allow using -O3 and above in the Linux kernel.
"- -O3 has a *loong* history of generating worse code than -O2 so I will *not* be taking these kinds of patches without some very serious explanations of why -O3 has suddenly become acceptable again. "
https://www.phoronix.com/scan.php?page=news_item&px=Linus-Against-O3-Kernel

Quote
I look at the synthesis result on small blocks that I wish to optimize or when learning to use a new tool.  If this is done routinely, like with writing C code, it becomes very time wasting.  I use the same coding styles over and over, so once I've learned a tool, I don't need to keep looking over my shoulder to check that the result is effective. 

The OP is not in that position.

My jobs have rarely involved such repetition, because if that was the case then it couldn't be my job!

Distracting uus with yor backwoods experiences won't shed any light on FPGA designs.

Quote
Here's an analogy.  I got a kayak and proceeded to kayak for some weeks or even months before learning from others.  I found I was gripping the paddle too tightly, trying to control every aspect of its motion.  I learned that the paddle finds its own center and a relaxed grip is much less tiring.  I code that way as well, relaxed, using the style that works for the tool I'm using.  I don't need to keep checking it unless there's a problem.

Like with the kayak paddle, if you are getting poor results, you probably have a poor style for that tool.  Rather than fix things with instantiation (gripping the paddle tightly) it is better to learn how to code properly for the tool (a relaxed grip with an understanding of how the paddle should be used).  I find it much less tiring to work with the tools, rather than to beat them into submission with excessive use of instantiation. 


Quote
Quote
Quote
Quote
Quote
Note those benefits are the same as the benefits for wiring ICs together :)

As opposed to writing HDL and using programmable logic?

I was discussing principle. Using pre-existing blocks, whether IPs or ICs, is conceptually very similar. The size/complexity hidden within the blocks changes over time, but the principle remains unchanged.

So you are talking modularity?  Yes, but even with that, my designs use most modules exactly once.  It's more a way of decomposing the design to give it structure and an means of testing units rather than the whole.  Instantiation is seldom about component reuse because most components don't get reused.  Pretty not much like wiring ICs together where you use the same ICs over and over.

We are discussing several effects, in this case modularity.

Whatever the modularity, whether or not you are instantiating one or more instances of a component is irrelevant.

I'm not sure what you are discussing.  Modularity in HDL is done with instantiation mostly.  Some people use procedures, but I find that limiting. 

Modularity is to facilitate understanding the design, as well as testing and decision hiding.  I don't use it to control layout, mostly because I seldom need to control layout.  Controlling layout to achieve timing, is under the heading of optimization which is to be avoided if possible.  I certainly don't do it routinely.

Suitable coding styles can indeed help the synthesiser and placement tools. Coding styles derived from previous experiences with procedural programming languages are not suitable.

Controlling layout is a last resort to achieve the required function. Yes, speed is normally part of the required function.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf