bit slice in vectors

Discussion in 'VHDL' started by alb, Sep 12, 2013.

  1. alb

    alb Guest

    Hi everyone,

    I have declared a set of constants in the following way:

    constant AB : unsigned(data_t'range) := x"01";
    constant CD : unsigned(data_t'range) := x"02";
    constant EF : unsigned(data_t'range) := x"04";
    constant GH : unsigned(data_t'range) := x"08";
    constant IJ : unsigned(data_t'range) := x"10";
    constant KL : unsigned(data_t'range) := x"20";
    constant MN : unsigned(data_t'range) := x"40";
    constant OP : unsigned(data_t'range) := x"80";

    where data_t is a constrained std_logic_vector(7 downto 0) type.
    If we declare a signal/variable foo of data_t type and we want to test
    if bit 'IJ' is set or not, what I'm currently doing is the following:

    if foo(to_integer(IJ) - 1) then
    -- do stuff
    end if;

    which I find rather ugly... And if the constant is an slv than I would
    need to do something like

    if foo(to_integer(unsigned(IJ) - 1)) then
    -- do stuff
    end if;

    which is even uglier!

    Is there a more readable way to do that?
    True I can write my function to handle the conversions and return a
    natural, but I didn't want to reinvent the wheel :)

    On top of this, the limitation of this approach is that if data_t change
    bus width the constants definitions will not work anymore. Any idea?

    Thanks a lot,

    alb, Sep 12, 2013
    1. Advertisements

  2. alb

    KJ Guest

    On Thursday, September 12, 2013 8:53:27 AM UTC-4, alb wrote:

    It's not clear to me why 'IJ' is anything other than an integer in your example. That would clean up most of what you seem to not like.

    As for a cleaner overall approach, presumably the reason that you're defining all of those constants is because the data should really be defined as arecord and there is a need to convert between the record type and std_logic_vectors. There probably isn't much value in your current definition of 'data_t' type as being just another vector. Take a look at this post...

    Kevin Jennings
    KJ, Sep 12, 2013
    1. Advertisements

  3. alb

    Andy Guest


    I would encourage to you to use integers (or subtypes thereof) wherever possible, particularly in places where unknown or tri-state representation is not needed, and the representation size is <= 31 bits unsigned or 32 bits signed.

    And as Kevin said, especialy for your constants.

    If the constants are also needed in unsigned/slv form, consider which is easier or less common in your application: converting slv/unsigned to integer, or integer to slv/unsigned?

    Andy, Sep 12, 2013
  4. alb

    alb Guest

    Hi KJ,

    because sometimes your 'emergency exit might be located just behind you'!
    Constants definition is used, for example, in an interrupt enable
    register assignment which can be easily performed this way:

    interrupt_reg := PD or PDE or TBE;

    or equivalently in the case of integer defined constants:

    interrupt_reg(PD) := '1';
    interrupt_reg(PDE) := '1';
    interrupt_reg(TBE) := '1';

    And by the way I just found that in the OP there's a mistake in the
    conversion, since it will only work for bit 1 and 2...!!!
    That post inspired me a great deal and now I do have conversion
    functions from/to my record types.
    alb, Sep 13, 2013
  5. alb

    Andy Guest


    Assuming the integer constants are locally static:

    interrupt_reg := (PD | PDE | TBE => '1', others => '0');

    would also work.

    Where there is a will, there is a way.
    Circumstances dictate whether the will is worth the way.

    Andy, Sep 16, 2013
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.