Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Shortening common idioms: bus assignment and 'prev' generation

Reply
Thread Tools

Shortening common idioms: bus assignment and 'prev' generation

 
 
Eli Bendersky
Guest
Posts: n/a
 
      04-03-2006
Hello all,

In high level programming languages it's possible to shorten common
programming idioms by encapsulating them into functions / modules /
classes. It is similarly possible in simulation-aimed VHDL, but is much
more difficult in synthesis-aimed VHDL.

Here is one:

some_bus(31 downto 27) <= (others => '0');
some_bus(26) <= my_sig_3;
some_bus(25) <= my_sig_4;
some_bus(24 downto 20) <= (others => '0');
some_bus(19) <= my_sig_11;
some_bus(18 downto 2) <= (others => '0');
some_bus(1 downto 0) <= another_bus(1 downto 0);

I wish there sould be a way to just assign 'all zeros' to some_bus and
then the signals to relevant bits:

some_bus(31 downto 0) <= (others => '0');
some_bus(26) <= my_sig_3;
some_bus(25) <= my_sig_4;
some_bus(19) <= my_sig_11;
some_bus(1 downto 0) <= another_bus(1 downto 0);

This, unfortunately, doesn't work. Setting some_bus to 'L' also doesn't
work for synthesis (only simulation).

Another common idiom is seeing when a signal changed:

signal my_sig, my_sig_prev: std_logic;
....
....
process (clk, reset_n)
begin
if reset_n = '0' then
my_sig_prev <= '0';
elsif rising_edge(clk) then
my_sig_prev <= my_sig;
end if;
end process;

And then:

some process:
....
if rising_edge(clk) then
if my_sig_prev /= my_sig then
...
....

How can this be shortened, in synthesis ? I find myself writing this or
similar code (checking for a rise, or fall, of my_sig, for instance, by
(my_sig = '0' and my_sig_prev = '1') for fall) too many times !

Eli

....

 
Reply With Quote
 
 
 
 
Mike Treseler
Guest
Posts: n/a
 
      04-03-2006
Eli Bendersky wrote:

> I wish there sould be a way to just assign 'all zeros' to some_bus and
> then the signals to relevant bits:
> some_bus(31 downto 0) <= (others => '0');
> some_bus(26) <= my_sig_3;
> some_bus(25) <= my_sig_4;
> some_bus(19) <= my_sig_11;
> some_bus(1 downto 0) <= another_bus(1 downto 0);
> This, unfortunately, doesn't work.


It would work inside a process.

> Another common idiom is seeing when a signal changed:
> signal my_sig, my_sig_prev: std_logic;
> ...
> ...
> process (clk, reset_n)
> begin
> if reset_n = '0' then
> my_sig_prev <= '0';
> elsif rising_edge(clk) then
> my_sig_prev <= my_sig;
> end if;
> end process;
> And then:
> some process:
> ...
> if rising_edge(clk) then
> if my_sig_prev /= my_sig then
> ...
> ...
> How can this be shortened, in synthesis ?


You only have to do this once
in a single process design.
See the examples here:

http://home.comcast.net/~mike_treseler/

-- Mike Treseler
 
Reply With Quote
 
 
 
 
Eli Bendersky
Guest
Posts: n/a
 
      04-04-2006
Mike Treseler wrote:
> Eli Bendersky wrote:
>
> > I wish there sould be a way to just assign 'all zeros' to some_bus and
> > then the signals to relevant bits:
> > some_bus(31 downto 0) <= (others => '0');
> > some_bus(26) <= my_sig_3;
> > some_bus(25) <= my_sig_4;
> > some_bus(19) <= my_sig_11;
> > some_bus(1 downto 0) <= another_bus(1 downto 0);
> > This, unfortunately, doesn't work.

>
> It would work inside a process.


Yes, but then it would also be delayed by one clock, which isn't always
desirable. I wonder why synthesis tools don't like the 'H' value. Since
they resolve all drivers for each signal anyway, it should be quite
simple to implement.

>
> > Another common idiom is seeing when a signal changed:
> > signal my_sig, my_sig_prev: std_logic;
> > ...
> > ...
> > process (clk, reset_n)
> > begin
> > if reset_n = '0' then
> > my_sig_prev <= '0';
> > elsif rising_edge(clk) then
> > my_sig_prev <= my_sig;
> > end if;
> > end process;
> > And then:
> > some process:
> > ...
> > if rising_edge(clk) then
> > if my_sig_prev /= my_sig then
> > ...
> > ...
> > How can this be shortened, in synthesis ?

>
> You only have to do this once
> in a single process design.
> See the examples here:
>
> http://home.comcast.net/~mike_treseler/
>


Interesting approach, but not to my taste, I think:

1) It interferes with the way I understand synthesizable code. I like
to be able to envision exactly how the hardware that's built from my
code looks - it aids greatly in understanding complex timing demands,
and overall I find that code written is such a way behaves very
similarly in real life and in simulation.
2) It is not flexible enough for large designs where usage of
'generate' is sometimes essential to avoid duplications, and where the
additional level of abstraction allowed by multiple processes is
precious.
3) I really like knowing where each signal is assigned, without looking
around too much. When each signal has one and only one process that
'drives' it, things are simpler to understand.

This all is, of course, IMHO

Eli

 
Reply With Quote
 
Allan Herriman
Guest
Posts: n/a
 
      04-04-2006
On 4 Apr 2006 01:05:22 -0700, "Eli Bendersky" <(E-Mail Removed)>
wrote:

>Mike Treseler wrote:
>> Eli Bendersky wrote:
>>
>> > I wish there sould be a way to just assign 'all zeros' to some_bus and
>> > then the signals to relevant bits:
>> > some_bus(31 downto 0) <= (others => '0');
>> > some_bus(26) <= my_sig_3;
>> > some_bus(25) <= my_sig_4;
>> > some_bus(19) <= my_sig_11;
>> > some_bus(1 downto 0) <= another_bus(1 downto 0);
>> > This, unfortunately, doesn't work.

>>
>> It would work inside a process.

>
>Yes, but then it would also be delayed by one clock, which isn't always
>desirable. I wonder why synthesis tools don't like the 'H' value. Since
>they resolve all drivers for each signal anyway, it should be quite
>simple to implement.


It works inside a combinatorial process. No clock delay is generated.
The language already does what you want in this regard. There is no
need to change anything.

'H' is for modeling driver strengths which is a completely independent
concept.

Regards,
Allan
 
Reply With Quote
 
Ben Jones
Guest
Posts: n/a
 
      04-04-2006

"Eli Bendersky" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...

> I wish there sould be a way to just assign 'all zeros' to some_bus and
> then the signals to relevant bits:


> some_bus(31 downto 0) <= (others => '0');
> some_bus(26) <= my_sig_3;
> some_bus(25) <= my_sig_4;
> some_bus(19) <= my_sig_11;
> some_bus(1 downto 0) <= another_bus(1 downto 0);


some_bus <=
( 26 => my_sig_3,
25 => my_sig_4,
19 => my_sig_11,
1 => another_bus(1),
0 => another_bus(0),
others => '0');

Not ideal when you have a lot of sub-buses to map, because AFAIK you have to
do them bit-by-bit... but is that what you had in mind?

This notation works the same both inside and outside a process.

-Ben-


 
Reply With Quote
 
Magne Munkejord
Guest
Posts: n/a
 
      04-04-2006
Eli Bendersky wrote:
> Hello all,
>
> In high level programming languages it's possible to shorten common
> programming idioms by encapsulating them into functions / modules /
> classes. It is similarly possible in simulation-aimed VHDL, but is much
> more difficult in synthesis-aimed VHDL.
>
> Here is one:
>
> some_bus(31 downto 27) <= (others => '0');
> some_bus(26) <= my_sig_3;
> some_bus(25) <= my_sig_4;
> some_bus(24 downto 20) <= (others => '0');
> some_bus(19) <= my_sig_11;
> some_bus(18 downto 2) <= (others => '0');
> some_bus(1 downto 0) <= another_bus(1 downto 0);
>
> I wish there sould be a way to just assign 'all zeros' to some_bus and
> then the signals to relevant bits:
>
> some_bus(31 downto 0) <= (others => '0');
> some_bus(26) <= my_sig_3;
> some_bus(25) <= my_sig_4;
> some_bus(19) <= my_sig_11;
> some_bus(1 downto 0) <= another_bus(1 downto 0);
>
> This, unfortunately, doesn't work. Setting some_bus to 'L' also doesn't
> work for synthesis (only simulation).
>
> Another common idiom is seeing when a signal changed:
>
> signal my_sig, my_sig_prev: std_logic;
> ...
> ...
> process (clk, reset_n)
> begin
> if reset_n = '0' then
> my_sig_prev <= '0';
> elsif rising_edge(clk) then
> my_sig_prev <= my_sig;
> end if;
> end process;
>
> And then:
>
> some process:
> ...
> if rising_edge(clk) then
> if my_sig_prev /= my_sig then
> ...
> ...
>
> How can this be shortened, in synthesis ? I find myself writing this or
> similar code (checking for a rise, or fall, of my_sig, for instance, by
> (my_sig = '0' and my_sig_prev = '1') for fall) too many times !
>
> Eli
>
> ...
>


I have used the concatenation operator '&' for signal assignment outside
a process like this
signal some_bus : std_logic_vector(15 downto 0);
signal another_bus : std_logic_vector(13 downto 0);
signal a_signal : std_logic;
signal b_signal : std_logic;

some_bus <= (another_bus & a_signal & b_signal);

also i _think_ this should work:
some_bus <= ((15 downto 10) => another_bus(13 downto , 5 => a_signal,
3 => '1', others => '0');

another trick for handling wide busses is to use aliases for segments of
your bus. Not sure about the syntax but it is something like:
alias bus_segment(7 downto 0) is some_bus(15 downto ;

As far as i know, you can use the 'last_value and 'event attributes for
your other problem.
 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      04-04-2006

Eli Bendersky wrote:


> 1) It interferes with the way I understand synthesizable code. I like
> to be able to envision exactly how the hardware that's built from my
> code looks - it aids greatly in understanding complex timing demands,
> and overall I find that code written is such a way behaves very
> similarly in real life and in simulation.
> 2) It is not flexible enough for large designs where usage of
> 'generate' is sometimes essential to avoid duplications, and where the
> additional level of abstraction allowed by multiple processes is
> precious.
> 3) I really like knowing where each signal is assigned, without looking
> around too much. When each signal has one and only one process that
> 'drives' it, things are simpler to understand.
>
> This all is, of course, IMHO
>
> Eli


I know and respect several designers that share your preferences on
coding style WRT separate processes. I think that style stems from the
earliest synthesis tools that could not infer storage (you had to
instantiate registers), and therefore all of the combinatorial code was
split up into multiple processes to keep the sensitivity lists as
simple as possible. As you pointed out, it has its advantages.

I am not a software person, but one reason I prefer RTL descriptions
that use variables instead of signals is because the sequential code
behaves like software, where the effect of order of read/write on
variables within a process means exactly what you would think from
reading code, whereas with signal assignments, it is irrelevent (a read
of a signal always gets the previous value).

If/then and for/loop constructs within processes, using globally static
conditions/bounds, operate exactly the same as equivalent generate
constructs for synthesis. I see no loss of flexibilty here.

I prefer more compact, single process code (not necessarily separate
procedures for init, update, output, etc.) rather than having the
redundant process & clock edge code. For me it's a matter of how much
(and how spread out) code there is to look through. I sometimes use
separate processes to keep somewhat isolated functions separate without
the overhead of full-up entity/architecture declarations, while still
taking advantage of the local scoping rules on variables.

All of this, though, is just IMHO too...

Andy

 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      04-04-2006
Eli Bendersky wrote:

> Interesting approach, but not to my taste, I think:
> 1) It interferes with the way I understand synthesizable code. I like
> to be able to envision exactly how the hardware that's built from my
> code looks


The actual hardware that's built is an
incomprehensible netlist of look up tables,
registers and wires. All else is abstraction.
I like to be assured that synthesis will
supply a netlist that works exactly the
same as the simulation of my preferred abstraction,
the vhdl synchronous process. Being assured
that this same netlist will also meet my Fmax constraints
seals the deal for me.

> - it aids greatly in understanding complex timing demands,
> and overall I find that code written is such a way behaves very
> similarly in real life and in simulation.


If that is your preference, then the overhead
of maintaining multiple processes and the
wiring between them is part of the bargain.

> 2) It is not flexible enough for large designs where usage of
> 'generate' is sometimes essential to avoid duplications, and where the
> additional level of abstraction allowed by multiple processes is
> precious.


Except for the case of tri-state nodes,
any synchronous logic description that can be
generated from multiple processes can also
be described by a single synchronous process
by using variable, procedure and function declarations.

> 3) I really like knowing where each signal is assigned, without looking
> around too much. When each signal has one and only one process that
> 'drives' it, things are simpler to understand.


I prefer to use signals at the top level
to wire up single-process entity instances.
Port modes (in, out) provide a compile-time
wiring check that is lacking in process to
process wiring.

> This all is, of course, IMHO


Same here.

-- Mike Treseler
 
Reply With Quote
 
Eli Bendersky
Guest
Posts: n/a
 
      04-06-2006

Allan Herriman wrote:
> On 4 Apr 2006 01:05:22 -0700, "Eli Bendersky" <(E-Mail Removed)>
> wrote:
>
> >Mike Treseler wrote:
> >> Eli Bendersky wrote:
> >>
> >> > I wish there sould be a way to just assign 'all zeros' to some_bus and
> >> > then the signals to relevant bits:
> >> > some_bus(31 downto 0) <= (others => '0');
> >> > some_bus(26) <= my_sig_3;
> >> > some_bus(25) <= my_sig_4;
> >> > some_bus(19) <= my_sig_11;
> >> > some_bus(1 downto 0) <= another_bus(1 downto 0);
> >> > This, unfortunately, doesn't work.
> >>
> >> It would work inside a process.

> >
> >Yes, but then it would also be delayed by one clock, which isn't always
> >desirable. I wonder why synthesis tools don't like the 'H' value. Since
> >they resolve all drivers for each signal anyway, it should be quite
> >simple to implement.

>
> It works inside a combinatorial process. No clock delay is generated.
> The language already does what you want in this regard. There is no
> need to change anything.
>


What should be in the sensitivity list of this process ? All of my_sig
signals ?

 
Reply With Quote
 
Allan Herriman
Guest
Posts: n/a
 
      04-07-2006
On 6 Apr 2006 07:42:03 -0700, "Eli Bendersky" <(E-Mail Removed)>
wrote:

>
>Allan Herriman wrote:
>> On 4 Apr 2006 01:05:22 -0700, "Eli Bendersky" <(E-Mail Removed)>
>> wrote:
>>
>> >Mike Treseler wrote:
>> >> Eli Bendersky wrote:
>> >>
>> >> > I wish there sould be a way to just assign 'all zeros' to some_bus and
>> >> > then the signals to relevant bits:
>> >> > some_bus(31 downto 0) <= (others => '0');
>> >> > some_bus(26) <= my_sig_3;
>> >> > some_bus(25) <= my_sig_4;
>> >> > some_bus(19) <= my_sig_11;
>> >> > some_bus(1 downto 0) <= another_bus(1 downto 0);
>> >> > This, unfortunately, doesn't work.
>> >>
>> >> It would work inside a process.
>> >
>> >Yes, but then it would also be delayed by one clock, which isn't always
>> >desirable. I wonder why synthesis tools don't like the 'H' value. Since
>> >they resolve all drivers for each signal anyway, it should be quite
>> >simple to implement.

>>
>> It works inside a combinatorial process. No clock delay is generated.
>> The language already does what you want in this regard. There is no
>> need to change anything.
>>

>
>What should be in the sensitivity list of this process ? All of my_sig
>signals ?


another_bus is needed as well. Or you could wait for the next version
of VHDL which allows you to have a sensitivity list that automatically
includes all the signals needed.

Regards,
Allan
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic URL shortening Littlefield, Tyler Python 0 06-15-2011 04:03 AM
RoR : Shortening this code Zouplaz Ruby 7 10-08-2006 10:31 AM
Shortening of syntax =?Utf-8?B?c3RldmVuIHNjYWlmZQ==?= ASP .Net 1 07-12-2006 10:59 AM
Address Bus and External Data Bus Confusion LoXodonte A+ Certification 1 04-18-2006 09:09 PM
How to disable stack-trace shortening? Alexey Verkhovsky Ruby 1 10-10-2004 11:12 AM



Advertisments