Mixed clocked/combinatorial coding styles

Andy wrote:

"We" have already given several examples that are compelling to many
of us:

Ease of discerning cycle based behavior from the code
Decoupling, etc. without resorting to separate files/entities/
architectures
Proximity of the variable definition to where it is used
Simulation efficiency
All true, but I'm missing the most important point: the difference
in semantics between signals and variables.

There are things you can do with variables that you cannot easily
accomplish with signals. So they add another dimension to the game.

In particular, in a clocked process the same variable can be used
both "combinatorially" and "as a register". Once you get that,
the opportunities for elegant HDL solutions for real problems
pop up everywhere.

I consider register inference from variables the most powerful
tool in the RTL toolbox - however it is poorly understood and
probably banned in a majority of design teams.

http://myhdl.jandecaluwe.com/doku.php/cookbook:jc2

Jan

--
Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
Kaboutermansstraat 97, B-3000 Leuven, Belgium
From Python to silicon:
http://myhdl.jandecaluwe.com
 
rickman <gnuarm@gmail.com> writes:

On Aug 22, 6:19 am, Jan Decaluwe <j...@jandecaluwe.com> wrote:

I consider register inference from variables the most powerful
tool in the RTL toolbox - however it is poorly understood and
probably banned in a majority of design teams.

Not to mention poorly supported compared to signals, both in
simulation and synthesis.
I really can't imagine a modern simulator not supporting variables to
spec, surely! That would be just plain broken!

If you use variables, you will see more bugs and limitations of the
tools. Why? I guess because it is just not as mainstream. Kinda
like driving a Maserati for the daily commute.
I've never seen a variable-related bug in my time. In the old days
there we *limitations*, but I haven't come across any of those
recently either in the tools I use. And I use a *lot* of variables
(and records, and procedures within processes, and all sorts of other
things that didn't used to work, but make my life easier *now*).

YMMV however :)

Cheers,
Martin

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
On Aug 22, 6:19 am, Jan Decaluwe <j...@jandecaluwe.com> wrote:
I consider register inference from variables the most powerful
tool in the RTL toolbox - however it is poorly understood and
probably banned in a majority of design teams.
Not to mention poorly supported compared to signals, both in
simulation and synthesis. If you use variables, you will see more
bugs and limitations of the tools. Why? I guess because it is just
not as mainstream. Kinda like driving a Maserati for the daily
commute.

Rick
 
On Aug 21, 1:11 pm, Mike Treseler <miket_trese...@comcast.net> wrote:
rickman wrote:
I have no idea why you would use two processes for the above???

I wouldn't.
I assumed that others would.
How would you do it?

Yes, it would appear that, to you, there are a lot of things that I
can't see. For example, I can't see how you would make use of a
variable outside of the process it is defined in. Or is "down here"
still inside the process?

Yes. Sorry but I can't publish this entire entity.
See my published examples for simpler cases.

Why is your point so hard to explain?

I don't know.
My preference is based on writing shell scripts, C and python.
Well, that makes sense. If you are used to writing software, then you
will be more comfortable with variables. I have a much stronger
hardware background. I design my hardware in block diagrams, tables
and state charts before I write any code (if needed). I then write
the code that describes the registers and logic. I take the D in HDL
literally (hardware Description language) and use the language to
describe the hardware I want. I actually did not get a job offer
once because I said that I code RTL. One of the lead engineers felt
very strongly that this was too inefficient to be effective and
blackballed an offer. Funny, I seem to be doing just fine on the
engineering side of things. I wish I had a business manager though.

This is in the clocked process
accum_v <= accum_v + addend_c;

This is a concurrent statement
msb_v <= accum_v(accum_v'high);

I don't recall needing this in a phase accumulator. Isn't the top bit
just your output signal? The NCOs I have written were producing a
digital output of 1 bit for use as a clock. Otherwise, why would you
need the carry? Actually, I didn't use the carry out. I used the
msb. Maybe I don't understand what you are doing with this.
accum_v(accum_v'length-1) := '0'; -- clear carry for next time

I guess my way uses an extra bit in the accumulator, one more than you
have in the phase increment register. You look at this as saving the
"carry" bit. But I don't get why you don't retain the carry bit into
the sum. But then it has been a while since I have done an NCO.
Maybe I am forgetting some things. BTW, "clearing" the carry can be
done in the sum if you really need to.

accum_v <= '0' & accum_v(accum_v'high-1 downto 0) + addend_c;

But where did the extra bit in the addend_c come from? Do you have a
bit in the addend that is never set?

Rick
 
rickman wrote:
I don't recall needing this in a phase accumulator. Isn't the top bit
just your output signal?
That would be a counter Q type output.
I need to enable a prescaler with a carry-out.

By saving the bit before clearing it
I have exactly what I need and synthesis
does a fine job with the carry chain details.
I guess the advantage I see with variables
is this ability to build up the values
I need in sequential steps and to make
the computer do more of the detail work.

-- Mike Treseler
 
On Fri, 22 Aug 2008 14:15:29 +0100, Martin Thompson wrote:

I've never seen a variable-related bug in my time. In the old days
there we *limitations*, but I haven't come across any of those
recently either in the tools I use. And I use a *lot* of variables
(and records, and procedures within processes, and all sorts of other
things that didn't used to work, but make my life easier *now*).

YMMV however :)
That's interesting. I did some Xilinx work recently, and reluctantly had
to change my code. I used variables for the sake of 'localization' - the
Xilinx simulator simulated it correctly, but XST gave me some warnings and
indeed when I scoped related outputs from the FPGA, some of the logic
related to the variables had been removed in line with the warnings.

My variable use was pretty simple - slv set in an async reset block and at
the end of the clocked part of the process, and used only in the clocked
part. I couldn't see anything wrong with it, and neither could the
simulator.

Regards,

Paul.
 
On Fri, 22 Aug 2008 05:39:40 -0700, rickman wrote:

Not to mention poorly supported compared to signals, both in
simulation and synthesis. If you use variables, you will see more
bugs and limitations of the tools. Why? I guess because it is just
not as mainstream. Kinda like driving a Maserati for the daily
commute.
If the tools don't support variables then I find that rather frustrating,
and using your car analogy, consider them old skoda style.

Regards,

Paul.
 
Paul Taylor wrote:

That's interesting. I did some Xilinx work recently, and reluctantly had
to change my code. I used variables for the sake of 'localization' - the
Xilinx simulator simulated it correctly, but XST gave me some warnings and
indeed when I scoped related outputs from the FPGA, some of the logic
related to the variables had been removed in line with the warnings.
Post the code and I'll have a look.
Did you miss a port assignment?
There are many reasons that synthesis may remove logic
and none that I know of have to do with variables vs signals.
My examples here:
http://mysite.verizon.net/miketreseler/
use variables exclusively, and work fine with xst.

-- Mike Treseler
 
On Sat, 23 Aug 2008 08:44:32 -0700, Mike Treseler wrote:

Paul Taylor wrote:

That's interesting. I did some Xilinx work recently, and reluctantly had
to change my code. I used variables for the sake of 'localization' - the
Xilinx simulator simulated it correctly, but XST gave me some warnings and
indeed when I scoped related outputs from the FPGA, some of the logic
related to the variables had been removed in line with the warnings.

Post the code and I'll have a look.
Did you miss a port assignment?
There are many reasons that synthesis may remove logic
and none that I know of have to do with variables vs signals.
My examples here:
http://mysite.verizon.net/miketreseler/
use variables exclusively, and work fine with xst.
I'll have access to the code again next week - I'll have another look at
it and post it.

Thanks,

Paul.
 
rickman wrote:
Of course with FPGAs also initial values can be used and then no reset
is connected to the FF. The initial value comes from the configuration
file in that case.

But this requires the global set reset signal. That is how the FFs
get their initial state.
No it does not. The FF state is set via the SRAM configuration cells
during the chip powerup.

Not always. You can also use the FFs without any reset and give initial
values for the signals. Most synthesizers can transfer those values
to configuration image.

I don't think this is the rule. If you want to write portable code,
you need to use a reset as part of the clocked process.
For portable code that works also with ASICs the reset signal is almost
mandatory. But for pure FPGAs the initial values can be used, and
for fast designs they save routing resources.

And and least Synplify supports initial values in signals and memories,
if the used FPGA also supports them. And most of the FPGA families
support setting of the initial value of FF, and also in many families
the memory contents can be set to predefined values.

It might cause problems, because the internal global reset lines inside
FPGA are quite slow. And the signal might not propagate trough the FPGA
...
Maybe if you are running at 200 MHz. There are always speed issues in
any design. That is why you use timing constraints. You do use
timing constraints, right?
Usually if you put timing constraint to the synchronous reset it pops
out from the global line, because it is too slow. And also for multiple
clock domains reset networks in normal routing are needed. I have
sometimes asked from the FPGA manufacturers if they could build global
resets that are fast, and can be split to create many clock domains.
After that they would be more useful, single clock domain designs are
quite rare at least in telecommunication side.

--Kim
 
On Aug 25, 3:17 am, Kim Enkovaara <kim.enkova...@iki.fi> wrote:
rickman wrote:
Of course with FPGAs also initial values can be used and then no reset
is connected to the FF. The initial value comes from the configuration
file in that case.

But this requires the global set reset signal. That is how the FFs
get their initial state.

No it does not. The FF state is set via the SRAM configuration cells
during the chip powerup.
You are confused. The FFs do not have SRAM configuration cells that
set the initial state of the FF. The configuration memory sets the
select lines on a number of multiplexers in the logic cell as well as
other control points that remain fixed throughout the life of a given
configuration. They also control the routing elements outside the
logic cell. Finally, they *are* the LUT (along with some pass
transistors) that determines the logic. But there is no configuration
ram that sets the initial state of the FFs in the logic cells of a
Xilinx, Altera or Lattice FPGA that I have seen.


For portable code that works also with ASICs the reset signal is almost
mandatory. But for pure FPGAs the initial values can be used, and
for fast designs they save routing resources.
The routing resource for the global set/reset is dedicated and can't
be used for any other purpose. Why? Because it is *always* used by
the GSR whether or not you decide to control its use.


And and least Synplify supports initial values in signals and memories,
if the used FPGA also supports them. And most of the FPGA families
support setting of the initial value of FF, and also in many families
the memory contents can be set to predefined values.
That may be true. But until it becomes a standard that is followed by
all vendors, you can't count on it when you write your code, unless
you don't care about portability. I sometimes write non-portable
code. But I try to limit it small, application specific code sections
that are well documented and easy to replace when doing a port. But
to toss the global set/reset would require a major rewrite if you need
to add it back at any time because you switched tools.


Usually if you put timing constraint to the synchronous reset it pops
out from the global line, because it is too slow. And also for multiple
clock domains reset networks in normal routing are needed. I have
sometimes asked from the FPGA manufacturers if they could build global
resets that are fast, and can be split to create many clock domains.
After that they would be more useful, single clock domain designs are
quite rare at least in telecommunication side.
That may be true for designs at very high speed, but actually a sync
reset can be distributed on a clock line which should do the job quite
nicely.

The main point is that one of us has a misunderstanding of how a logic
cell FF gets it's initial state. I think this is fundamental to the
discussion. I am pretty confident that I am correct, but if you know
I am wrong, I would like to know that. I would feel like a fool if I
were having this discussion with a customer and turned out to be
wrong. I much prefer to find out now.

Rick
 
On Aug 22, 7:55 am, rickman <gnu...@gmail.com> wrote:
Well, that makes sense. If you are used to writing software, then you
will be more comfortable with variables. I have a much stronger
hardware background. I design my hardware in block diagrams, tables
and state charts before I write any code (if needed). I then write
the code that describes the registers and logic. I take the D in HDL
literally (hardware Description language) and use the language to
describe the hardware I want. I actually did not get a job offer
once because I said that I code RTL. One of the lead engineers felt
very strongly that this was too inefficient to be effective and
blackballed an offer. Funny, I seem to be doing just fine on the
engineering side of things. I wish I had a business manager though.

SW vs HW orientation as a preference motivation makes sense to me
also. I have more background in HW design than in SW, but when it
comes to executable language based descriptions (HDL), I guess I now
emphasize the L(anguage) part more. I started out coding HDL like I
used to draw schematics (this is a register, that is the gates, etc.),
but saw very limited benefit to using the language that way. I can
place and wire up a schematic symbol for a register faster than I can
type it's inference. The ability to describe more complex things like
state machines etc. was much easier in HDL though, especially when I
learned that you can infer the register for free in the same process.
From there I gradually adopted a more "software-like" approach to RTL
coding. I also took a couple of ada programming courses to gain some
knowledge in the use of packages, procedures, functions, etc. That's
where I started learning about using scoping rules to isolate an
implementation from its interface, at various levels of design. I
started out using all that stuff (including variables) in test
benches, then gradually started using it in RTL code (perhaps a bit of
a misnomer).

Mike's example is a very good one because it demonstrates that you can
take advantage of the immediate update behavior of variables to do
things that would be more difficult in signals. Your counter-example
of using a concurrent assignment is functionally valid, but I prefer
not to hop out of a sequential process, into a concurrent statement,
and then back to the process when I can use a variable to do the same
thing without changing contexts. Another benefit occurs when the
device driver writer and I are in the lab, integrating his SW with my
HW. Having an HDL coding style that both of us can understand is very
handy (I could already understand his programming language). I lost
count of how many times I used to have to explain that sequential code
(processes) using signals is only partially sequential, the updates
still happen concurrently. Perhaps that's another reason why the HW
approach to HDL coding makes more sense to some users: that's the only
way you can really make sense of signals in clocked processes (by
mentally mapping them to registers), they sure don't make sense
functionally to me.

I use Synplify almost exclusively, and it is very good with variables.
The times I've tried XST (admittedly somewhat in the past), I did not
appreciate its relative inflexibility, and usually got better results
from Synplify anyway.

Andy
 
On Aug 25, 1:08 pm, rickman <gnu...@gmail.com> wrote:
On Aug 25, 3:17 am, Kim Enkovaara <kim.enkova...@iki.fi> wrote:

rickman wrote:
Of course with FPGAs also initial values can be used and then no reset
is connected to the FF. The initial value comes from the configuration
file in that case.

But this requires the global set reset signal.  That is how the FFs
get their initial state.

No it does not. The FF state is set via the SRAM configuration cells
during the chip powerup.

You are confused.  The FFs do not have SRAM configuration cells that
set the initial state of the FF.  
Kim said the 'configuration file' not 'SRAM configuration cells',
there is a difference.

The configuration memory sets the
select lines on a number of multiplexers in the logic cell as well as
other control points that remain fixed throughout the life of a given
configuration.  They also control the routing elements outside the
logic cell.  Finally, they *are* the LUT (along with some pass
transistors) that determines the logic.  But there is no configuration
ram that sets the initial state of the FFs in the logic cells of a
Xilinx, Altera or Lattice FPGA that I have seen.
There might not be a 'configuration ram' (as you call it), but there
are bits in the bitstream in the 'configuration file' (as Kim calls
it) that are a part of the data set that gets downloaded to the device
to implement the initial values. At leasst with Altera devices, this
all gets done without any 'global set/reset' signals, the only signals
needed are the ones needed to download the bitstream file. Once the
device configuration process has been completed, those initial values
are there.

Lastly, I might add that there may not even be specific bits in the
bitstream to say that flip flop #235 which happens to hold signal
'xyz' needs to be initialized to '1'. Instead the logic can be
implemented in such a fashion that the device, when it finishes
configuration and is begining initialization *prior* to coming alive
and being in user mode (i.e the chip at this point isn't totally alive
yet running your design) that all the flip flops simply get reset. In
that type of situation, the code would implement negative logic for
signal 'xyz' and then wherever 'xyz' is used, it would invert it
again. This double inversion is a fairly common way to implement
arbitrary power up states and since invertors are 'free' inside an
FPGA it is a very cost effective way as well.

For a discussion of Altera Cyclone II devices refer to
http://www.altera.com/literature/hb/cyc2/cyc2_cii5v1_06.pdf

They don't specifically say *how* they get things into the proper
initialization state but
- They do initialize memory and flip flops
- No special pins are needed (just the pins used to download the
bitstream). Spcifically there is no need for a 'GSR'.
- User specified default values for memory and flops are honored.

And and least Synplify supports initial values in signals and memories,
if the used FPGA also supports them. And most of the FPGA families
support setting of the initial value of FF, and also in many families
the memory contents can be set to predefined values.

That may be true.  But until it becomes a standard that is followed by
all vendors, you can't count on it when you write your code, unless
you don't care about portability.  
It is already is a standard (i.e. the VHDL language says so). Although
I haven't looked to see if it is part of the synthesis subset in IEEE
1076.6. even if it is not, once some of the competition supports
something that gives the users of the laggard tools some ammo to have
them get their tools up to date. What tool are you using that does
not support it? Perhaps you should consider opening a case with
them. After all, there aren't that many synthesis tools out there,
opening a case can get results...maybe not when you need it 'today',
but at least by the time you need it down the road. That improves the
tools for everyone.

That may be true for designs at very high speed, but actually a sync
reset can be distributed on a clock line which should do the job quite
nicely.

The main point is that one of us has a misunderstanding of how a logic
cell FF gets it's initial state.  I think this is fundamental to the
discussion.  I am pretty confident that I am correct, but if you know
I am wrong, I would like to know that.  I would feel like a fool if I
were having this discussion with a customer and turned out to be
wrong.  I much prefer to find out now.
I think the method by which initial values get loaded could be a
device specific discussion that the vendors may not fully disclose.

I will say that for the devices I've been using I do not need to use
the asynchronous reset form of a process or have any GSR signal to get
initial values loaded. Those initial values specified in the source
code get turned into a bitstream that when downloaded to the device
does seem to work...and when it doesn't I open a case with the
supplier.

But as I mentioned a while back, about the only time I actually *use*
initial values or async resets at all is to for the shift register(s)
used to generate the reset signal(s) that are synchronized to the
various clock(s)...and I can do it all without need for any external I/
O pin to initiate that reset.

KJ
 
On Aug 25, 12:08 pm, rickman <gnu...@gmail.com> wrote:
On Aug 25, 3:17 am, Kim Enkovaara <kim.enkova...@iki.fi> wrote:

rickman wrote:
Of course with FPGAs also initial values can be used and then no reset
is connected to the FF. The initial value comes from the configuration
file in that case.

But this requires the global set reset signal. That is how the FFs
get their initial state.

No it does not. The FF state is set via the SRAM configuration cells
during the chip powerup.

You are confused. The FFs do not have SRAM configuration cells that
set the initial state of the FF. The configuration memory sets the
select lines on a number of multiplexers in the logic cell as well as
other control points that remain fixed throughout the life of a given
configuration. They also control the routing elements outside the
logic cell. Finally, they *are* the LUT (along with some pass
transistors) that determines the logic. But there is no configuration
ram that sets the initial state of the FFs in the logic cells of a
Xilinx, Altera or Lattice FPGA that I have seen.

For portable code that works also with ASICs the reset signal is almost
mandatory. But for pure FPGAs the initial values can be used, and
for fast designs they save routing resources.

The routing resource for the global set/reset is dedicated and can't
be used for any other purpose. Why? Because it is *always* used by
the GSR whether or not you decide to control its use.

And and least Synplify supports initial values in signals and memories,
if the used FPGA also supports them. And most of the FPGA families
support setting of the initial value of FF, and also in many families
the memory contents can be set to predefined values.

That may be true. But until it becomes a standard that is followed by
all vendors, you can't count on it when you write your code, unless
you don't care about portability. I sometimes write non-portable
code. But I try to limit it small, application specific code sections
that are well documented and easy to replace when doing a port. But
to toss the global set/reset would require a major rewrite if you need
to add it back at any time because you switched tools.

Usually if you put timing constraint to the synchronous reset it pops
out from the global line, because it is too slow. And also for multiple
clock domains reset networks in normal routing are needed. I have
sometimes asked from the FPGA manufacturers if they could build global
resets that are fast, and can be split to create many clock domains.
After that they would be more useful, single clock domain designs are
quite rare at least in telecommunication side.

That may be true for designs at very high speed, but actually a sync
reset can be distributed on a clock line which should do the job quite
nicely.

The main point is that one of us has a misunderstanding of how a logic
cell FF gets it's initial state. I think this is fundamental to the
discussion. I am pretty confident that I am correct, but if you know
I am wrong, I would like to know that. I would feel like a fool if I
were having this discussion with a customer and turned out to be
wrong. I much prefer to find out now.

Rick
To be precise, at least in Xilinx FPGAs, there is a configuration bit
that determines whether the GSR signal will reset or preset the
associated register(s). The GSR signal is asserted during and until
shortly after configuration. The GSR signal is what activates the set/
preset, but the configuration bit determines the initial state of the
register.

The application of a "synchronized asynchronous" reset (asynchronous
assertion and reset/preset operation, synchronous deassertion and
resumption of clocked operation) for multiple clock domains requires
multiple reset signals, each one appropriately synchronized to the
destination clock.

The GSR and such locally synchronized reset signals are logically
OR'ed at each CLB. The GSR block used to allow synchronization of GSR
to a single user clock, but I'm not sure if it still does, or if
synthesis tools typically implement it that way, since the propagation
delay on the GSR net is very slow.

I can personally attest that asynchronous reset synchronization is
most certainly NOT a red herring!

Andy
 
On Aug 25, 2:59 pm, Andy <jonesa...@comcast.net> wrote:
I also took a couple of ada programming courses to gain some
knowledge in the use of packages, procedures, functions, etc. That's
where I started learning about using scoping rules to isolate an
implementation from its interface, at various levels of design.
Ok, now we are getting somewhere. When you took the programming
courses, what did they teach was the reason for wanting to use
"scoping rules to isolate an implementation from it's interface"? If
those reasons are not concrete and don't apply equally to HDL as to
software, then I see no need to carry that baggage.

I find there are any number of important techniques in software design
that are much less important when coding in an HDL. The idea of scope
is one of those rules. The concept of scope is to prevent you from
using the wrong variable in the wrong situation when you only need to
be able to access a few "local" variables. Why is this important in
software design? Because when variables were global, people often
used them in very confusing ways. The real issue is how people used
them. A method of forcing better programming skills is to limit how
you can access variables.

I don't find this to be an issue in coding in HDL. For one, my code
is generally structured by using entities. For another, these sort of
rules have much less benefit for more experienced programmers. It is
not unlike training wheels. When you are learning, they help keep you
from making mistakes. But once you have enough experience to balance
on your own, why keep the training wheels? I have given up on a
number of software rules that I learned in college. Not that they
aren't useful, I just don't need to enforce them strictly because I
know when they are useful and when they get in the way.


Mike's example is a very good one because it demonstrates that you can
take advantage of the immediate update behavior of variables to do
things that would be more difficult in signals. Your counter-example
of using a concurrent assignment is functionally valid, but I prefer
not to hop out of a sequential process, into a concurrent statement,
and then back to the process when I can use a variable to do the same
thing without changing contexts.
Hopping, I don't think I have ever heard it expressed that way. I
don't like breaking code up into excessively small pieces either. But
I find very few cases where this happens. The only time I pull logic
outside of a process is when the signal is useful outside of the
process and I want it to be combinatorial, not sequential. If I don't
want a signal to be clocked, I just don't make an assignment to it
inside a clocked process. In fact, to use a variable outside of a
process requires that you make it a global variable and that opens the
can of worms that you are trying to keep a lid on.


Another benefit occurs when the
device driver writer and I are in the lab, integrating his SW with my
HW. Having an HDL coding style that both of us can understand is very
handy (I could already understand his programming language). I lost
count of how many times I used to have to explain that sequential code
(processes) using signals is only partially sequential, the updates
still happen concurrently. Perhaps that's another reason why the HW
approach to HDL coding makes more sense to some users: that's the only
way you can really make sense of signals in clocked processes (by
mentally mapping them to registers), they sure don't make sense
functionally to me.
I don't want to badmouth software people. But the last couple of
cooperative working situations I had made me want to work alone as
much as possible. But I feel no need in any case to alter the way I
code to suit someone who has no need to view my code. That is
certainly no reason to burden myself with using features that I have
no need for.

Rick
 
rickman wrote:
The main point is that one of us has a misunderstanding of how a logic
cell FF gets it's initial state. I think this is fundamental to the
discussion. I am pretty confident that I am correct, but if you know
I am wrong, I would like to know that. I would feel like a fool if I
were having this discussion with a customer and turned out to be
wrong. I much prefer to find out now.
I would say that this information is device family specific and
information that the vendors are not telling in their datasheets
completely, it is partly visible in the netlists the external
synthesizers generate, but how are those attributes transferred to
bitstream is proprietary.

For example in V5 FF there are 6 settable parameters (FF, LATCH,
INIT1, INIT0, SRHIGH, SRLOW). Are those INIT0/1 bits only in the
bitstream and processed during the upload, or are they persistent,
I do not know. At the end of September I'll meet some A and X guys
who might know the answer, I'll ask if I remember.

This is for example from the V5 manual. How this is implemented is not
told.

"The initial state after configuration or global initial state is
defined by separate INIT0 and INIT1 attributes. By default, setting the
SRLOW attribute sets INIT0, and setting the SRHIGH attribute sets INIT1.
Virtex-5 devices can set INIT0 and INIT1 independent of SRHIGH and
SRLOW."

For Altera the SIV documentation was quite vague on this area. But
at least in the past they had only "init to zero" style thing, and
they added inversion if one was needed. Actually Synplify 8.8
had a bug in this inversion, with retiming it got very confused
wheter the signal was inverted or not ;)


--Kim
 
rickman wrote:

For one, my code
is generally structured by using entities.
I share this preference narrowly:

1. When I do have to wire things up myself,
I prefer to map pretested boxes with
the outs and ins clearly marked.

2. In a single-process box, variable/register IDs
are just as "global" as architecture signal IDs.

I find keeping track of signal drivers
and receivers for wires inside a multi-process box
to be tedious and hard to test.

Inside a single process box, synthesis is happy to
wire up the variable/registers and subprogram/gates
for me and then draw a schematic.
(thank you very much)

My logical "structures" are the types and subtypes
used to declare, and update, a gaggle of variable/registers at a time.

-- Mike Treseler
 
On Aug 26, 2:18 am, Kim Enkovaara <kim.enkova...@iki.fi> wrote:
rickman wrote:
The main point is that one of us has a misunderstanding of how a logic
cell FF gets it's initial state. I think this is fundamental to the
discussion. I am pretty confident that I am correct, but if you know
I am wrong, I would like to know that. I would feel like a fool if I
were having this discussion with a customer and turned out to be
wrong. I much prefer to find out now.

I would say that this information is device family specific and
information that the vendors are not telling in their datasheets
completely, it is partly visible in the netlists the external
synthesizers generate, but how are those attributes transferred to
bitstream is proprietary.

For example in V5 FF there are 6 settable parameters (FF, LATCH,
INIT1, INIT0, SRHIGH, SRLOW). Are those INIT0/1 bits only in the
bitstream and processed during the upload, or are they persistent,
I do not know. At the end of September I'll meet some A and X guys
who might know the answer, I'll ask if I remember.

This is for example from the V5 manual. How this is implemented is not
told.

"The initial state after configuration or global initial state is
defined by separate INIT0 and INIT1 attributes. By default, setting the
SRLOW attribute sets INIT0, and setting the SRHIGH attribute sets INIT1.
Virtex-5 devices can set INIT0 and INIT1 independent of SRHIGH and
SRLOW."

For Altera the SIV documentation was quite vague on this area. But
at least in the past they had only "init to zero" style thing, and
they added inversion if one was needed. Actually Synplify 8.8
had a bug in this inversion, with retiming it got very confused
wheter the signal was inverted or not ;)
There is a very simple test. Does the GSR control the FF? If the GSR
signal controls the power up state of the FF, then there is no reason
to add extra controls to the bitstream and hardware. The answer is,
Yes, the GSR *will* control the state of a FF which has an initial
value.

Why anyone would imagine that there is extra logic and configuration
memory to control the initial state of CLB FFs is beyond me. There is
no reason to do it this way and the extra logic required is just
wasted silicon.

Rick
 
On Aug 26, 9:32 am, rickman <gnu...@gmail.com> wrote:
On Aug 26, 2:18 am, Kim Enkovaara <kim.enkova...@iki.fi> wrote:

There is a very simple test.  Does the GSR control the FF?  The answer is,
Yes, the GSR *will* control the state of a FF which has an initial
value.
But only for those devices that have this extraneous 'GSR' that the
user apparently is forced to worry about...simply to get the device
into a specified state at power up. Glad I don't have those worries.

KJ
 
On Aug 25, 6:24 pm, rickman <gnu...@gmail.com> wrote:
Ok, now we are getting somewhere. When you took the programming
courses, what did they teach was the reason for wanting to use
"scoping rules to isolate an implementation from it's interface"? If
those reasons are not concrete and don't apply equally to HDL as to
software, then I see no need to carry that baggage.
The ada courses taught me a lot about how to design/code with
maintenance in mind, with a LOT more than just limiting scope. In this
regard, limiting the scope of a sig/var limits the impact on later
changes to the behavior of that sig/var. For example, if my FSM state
is held in a variable, then there is nothing outside of the process
that depends directly on the state definitions, transitions, etc.,
since all those dependencies must be transmitted through separate,
well-defined (hopefully) signals of wider scope. I can later modify
the state machine, and be confident that all references to it are
contained within that process, where they can be modified accordingly.
Can you do this without variables or blocks? Sure you can, but there
is no compiler keeping you honest. More importantly, if you are
modifying someone else's design/code, there was no compiler keeping
them honest either.

Of course you could break everything down into tiny entities and
architectures to achieve the same scope control, but blocks and
variables allow a "lightweight" hierarchy, with less coding overhead
(no entity definitions or port maps), and a "semi-global" signal
concept (external signals are not global, but also not completely
local). There is a place for entity level hierarchy, and there is a
place for block/process level hierarchy.

Just like in SW, how you write HDL code depends a lot on your work
environment. If you typically work alone, and don't have a lot of
reuse across projects, then some of these techniques make less sense
in your environment. If you work in teams, on large projects, these
concepts can save a lot of time and effort down the road. In my
experience, once you are familiar with the concepts, the additional up
front effort is negligible.

I should also mention that not everything I learned in the ada courses
was taught by the instructors. I learned a lot from the other SW
students while working through lab exercises and just in general
conversation. I learned an awful lot about SW development on a large
scale, and design/code techniques that do and don't work on a large
scale project. I was a pretty good coder in C and VHDL before the
class. Afterwards, I was a better designer/developer/engineer.

I find there are any number of important techniques in software design
that are much less important when coding in an HDL. The idea of scope
is one of those rules. The concept of scope is to prevent you from
using the wrong variable in the wrong situation when you only need to
be able to access a few "local" variables. Why is this important in
software design? Because when variables were global, people often
used them in very confusing ways. The real issue is how people used
them. A method of forcing better programming skills is to limit how
you can access variables.

I don't find this to be an issue in coding in HDL. For one, my code
is generally structured by using entities. For another, these sort of
rules have much less benefit for more experienced programmers. It is
not unlike training wheels. When you are learning, they help keep you
from making mistakes. But once you have enough experience to balance
on your own, why keep the training wheels? I have given up on a
number of software rules that I learned in college. Not that they
aren't useful, I just don't need to enforce them strictly because I
know when they are useful and when they get in the way.
This is true so long as only you have to maintain only your code.

I don't want to badmouth software people. But the last couple of
cooperative working situations I had made me want to work alone as
much as possible. But I feel no need in any case to alter the way I
code to suit someone who has no need to view my code. That is
certainly no reason to burden myself with using features that I have
no need for.
I try to learn from different disciplines as much as I can. Some
things are useful, some things aren't. I've also had SW "experts" tell
me I had too many levels of nested case/if/loop statements in my
code...

I understand where you are coming from. Your style makes sense and
works for you in your environment. Mine makes sense and works in my
environment.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top