Sequential Declaration Regions

Proposal Editing Information

  • Who Updates: JimLewis, <Add YourName>, ...
  • Date Proposed: 2012-08-18
  • Date Last Updated: 2012-08-18
  • Priority:
  • Complexity:
  • Focus: Testbench

Requirement Summary

Some problems require some calculations before an intermediate variable can be created.

Related and/or Competing Issues: ?Garbage Collection?

Use Models:

Embedded declarative region

-- This use model could be replaced by having garbage collection. The goal is to minimize the amount of information that needs to be sent.

Example 
  function to_string (
    value      : in integer_vector
  ) return string is
    variable L : line; 
  begin
    write(L, value) ;    
    inner_blk : block
     variable result : string(L'range) ; 
    begin
      result := L.all ; 
      deallocate(L) ; 
      return result ; 
    end block ; 
  end function to_string ; 

Sequential statements with declarative parts

This example is taken from the Picoblaze-Library: https://github.com/Paebbels/PicoBlaze-Library/blob/master/vhdl/pb.pkg.vhdl?ts=2#L1037

function pb_GetInterruptVector(PicoBlazeBus : T_PB_IOBUS_DEV_PB_VECTOR; System : T_PB_SYSTEM) return STD_LOGIC_VECTOR is
  variable Result           : STD_LOGIC_VECTOR(System.DeviceInstanceCount - 1 downto 0);
  variable DeviceInstance   : T_PB_DEVICE_INSTANCE;
  variable BusIndex         : T_PB_BUSID;
  variable InterruptPortID  : T_UINT_8;
begin
  InterruptPortID   := 0;
  for i in 0 to System.DeviceInstanceCount - 1 loop
    DeviceInstance  := System.DeviceInstances(i);
    BusIndex        := pb_GetBusIndex(System, DeviceInstance.DeviceShort);
  
    if (DeviceInstance.Device.CreatesInterrupt = TRUE) then
      Result(InterruptPortID) := PicoBlazeBus(BusIndex).Interrupt;
      InterruptPortID         := InterruptPortID + 1;
    end if;
  end loop;
  return Result(InterruptPortID - 1 downto 0);
end function;

A common coding style is to declare variables as late as possible and restrict their scope. With declarative parts in normal sequential statements, it's now possible to move the variable declarations of DeviceInstance and BusIndex into the scope of the for loop. Moreover, it's now even possible to convert the variables into constants and ensure that these values are never overwrite except if the loop increments.

function pb_GetInterruptVector(PicoBlazeBus : T_PB_IOBUS_DEV_PB_VECTOR; System : T_PB_SYSTEM) return STD_LOGIC_VECTOR is
  variable Result           : STD_LOGIC_VECTOR(System.DeviceInstanceCount - 1 downto 0);
  variable InterruptPortID  : T_UINT_8;
begin
  InterruptPortID   := 0;
  for i in 0 to System.DeviceInstanceCount - 1 loop
    constant DeviceInstance   : T_PB_DEVICE_INSTANCE := System.DeviceInstances(i);
    constant BusIndex         : T_PB_BUSID pb_GetBusIndex(System, DeviceInstance.DeviceShort);
  begin
    if (DeviceInstance.Device.CreatesInterrupt = TRUE) then
      Result(InterruptPortID) := PicoBlazeBus(BusIndex).Interrupt;
      InterruptPortID         := InterruptPortID + 1;
    end if;
  end loop;
  return Result(InterruptPortID - 1 downto 0);
end function;

Proposal

Questions

General Comments

-- RyanHinton - 2013-04-10: I would really like something like this. One of my favorite changes going from C to C++ was that I could declare new variables right where I needed them instead of going back up to the top of the function. I like the structured feel of VHDL, but forbidding declarations in the code really cramps my style. At least C allows for declaring new variables at the beginning of a new block, e.g. an 'if' or 'for' statement. This may require labels on statements in processes to refer to variables declared in a 'for' loop inside a process.

-- BrianDrummond - 2013-11-21 : This feature is also common in Ada for various purposes including (as illustrated in the example above) runtime-sized storage on the stack . The ability to determine an object's size, then declare it is useful and appears to have no downside. It is not merely about not having to scroll back to the declaration area! Eliminating many uses of access types or C pointers eliminates many deallocation bugs. Ada uses the word "declare" where the example uses "block", but the latter has precedents in VHDL.

-- DavidKoontz - 2013-11-22 As Brian points out the example manipulates runtime storage and doesn't represent realizable hardware. You could imagine this limits use of this aspect to subprograms (likely functions). I also don't recall seeing any mention (discussion) of sequential block statements. For consideration perhaps one or more fully supported use models might be demonstrated as well as fleshing out the proposal.

I'd imagine the immutable nature of a network representing actual hardware after elaboration supports fixed declarative regions closely, implying at a minium declarative associativity need be specified. There are other aspects of sequential statements (e.g. sequential signal assignment, sensititivity lists) requiring hardware implementation thinking that invalidate following software programming language paradigms.

-- BrianDrummond - 2013-11-22 : Where the storage size is fixed - or, perhaps, bounded - it could be synthesisable, but that does limit its usefulness! I was thinking of it primarily for simulation, allowed both in process and subprogram. (The block is very similar to an anonymous parameterless procedure with one caller!) And since it is the declaration area of a sequential block statement, I think this proposal implies the latter.

-- JimLewis - 2014-11-11: I am not be against using the Ada Keyword "declare". Would using "block" here make parsing harder and more likely to produce strange error messages?

Supporters

-- BrianDrummond - 2013-11-21

-- RyanHinton - 2014-11-05

-- JimLewis - 2014-12-04

-- MortenZilmer - 2015-01-21

Topic revision: r11 - 2020-02-17 - 15:34:38 - JimLewis
 
Copyright © 2008-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback