New Bitwise Operator support in Fixed Point Toolbox
This demo introduces user to the new and enhanced bitwise operators provided in Fixed Point toolbox in R2007b. These functions are supported by Embedded MATLAB block for both software and hardware modeling and code generation (C and HDL).
Contents
- Motivation
- Quick Introduction
- MATLAB examples
- BITGET (Get bit)
- BITSLICEGET (Get slice of bits)
- GETMSB, GETLSB (Get significant bits)
- BITCONCAT (Concat stored integer bits)
- BITSET (Set bit)
- BITCMP (Complement bits)
- BITSHIFT (Shift bits left/right)
- BITSLL (Shift left logical)
- BITSRA (Shift right arithmetic)
- BITSRL (Shift right logical)
- BITROL (Rotate left)
- BITROR (Rotate right)
- BITOR/BITAND/BITXOR (Bitwise operators)
- BITORREDUCE/BITANDREDUCE/BITXORREDUCE (Bitwise reduction operators)
- Embedded MATLAB HDL Application Examples
- Nibble swap using bitwise operators in Embedded MATLAB
- Getting More Help
Motivation
Bit manipulation functions in fixed point toolbox provide functionality to manipulate and access arbitrary bits of stored integer in a fixed point word. These bitwise functions are very useful in modeling hardware centric algorithms. HDL programming tasks that require bit manipulation include low-level device control, error correction and detection, encryiption etc., Usage of these high level bitwise functions helps to directly map algorithms written in Embedded MATLAB into HDL.
Quick Introduction
The fixed point toolbox provides following set of bitwise operators. All these functions operate on stored integer bits of a fixed point operand.
- bitget(a,idx)
- bitsliceget(a, lidx, ridx)
- bitconcat(a, b)
- bitset(a, idx, val)
- bitcmp(a)
- bitshift(a, idx)
- bitsra(a, idx)
- bitsrl(a, idx)
- bitsll(a, idx)
- bitror(a, idx)
- bitrol(a, idx)
- bitor(a, b)
- bitand(a, b)
- bitxor(a, b)
- bitandreduce(a, lidx, ridx)
- bitorreduce(a, lidx, ridx)
- bitxorreduce(a, lidx, ridx)
MATLAB examples
Here is a set of examples to quickly illustrate the behavior of these functions.
% Setup fi preferences for display fp = fipref; % show fixed point values in binary format fp.NumberDisplay = 'bin'; fp.FimathDisplay = 'none'; fp.NumericTypeDisplay = 'short';
BITGET (Get bit)
controlword = fi(85, 0, 8, 0) % access bit at position 2 bit2 = bitget(controlword, 2) % grab values of all odd bits in the controlword oddbits = bitget(controlword, 1:2:8) % please note that MATLAB uses one based indexing % (LSB position == 1, MSB position == wordlength(controlword))
controlword =
01010101
u8,0
bit2 =
0
u1,0
oddbits =
1 1 1 1
u1,0
BITSLICEGET (Get slice of bits)
wordtoslice = fi(85, 0, 8, 0)
% access consecutive set of bits 8 to 3
bits8to3 = bitsliceget(wordtoslice, 8, 3)
wordtoslice =
01010101
u8,0
bits8to3 =
010101
u6,0
GETMSB, GETLSB (Get significant bits)
cword = fi(-3.5, 1, 4, 1) cw_signbit = getmsb(cword) cw_scalebit = getlsb(cword)
cword =
1001
s4,1
cw_signbit =
1
u1,0
cw_scalebit =
1
u1,0
BITCONCAT (Concat stored integer bits)
word1 = fi(5, 0, 4, 0)
word2 = fi(10, 0, 4, 0)
% concat stored integer bits of mask1 and mask2
finalword = bitconcat(word1, word2)
word1 =
0101
u4,0
word2 =
1010
u4,0
finalword =
01011010
u8,0
BITSET (Set bit)
flagreg = fi(5, 0, 4, 0) % set bit 2 of flagreg flagreg = bitset(flagreg, 2, 1) % clear bit 1 of flagreg flagreg = bitset(flagreg, 1, 0)
flagreg =
0101
u4,0
flagreg =
0111
u4,0
flagreg =
0110
u4,0
BITCMP (Complement bits)
acc = fi(5, 0, 4, 0)
% complement all bits of an accumulator
newacc = bitcmp(acc)
acc =
0101
u4,0
newacc =
1010
u4,0
BITSHIFT (Shift bits left/right)
shiftreg = fi(4, 0, 4, 0) fm = fimath(shiftreg); display(sprintf('overflow mode : %s', fm.OverflowMode)) % shift left once shiftonce = bitshift(shiftreg, 1) % shift left twice (resultant value saturates, see fimath) shifttwice = bitshift(shiftreg, 2) % shift right by one bit shiftreg = fi(10, 0, 4, 0) shiftreg = bitshift(shiftreg, -1)
shiftreg =
0100
u4,0
overflow mode : saturate
shiftonce =
1000
u4,0
shifttwice =
1111
u4,0
shiftreg =
1010
u4,0
shiftreg =
0101
u4,0
BITSLL (Shift left logical)
shiftreg = fi(10, 0, 4, 0) % shift left by one bit shiftreg = bitsll(shiftreg, 1) % shift left by one more bit (value does not saturate) shiftreg = bitsll(shiftreg, 1)
shiftreg =
1010
u4,0
shiftreg =
0100
u4,0
shiftreg =
1000
u4,0
BITSRA (Shift right arithmetic)
shiftreg = fi(-8, 1, 4, 0) % shift right by one bit shiftreg = bitsra(shiftreg, 1) % zeros are shifted in from left if input is unsigned % actual value of msb is shifted in from left if input is signed
shiftreg =
1000
s4,0
shiftreg =
1100
s4,0
BITSRL (Shift right logical)
shiftreg = fi(-8, 1, 4, 0)
% shift right by one bit, always shift in zeros from left
bitsrl(shiftreg, 1)
shiftreg =
1000
s4,0
ans =
0100
s4,0
BITROL (Rotate left)
shiftreg = fi(10, 0, 4, 0) % roate left once bitrol(shiftreg, 1) % roate left twice bitrol(shiftreg, 2)
shiftreg =
1010
u4,0
ans =
0101
u4,0
ans =
1010
u4,0
BITROR (Rotate right)
shiftreg = fi(5, 0, 4, 0) % roate right once bitror(shiftreg, 1) % roate right one more time bitror(shiftreg, 2)
shiftreg =
0101
u4,0
ans =
1010
u4,0
ans =
0101
u4,0
BITOR/BITAND/BITXOR (Bitwise operators)
mask1 = fi(5, 0, 4, 0) mask2 = fi(10, 0, 4, 0) % mask1 or mask2 or_bits = bitor(mask1, mask2) % mask1 and mask2 and_bits = bitand(mask1, mask2) % mask1 xor mask2 xor_bits = bitxor(mask1, mask2)
mask1 =
0101
u4,0
mask2 =
1010
u4,0
or_bits =
1111
u4,0
and_bits =
0000
u4,0
xor_bits =
1111
u4,0
BITORREDUCE/BITANDREDUCE/BITXORREDUCE (Bitwise reduction operators)
mask1 = fi(5, 0, 4, 0) % reduce all bits in mask1 by or'ing them rbyor = bitorreduce(mask1) % and bits 2 to 1 in mask1 rbyand = bitandreduce(mask1, 2, 1) % xor bits 4 to 3 in mask1 rbyxor = bitxorreduce(mask1, 4, 3)
mask1 =
0101
u4,0
rbyor =
1
u1,0
rbyand =
0
u1,0
rbyxor =
1
u1,0
Embedded MATLAB HDL Application Examples
The following section illustrates how these new functions can be used to generate efficient HDL code when used in an Embedded MATLAB block.
Nibble swap using bitwise operators in Embedded MATLAB
Open the model nibble_swap
mdl_name = 'bitops_nibble_swap_7b'; open_system(mdl_name); disp(sprintf('\nModel Name --------------------------> %s', mdl_name)); disp_eml_script(mdl_name); checklicense = builtin('license','checkout','Simulink_HDL_Coder'); if checklicense % choose device under test dut_name = [mdl_name '/DUT']; disp(sprintf('\n\nDUT Name:--------------------------> %s', dut_name)); disp(sprintf('\n\nGenerating VHDL ------------------->')); makehdl(dut_name, 'targetlang', 'vhdl', 'targetdir', 'hdlsrc_vh'); disp(sprintf('\n\nDisplaying generated code --------->')); !cat hdlsrc_vh\nibble_swap_7b.vhd disp(sprintf('\n\nGenerating Verilog ------------------->')); makehdl(dut_name, 'targetlang', 'verilog', 'targetdir', 'hdlsrc_ve'); disp(sprintf('\n\nDisplaying generated code --------->')); !cat hdlsrc_ve\nibble_swap_7b.v end
Model Name --------------------------> bitops_nibble_swap_7b
Block Name --------------------------> bitops_nibble_swap_7b/DUT/nibble_swap
function y = fcn(u)
% NIBBLE SWAP
% assumes u is of type ufix8
% lmask = 0x0F
lmask = fi(15, 0, 8, 0, 'fimath', fimath(u));
% lmask = 0xF0
umask = bitsll(lmask, 4);
% mask upper nibble
l_nibble = bitand(u, lmask);
% mask lower nibble
u_nibble = bitand(u, umask);
% shift lower nibble left
ls = bitsll(l_nibble, 4);
% shift upper nibble right
ur = bitsrl(u_nibble, 4);
% final output
y = bitor(ls, ur);
Block Name --------------------------> bitops_nibble_swap_7b/DUT/nibble_swap_easy
function y = fcn(u)
% NIBBLE SWAP
y = bitconcat(bitsliceget(u, 4, 1), bitsliceget(u, 8, 5));
DUT Name:--------------------------> bitops_nibble_swap_7b/DUT
Generating VHDL ------------------->
Embedded MATLAB parsing for model "bitops_nibble_swap_7b"...Done
Embedded MATLAB code generation for model "bitops_nibble_swap_7b".....Done
Embedded MATLAB compilation for model "bitops_nibble_swap_7b"... 1 file(s) copied.
Done
### Applying HDL Code Generation Control Statements
### Begin VHDL Code Generation
### Working on Timing Controller as <a href="matlab:edit ('hdlsrc_vh\Timing_Controller.vhd')">hdlsrc_vh\Timing_Controller.vhd</a>
### Working on bitops_nibble_swap_7b/DUT as <a href="matlab:edit ('hdlsrc_vh\DUT.vhd')">hdlsrc_vh\DUT.vhd</a>
### Working on bitops_nibble_swap_7b/DUT/nibble_swap as <a href="matlab:edit('hdlsrc_vh\nibble_swap.vhd')">hdlsrc_vh\nibble_swap.vhd</a>
Embedded MATLAB parsing for model "bitops_nibble_swap_7b"...Done
Embedded MATLAB code generation for model "bitops_nibble_swap_7b"....Done
### Working on bitops_nibble_swap_7b/DUT/nibble_swap_easy as <a href="matlab:edit('hdlsrc_vh\nibble_swap_easy.vhd')">hdlsrc_vh\nibble_swap_easy.vhd</a>
Embedded MATLAB parsing for model "bitops_nibble_swap_7b"...Done
Embedded MATLAB code generation for model "bitops_nibble_swap_7b"....Done
### HDL Code Generation Complete.
Displaying generated code --------->
-----------------------------------------------------------
-- Embedded MATLAB Function HDL code generation for Block:
-- bitops_nibble_swap_7b/DUT/nibble_swap_7b
--
-- Target language : vhdl
-- Date of code generation : 31-Aug-2007 16:36:15
--
-- Entity name : nibble_swap_7b
-- Register output : ON
-- Clock name : clk
-- Clock_enable name : clk_enable
-- Reset name : reset
-- Reset type : Asynchronous
-----------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY nibble_swap_7b IS
PORT (
clk : IN std_logic;
clk_enable : IN std_logic;
reset : IN std_logic;
u : IN std_logic_vector(7 DOWNTO 0);
y : OUT std_logic_vector(7 DOWNTO 0));
END nibble_swap_7b;
ARCHITECTURE fsm_SFHDL OF nibble_swap_7b IS
BEGIN
-- NIBBLE SWAP
y <= u(3 DOWNTO 0) & u(7 DOWNTO 4);
END fsm_SFHDL;
Generating Verilog ------------------->
### Applying HDL Code Generation Control Statements
### Begin Verilog Code Generation
### Working on Timing Controller as <a href="matlab:edit ('hdlsrc_ve\Timing_Controller.v')">hdlsrc_ve\Timing_Controller.v</a>
### Working on bitops_nibble_swap_7b/DUT as <a href="matlab:edit ('hdlsrc_ve\DUT.v')">hdlsrc_ve\DUT.v</a>
### Working on bitops_nibble_swap_7b/DUT/nibble_swap as <a href="matlab:edit('hdlsrc_ve\nibble_swap.v')">hdlsrc_ve\nibble_swap.v</a>
Embedded MATLAB parsing for model "bitops_nibble_swap_7b"...Done
Embedded MATLAB code generation for model "bitops_nibble_swap_7b"....Done
### Working on bitops_nibble_swap_7b/DUT/nibble_swap_easy as <a href="matlab:edit('hdlsrc_ve\nibble_swap_easy.v')">hdlsrc_ve\nibble_swap_easy.v</a>
Embedded MATLAB parsing for model "bitops_nibble_swap_7b"...Done
Embedded MATLAB code generation for model "bitops_nibble_swap_7b"....Done
### HDL Code Generation Complete.
Displaying generated code --------->
/////////////////////////////////////////////////////////
// Embedded MATLAB Function HDL code generation for Block:
// bitops_nibble_swap_7b/DUT/nibble_swap_7b
//
// Target language : verilog
// Date of code generation : 31-Aug-2007 16:36:22
//
// Module name : nibble_swap_7b
// Register output : ON
// Clock name : clk
// Clock_enable name : clk_enable
// Reset name : reset
// Reset type : Asynchronous
///////////////////////////////////////////////////////////
`timescale 1 ns / 1 ns
module nibble_swap_7b (clk, clk_enable, reset, u, y );
input clk;
input clk_enable;
input reset;
input [7:0] u;
output [7:0] y;
// NIBBLE SWAP
assign y = {u[3:0], u[7:4]};
endmodule
Getting More Help
For more HDL Code generation info search Simulink HDLCoder documentation or run the following command
>> docsearch ('Using Fixed Point Bitwise Functions‘)
% Also see help for these functions in Fixed point toolbox % >>help embedded.fi.bitconcat help embedded.fi.bitconcat
BITCONCAT Combine stored integer bits of two fixed point words
SYNTAX
c = bitconcat(a, b)
DESCRIPTION:
c = bitconcat(a, b) returns a new fixed value with a concatenated bit
representation of input operands 'a' and 'b'.
1) Requires two fixed point input operands.
2) Output type is always unsigned with wordlength equal to sum of
input fixed point word lengths.
3) Scaling has no bearing on the result type and value.
4) The two's complement representation of inputs are concatenated to
form the stored integer value of the output.
5) Mix and match of signed and unsigned inputs are allowed. Signed bit
is treated like any other bit.
6) Input operands 'a' and 'b' can be vectors but should be of same
size. If the operands are vectors then concatenation will be
performed element-wise.
7) does not support complex inputs
See also EMBEDDED.FI/BITSLICEGET, EMBEDDED.FI/BITGET, EMBEDDED.FI/BITSET,
EMBEDDED.FI/BITAND, EMBEDDED.FI/BITOR, EMBEDDED.FI/BITXOR
EMBEDDED.FI/BITANDREDUCE, EMBEDDED.FI/BITORREDUCE,
EMBEDDED.FI/BITXORREDUCE