Re: [vhdl-200x] Request for Input

From: Daniel Kho <daniel.kho@gmail.com>
Date: Fri Dec 31 2010 - 01:09:32 PST

Hi Ben,
I need to study your suggestion. It could probably work, however, as of now,
I'm not sure as to how to use it (yet). Perhaps it would be better if I
explain what I need in some of my applications.

Well, there came a need for me to use optimised versions of certain library
functions, which are implemented not efficiently enough (as required by my
application) by the synthesis tool.

I wish to maintain the behavioural description of the design, such as the
DSP equations as they are. And I wanted to overload some of the predefined
library functions with my own. However, there is a problem as I wish to have
those functions clocked instead of synthesized to pure combinatorial logic.
I can afford a slower design, but I needed it to fit into a smaller area.

Currently, there is no way (that I know of) of doing this. A function always
synthesizes to pure combinatorial logic, and most of the time, always takes
up too much area. So, I decided to design clocked processes instead, and did
so in separate modules. These processes gives the same results as the
original predefined library "functions", only optimized and clocked (and
gives the final result in multiple clock cycles).

Now. to use these clocked processes, I had to change the original design
(with DSP equations) into something less understandable, which became a
structural description connecting different signals to different modules
that perform simple mathematical operations (such as multiplication,
division, etc.). The result is that the original DSP (or mathematical)
equations are gone, and replaced with signals connecting to each other via
"mathematical modules".

So, I wish to maintain the original behavioural description of the design
(with the DSP equations), and change (or overload) only some library
functions to clocked processes to be used by the behavioural design.

I am open to any simple way of doing this.

Regards,
Daniel
On Fri, Dec 31, 2010 at 4:27 PM, ben cohen <hdlcohen@gmail.com> wrote:

> No, macros are not exactly pragmas, but they are compiler directives.
> SV supports the following:
> `include
> `define, `undef and `undefineall
> `ifdef, `else, `elsif, `endif, `ifndef
>
> text_macro_definition ::=
> `define text_macro_name macro_text
> text_macro_name ::=
> text_macro_identifier [ ( list_of_formal_arguments ) ]
> list_of_formal_arguments ::=
> formal_argument { , formal_argument }
> formal_argument ::=
> simple_identifier [ = default_text ]
> text_macro_identifier ::=
> identifier
>
> Example, from the LRM:
> `define MACRO1(a=5,b="B",c) $display(a,,b,,c);
> `MACRO1 ( , 2, 3 ) // argument a omitted, replaced by default
> // expands to '$display(5,,2,,3);'
> `MACRO1 ( 1 , , 3 ) // argument b omitted, replaced by default
>
> * I was thinking that we could create a package of "processes" similar to
> the way we create a package of "functions".*
> *And we use these processes in behavioural code instead of structural,
> similar to the way we use functions.*
>
> That might work, but it needs an analysis. The `define or `include
> equivalents would also work, but are simpler, IMHO.
> Ben Cohen
>
> On Fri, Dec 31, 2010 at 12:05 AM, Daniel Kho <daniel.kho@gmail.com>wrote:
>
>> Hi Ben,
>> *I don't believe that the community would buy the idea of a function (or
>> something like it) that returns a module since it is equivalent to a module
>> instantiation. *
>> Probably. But I am in the view that we perhaps do not need to
>> "instantiate" the whole module, rather some processes in the module will be
>> converted to logic, while the other processes will not be synthesized.
>> A function could trigger a process within a module, that's the idea. So
>> only that process gets synthesized to logic.
>>
>> Well, I'm open to other suggestions too, including the use of macros. Are
>> they similar to synthesis pragmas in VHDL?
>>
>> Regards,
>> Daniel
>> On Fri, Dec 31, 2010 at 3:46 PM, ben cohen <hdlcohen@gmail.com> wrote:
>>
>>> Hi Daniel,
>>> * Currently, writing the equation is already possible for most synthesis
>>> tools, however, the tool will select the divider and power-of-two functions
>>> from its own predefined library, and sometimes there is a need to optimize
>>> these functions by writing (or overloading) your own. This is where my
>>> suggestion of having a function link to a process (a process is similar to
>>> an "always" block in SV) of an entity/module comes in.*
>>> The fact that the language supports equations with multiplications and
>>> divisions, along with function calls that return a single value) means that
>>> it expresses the desired functionality for what you are addressing. Also,
>>> as you said, synthesis tools support such features with the use of libraries
>>> that need to be tuned -- that reality. I don't believe that the community
>>> would buy the idea of a function (or something like it) that returns a
>>> module since it is equivalent to a module instantiation.
>>>
>>> One could reduce the typing (in SystemVerilog) with
>>> macro definitions ('define). Maybe something like that could be added (but I
>>> see that as a low priority item). It takes one vote to kill a proposal.
>>> Besides, there are so many more important things that need to be fixed or
>>> improved in VHDL, that this proposal is too far from the tasks at hand.
>>>
>>> BTW, I am very familiar with VHDL as I wrote 6 books on the subject, plus
>>> one on PSL that uses VHDL.
>>> Ben Cohen SystemVerilog.us
>>>
>>> On Thu, Dec 30, 2010 at 11:24 PM, Daniel Kho <daniel.kho@gmail.com>wrote:
>>>
>>>> Hi Ben,
>>>> In our case here, though we have the module instantiation concept (or
>>>> entity instantiation) in VHDL and Verilog, there are limitations such as
>>>> what I've mentioned in my earlier email. For example, we have to declare
>>>> separate modules (or entities) and connect them structurally, when it is
>>>> much easier if we create a function and write the DSP equation as an
>>>> equation.
>>>>
>>>> For the example earlier, writing out *z <= x**2 / y;* is much easier
>>>> than instantiating separate modules/entities for a divider and a
>>>> power-of-two and connecting all the signals together as a structural
>>>> description. Currently, writing the equation is already possible for most
>>>> synthesis tools, however, the tool will select the divider and power-of-two
>>>> functions from its own predefined library, and sometimes there is a need to
>>>> optimize these functions by writing (or overloading) your own. This is where
>>>> my suggestion of having a function link to a process (a process is similar
>>>> to an "always" block in SV) of an entity/module comes in.
>>>>
>>>> Sorry I'm not too familiar with SystemVerilog. Anyway, I believe the ##
>>>> notation in SV is probably similar to the "after" clause in VHDL? We can
>>>> specify delays using the "after" clause, though this is usually ignored by
>>>> synthesis tools, as delays with specific timing are non-synthesizable.
>>>>
>>>> Regards,
>>>> Daniel
>>>>
>>>> On Fri, Dec 31, 2010 at 2:57 PM, ben cohen <hdlcohen@gmail.com>wrote:
>>>>
>>>>> Daniel,
>>>>> *z <= x**2 / y; --where "/" is an internal function (I think it's
>>>>> in the std library - not too sure)
>>>>> *
>>>>> *instead of writing:*
>>>>> *q<=x**2;*
>>>>> *divider0: entity work.div32(rtl) port map(a=>q, b=>y, res=>z,
>>>>> remainder=>remainder);*
>>>>> Behavioral synthesis would accept "z <= x**2 / y;"
>>>>> To have a function return an instantiation is not a good idea since we
>>>>> have in both VHDL and SystemVerilog the module instantiation concept.
>>>>>
>>>>> I never used behavioral synthesis; however, below is a SystemVerilog
>>>>> model where the assignment to z occurs after 10 clock cycles if "go" is
>>>>> enabled. The ## is a clock cycle delay.
>>>>> I am not necessarily suggesting this for VHDL. I am just showing how
>>>>> SystemVerilog can handle in clock delays using a notation.
>>>>> Of course, there are other ways to express this delay.
>>>>> module f;
>>>>> int x, y, z;
>>>>> logic clk, clk_dsp, go;
>>>>>
>>>>> default clocking default_clk @ (posedge clk_dsp); endclocking
>>>>>
>>>>> always @ (posedge clk)
>>>>> if(go) ##10 z <= x**2 / y;
>>>>>
>>>>> endmodule : f
>>>>>
>>>>>
>>>>> On Thu, Dec 30, 2010 at 10:12 PM, Daniel Kho <daniel.kho@gmail.com>wrote:
>>>>>
>>>>>> Hi all,
>>>>>> There have been some discussions and suggestions (here and in separate
>>>>>> email threads - such as "Strong Timing" as first suggested by Jonathan, as
>>>>>> well as OO and others) on the next revision of VHDL.
>>>>>>
>>>>>> I decided (finally) to ask a few questions to the reflector. These
>>>>>> could appear as suggestions or "request for suggestions" and may stir up
>>>>>> some inspiration from the SG on new ideas for the next revision.
>>>>>>
>>>>>> I have found it troublesome to do certain things in HDL-based digital
>>>>>> design. I believe these apply to both VHDL and SystemVerilog.
>>>>>>
>>>>>> First, on VHDL "functions". All functions synthesize to regular
>>>>>> (combinatorial) logic (muxes, gates) and never to clocked/registered logic.
>>>>>> Meanwhile, if you were to design a clocked circuit, you will most definitely
>>>>>> need to use "processes", or alternately, concurrent statements sensitive to
>>>>>> a clock signal.
>>>>>>
>>>>>> I find it really troublesome to have to describe a simple algorithmic
>>>>>> (or DSP) design as separate "entities" and connect those entities
>>>>>> "structurally" as a synchronous circuit. For example, say I need to use a
>>>>>> divider for my current design. If I want a clocked arithmetic divider (I
>>>>>> would want this since it uses much less logic resources, and I can afford
>>>>>> many clock cycles for the computation), I would have to describe it
>>>>>> separately as another entity (say we name it "div32") with a clocked process
>>>>>> in its architecture. I would then have to connect that div32 block to my
>>>>>> design structurally, i.e. using port maps to internal signals in my design.
>>>>>> Writing the process into the top-level design works too, but this
>>>>>> unnecessarily makes the top-level design larger, and look less modular and
>>>>>> more complex.
>>>>>>
>>>>>> I would really like to stick to the "function" way of describing this,
>>>>>> as it is much less verbose, though I would also like to have a way for
>>>>>> functions to be able to be clocked. So, in my design, I can just stick to
>>>>>> something like:
>>>>>> z <= x**2 / y; --where "/" is an internal function (I think it's in
>>>>>> the std library - not too sure)
>>>>>> instead of writing:
>>>>>> q<=x**2;
>>>>>> divider0: entity work.div32(rtl) port map(a=>q, b=>y, res=>z,
>>>>>> remainder=>remainder);
>>>>>>
>>>>>> and creating a separate entity to perform the division.
>>>>>>
>>>>>> Perhaps we can think of a way for functions to access clocked
>>>>>> processes? Or maybe a link between a function and an entity-architecture?
>>>>>> Something like accessing an entity's process from within a function, like
>>>>>> below?
>>>>>> function "/"({parameter_list})
>>>>>> begin
>>>>>> return entityName.architectureName.processName({parameter_list});
>>>>>> end function "/";
>>>>>> where parameter_list is just the inputs to the process (no outputs in
>>>>>> parameter_list), and the output (or return value) of the process is
>>>>>> automatically mapped to the function caller. This would mean that by
>>>>>> specifying it this way, we allow the process to drive only a single output
>>>>>> (since the function has only a single return value):
>>>>>> z <= a / b;
>>>>>> In this case, "a" and "b" are both inputs to the function (and the
>>>>>> process), and the process is checked to have only a single output, which is
>>>>>> mapped to "z".
>>>>>> I'm not too sure, hopefully we can brainstorm more ideas.
>>>>>>
>>>>>> Another thing I found troublesome was type conversions or type
>>>>>> casting. Also, that certain library functions only support a limited set of
>>>>>> types.
>>>>>> One example mentioned earlier was in the use of literals. The
>>>>>> following statement is invalid (not supported) at the moment:
>>>>>> signal a:integer:=x"1a2b";
>>>>>>
>>>>>> though ironically this is supported:
>>>>>> signal a:integer:=16#1a2b#;
>>>>>>
>>>>>> Also, one example regarding certain library functions only supporting
>>>>>> a limited set of datatypes is the arithmetic shift operations: sra, sla.
>>>>>> The arithmetic shifts only support the bit_vector type, and doesn't
>>>>>> support std_logic_vector or unsigned/signed. And up till now, since I
>>>>>> haven't been using a lot of bit_vectors, I am still in the dark on how to
>>>>>> convert bit_vectors to say, std_logic_vectors?
>>>>>>
>>>>>> Comments and ideas, anyone?
>>>>>>
>>>>>> Regards,
>>>>>> Daniel Kho
>>>>>> On Tue, Dec 21, 2010 at 12:58 AM, Evan Lavelle <
>>>>>> eml-vhdl-200x@cyconix.com> wrote:
>>>>>>
>>>>>>> +1
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> This message has been scanned for viruses and
>>>>>>> dangerous content by MailScanner, and is
>>>>>>> believed to be clean.
>>>>>>>
>>>>>>>
>>>>>> --
>>>>>> This message has been scanned for viruses and
>>>>>> dangerous content by *MailScanner* <http://www.mailscanner.info/>,
>>>>>> and is
>>>>>> believed to be clean.
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Fri Dec 31 01:10:18 2010

This archive was generated by hypermail 2.1.8 : Fri Dec 31 2010 - 01:10:47 PST