Bit utility macros

E

Evan Lavelle

Guest
After much wheel re-inventing, I'm posting some macros which may be of
use to others:

IS_META(n) returns 1 if object 'n' contains any metadata
(x or z bits), and 0 otherwise
IS_MSB_SET(n) returns 1 if the MSB in object 'n' is 1, and 0 if it is
0, x, or z
NBITS(n) Returns the declared width of object 'n'
SET_ALL(n) Sets all bits in object 'n' to 1
ILOG2(n) Returns the index of the top set bit in object 'n'; only
works for objects of 32 bits or less. Note that
this returns 0 if there are no set bits in 'n'.

Corrections/improvements welcome.

Evan

=================================================================

/*
----------------------------------------------------------------------------
*
* Some utility macros, and test code. The expected output of the test
code
* is at the end of the file. The code has been tested on 3 simulators
* (but 2 other (free) simulators currently won't compile it). It's
not
* V95-compatible, since it requires $signed, $unsigned, and signed
constants
* from V-2001.
*
* IS_META(n) returns 1 if object 'n' contains any metadata (x or z
bits),
* and 0 otherwise
* IS_MSB_SET(n) returns 1 if the MSB in object 'n' is 1, and 0 if it
is
* 0, x, or z
* NBITS(n) Returns the declared width of object 'n'
* SET_ALL(n) Sets all bits in object 'n' to 1
* ILOG2(n) Returns the index of the top set bit in object 'n';
only
* works for objects of 32 bits or less. Note that this
returns
* 0 if there are no set bits in 'n'.
*
* Author E.M. Lavelle (www.riverside-machines.com)
* Date 13/09/2007
* Licence None
*
*
-------------------------------------------------------------------------
*/

`define ILOG2(n) (\
(n) >= (1<<16)? (((n) >= (1<<24))? (((n) >= (1<<28))? (((n) >=
(1<<30))? (((n) >= (1<<31)) ? 31 : 30) : \

(((n) >= (1<<29)) ? 29 : 28)) : \
(((n) >=
(1<<26))? (((n) >= (1<<27)) ? 27 : 26) : \

(((n) >= (1<<25)) ? 25 : 24))) : \
(((n) >= (1<<20))? (((n) >=
(1<<22))? (((n) >= (1<<23)) ? 23 : 22) : \

(((n) >= (1<<21)) ? 21 : 20)) : \
(((n) >=
(1<<18))? (((n) >= (1<<19)) ? 19 : 18) : \

(((n) >= (1<<17)) ? 17 : 16)))) : \
(((n) >= (1<<8))? (((n) >= (1<<12))? (((n) >=
(1<<14))? (((n) >= (1<<15)) ? 15 : 14) : \

(((n) >= (1<<13)) ? 13 : 12)) : \
(((n) >=
(1<<10))? (((n) >= (1<<11)) ? 11 : 10) : \

(((n) >= (1<<9 )) ? 9 : 8 ))) : \
(((n) >= (1<<4 ))? (((n) >= (1<<6
))? (((n) >= (1<<7 )) ? 7 : 6 ) : \

(((n) >= (1<<5 )) ? 5 : 4 )) : \
(((n) >= (1<<2
))? (((n) >= (1<<3 )) ? 3 : 2 ) : \

(((n) >= (1<<1 )) ? 1 : 0 )))))
`define SET_ALL(n) (`IS_META(n)? ~((n) & 1'b0) : ((n) - (n) -
1'b1))
`define IS_META(n) (($signed(n) === 1'sbx) || ($signed(n + 1'b1)
=== 1'sbx))
`define NBITS(n) (`ILOG2({`SET_ALL(n)}) + 1)
`define IS_MSB_SET(n) (((n) >> (`NBITS(n)-1)) === 1)

// --- test code ----

module test;
reg a1;
reg [1:0] a2;
reg [2:0] a3;
reg [3:0] a4;
reg [4:0] a5;
reg [5:0] a6;
reg [6:0] a7;
reg [7:0] a8;
reg [8:0] a9;
reg [9:0] a10;
reg [10:0] a11;
reg [11:0] a12;
reg [12:0] a13;
reg [13:0] a14;
reg [14:0] a15;
reg [15:0] a16;
reg [16:0] a17;
reg [17:0] a18;
reg [18:0] a19;
reg [19:0] a20;
reg [20:0] a21;
reg [21:0] a22;
reg [22:0] a23;
reg [23:0] a24;
reg [24:0] a25;
reg [25:0] a26;
reg [26:0] a27;
reg [27:0] a28;
reg [28:0] a29;
reg [29:0] a30;
reg [30:0] a31;
reg [31:0] a32;
initial
main;
task main;
begin

// a1, a31, a32 are uninitialised; the others are set to
arbitrary
// values
a2 = 2'b01; a3 = 3'b000; a4 = 4'bx000;
a5 = 5'bxxxxx; a6 = 6'bzzzzzz; a7 = 7'bxzxzxzx; a8 =
8'hde;
a9 = 9'h1a5; a10 = 'habcd; a11 = 'habcd; a12 =
'habcd;
a13 = 'habcd; a14 = 'habcd; a15 = 'habcd; a16 =
'habcd;
a17 = 'haaaaaaaa; a18 = 'haaaaaaaa; a19 = 'haaaaaaaa; a20 =
'haaaaaaaa;
a21 = 'haaaaaaza; a22 = 'haaaaaaaa; a23 = 'haaaaxaaa; a24 =
'haaZXaaaa;
a25 = 'haaaaaaaa; a26 = 'haaaaaxxa; a27 = 'haaaaaaaa; a28 =
'haaaaa???;
a29 = 'haaaxaaaa; a30 = 'hazaaaaaa;

$display("a1: %0d bit; top bit set: %s %b", `NBITS(a1),
`IS_MSB_SET(a1)? "Y":"N", a1);
$display("a2: %0d bits; top bit set: %s %b", `NBITS(a2),
`IS_MSB_SET(a2)? "Y":"N", a2);
$display("a3: %0d bits; top bit set: %s %b", `NBITS(a3),
`IS_MSB_SET(a3)? "Y":"N", a3);
$display("a4: %0d bits; top bit set: %s %b", `NBITS(a4),
`IS_MSB_SET(a4)? "Y":"N", a4);
$display("a5: %0d bits; top bit set: %s %b", `NBITS(a5),
`IS_MSB_SET(a5)? "Y":"N", a5);
$display("a6: %0d bits; top bit set: %s %b", `NBITS(a6),
`IS_MSB_SET(a6)? "Y":"N", a6);
$display("a7: %0d bits; top bit set: %s %b", `NBITS(a7),
`IS_MSB_SET(a7)? "Y":"N", a7);
$display("a8: %0d bits; top bit set: %s %b", `NBITS(a8),
`IS_MSB_SET(a8)? "Y":"N", a8);
$display("a9: %0d bits; top bit set: %s %b", `NBITS(a9),
`IS_MSB_SET(a9)? "Y":"N", a9);
$display("a10: %0d bits; top bit set: %s %b", `NBITS(a10),
`IS_MSB_SET(a10)? "Y":"N", a10);
$display("a11: %0d bits; top bit set: %s %b", `NBITS(a11),
`IS_MSB_SET(a11)? "Y":"N", a11);
$display("a12: %0d bits; top bit set: %s %b", `NBITS(a12),
`IS_MSB_SET(a12)? "Y":"N", a12);
$display("a13: %0d bits; top bit set: %s %b", `NBITS(a13),
`IS_MSB_SET(a13)? "Y":"N", a13);
$display("a14: %0d bits; top bit set: %s %b", `NBITS(a14),
`IS_MSB_SET(a14)? "Y":"N", a14);
$display("a15: %0d bits; top bit set: %s %b", `NBITS(a15),
`IS_MSB_SET(a15)? "Y":"N", a15);
$display("a16: %0d bits; top bit set: %s %b", `NBITS(a16),
`IS_MSB_SET(a16)? "Y":"N", a16);
$display("a17: %0d bits; top bit set: %s %b", `NBITS(a17),
`IS_MSB_SET(a17)? "Y":"N", a17);
$display("a18: %0d bits; top bit set: %s %b", `NBITS(a18),
`IS_MSB_SET(a18)? "Y":"N", a18);
$display("a19: %0d bits; top bit set: %s %b", `NBITS(a19),
`IS_MSB_SET(a19)? "Y":"N", a19);
$display("a20: %0d bits; top bit set: %s %b", `NBITS(a20),
`IS_MSB_SET(a20)? "Y":"N", a20);
$display("a21: %0d bits; top bit set: %s %b", `NBITS(a21),
`IS_MSB_SET(a21)? "Y":"N", a21);
$display("a22: %0d bits; top bit set: %s %b", `NBITS(a22),
`IS_MSB_SET(a22)? "Y":"N", a22);
$display("a23: %0d bits; top bit set: %s %b", `NBITS(a23),
`IS_MSB_SET(a23)? "Y":"N", a23);
$display("a24: %0d bits; top bit set: %s %b", `NBITS(a24),
`IS_MSB_SET(a24)? "Y":"N", a24);
$display("a25: %0d bits; top bit set: %s %b", `NBITS(a25),
`IS_MSB_SET(a25)? "Y":"N", a25);
$display("a26: %0d bits; top bit set: %s %b", `NBITS(a26),
`IS_MSB_SET(a26)? "Y":"N", a26);
$display("a27: %0d bits; top bit set: %s %b", `NBITS(a27),
`IS_MSB_SET(a27)? "Y":"N", a27);
$display("a28: %0d bits; top bit set: %s %b", `NBITS(a28),
`IS_MSB_SET(a28)? "Y":"N", a28);
$display("a29: %0d bits; top bit set: %s %b", `NBITS(a29),
`IS_MSB_SET(a29)? "Y":"N", a29);
$display("a30: %0d bits; top bit set: %s %b", `NBITS(a30),
`IS_MSB_SET(a30)? "Y":"N", a30);
$display("a31: %0d bits; top bit set: %s %b", `NBITS(a31),
`IS_MSB_SET(a31)? "Y":"N", a31);
$display("a32: %0d bits; top bit set: %s %b", `NBITS(a32),
`IS_MSB_SET(a32)? "Y":"N", a32);

end
endtask
endmodule

/*
----------------------------------------------------------------------------

The expected output is:

a1: 1 bit; top bit set: N x
a2: 2 bits; top bit set: N 01
a3: 3 bits; top bit set: N 000
a4: 4 bits; top bit set: N x000
a5: 5 bits; top bit set: N xxxxx
a6: 6 bits; top bit set: N zzzzzz
a7: 7 bits; top bit set: N xzxzxzx
a8: 8 bits; top bit set: Y 11011110
a9: 9 bits; top bit set: Y 110100101
a10: 10 bits; top bit set: Y 1111001101
a11: 11 bits; top bit set: N 01111001101
a12: 12 bits; top bit set: Y 101111001101
a13: 13 bits; top bit set: N 0101111001101
a14: 14 bits; top bit set: Y 10101111001101
a15: 15 bits; top bit set: N 010101111001101
a16: 16 bits; top bit set: Y 1010101111001101
a17: 17 bits; top bit set: N 01010101010101010
a18: 18 bits; top bit set: Y 101010101010101010
a19: 19 bits; top bit set: N 0101010101010101010
a20: 20 bits; top bit set: Y 10101010101010101010
a21: 21 bits; top bit set: N 0101010101010zzzz1010
a22: 22 bits; top bit set: Y 1010101010101010101010
a23: 23 bits; top bit set: N 0101010xxxx101010101010
a24: 24 bits; top bit set: N zzzzxxxx1010101010101010
a25: 25 bits; top bit set: N 0101010101010101010101010
a26: 26 bits; top bit set: Y 10101010101010xxxxxxxx1010
a27: 27 bits; top bit set: N 010101010101010101010101010
a28: 28 bits; top bit set: Y 1010101010101010zzzzzzzzzzzz
a29: 29 bits; top bit set: N 010101010xxxx1010101010101010
a30: 30 bits; top bit set: Y 10zzzz101010101010101010101010
a31: 31 bits; top bit set: N xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
a32: 32 bits; top bit set: N xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

*
-------------------------------------------------------------------------
*/

// ----------------------------------- EOF
------------------------------------
 
On Thu, 13 Sep 2007 12:07:23 +0100, Evan Lavelle <nospam@nospam.com>
wrote:

After much wheel re-inventing, I'm posting some macros which may be of
use to others:
Looks very useful.

Any reason why you didn't use this form of IS_META?
Seems simpler to me (though, of course, that doesn't
much matter if it's hidden away in a macro):

(^(n)===1'bx)

Your use of 1'sbx to get something that extends itself to a
context-determined bunch of Xs is exceedingly cool, and I
hadn't thought of it before.

thanks
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Wed, 19 Sep 2007 21:44:45 +0100, Jonathan Bromley
<jonathan.bromley@MYCOMPANY.com> wrote:

Any reason why you didn't use this form of IS_META?
Seems simpler to me (though, of course, that doesn't
much matter if it's hidden away in a macro):

(^(n)===1'bx)
Yes. Didn't think of it... :)
 

Welcome to EDABoard.com

Sponsor

Back
Top