FPGARelated.com
Forums

Basic question: sequence of execution within FPGAs

Started by Unknown August 8, 2014
Trying to get my head around FPGAs after 40 years of 2GLs. I can't
seem to find a clear exposition of the following, would appreciate if
someone could confirm or clarify the following assumption:

I have the following Verilog code say:

always @ (posedge clk)
	begin
	do 1
	do 2
	do 3
	end

assign outA = wireA & wireB
assign outB = wireC & wireD

always @ (posedgeclk)
	begin
	do 4
	do 5
	end


Is the following correct?

1, 2 and 3 are done (more or less) in a sequential manner, ie. the
result of 1 will be present when 2 is performed. Hence, statement
order is important here.

4 and 5 will be done using their own gate resources, clocked "more or
less" in parallel with 1,2,3. However, presumably assuming any sort of
time alignment between the results of the two always blocks would be
risky at best (explicit synchronisation required).   

For the assign statements, does clocking pay a part, or do these
statements simply run at gate delay speed? Or is the answer
device-dependent?

Hi,

you may want to get a modern textbook on synchronous logic. With FPGAs, the
design needs to follow a certain pattern, or things get much more difficult
than they need to be.

In Verilog, don't think of a sequence of statements as ordered in time.
Everything happens concurrently. 
Sometimes the order of statements sets a priority, in a sense that the last
assignment holds.

Here is an example for later statements overruling earlier ones. This isn't
directly related to your example, maybe it is useful, maybe not. 
The code works on a Spartan 6 at 100 MHz.

This...

   always @(posedge i_clk) begin      
      //*****************************************************************
      // default: external bus access, confirmed by o_ack
      //*****************************************************************
      db_addrA		<= i_addr;
      db_dataWA		<= i_data;
      db_weA 		<= i_we;
      o_ack 		<= 1'b1;

assigns input from an external bus source (i_addr, i_data, i_we) to
registers that access a memory internal to this subsystem.

Later during the same block, when moon and stars are in the right
constellation, the unit decides to do its own memory access during the same
cycle, and executes this:

if (... certain conditions apply)
      // reads from data memory
      db_addrA		<= addr;
      // take priority over any external memory access attempt
      db_weA 		<= 1'b0;
      o_ack 		<= 1'b0;

What happens is that any earlier assignment is overruled: A different
address is set, different data, and the write_enable flag is changed as
needed. In this example, "o_ack" gets cleared to tell the outside world
"your bus access attempt was ignored - try again"

	   
					
---------------------------------------		
Posted through http://www.FPGARelated.com
On Fri, 08 Aug 2014 17:38:23 +0800, Bruce Varley wrote:

> Trying to get my head around FPGAs after 40 years of 2GLs. I can't seem > to find a clear exposition of the following, would appreciate if someone > could confirm or clarify the following assumption: > > I have the following Verilog code say: > > always @ (posedge clk) > begin do 1 do 2 do 3 end > > assign outA = wireA & wireB assign outB = wireC & wireD > > always @ (posedgeclk) > begin do 4 do 5 end > > > Is the following correct? > > 1, 2 and 3 are done (more or less) in a sequential manner, ie. the > result of 1 will be present when 2 is performed. Hence, statement order > is important here.
No. Presumably 1, 2 and 3 involve non-blocking assignments (i.e. using <= ) to regs and the statement order isn't important. I assume your code looks something like this: always @(posedge clk) begin reg1 <= (some logic); reg2 <= (some logic); reg3 <= (some logic); end Most coding guides will tell you to only using non-blocking assignments inside a clocked "always block". *Very* roughly, these work in simulation by not updating the destination reg until all the statements have been executed in all the always blocks sensitive to that clock edge. That simulation behaviour matches flip flop functionality in hardware. Note that the following two code fragments are equivalent, both in terms of simulation behaviour and the hardware described, despite one having the statements in reverse order: always @(posedge clk) begin reg1 <= (some logic); reg2 <= reg1; reg3 <= reg2; end always @(posedge clk) begin reg3 <= reg2; reg2 <= reg1; reg1 <= (some logic); end At each clock, reg1 gets the value of (some logic) from before the clock edge. reg2 gets the value of reg1 from before the clock edge. reg3 gets the value of reg2 from before the clock edge. [Switch to fixed point font for the ASCII art] Here are the three flip flops inferred by those code fragments: clk--------+------------+------------+ | | | +-----+ +-----+ +-----+ | C | | C | | C | some | | reg1 | | reg2 | | reg3 logic-->|D Q|----->|D Q|----->|D Q|----> | | | | | | | | | | | | +-----+ +-----+ +-----+ Blocking assignments (using = ) to regs behave roughly like software variables and you can have races between always statements. Don't do that, even though it will seem more familiar to you with your software background. You aren't writing software - you are modelling hardware using a hardware description language (HDL). Make sure you think in terms of hardware, not software.
> 4 and 5 will be done using their own gate resources, clocked "more or > less" in parallel with 1,2,3.
No. Assuming you have used non-blocking statements, 1, 2, 3, 4 and 5 all infer flip flops clocked by the same clock signal. Logic resources will be allocated / shared / replicated / optimised at the synthesiser's whim and this is not necessarily influenced by grouping (or even hierarchy) in your source code, unless you have explicitly told the synthesiser not to share (perhaps with an attribute). You should group them so that it makes the code easier to understand and maintain.
> However, presumably assuming any sort of > time alignment between the results of the two always blocks would be > risky at best (explicit synchronisation required).
Again, if using non-blocking assignments, you can ignore execution order.
> For the assign statements, does clocking pay a part, or do these > statements simply run at gate delay speed? Or is the answer > device-dependent?
They describe combinatorial logic. No clock is involved. In hardware, two AND gates are generated. The actual delay you get will be determined by ... well, it's probably more determined by the routing than the actual gates (which are pretty fast in contemporary devices). You can control the delay by applying timing constraints in the tools. In most cases you won't do this as the output of the combinatorial logic is simply feeding another flip flop, and the timing constraint you gave for the minimum clock period takes care of all paths (including the combinatorial logic) between flip flops clocked by that clock. I hope this helps. [I apologise if some of my descriptions don't use the correct terminology wrt the Verilog LRM. I'm just trying to explain the gist of the thing.] Allan
On Fri, 08 Aug 2014 17:38:23 +0800, Bruce Varley wrote:

> Trying to get my head around FPGAs after 40 years of 2GLs. I can't seem > to find a clear exposition of the following, would appreciate if someone > could confirm or clarify the following assumption: > > I have the following Verilog code say: > > always @ (posedge clk) > begin do 1 do 2 do 3 end > > assign outA = wireA & wireB assign outB = wireC & wireD > > always @ (posedgeclk) > begin do 4 do 5 end > > > Is the following correct? > > 1, 2 and 3 are done (more or less) in a sequential manner, ie. the > result of 1 will be present when 2 is performed. Hence, statement order > is important here. > > 4 and 5 will be done using their own gate resources, clocked "more or > less" in parallel with 1,2,3. However, presumably assuming any sort of > time alignment between the results of the two always blocks would be > risky at best (explicit synchronisation required). > > For the assign statements, does clocking pay a part, or do these > statements simply run at gate delay speed? Or is the answer > device-dependent?
Hey Bruce: This is just a supplement to what Allan and Mark have said: You are NOT writing software. The reason it's called a hardware description language is because it does just that -- it describes the structure of some hardware. It's up to you to make sure that the structure thus described behaves the way you want it to. This isn't easy for a seasoned software engineer to wrap their heads around -- I have trouble with it whenever I go visiting FPGA-land, in spite of the fact that I have no such trouble when I'm designing analog circuits with schematics. I agree with Allan's recommendation -- get a book on logic design with Verilog. A good book will devote at least half of the content to language-independent issues, essentially telling you what you want to get. The rest of the content will go into the differences between simulation and synthesis, how to write the code for synthesis, and how to structure your test bench to properly test the code that'll actually make an FPGA. -- Tim Wescott Control system and signal processing consulting www.wescottdesign.com
On Fri, 08 Aug 2014 17:38:23 +0800, Bruce Varley wrote:

>Trying to get my head around FPGAs after 40 years of 2GLs. I can't >seem to find a clear exposition of the following, would appreciate if >someone could confirm or clarify the following assumption: > >I have the following Verilog code say: > >always @ (posedge clk) > begin > do 1 > do 2 > do 3 > end > >assign outA = wireA & wireB >assign outB = wireC & wireD > >always @ (posedgeclk) > begin > do 4 > do 5 > end > > >Is the following correct? > >1, 2 and 3 are done (more or less) in a sequential manner, ie. the >result of 1 will be present when 2 is performed. Hence, statement >order is important here. > >4 and 5 will be done using their own gate resources, clocked "more or >less" in parallel with 1,2,3. However, presumably assuming any sort of >time alignment between the results of the two always blocks would be >risky at best (explicit synchronisation required). > >For the assign statements, does clocking pay a part, or do these >statements simply run at gate delay speed? Or is the answer >device-dependent?
Well, I have some work (and some backtracking) to do. Many thanks for the good info, folks.
On 8/8/2014 12:09 PM, Tim Wescott wrote:
> > I agree with Allan's recommendation -- get a book on logic design with > Verilog. A good book will devote at least half of the content to > language-independent issues, essentially telling you what you want to > get. The rest of the content will go into the differences between > simulation and synthesis, how to write the code for synthesis, and how to > structure your test bench to properly test the code that'll actually make > an FPGA.
Most of my HDL background is with VHDL and I have only used Verilog when required. I have asked a number of times about a good Verilog reference and been repeatedly told there aren't any. Has that changed? Do you have one you like? -- Rick
On Sun, 10 Aug 2014 14:20:09 -0400, rickman wrote:

> On 8/8/2014 12:09 PM, Tim Wescott wrote: >> >> I agree with Allan's recommendation -- get a book on logic design with >> Verilog. A good book will devote at least half of the content to >> language-independent issues, essentially telling you what you want to >> get. The rest of the content will go into the differences between >> simulation and synthesis, how to write the code for synthesis, and how >> to structure your test bench to properly test the code that'll actually >> make an FPGA. > > Most of my HDL background is with VHDL and I have only used Verilog when > required. I have asked a number of times about a good Verilog reference > and been repeatedly told there aren't any. Has that changed? Do you > have one you like?
I'm not really qualified to answer that. By training I'm a designer of analog circuits, control systems, and low-level communications algorithms (i.e., detecting bits). By experience I'm all of those, but my actual customer deliverables have been primarily lines of C or C++ code; a GOOD project is one where I'm backing that up with control or comms design. I have done exactly one small job each with Verilog and VHDL, and the comment I got back from the (real) digital guys on my VHDL code was "you're a software guy, aren't you?" (well, no -- I'm an analog circuit designer who puts food on the table by writing C++ code, but I certainly LOOK like a software guy when the light is shining from a certain direction). The books that I have are "The Verilog Hardware Description Language" by Thomas & Moorby, and the IEEE Verilog Standard. Thomas & Moorby was selected because, out of the three books on the shelf at Powell's Technical Books that day in 2003, it was the one that seemed to be the most clear and informative. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
On 8/10/2014 3:19 PM, Tim Wescott wrote:
> On Sun, 10 Aug 2014 14:20:09 -0400, rickman wrote: > >> On 8/8/2014 12:09 PM, Tim Wescott wrote: >>> >>> I agree with Allan's recommendation -- get a book on logic design with >>> Verilog. A good book will devote at least half of the content to >>> language-independent issues, essentially telling you what you want to >>> get. The rest of the content will go into the differences between >>> simulation and synthesis, how to write the code for synthesis, and how >>> to structure your test bench to properly test the code that'll actually >>> make an FPGA. >> >> Most of my HDL background is with VHDL and I have only used Verilog when >> required. I have asked a number of times about a good Verilog reference >> and been repeatedly told there aren't any. Has that changed? Do you >> have one you like?
...snip...
> The books that I have are "The Verilog Hardware Description Language" by > Thomas & Moorby, and the IEEE Verilog Standard. Thomas & Moorby was > selected because, out of the three books on the shelf at Powell's > Technical Books that day in 2003, it was the one that seemed to be the > most clear and informative.
The most important thing I would want from a Verilog book wasn't mentioned in your list of features of a good Verilog book, a description of the pitfalls of the Verilog language. The issues you cover are all language independent in my opinion. I once asked specifically about finding a book to cover the pitfalls and was told that none existed. I asked again a year or two ago and was told the same thing. Unfortunately I have become very accustomed to writing VHDL and have lost any strong desire to become as proficient in Verilog. If "the" book becomes available I might buy it and finish my education, but I'm not expecting that to happen. -- Rick
Tim Wescott <seemywebsite@myfooter.really> wrote:
> On Sun, 10 Aug 2014 14:20:09 -0400, rickman wrote:
(snip)
>> Most of my HDL background is with VHDL and I have only used Verilog when >> required. I have asked a number of times about a good Verilog reference >> and been repeatedly told there aren't any. Has that changed? Do you >> have one you like?
(snip)
> I have done exactly one small job each with Verilog and VHDL, and the > comment I got back from the (real) digital guys on my VHDL code was > "you're a software guy, aren't you?" (well, no -- I'm an analog circuit > designer who puts food on the table by writing C++ code, but I certainly > LOOK like a software guy when the light is shining from a certain > direction).
> The books that I have are "The Verilog Hardware Description Language" by > Thomas & Moorby, and the IEEE Verilog Standard. Thomas & Moorby was > selected because, out of the three books on the shelf at Powell's > Technical Books that day in 2003, it was the one that seemed to be the > most clear and informative.
Yes, and I would recommend it, too. You want a nice reference that you can look something up in when you need to. Some will probably complain that it isn't up to date with the newer standards, but most of the time that isn't a problem. I like writing structural verilog, using continuous assignment and module references, except that registers are in behavioral verilog. I put the registers into a module, and just reference that when I need one. (Like reg8 for an 8 bit register.) Some people like behavioral verilog, as it is more similar to writing software, but to me that distracts from the fact that it isn't software. Like analog circuits and digital logic, you have to remember that everything happens all the time, not sequentially like in C. If you think sequentially, you will write poor and inefficient verilog (or VHDL). For those who grew up in the days of TTL (or MSI CMOS), thinking about wiring up gates, I believe it is fairly easy to learn to think in verilog. Think about wires and gates. (And it shouldn't be so hard for analog designers.) But people used to thinking sequentially, like writing a C program, will have a harder time. Now, consider the design of a digital clock. Years ago, you would wire up some 7490 and 7492 counters, some 7447 (or maybe 7441) decoders, and let them count away. A little more recently, it might be done with a microprocessor or microcontroller, probably multiplexing the display. (That is, for those that don't use an LSI clock chip.) In the case of a digital clock, you don't need anywhere near the 10's of MHz that TTL can run at, and there is plenty of time to update the display in a software loop. Both make inefficent use of the available hardware resources, but that is fine. -- glen
It is crucial to understand how synthesis works, but it is not necessary to=
 code a netlist of the HW you think will do what you want.

In 20+ years of VHDL-based FPGA development, I have made behavioral mistake=
s FAR more often than I have made HW design mistakes (in other words, the c=
ircuit was viable and reliable, it just didn't do what I wanted it to).

Writing the code such that the clock cycle behavior is at least as apparent=
, if not moreso, than the HW circuit helps avoid the most common mistakes.

Sure, there are cases where I have to code "closer to the HW" to get perfor=
mance or utilization where I need it, but those are few and far between. To=
o far to code that way all the time.

Learn what behaviors infer latches (bad), registers and ram (good). Study t=
he synthesis tool's examples for ram inference, but learn their behavior, n=
ot so much about how they happened to code that behavior. This will let you=
 write portable code that will work for multiple target FPGAs.

Describe the desired behavior on every clock cycle. Think in terms of behav=
ior and clock cycles of latency, rather than gates and registers. The latte=
r will go to pot as soon as you turn on retiming and pipelining optimizatio=
ns anyway.

Andy