]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/tumbl.git/blob - hw/mbl_Pkg.vhd
Customized instruction set (with compatibility mode)
[fpga/lx-cpu1/tumbl.git] / hw / mbl_Pkg.vhd
1 ---------------------------------------------------------------------------------
2 --
3 --  Package:      mbl_Pkg
4 --  Filename:     mbl_Pkg.vhd
5 --  Description:  Package for the TUD MB-Lite implementation
6 --
7 --  Author:       Huib Lincklaen Arriens
8 --                Delft University of Technology
9 --                Faculty EEMCS, Department ME&CE, Circuits and Systems
10 --  Date:         September, 2010
11 --
12 --  Modified:     September, 2013: Removed FSL
13 --                     June, 2011: ALU_ACTION_Type extended to incorporate
14 --                                 MUL and BS instructions (Huib)
15 --                                 Adapted to work with separate fsl_M-
16 --                                 and fsl_S selectors and automatic
17 --                                 tumbl<_jtag><_fsl>.vhd generation (Huib)
18 --                     July, 2011: function ef_nbits added (Huib)
19 --  Remarks:
20 --
21 --------------------------------------------------------------------------------
22
23 LIBRARY IEEE;
24 USE IEEE.std_logic_1164.all;
25 USE IEEE.std_logic_unsigned.all;
26 USE IEEE.numeric_std.all;
27
28
29 --------------------------------------------------------------------------------
30 PACKAGE mbl_Pkg IS
31 --------------------------------------------------------------------------------
32
33     CONSTANT  C_8_ZEROS : STD_LOGIC_VECTOR ( 7 DOWNTO 0) :=       X"00";
34     CONSTANT C_16_ZEROS : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"0000";
35     CONSTANT C_24_ZEROS : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"000000";
36     CONSTANT C_32_ZEROS : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000";
37
38     CONSTANT C_16_ONES  : STD_LOGIC_VECTOR (15 DOWNTO 0) :=     X"FFFF";
39     CONSTANT C_24_ONES  : STD_LOGIC_VECTOR (23 DOWNTO 0) :=   X"FFFFFF";
40
41
42 ----------------------------------------------------------------------------------------------
43 -- TYPE DEFINITIONS
44 ----------------------------------------------------------------------------------------------
45
46     TYPE ALU_ACTION_Type    IS (A_NOP, A_ADD, A_CMP, A_CMPU, A_OR, A_AND, A_XOR,
47                                         A_SHIFT, A_SEXT8, A_SEXT16, A_MFS, A_MTS,
48                                         A_MUL, A_BSLL, A_BSRL, A_BSRA, A_HALT);
49     TYPE ALU_IN1_Type       IS (ALU_IN_REGA, ALU_IN_NOT_REGA, ALU_IN_PC, ALU_IN_ZERO);
50     TYPE ALU_IN2_Type       IS (ALU_IN_REGB, ALU_IN_NOT_REGB, ALU_IN_IMM, ALU_IN_NOT_IMM);
51     TYPE ALU_CIN_Type       IS (CIN_ZERO, CIN_ONE, FROM_MSR, FROM_IN1);
52     TYPE MSR_ACTION_Type    IS (UPDATE_CARRY, KEEP_CARRY);
53     TYPE BRANCH_ACTION_Type IS (NO_BR, BR, BRL, BEQ, BNE, BLT, BLE, BGT, BGE);
54     TYPE WRB_ACTION_Type    IS (NO_WRB, WRB_EX, WRB_MEM);
55     TYPE MEM_ACTION_Type    IS (NO_MEM, WR_MEM, RD_MEM);
56     TYPE TRANSFER_SIZE_Type IS (WORD, HALFWORD, BYTE);
57     TYPE SAVE_REG_Type      IS (NO_SAVE, SAVE_RA, SAVE_RB);
58     --
59     TYPE IF2ID_Type IS RECORD
60         program_counter : STD_LOGIC_VECTOR (31 DOWNTO 0);
61     END RECORD;
62
63     TYPE ID2EX_Type IS RECORD
64         program_counter  : STD_LOGIC_VECTOR (31 DOWNTO 0);
65         rdix_rA          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
66         rdix_rB          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
67         curr_rD          : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
68         alu_Action       : ALU_ACTION_Type;
69         alu_Op1          : ALU_IN1_Type;
70         alu_Op2          : ALU_IN2_Type;
71         alu_Cin          : ALU_CIN_Type;
72         IMM16            : STD_LOGIC_VECTOR (15 DOWNTO 0);
73         IMM_Lock         : STD_LOGIC;
74         msr_Action       : MSR_ACTION_Type;
75         branch_Action    : BRANCH_ACTION_Type;
76         mem_Action       : MEM_ACTION_Type;         -- rd_mem implies writeback
77         transfer_Size    : TRANSFER_SIZE_Type;
78         wrb_Action       : WRB_ACTION_Type;
79     END RECORD;
80
81     TYPE ID2GPRF_Type IS RECORD
82         rdix_rA : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
83         rdix_rB : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
84         rdix_rD : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
85     END RECORD;
86
87     TYPE INT_CTRL_Type IS RECORD
88         setup_int  : STD_LOGIC;
89         rti_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
90         int_busy   : STD_LOGIC;
91     END RECORD;
92
93     TYPE ID2CTRL_Type IS RECORD
94         delayBit : STD_LOGIC;
95         int_busy : STD_LOGIC;
96     END RECORD;
97
98     TYPE GPRF2EX_Type IS RECORD
99         data_rA : STD_LOGIC_VECTOR (31 DOWNTO 0);
100         data_rB : STD_LOGIC_VECTOR (31 DOWNTO 0);
101         data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
102     END RECORD;
103
104     TYPE IMM_LOCK_Type IS RECORD
105         locked   : STD_LOGIC;
106         IMM_hi16 : STD_LOGIC_VECTOR (15 DOWNTO 0);
107     END RECORD;
108
109     TYPE MSR_Type IS RECORD
110         IE  : STD_LOGIC;        -- MSR[VHDL b1] = [MicroBlaze b30]
111         C   : STD_LOGIC;        -- MSR[VHDL b2 and b31] = [MicroBlaze b29 and b0]
112     END RECORD;
113
114     TYPE EX2IF_Type IS RECORD
115         take_branch   : STD_LOGIC;
116         branch_target : STD_LOGIC_VECTOR (31 DOWNTO 0);
117     END RECORD;
118
119     TYPE HALT_Type IS RECORD
120         halt          : STD_LOGIC;
121         halt_code     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
122     END RECORD;
123
124     TYPE EX2MEM_Type IS RECORD
125         mem_Action      : MEM_ACTION_Type;                  -- RD_MEM implies writeback
126         wrb_Action      : WRB_ACTION_Type;
127         exeq_result     : STD_LOGIC_VECTOR (31 DOWNTO 0);
128         data_rD         : STD_LOGIC_VECTOR (31 DOWNTO 0);
129         byte_Enable     : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
130         wrix_rD         : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
131     END RECORD;
132
133     TYPE WRB_Type IS RECORD
134         wrb_Action : WRB_ACTION_Type;
135         wrix_rD    : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
136         data_rD    : STD_LOGIC_VECTOR (31 DOWNTO 0);
137     END RECORD;
138
139     TYPE HAZARD_WRB_Type IS RECORD
140         hazard  : STD_LOGIC;
141         save_rX : SAVE_REG_Type;
142         data_rX : STD_LOGIC_VECTOR (31 DOWNTO 0);
143         data_rD : STD_LOGIC_VECTOR (31 DOWNTO 0);
144     END RECORD;
145
146     TYPE MEM_REG_Type IS RECORD
147         wrb_Action  : WRB_ACTION_Type;
148         exeq_result : STD_LOGIC_VECTOR (31 DOWNTO 0);
149         byte_Enable : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
150         wrix_rD     : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
151     END RECORD;
152
153     TYPE MEM2CTRL_Type IS RECORD
154         clken : STD_LOGIC;
155         int   : STD_LOGIC;
156     END RECORD;
157
158     TYPE CORE2DMEMB_Type IS RECORD
159         ena   : STD_LOGIC;
160         addr  : STD_LOGIC_VECTOR (31 DOWNTO 0);
161         bSel  : STD_LOGIC_VECTOR ( 3 DOWNTO 0);
162         wre   : STD_LOGIC;
163         data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
164     END RECORD;
165
166     TYPE DMEMB2CORE_Type IS RECORD
167         clken : STD_LOGIC;
168         data  : STD_LOGIC_VECTOR (31 DOWNTO 0);
169         int   : STD_LOGIC;
170     END RECORD;
171
172     TYPE MEMORY_MAP_Type IS ARRAY(NATURAL RANGE <>) OF STD_LOGIC_VECTOR (31 DOWNTO 0);
173     -- NOTE: Use the named association format  xxxx := ( 0 => X"A0010000" );
174     --       in case the array has to contain only one element !!
175
176 ----------------------------------------------------------------------------------------------
177 -- COMPONENTS
178 ----------------------------------------------------------------------------------------------
179
180     COMPONENT fetch IS
181         PORT (
182             prog_cntr_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
183             inc_pc_i    :  IN STD_LOGIC;
184             EX2IF_i     :  IN EX2IF_Type;
185             IF2ID_o     : OUT IF2ID_Type
186             );
187     END COMPONENT;
188
189     COMPONENT decode IS
190         GENERIC (
191             USE_HW_MUL_g : BOOLEAN := TRUE;
192             USE_BARREL_g : BOOLEAN := TRUE;
193             COMPATIBILITY_MODE_g : BOOLEAN := FALSE
194             );
195         PORT (
196             IF2ID_i     :  IN IF2ID_Type;
197             imem_data_i :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
198             --
199             ID2GPRF_o   : OUT ID2GPRF_Type;
200             ID2EX_o     : OUT ID2EX_Type;
201             --
202             INT_CTRL_i  :  IN INT_CTRL_Type;
203             ID2CTRL_o   : OUT ID2CTRL_Type;
204             --
205             noLiteOpc_o : OUT STD_LOGIC
206             );
207     END COMPONENT;
208
209     COMPONENT adder IS
210         GENERIC (
211             DW_g : POSITIVE := 32;
212             LW_g : POSITIVE := 15
213         );
214         PORT (
215             in1  :  IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
216             in2  :  IN STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
217             cin  :  IN STD_LOGIC;
218             sum  : OUT STD_LOGIC_VECTOR (DW_g-1 DOWNTO 0);
219             cout : OUT STD_LOGIC
220             );
221     END COMPONENT;
222
223     COMPONENT exeq IS
224         GENERIC (
225             USE_HW_MUL_g : BOOLEAN := FALSE;
226             USE_BARREL_g : BOOLEAN := FALSE
227             );
228         PORT (
229             ID2EX_i      :  IN ID2EX_Type;
230             GPRF2EX_i    :  IN GPRF2EX_Type;
231             EX2IF_o      : OUT EX2IF_Type;
232             HALT_o       : OUT HALT_Type;
233             --
234             EX_WRB_i     :  IN WRB_Type;
235             EX_WRB_o     : OUT WRB_Type;
236             MEM_WRB_i    :  IN WRB_Type;
237             --
238             HAZARD_WRB_i :  IN HAZARD_WRB_Type;
239             HAZARD_WRB_o : OUT HAZARD_WRB_Type;
240             --
241             IMM_LOCK_i   :  IN IMM_LOCK_Type;
242             IMM_LOCK_o   : OUT IMM_LOCK_Type;
243             --
244             MSR_i        :  IN MSR_Type;
245             MSR_o        : OUT MSR_Type;
246             --
247             EX2MEM_o     : OUT EX2MEM_Type
248             );
249     END COMPONENT;
250
251     COMPONENT mem IS
252         PORT (
253             EX2MEM_i    :  IN EX2MEM_Type;
254             --
255             DMEMB_i     :  IN DMEMB2CORE_Type;
256             DMEMB_o     : OUT CORE2DMEMB_Type;
257             --
258             MEM_REG_i   :  IN MEM_REG_Type;
259             MEM_REG_o   : OUT MEM_REG_Type;
260             --
261             MEM_WRB_o   : OUT WRB_Type;
262             MEM2CTRL_o  : OUT MEM2CTRL_Type
263             );
264     END COMPONENT;
265
266     COMPONENT core_ctrl IS
267         GENERIC (
268             COMPATIBILITY_MODE_g : BOOLEAN := FALSE
269             );
270         PORT (
271             clk_i           :  IN STD_LOGIC;
272             rst_i           :  IN STD_LOGIC;
273             halt_i          :  IN STD_LOGIC;
274             bad_op_i        :  IN STD_LOGIC;
275             int_i           :  IN STD_LOGIC;
276             trace_i         :  IN STD_LOGIC;
277             trace_kick_i    :  IN STD_LOGIC;
278             core_clken_o    : OUT STD_LOGIC;
279             -- specific fetch i/o
280             imem_addr_o     : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
281             imem_clken_o    : OUT STD_LOGIC;
282             pc_ctrl_o       : OUT STD_LOGIC;
283             -- fetch to decode pipeline registers
284             IF2ID_REG_i     :  IN IF2ID_Type;
285             IF2ID_REG_o     : OUT IF2ID_Type;
286             -- decode to exeq pipeline registers
287             ID2EX_REG_i     :  IN ID2EX_Type;
288             ID2EX_REG_o     : OUT ID2EX_Type;
289             -- GPRF control
290             gprf_clken_o    : OUT STD_LOGIC;
291             -- exeq to fetch feedback registers
292             EX2IF_REG_i     :  IN EX2IF_Type;
293             EX2IF_REG_o     : OUT EX2IF_Type;
294             -- exeq to core (halting)
295             exeq_halt_i     :  IN STD_LOGIC;
296             -- exeq to mem pipeline registers
297             EX2MEM_REG_i    :  IN EX2MEM_Type;
298             EX2MEM_REG_o    : OUT EX2MEM_Type;
299             -- mem pipeline register
300             MEM_REG_i       :  IN MEM_REG_Type;
301             MEM_REG_o       : OUT MEM_REG_Type;
302             -- decode control i/o
303             ID2CTRL_i       :  IN ID2CTRL_Type;
304             INT_CTRL_o      : OUT INT_CTRL_Type;
305             -- exeq control i/o
306             EX_WRB_i        :  IN WRB_Type;
307             EX_WRB_o        : OUT WRB_Type;
308             -- data hazard i/o
309             HAZARD_WRB_i    :  IN HAZARD_WRB_Type;
310             HAZARD_WRB_o    : OUT HAZARD_WRB_Type;
311             -- for handling the 'IMM' instruction
312             IMM_LOCK_i      :  IN IMM_LOCK_Type;
313             IMM_LOCK_o      : OUT IMM_LOCK_Type;
314             -- for handling the Machine Status Register
315             MSR_i           :  IN MSR_Type;
316             MSR_o           : OUT MSR_Type;
317             -- miscellaneous
318             MEM2CTRL_i      :  IN MEM2CTRL_Type
319             );
320     END COMPONENT;
321
322 ----------------------------------------------------------------------------------------------
323 -- FUNCTION, PROCEDURE DECLARATIONS
324 ----------------------------------------------------------------------------------------------
325
326     PROCEDURE ep_add32 ( a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
327                          ci   :  IN STD_LOGIC;
328                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
329                          VARIABLE co : OUT STD_LOGIC );
330
331     PROCEDURE ep_add32nc ( a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
332                          ci   :  IN STD_LOGIC;
333                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0));
334
335 --  PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
336 --                       VARIABLE s  : OUT STD_LOGIC_VECTOR;
337 --                       VARIABLE co : OUT STD_LOGIC );
338
339     FUNCTION ef_nbits ( value : NATURAL ) RETURN POSITIVE;
340
341 END PACKAGE mbl_Pkg;
342
343
344 ----------------------------------------------------------
345 PACKAGE BODY mbl_Pkg IS
346 ----------------------------------------------------------
347
348     PROCEDURE ep_add32 (        a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
349                                 ci   :  IN STD_LOGIC;
350                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
351                          VARIABLE co : OUT STD_LOGIC ) IS
352
353         CONSTANT NBITS_LO_c : POSITIVE := 17;
354         CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
355         VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
356         VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
357         VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
358     BEGIN
359         tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
360                                        UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
361         tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
362                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
363         tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
364                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
365         IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
366             s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
367             co := tmp_hi0_v(NBITS_HI_c +1);
368         ELSE
369             s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
370             co := tmp_hi1_v(NBITS_HI_c +1);
371         END IF;
372     END PROCEDURE;
373
374     PROCEDURE ep_add32nc (        a, b :  IN STD_LOGIC_VECTOR (31 DOWNTO 0);
375                                 ci   :  IN STD_LOGIC;
376                          VARIABLE s  : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) ) IS
377
378         CONSTANT NBITS_LO_c : POSITIVE := 17;
379         CONSTANT NBITS_HI_c : POSITIVE := 32 -NBITS_LO_c;
380         VARIABLE tmp_lo_v   : STD_LOGIC_VECTOR (NBITS_LO_c +1 DOWNTO 0);
381         VARIABLE tmp_hi0_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
382         VARIABLE tmp_hi1_v  : STD_LOGIC_VECTOR (NBITS_HI_c +1 DOWNTO 0);
383     BEGIN
384         tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(NBITS_LO_c -1 DOWNTO  0) & '1' ) +
385                                        UNSIGNED( '0' & b(NBITS_LO_c -1 DOWNTO  0) & ci  ));
386         tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
387                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '0'));
388         tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(31 DOWNTO (32 - NBITS_HI_c)) & '1') +
389                                        UNSIGNED( '0' & b(31 DOWNTO (32 - NBITS_HI_c)) & '1'));
390         IF (tmp_lo_v(NBITS_LO_c +1) = '0') THEN
391             s  := tmp_hi0_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
392         ELSE
393             s  := tmp_hi1_v(NBITS_HI_c DOWNTO 1) & tmp_lo_v(NBITS_LO_c DOWNTO 1);
394         END IF;
395     END PROCEDURE;
396
397 --  PROCEDURE ep_add32 ( a, b : IN STD_LOGIC_VECTOR; ci : IN STD_LOGIC;
398 --                       VARIABLE s  : OUT STD_LOGIC_VECTOR;
399 --                       VARIABLE co : OUT STD_LOGIC ) IS
400 --        VARIABLE tmp_lo_v  : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
401 --        VARIABLE tmp_hi0_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
402 --        VARIABLE tmp_hi1_v : STD_LOGIC_VECTOR (a'LENGTH/2 +1 DOWNTO 0);
403 --    BEGIN
404 --      tmp_lo_v  := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH/2 -1 DOWNTO  0) & '1' ) +
405 --                                     UNSIGNED( '0' & b(a'LENGTH/2 -1 DOWNTO  0) & ci  ));
406 --      tmp_hi0_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
407 --                                     UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '0'));
408 --      tmp_hi1_v := STD_LOGIC_VECTOR( UNSIGNED( '0' & a(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1') +
409 --                                     UNSIGNED( '0' & b(a'LENGTH -1 DOWNTO a'LENGTH/2) & '1'));
410 --      IF (tmp_lo_v(a'LENGTH/2 +1) = '0') THEN
411 --          s  := tmp_hi0_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
412 --          co := tmp_hi0_v(a'LENGTH/2 +1);
413 --      ELSE
414 --          s  := tmp_hi1_v(a'LENGTH/2 DOWNTO 1) & tmp_lo_v(a'LENGTH/2 DOWNTO 1);
415 --          co := tmp_hi1_v(a'LENGTH/2 +1);
416 --      END IF;
417 --  END PROCEDURE;
418
419 --  Function ef_nbits returns the minimum number of binary bits to represent
420 --  a value N with:
421 --  so N =  0,1       NBITS = 1
422 --     N =  2,3       NBITS = 2
423 --     N =  4,5,6,7   NBITS = 3
424 --     N =  8..15     NBITS = 4
425 --     N = 16..31     NBITS = 5
426 --       etc.
427
428     FUNCTION ef_nbits( value : NATURAL ) RETURN POSITIVE IS
429         VARIABLE temp_v : POSITIVE;
430     BEGIN
431         temp_v := 1;
432         FOR i IN 1 TO INTEGER'HIGH LOOP
433             temp_v := 2*temp_v;
434             IF (temp_v > value) THEN
435                 RETURN i;
436             END IF;
437         END LOOP;
438                                 RETURN 32;
439     END FUNCTION;
440
441 END PACKAGE BODY mbl_Pkg;