Clock Edge notation

rickman <gnuarm@gmail.com> writes:

On Apr 20, 5:11 am, Martin Thompson <martin.j.thomp...@trw.com> wrote:
The problem (as I see it) comes with languages (or past
design-techniques enforced by synthesis tools) which are not
descriptive enough to allow you to express your intent in a
"relatively" small amount of code.  Which is why assembly is not as
widely used anymore, and more behavioural descriptions win out over
instantiating LUTs/FFs by hand.  It's not about the verboseness of the
language per-se, more about the ability to show (clearly) your intent
relatively concisely.

Or do you think it has to do with the fact that the tools do a better
job so that the efficiencies of using assembly language and
instantiating components is greatly reduced?
Well, that's the reason we *had* to use assembly in the past, the
tools weren't up to the job of *allowing* us to specify the behaviour
in a higher-level way. I know very few people who would choose to
write assembly unless they have a problem they just can't solve in C
for example.

And much of the "verboseness" in VHDL can be mitigated with tools like
Emacs or Sigasi's product.  And much of the other perceived
verboseness can be overcome by writing "modern" code: single process,
using variables, functions, procedures (the sort of thing some of us
do all the time!)

I am going to give Emacs a try this summer when I have more free
time.
Emacs is a quite a big investment, but it's a tool for life. I wonder
what looks I'll garner when I'm still using it in 20 years time :)

I don't see the things you mention as being a solution because
they don't address the problem.
What is the problem - that there's a lot of typing? If that's it then
they *do* solve the problem. VHDL-mode pretty much makes it so you
only have to type in the bits that really matter, all the boilerplate
is done for you (up to and including testbenches if you want).

The verboseness is inherent in VHDL.
To some extent it is, but it's there to be used (as Andy pointed out).
VHDL has a lot less overhead when you use a single process inside each
entity. And the instantiation matching ports to wires (which looks
terribly verbose and is a pain to do in a copy/paste style) stops a
lot of silly "positioning" mistakes. (You could always choose to just
do a positional instantiation IIRC).

Type casting is something that makes it verbose.
Yes, but it forces you to show you know what you're doing, rather than
the compiler just allowing you to do it, and it works for now, but in
the future some corner-case comes up which breaks the implicit
assumptions that you have put in the code. With strong typing, you
have to be explicit about the assumptions.

That can often be mitigated by using the right types in the right
places.
I'd say it's almost always mitigated by using the right types in the
right places. The times it causes me pain is when I have to
instantiate a 3rd party entity (usually an FPGA-vendor RAM) which has
bag-of-bits vectors everywhere, (even on the address lines for example).

I never use std_logic_vector anymore.
I wouldn't go that far, but I use them a lot less than some others do
:)

Cheers,
Martin

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
Cesar <cesteban75@gmail.com> writes:

On Apr 20, 11:11 am, Martin Thompson <martin.j.thomp...@trw.com
wrote:
And much of the "verboseness" in VHDL can be mitigated with tools like
Emacs or Sigasi's product.  And much of the other perceived
verboseness can be overcome by writing "modern" code: single process,
using variables, functions, procedures (the sort of thing some of us
do all the time!)

BTW, it's long time I hear about VHDL "modern" code and the methods
you enumerate. Since typical VHDL books do not deal with coding style,
do you know about any VHDL book explaining this modern coding style?
Sorry, no.

Maybe some of us should take some of the sample code from the classic
texts and rewrite it "our way" :)

Cheers,
Martin

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
On 4/22/2010 3:26 AM, dlopez wrote:
Hi,
I'm trying to calculate the absolute value of a signed number (two's
complement).

Right now, I sign extend the input, and when msb=1, inverse all bits and
add 1. The sign extend is to take care of the most negative number.
So, if I read numeric_std correctly (see below), in VHDL, for (say) four
bit signed numbers, abs("1000"), aka abs(-8), equals zero. What am I
missing?
Thanks, Symon.
p.s. This thought came from a post comp.arch.fpga

--=========================Exported
Functions=================================

-- Id: A.1
function "abs" ( X : SIGNED) return SIGNED is
constant ARG_LEFT:INTEGER:= X'length-1;
alias XX : SIGNED(ARG_LEFT downto 0) is X;
variable RESULT: SIGNED (ARG_LEFT downto 0);
begin
if X'length<1 then return NAS; end if;
RESULT:=TO_01(xx,'X');
if (RESULT(RESULT'left)='X') then return RESULT; end if;
if RESULT(RESULT'left) = '1' then
RESULT:= -RESULT;
end if;
return RESULT;
end; -- "abs"


-- Id: A.2
function "-" ( ARG: SIGNED) return SIGNED is
constant ARG_LEFT:INTEGER:= ARG'length-1;
alias XARG: SIGNED(ARG_LEFT downto 0) is ARG;
variable RESULT,XARG01 : SIGNED(ARG_LEFT downto 0);
variable CBIT : STD_LOGIC:= '1';
begin
if ARG'length<1 then return NAS; end if;
XARG01 := TO_01(ARG,'X');
if (XARG01(XARG01'left)='X') then return XARG01; end if;
for i in 0 to RESULT'left loop
RESULT(i) := not(XARG01(i)) xor CBIT;
CBIT := CBIT and not(XARG01(i));
end loop;
return RESULT;
end; -- "-"
 
Symon wrote:
So, if I read numeric_std correctly (see below), in VHDL, for (say) four
bit signed numbers, abs("1000"), aka abs(-8), equals zero. What am I
missing?
Considering that in two's complement, a 4 bit signed is defined from -8 to 7,
what result did you hope for? The lowest negative number in two's complement
is always a special case. It is up to you if you wish to check for it or not.

Kind regards,

Pieter Hulshoff
 
On 4/22/2010 1:38 PM, Pieter Hulshoff wrote:
Symon wrote:
So, if I read numeric_std correctly (see below), in VHDL, for (say) four
bit signed numbers, abs("1000"), aka abs(-8), equals zero. What am I
missing?

Considering that in two's complement, a 4 bit signed is defined from -8 to 7,
what result did you hope for? The lowest negative number in two's complement
is always a special case. It is up to you if you wish to check for it or not.

Kind regards,

Pieter Hulshoff
Sure, I just wanted to be sure that's what happens. Before I looked in
numeric_std, I expected abs to take a signed argument and return an
unsigned value. However, it doesn't.
Thanks, Syms.
 
On 4/22/2010 7:49 AM, Symon wrote:
On 4/22/2010 1:38 PM, Pieter Hulshoff wrote:
Symon wrote:
So, if I read numeric_std correctly (see below), in VHDL, for (say) four
bit signed numbers, abs("1000"), aka abs(-8), equals zero. What am I
missing?

Considering that in two's complement, a 4 bit signed is defined from
-8 to 7,
what result did you hope for? The lowest negative number in two's
complement
is always a special case. It is up to you if you wish to check for it
or not.

Kind regards,

Pieter Hulshoff

Sure, I just wanted to be sure that's what happens. Before I looked in
numeric_std, I expected abs to take a signed argument and return an
unsigned value. However, it doesn't.
Thanks, Syms.
Yeah, numeric_std makes a couple of interesting choices regarding output
formats. I can understand the idea of always wanting your outputs to
remain the same type (signing and range) as your inputs, but it
definitely means that some math expressions require a truly ugly amount
of casting and '0' &.

--
Rob Gaddi, Highland Technology
Email address is currently out of order
 
On Apr 22, 11:04 am, Rob Gaddi <rga...@technologyhighland.com> wrote:
On 4/22/2010 7:49 AM, Symon wrote:





On 4/22/2010 1:38 PM, Pieter Hulshoff wrote:
Symon wrote:
So, if I read numeric_std correctly (see below), in VHDL, for (say) four
bit signed numbers, abs("1000"), aka abs(-8), equals zero. What am I
missing?

Considering that in two's complement, a 4 bit signed is defined from
-8 to 7,
what result did you hope for? The lowest negative number in two's
complement
is always a special case. It is up to you if you wish to check for it
or not.

Kind regards,

Pieter Hulshoff

Sure, I just wanted to be sure that's what happens. Before I looked in
numeric_std, I expected abs to take a signed argument and return an
unsigned value. However, it doesn't.
Thanks, Syms.

Yeah, numeric_std makes a couple of interesting choices regarding output
formats.  I can understand the idea of always wanting your outputs to
remain the same type (signing and range) as your inputs, but it
definitely means that some math expressions require a truly ugly amount
of casting and '0' &.

--
Rob Gaddi, Highland Technology
Email address is currently out of order- Hide quoted text -

- Show quoted text -
You could use fixed point with no fractional bits. It extends the size
to handle the largest possible result. But unfortunately, ufixed -
ufixed is still ufixed, so it does not always handle that correctly.

Andy
 
Symon wrote:
So, if I read numeric_std correctly (see below), in VHDL, for (say) four
bit signed numbers, abs("1000"), aka abs(-8), equals zero. What am I
missing?
No, for a 4-bit signed, abs(-8) = -8!

In 2's-complement notation, and therefore in numeric_std, the negation
of the most negative value is itself. So, in this case, the negation of
1000 (-8) is 1000 (-8).

If you consider what would happen if you sign-extended first, you can
see what's happening - 11000 (-8) gets negated to 01000 (+8).

This is a side-effect of the asymmetry in 2's-complement notation and
not a bug. Deciding what to do with asymmetrical number ranges is an
essential design decision in any design using either 2's-complement
integer or fixed-point numbers.

You can either decide to support the restricted range -7 to 7 and
consider -8 to be out of range, or you can extend the value to 5 bits to
include the whole representable range. If you want to support the full
range of the input type, resize one-bit bigger first (before the abs).

e.g. abs(resize(x,5))

Thanks, Symon.
p.s. This thought came from a post comp.arch.fpga

--=========================Exported
Functions=================================

-- Id: A.1
function "abs" ( X : SIGNED) return SIGNED is
constant ARG_LEFT:INTEGER:= X'length-1;
alias XX : SIGNED(ARG_LEFT downto 0) is X;
variable RESULT: SIGNED (ARG_LEFT downto 0);
begin
if X'length<1 then return NAS; end if;
RESULT:=TO_01(xx,'X');
if (RESULT(RESULT'left)='X') then return RESULT; end if;
if RESULT(RESULT'left) = '1' then
RESULT:= -RESULT;
end if;
return RESULT;
end; -- "abs"


-- Id: A.2
function "-" ( ARG: SIGNED) return SIGNED is
constant ARG_LEFT:INTEGER:= ARG'length-1;
alias XARG: SIGNED(ARG_LEFT downto 0) is ARG;
variable RESULT,XARG01 : SIGNED(ARG_LEFT downto 0);
variable CBIT : STD_LOGIC:= '1';
begin
if ARG'length<1 then return NAS; end if;
XARG01 := TO_01(ARG,'X');
if (XARG01(XARG01'left)='X') then return XARG01; end if;
for i in 0 to RESULT'left loop
RESULT(i) := not(XARG01(i)) xor CBIT;
CBIT := CBIT and not(XARG01(i));
end loop;
return RESULT;
end; -- "-"
 
On 4/23/2010 10:56 AM, Andy Rushton wrote:
Symon wrote:

So, if I read numeric_std correctly (see below), in VHDL, for (say)
four bit signed numbers, abs("1000"), aka abs(-8), equals zero. What
am I missing?

No, for a 4-bit signed, abs(-8) = -8!

Aha! OK, I see it now, many thanks.
 
On 4/23/2010 2:56 AM, Andy Rushton wrote:
Symon wrote:

So, if I read numeric_std correctly (see below), in VHDL, for (say)
four bit signed numbers, abs("1000"), aka abs(-8), equals zero. What
am I missing?

No, for a 4-bit signed, abs(-8) = -8!

In 2's-complement notation, and therefore in numeric_std, the negation
of the most negative value is itself. So, in this case, the negation of
1000 (-8) is 1000 (-8).

If you consider what would happen if you sign-extended first, you can
see what's happening - 11000 (-8) gets negated to 01000 (+8).

This is a side-effect of the asymmetry in 2's-complement notation and
not a bug. Deciding what to do with asymmetrical number ranges is an
essential design decision in any design using either 2's-complement
integer or fixed-point numbers.

You can either decide to support the restricted range -7 to 7 and
consider -8 to be out of range, or you can extend the value to 5 bits to
include the whole representable range. If you want to support the full
range of the input type, resize one-bit bigger first (before the abs).

e.g. abs(resize(x,5))

[snip]
Or just copy/paste/tweak the numeric_std code to write your own abs
function that returns an unsigned of the same width as the signed input.

--
Rob Gaddi, Highland Technology
Email address is currently out of order
 
Symon wrote:
On 4/22/2010 3:26 AM, dlopez wrote:
Hi,
I'm trying to calculate the absolute value of a signed number (two's
complement).

Right now, I sign extend the input, and when msb=1, inverse all bits and
add 1. The sign extend is to take care of the most negative number.


So, if I read numeric_std correctly (see below), in VHDL, for (say) four
bit signed numbers, abs("1000"), aka abs(-8), equals zero. What am I
missing?
Thanks, Symon.
p.s. This thought came from a post comp.arch.fpga
I noticed this when I did the fixed point package. If you use fixed
point then a bit gets added when you do an "abs".
Thus:
constant sf8 : sfixed (3 downto 0) := "1000";
variable sf8p : sfixed (4 downto 0);

....
sf8p := abs (sf8);

You will get "01000" as the result.
 
On Apr 23, 6:34 am, Symon <symon_bre...@hotmail.com> wrote:
On 4/23/2010 10:56 AM, Andy Rushton wrote:> Symon wrote:

So, if I read numeric_std correctly (see below), in VHDL, for (say)
four bit signed numbers, abs("1000"), aka abs(-8), equals zero. What
am I missing?

No, for a 4-bit signed, abs(-8) = -8!

Aha! OK, I see it now, many thanks.
I'm not sure I see the problem. If you need the result as a signed
number, you have to extend the result by one bit. This can be done
after the abs like this...

signed(resize(unsigned(abs(foo)), foo'length+1))

I guess that is a bit messy, but you can encapsulate this in a
function.

If you want the result as an unsigned number, you just re-type it...

unsigned(abs(foo)), foo'length)

The unsigned result fits in the same number of bits as the signed
value.

Rick
 
Rob Gaddi wrote:
Or just copy/paste/tweak the numeric_std code to write your own abs
function that returns an unsigned of the same width as the signed input.
Not a good idea. Synthesis tools do not necessarily synthesise the body
of the package, in fact they almost certainly do not. Typically
operators have straight mappings to hardware. These mappings may be
pre-optimised. If you copy the body code, you may lose those
optimisations brought about by the straight mappings.

If you want an unsigned result from signed abs:

signal x : signed(3 downto 0);
signal z : unsigned(3 downto 0);

z <= unsigned(abs x);

Notice that the result is the same size as the input. However, z has the
range 0 to 15 and x has the range -8 to 7. The value -8 will get mapped
by abs onto -8, but the type conversion to unsigned will map it onto +8.
So everything pans out OK in the end.
 
On Apr 23, 3:01 am, Bernd Paysan <bernd.pay...@gmx.de> wrote:
Andy wrote:
Other than twice the declarations, unintentional latches, explicitly
coding clock enables, simulation penalties, etc., using separate
combinatorial and sequential blocks is just fine.

LoL.  Note that there are further difficulties to understand this separated
code due to the fact that things which conceptually belong together are
spread apart over the file.  This is just too messy.

Most designers here use single clocked processes / always blocks.
Those that don't are 'encouraged' to.

I'm fully on your side.
Same here. In the over one hundred posts in this thread, I still
haven't figured out exactly what benefits Patrick sees in the two-
process model.

Unless he likes the names of his machine's states to line up with the
signal assignments in the waveform view, as opposed to seeing the new
assignments in the _next_ state.

-a
 
Andy Peters <google@latke.net> writes:

On Apr 23, 3:01 am, Bernd Paysan <bernd.pay...@gmx.de> wrote:
Andy wrote:
Other than twice the declarations, unintentional latches, explicitly
coding clock enables, simulation penalties, etc., using separate
combinatorial and sequential blocks is just fine.

LoL.  Note that there are further difficulties to understand this separated
code due to the fact that things which conceptually belong together are
spread apart over the file.  This is just too messy.

Most designers here use single clocked processes / always blocks.
Those that don't are 'encouraged' to.

I'm fully on your side.

Same here.
Me too.

In the over one hundred posts in this thread, I still
haven't figured out exactly what benefits Patrick sees in the two-
process model.
I may be entirely wrong, but I *think* it's a Verilog thing - it's a
way to make it easy to check that the rules about sharing "variables"
don't go wrong, giving you races.

We VHDLers don't have to worry about it, so the discussion made little
sense within this newsgroup.

Cheers,
Martin

--
martin.j.thompson@trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
 
On Jul 30, 12:20 pm, rickman <gnu...@gmail.com> wrote:
On Jul 29, 6:43 am, Kolja Sulimma <ksuli...@googlemail.com> wrote:

On 29 Jul., 02:34, KJ <kkjenni...@sbcglobal.net> wrote:

Instead of this:
    Some_slv_sig <= std_logic_vector(Some_unsigned);
Do this
    Some_slv_sig <= std_ulogic_vector(Some_unsigned);

a package numeric_unresolved would be nice....

Kolja

There is no reason why unresolved can't be added to numeric_std is
there?
I don't think you could really *add* the unresolved types to
numeric_std because to do so you would have to create new types other
than 'unsigned' and 'signed' that are based on std_ulogic. Then of
course you would have to get all of the synthesis and simulation
vendors on board with the change before you could really use the new
types. In the mean time, the 'least common denominator' rule will
apply and everyone would continue to use the more supported current
data types that are based on the resolved std_logic type...which would
then kill all momentum for any of the vendors to support the change
and the proposal would likely die quietly.

If instead, numeric_std was simply changed from this...
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
type SIGNED is array (NATURAL range <>) of STD_LOGIC;

to this...
type UNSIGNED is array (NATURAL range <>) of STD_ULOGIC;
type SIGNED is array (NATURAL range <>) of STD_ULOGIC;

Then the only ones the user community would have to beat on to get
this implemented would be the simulation vendors. Synthesis vendors
already flag multiple driver violations as a standard part of
synthesis since they (for the most part) do not implement multiple net
drivers.

Changes to standard packages should of course not be taken lightly,
but off the top of my head, I can't think of anyone that would be
negatively impacted by this. I'll toss this out to the newsgroupies
first to see if someone can come up with a use case where the change
in the definition of 'unsigned' and 'signed' would negatively impact
something. If not, then I'll submit it to the standards group for
consideration...numeric_std was so close, they were only two letters
short in the source code. Sooooo close.

Kevin Jennings
 
It would break existing code that used signed/unsigned like SLV, and
needed the tri-state, multi-driver logic. Also, elements of unsigned
would not be SL, with the same problem.

Am I just dreaming, or wasn't there an effort to change the
relationship between SLV and SULV such that they would become
interchangeable subtypes like SUL and SL are? E.G. subtype SLV is
resolved(SULV); or similar, with a new version of resolved() to match.
It seems like the gotcha was that an element of such an SLV would no
longer be SL, but SUL. But I thought they got around that.

Andy
 
On Jul 31, 1:50 pm, Andy <jonesa...@comcast.net> wrote:
It would break existing code that used signed/unsigned like SLV, and
needed the tri-state, multi-driver logic. Also, elements of unsigned
would not be SL, with the same problem.
Actually, I intended my question more along the lines of if signed/
unsigned were changed to be collections of std_ulogic rather than
std_logic, how many would really notice/care? I understand that those
who use signed/unsigned with multiple drivers would be affected...but
how many of those cases are actually out there? So, do *you* use
multiple drivers on signed/unsigned signals? Is that actually
important to you?

KJ
 
On Aug 3, 8:40 am, KJ <kkjenni...@sbcglobal.net> wrote:
On Jul 31, 1:50 pm, Andy <jonesa...@comcast.net> wrote:

It would break existing code that used signed/unsigned like SLV, and
needed the tri-state, multi-driver logic. Also, elements of unsigned
would not be SL, with the same problem.

Actually, I intended my question more along the lines of if signed/
unsigned were changed to be collections of std_ulogic rather than
std_logic, how many would really notice/care?  I understand that those
who use signed/unsigned with multiple drivers would be affected...but
how many of those cases are actually out there?  So, do *you* use
multiple drivers on signed/unsigned signals?  Is that actually
important to you?

KJ
Mostly in places where I have an inout port (or procedure argument) of
a record type, and I need resolution functions to manage in and out
elements more often than I actually use a bidirectional element. My
test benches tend to have lots of procedures like read/write(bus,
address, data)

I have also used unsigned on tri-stated primary IOs of FPGAs (it is
easy enough to convert them back to SLV if I need to use the gate
level models).

Internally, I have used them with a tri-state bus description, knowing
full-well that the synthesis tool would convert them to muxes for me.
The added benefit is that the synthesis tool can assume that the tri-
state enables are mutually exclusive, which allows it to optimize the
muxes. Sometimes it is just easier to describe an interface with a
bus, than to create the mux and the plumbing for it. I don't usually
do truly bi-directional busses, but sometimes...

So, yes, I have used them in several areas.

IMHO, changes to the language or standard packages must be backwards
compatible (even though in rare cases in the past they have not been
so), so that they don't break anyone's code, regardless of how common
(or even "useful") a given usage is. The "prime directive" WRT changes
to the standards should be "do no harm". If we need a different
numeric_std-like package, so be it.

Andy
 
On Aug 3, 12:04 pm, Andy <jonesa...@comcast.net> wrote:
On Aug 3, 8:40 am, KJ <kkjenni...@sbcglobal.net> wrote:
IMHO, changes to the language or standard packages must be backwards
compatible (even though in rare cases in the past they have not been
so),
Backwards compatibility should not be a 'must have'...although I
certainly agree that it is something worth working for to get if you
can. Examples of changes that are definitely more onerous to 'used to
be working just fine' code were the changes to type 'FILE' and 'shared
variables'.

so that they don't break anyone's code, regardless of how common
(or even "useful") a given usage is.
I think the cost/benefit should be weighed although just how well one
can weigh this with actual users is a bit of a question.

The "prime directive" WRT changes
to the standards should be "do no harm".
'Do no harm' applies to doctors, not engineering standards. If
something needs to be improved and is 'worth it' to the users then it
should be improved. The definition of whether something is 'worth it'
or not is subjective.

If we need a different
numeric_std-like package, so be it.

Maybe just use the fixed point package. The documentation says it
uses std_logic as the base, but the actual code says std_ulogic.

Thanks for your input on how you use/need multi-driver signed/unsigned

Kevin Jennings
 

Welcome to EDABoard.com

Sponsor

Back
Top