Thread overview
Understanding and new language feature proposal
Jan 06, 2014
Sumit Adhikari
Jan 06, 2014
bearophile
Jan 06, 2014
Sumit Adhikari
Jan 06, 2014
Mike
Jan 06, 2014
Dmitry Olshansky
Jan 07, 2014
Sumit Adhikari
Jan 06, 2014
Sumit Adhikari
January 06, 2014
The birth and evolution of d language is to provide a modern and
better alternative to C++! If I look at C++ then C++ is a systems
programming language. The use cases of C++ is OS and embedded
systems writing.  Why? C++ claims to extract last drop out of HW. If I
look correctly rarely C++ is used and C is the commonly used language.
The abstraction provided by C++ is often ignored as useful feature. D
being a systems programming language competes and the use area is in
embedded systems and indirectly competes plain C.

What is more challenging in embedded systems? It is low level detail!
And the programmer is so much overwhelmed with it and spends so much
time to do it correctly that she/he cannot afford to look at abstract
feature of the language. Let me elaborate the problem! Let us consider
two unsigned 3 bit addition (C++ syntax):

unsigned char a ;
unsigned char b ;

unsigned char result = a + b ;
              result = result & 7 ;


Consider we need to add two 179 bits wide numbers. How will be the
effort. But how about if there is a way like as follows available:


unsigned bits(179:0) a ;
unsigned bits(179:0) b ;
unsigned bits(179:0) result = a + b ;

Looks familiar? remember verilog ?

Where is the use case ? DSP, Protocol stack and driver writing. In DSP
most unusual bit widths are used. In protocol stack very often
calculation are with unusual bitwidth (crc, parity, status, ....).
Consider following case when you want to do some operations by
checking 5th and 6th bit of a register.


unsigned bits(7:0) m_reg ;
unsigned bits(7:0) sts_reg ;

if(m_reg(6:5) == 2) sts_reg(2) = false ;

How convenient is this ?

Want to create a signed 3-bit adder ?


bits(2:0) a ;
bits(2:0) b ;
bits(2:0) y = a * b ;

The use cases are lot. Ask me who is a VLSI SoC architect.

Therefore I would like to propose inclusion of arbitrary bit-width
(native to D) data-type in D language for providing a better way to deal
signal processing, protocol stack, driver writing and lot more.

I completely understand these kind of libraries exists and they are
JUST LIBRARIES.

Regards, Sumit





January 06, 2014
Sumit Adhikari:

> unsigned bits(179:0) a ;
> unsigned bits(179:0) b ;
> unsigned bits(179:0) result = a + b ;

What about this syntax:

UnsignedBits!(179, 0) a, b;
UnsignedBits!(179, 0) result = a + b;

Or better:

alias ubits = UnsignedBits!(179, 0)
ubits a, b;
ubits result = a + b;

Bye,
bearophile
January 06, 2014
This is a great syntax and I am doing this :p.

But there are many many many many issues associated with this (I mentioned that I wanted them natively, templates are problems). The library needed a significant coding and still to match with immutable, support from phobos - it is tough.....

C++ also has some of these implementation (SystemC) - but that did not made it acceptable to embedded systems programmer. Again a library will not allow me to extract last drop from my HW - for every library and everybody :). The internal implementation of these libraries are memory hungry and not embedded systems friendly.

Regards, Sumit




On Monday, 6 January 2014 at 09:41:12 UTC, bearophile wrote:
> Sumit Adhikari:
>
>> unsigned bits(179:0) a ;
>> unsigned bits(179:0) b ;
>> unsigned bits(179:0) result = a + b ;
>
> What about this syntax:
>
> UnsignedBits!(179, 0) a, b;
> UnsignedBits!(179, 0) result = a + b;
>
> Or better:
>
> alias ubits = UnsignedBits!(179, 0)
> ubits a, b;
> ubits result = a + b;
>
> Bye,
> bearophile

January 06, 2014
Just a twist :

unsigned bits(179:0) a ;
unsigned bits(179:0) b ;
unsigned bits(190:0) result = a + b ;

OR

unsigned bits(108826676:0) result = a + b ;


Regards, Sumit


On Monday, 6 January 2014 at 09:41:12 UTC, bearophile wrote:
> Sumit Adhikari:
>
>> unsigned bits(179:0) a ;
>> unsigned bits(179:0) b ;
>> unsigned bits(179:0) result = a + b ;
>
> What about this syntax:
>
> UnsignedBits!(179, 0) a, b;
> UnsignedBits!(179, 0) result = a + b;
>
> Or better:
>
> alias ubits = UnsignedBits!(179, 0)
> ubits a, b;
> ubits result = a + b;
>
> Bye,
> bearophile

January 06, 2014
On Monday, 6 January 2014 at 10:31:46 UTC, Sumit Adhikari wrote:
> Again a library will not allow me to extract last drop from my HW - for every library and everybody :). The internal implementation of these libraries are memory hungry and not embedded systems friendly.

I challenge this statement as often the code generated by templates can be evaluated at compile time.  This means there is no runtime cost except for what is absolutely necessary.  It can also reduce code size.

Take a look at this article by Ken Smith, "C++ Register Access Redux" (http://yogiken.files.wordpress.com/2010/02/c-register-access.pdf).  Specifically read pp 9 and 10.  The code generated by the C++ code and C code turn out to be EXACTLY the same.

I'm taking this same approach in my embedded system with D.  I just wrote it a few hours ago, and haven't run it yet on my hardware, but it looks something like this.

enum Policy
{
    Read,
    Write,
    ReadWrite
}

size_t GetValue(size_t address)
{
    return *(cast(size_t*)address);
}

void SetValue(size_t address, size_t value)
{
    *(cast(size_t*)address) = value;
}

mixin template Register(size_t address, size_t resetValue = 0)
{
    struct BitField(TReturnType, size_t msb, size_t lsb, Policy policy)
    {
        static @property size_t MSBIndex()
        {
            return msb >= lsb ? msb : lsb;
        }

        static @property size_t LSBIndex()
        {
            return lsb <= msb ? lsb : msb;
        }

        static @property size_t NumOfBits()
        {
            return MSBIndex - LSBIndex + 1;
        }

        @property size_t BitMask()
        {
            return ((1 << NumOfBits()) - 1) << LSBIndex();
        }

		static if (policy == Policy.Read || policy == Policy.ReadWrite)
		{
            @property TReturnType Value()
            {
                return cast(TReturnType)((GetValue(address) & BitMask) >> LSBIndex);
            }
		}

        static if (policy == Policy.Write || policy == Policy.ReadWrite)
        {
            @property void Value(TReturnType value)
            {
                SetValue(address, (GetValue(address) & ~BitMask) | ((cast(size_t)value) << LSBIndex));
            }
        }
	}

    static @property size_t ResetValue()
    {
        return resetValue;
    }

    static void Reset()
    {
        Value = resetValue;
    }

    static @property size_t Value()
    {
        return GetValue(address);
    }

    static @property void Value(size_t value)
    {
        SetValue(address, value);
    }
}

//Define your register like this
struct MyRegister
{
    mixin Register!(0x20000000, 0);

    static BitField!(uint, 31, 0, Policy.ReadWrite) Field1;
    static BitField!(ushort, 15, 0, Policy.ReadWrite) Field2;
    static BitField!(bool, 0, 0, Policy.ReadWrite) Field3;
    static BitField!(int, 31, 0, Policy.ReadWrite) Field4;
    static BitField!(int, 31, 0, Policy.ReadWrite) Field4;
}

//Use your register like this
void main()
{
    MyRegister.Field1 = 123;
    MyRegister.Field3 = true;

    ... etc..
}

Mike


January 06, 2014
06-Jan-2014 14:31, Sumit Adhikari пишет:
>
> This is a great syntax and I am doing this :p.
>
> But there are many many many many issues associated with this (I
> mentioned that I wanted them natively, templates are problems). The
> library needed a significant coding and still to match with immutable,
> support from phobos - it is tough.....
>

So you want to put this burden on compiler writers. Can't really sympathize ;)


-- 
Dmitry Olshansky
January 07, 2014
Too bad that I cannot reply all.

Dear people,

Requesting for a domain specific data type is not a sin :D.

If there can be support for arbitrary precision floating point number, then there can be arbitrary precision bit-vector :D. Libraries are good, but they depends on library writer! that's all I wanted to say. Do not want to up-cast and then down-cast or vice-versa. I just requested for a clean thing which will be used a lot if available.




On Monday, 6 January 2014 at 11:27:03 UTC, Dmitry Olshansky wrote:
> 06-Jan-2014 14:31, Sumit Adhikari пишет:
>>
>> This is a great syntax and I am doing this :p.
>>
>> But there are many many many many issues associated with this (I
>> mentioned that I wanted them natively, templates are problems). The
>> library needed a significant coding and still to match with immutable,
>> support from phobos - it is tough.....
>>
>
> So you want to put this burden on compiler writers. Can't really sympathize ;)