]> rtime.felk.cvut.cz Git - fpga/plasma.git/blob - vhdl/mlite_pack.vhd
Local copy of Plasma MIPS project.
[fpga/plasma.git] / vhdl / mlite_pack.vhd
1 ---------------------------------------------------------------------
2 -- TITLE: Plasma Misc. Package
3 -- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4 -- DATE CREATED: 2/15/01
5 -- FILENAME: mlite_pack.vhd
6 -- PROJECT: Plasma CPU core
7 -- COPYRIGHT: Software placed into the public domain by the author.
8 --    Software 'as is' without warranty.  Author liable for nothing.
9 -- DESCRIPTION:
10 --    Data types, constants, and add functions needed for the Plasma CPU.
11 ---------------------------------------------------------------------
12 library ieee;
13 use ieee.std_logic_1164.all;
14
15 package mlite_pack is
16    constant ZERO          : std_logic_vector(31 downto 0) :=
17       "00000000000000000000000000000000";
18    constant ONES          : std_logic_vector(31 downto 0) :=
19       "11111111111111111111111111111111";
20    --make HIGH_Z equal to ZERO if compiler complains
21    constant HIGH_Z        : std_logic_vector(31 downto 0) :=
22       "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
23   
24    subtype alu_function_type is std_logic_vector(3 downto 0);
25    constant ALU_NOTHING   : alu_function_type := "0000";
26    constant ALU_ADD       : alu_function_type := "0001";
27    constant ALU_SUBTRACT  : alu_function_type := "0010";
28    constant ALU_LESS_THAN : alu_function_type := "0011";
29    constant ALU_LESS_THAN_SIGNED : alu_function_type := "0100";
30    constant ALU_OR        : alu_function_type := "0101";
31    constant ALU_AND       : alu_function_type := "0110";
32    constant ALU_XOR       : alu_function_type := "0111";
33    constant ALU_NOR       : alu_function_type := "1000";
34
35    subtype shift_function_type is std_logic_vector(1 downto 0);
36    constant SHIFT_NOTHING        : shift_function_type := "00";
37    constant SHIFT_LEFT_UNSIGNED  : shift_function_type := "01";
38    constant SHIFT_RIGHT_SIGNED   : shift_function_type := "11";
39    constant SHIFT_RIGHT_UNSIGNED : shift_function_type := "10";
40
41    subtype mult_function_type is std_logic_vector(3 downto 0);
42    constant MULT_NOTHING       : mult_function_type := "0000";
43    constant MULT_READ_LO       : mult_function_type := "0001";
44    constant MULT_READ_HI       : mult_function_type := "0010";
45    constant MULT_WRITE_LO      : mult_function_type := "0011";
46    constant MULT_WRITE_HI      : mult_function_type := "0100";
47    constant MULT_MULT          : mult_function_type := "0101";
48    constant MULT_SIGNED_MULT   : mult_function_type := "0110";
49    constant MULT_DIVIDE        : mult_function_type := "0111";
50    constant MULT_SIGNED_DIVIDE : mult_function_type := "1000";
51
52    subtype a_source_type is std_logic_vector(1 downto 0);
53    constant A_FROM_REG_SOURCE : a_source_type := "00";
54    constant A_FROM_IMM10_6    : a_source_type := "01";
55    constant A_FROM_PC         : a_source_type := "10";
56
57    subtype b_source_type is std_logic_vector(1 downto 0);
58    constant B_FROM_REG_TARGET : b_source_type := "00";
59    constant B_FROM_IMM        : b_source_type := "01";
60    constant B_FROM_SIGNED_IMM : b_source_type := "10";
61    constant B_FROM_IMMX4      : b_source_type := "11";
62
63    subtype c_source_type is std_logic_vector(2 downto 0);
64    constant C_FROM_NULL       : c_source_type := "000";
65    constant C_FROM_ALU        : c_source_type := "001";
66    constant C_FROM_SHIFT      : c_source_type := "001"; --same as alu
67    constant C_FROM_MULT       : c_source_type := "001"; --same as alu
68    constant C_FROM_MEMORY     : c_source_type := "010";
69    constant C_FROM_PC         : c_source_type := "011";
70    constant C_FROM_PC_PLUS4   : c_source_type := "100";
71    constant C_FROM_IMM_SHIFT16: c_source_type := "101";
72    constant C_FROM_REG_SOURCEN: c_source_type := "110";
73
74    subtype pc_source_type is std_logic_vector(1 downto 0);
75    constant FROM_INC4       : pc_source_type := "00";
76    constant FROM_OPCODE25_0 : pc_source_type := "01";
77    constant FROM_BRANCH     : pc_source_type := "10";
78    constant FROM_LBRANCH    : pc_source_type := "11";
79
80    subtype branch_function_type is std_logic_vector(2 downto 0);
81    constant BRANCH_LTZ : branch_function_type := "000";
82    constant BRANCH_LEZ : branch_function_type := "001";
83    constant BRANCH_EQ  : branch_function_type := "010";
84    constant BRANCH_NE  : branch_function_type := "011";
85    constant BRANCH_GEZ : branch_function_type := "100";
86    constant BRANCH_GTZ : branch_function_type := "101";
87    constant BRANCH_YES : branch_function_type := "110";
88    constant BRANCH_NO  : branch_function_type := "111";
89
90    -- mode(32=1,16=2,8=3), signed, write
91    subtype mem_source_type is std_logic_vector(3 downto 0);
92    constant MEM_FETCH   : mem_source_type := "0000";
93    constant MEM_READ32  : mem_source_type := "0100";
94    constant MEM_WRITE32 : mem_source_type := "0101";
95    constant MEM_READ16  : mem_source_type := "1000";
96    constant MEM_READ16S : mem_source_type := "1010";
97    constant MEM_WRITE16 : mem_source_type := "1001";
98    constant MEM_READ8   : mem_source_type := "1100";
99    constant MEM_READ8S  : mem_source_type := "1110";
100    constant MEM_WRITE8  : mem_source_type := "1101";
101
102    function bv_adder(a     : in std_logic_vector;
103                      b     : in std_logic_vector;
104                      do_add: in std_logic) return std_logic_vector;
105    function bv_negate(a : in std_logic_vector) return std_logic_vector;
106    function bv_increment(a : in std_logic_vector(31 downto 2)
107                          ) return std_logic_vector;
108    function bv_inc(a : in std_logic_vector
109                   ) return std_logic_vector;
110
111    -- For Altera
112    COMPONENT lpm_ram_dp
113       generic (
114          LPM_WIDTH : natural;    -- MUST be greater than 0
115          LPM_WIDTHAD : natural;    -- MUST be greater than 0
116          LPM_NUMWORDS : natural := 0;
117          LPM_INDATA : string := "REGISTERED";
118          LPM_OUTDATA : string := "REGISTERED";
119          LPM_RDADDRESS_CONTROL : string := "REGISTERED";
120          LPM_WRADDRESS_CONTROL : string := "REGISTERED";
121          LPM_FILE : string := "UNUSED";
122          LPM_TYPE : string := "LPM_RAM_DP";
123          USE_EAB  : string := "OFF";
124          INTENDED_DEVICE_FAMILY  : string := "UNUSED";
125          RDEN_USED  : string := "TRUE";
126          LPM_HINT : string := "UNUSED");
127       port (
128          RDCLOCK   : in std_logic := '0';
129          RDCLKEN   : in std_logic := '1';
130          RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
131          RDEN      : in std_logic := '1';
132          DATA      : in std_logic_vector(LPM_WIDTH-1 downto 0);
133          WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
134          WREN      : in std_logic;
135          WRCLOCK   : in std_logic := '0';
136          WRCLKEN   : in std_logic := '1';
137          Q         : out std_logic_vector(LPM_WIDTH-1 downto 0));
138    END COMPONENT;
139
140    -- For Altera
141    component LPM_RAM_DQ
142       generic (
143          LPM_WIDTH    : natural;    -- MUST be greater than 0
144          LPM_WIDTHAD  : natural;    -- MUST be greater than 0
145          LPM_NUMWORDS : natural := 0;
146          LPM_INDATA   : string := "REGISTERED";
147          LPM_ADDRESS_CONTROL: string := "REGISTERED";
148          LPM_OUTDATA  : string := "REGISTERED";
149          LPM_FILE     : string := "UNUSED";
150          LPM_TYPE     : string := "LPM_RAM_DQ";
151          USE_EAB      : string := "OFF";
152          INTENDED_DEVICE_FAMILY  : string := "UNUSED";
153          LPM_HINT     : string := "UNUSED");
154                 port (
155          DATA     : in std_logic_vector(LPM_WIDTH-1 downto 0);
156          ADDRESS  : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
157          INCLOCK  : in std_logic := '0';
158          OUTCLOCK : in std_logic := '0';
159          WE       : in std_logic;
160          Q        : out std_logic_vector(LPM_WIDTH-1 downto 0));
161    end component;
162
163    -- For Xilinx
164    component RAM16X1D 
165       -- synthesis translate_off 
166       generic (INIT : bit_vector := X"16"); 
167       -- synthesis translate_on 
168       port (DPO   : out STD_ULOGIC; 
169             SPO   : out STD_ULOGIC; 
170             A0    : in STD_ULOGIC; 
171             A1    : in STD_ULOGIC; 
172             A2    : in STD_ULOGIC; 
173             A3    : in STD_ULOGIC; 
174             D     : in STD_ULOGIC; 
175             DPRA0 : in STD_ULOGIC; 
176             DPRA1 : in STD_ULOGIC; 
177             DPRA2 : in STD_ULOGIC; 
178             DPRA3 : in STD_ULOGIC; 
179             WCLK  : in STD_ULOGIC; 
180             WE    : in STD_ULOGIC); 
181    end component;\r
182         \r
183    -- For Xilinx Virtex-5
184    component RAM32X1D 
185       -- synthesis translate_off 
186       generic (INIT : bit_vector := X"32"); 
187       -- synthesis translate_on 
188       port (DPO   : out STD_ULOGIC; 
189             SPO   : out STD_ULOGIC; 
190             A0    : in STD_ULOGIC; 
191             A1    : in STD_ULOGIC; 
192             A2    : in STD_ULOGIC; 
193             A3    : in STD_ULOGIC; 
194             A4    : in STD_ULOGIC; 
195             D     : in STD_ULOGIC; 
196             DPRA0 : in STD_ULOGIC; 
197             DPRA1 : in STD_ULOGIC; 
198             DPRA2 : in STD_ULOGIC; 
199             DPRA3 : in STD_ULOGIC; 
200             DPRA4 : in STD_ULOGIC; 
201             WCLK  : in STD_ULOGIC; 
202             WE    : in STD_ULOGIC); 
203    end component; 
204         
205    component pc_next
206       port(clk         : in std_logic;
207            reset_in    : in std_logic;
208            pc_new      : in std_logic_vector(31 downto 2);
209            take_branch : in std_logic;
210            pause_in    : in std_logic;
211            opcode25_0  : in std_logic_vector(25 downto 0);
212            pc_source   : in pc_source_type;
213            pc_future   : out std_logic_vector(31 downto 2);
214            pc_current  : out std_logic_vector(31 downto 2);
215            pc_plus4    : out std_logic_vector(31 downto 2));
216    end component;
217
218    component mem_ctrl
219       port(clk          : in std_logic;
220            reset_in     : in std_logic;
221            pause_in     : in std_logic;
222            nullify_op   : in std_logic;
223            address_pc   : in std_logic_vector(31 downto 2);
224            opcode_out   : out std_logic_vector(31 downto 0);
225
226            address_in   : in std_logic_vector(31 downto 0);
227            mem_source   : in mem_source_type;
228            data_write   : in std_logic_vector(31 downto 0);
229            data_read    : out std_logic_vector(31 downto 0);
230            pause_out    : out std_logic;
231
232            address_next : out std_logic_vector(31 downto 2);
233            byte_we_next : out std_logic_vector(3 downto 0);
234
235            address      : out std_logic_vector(31 downto 2);
236            byte_we      : out std_logic_vector(3 downto 0);
237            data_w       : out std_logic_vector(31 downto 0);
238            data_r       : in std_logic_vector(31 downto 0));
239    end component;
240
241    component control 
242       port(opcode       : in  std_logic_vector(31 downto 0);
243            intr_signal  : in  std_logic;
244            rs_index     : out std_logic_vector(5 downto 0);
245            rt_index     : out std_logic_vector(5 downto 0);
246            rd_index     : out std_logic_vector(5 downto 0);
247            imm_out      : out std_logic_vector(15 downto 0);
248            alu_func     : out alu_function_type;
249            shift_func   : out shift_function_type;
250            mult_func    : out mult_function_type;
251            branch_func  : out branch_function_type;
252            a_source_out : out a_source_type;
253            b_source_out : out b_source_type;
254            c_source_out : out c_source_type;
255            pc_source_out: out pc_source_type;
256            mem_source_out:out mem_source_type;
257            exception_out: out std_logic);
258    end component;
259
260    component reg_bank
261       generic(memory_type : string := "XILINX_16X");
262       port(clk            : in  std_logic;
263            reset_in       : in  std_logic;
264            pause          : in  std_logic;
265            rs_index       : in  std_logic_vector(5 downto 0);
266            rt_index       : in  std_logic_vector(5 downto 0);
267            rd_index       : in  std_logic_vector(5 downto 0);
268            reg_source_out : out std_logic_vector(31 downto 0);
269            reg_target_out : out std_logic_vector(31 downto 0);
270            reg_dest_new   : in  std_logic_vector(31 downto 0);
271            intr_enable    : out std_logic);
272    end component;
273
274    component bus_mux 
275       port(imm_in       : in  std_logic_vector(15 downto 0);
276            reg_source   : in  std_logic_vector(31 downto 0);
277            a_mux        : in  a_source_type;
278            a_out        : out std_logic_vector(31 downto 0);
279
280            reg_target   : in  std_logic_vector(31 downto 0);
281            b_mux        : in  b_source_type;
282            b_out        : out std_logic_vector(31 downto 0);
283
284            c_bus        : in  std_logic_vector(31 downto 0);
285            c_memory     : in  std_logic_vector(31 downto 0);
286            c_pc         : in  std_logic_vector(31 downto 2);
287            c_pc_plus4   : in  std_logic_vector(31 downto 2);
288            c_mux        : in  c_source_type;
289            reg_dest_out : out std_logic_vector(31 downto 0);
290
291            branch_func  : in  branch_function_type;
292            take_branch  : out std_logic);
293    end component;
294
295    component alu
296       generic(alu_type  : string := "DEFAULT");
297       port(a_in         : in  std_logic_vector(31 downto 0);
298            b_in         : in  std_logic_vector(31 downto 0);
299            alu_function : in  alu_function_type;
300            c_alu        : out std_logic_vector(31 downto 0));
301    end component;
302
303    component shifter
304       generic(shifter_type : string := "DEFAULT" );
305       port(value        : in  std_logic_vector(31 downto 0);
306            shift_amount : in  std_logic_vector(4 downto 0);
307            shift_func   : in  shift_function_type;
308            c_shift      : out std_logic_vector(31 downto 0));
309    end component;
310
311    component mult
312       generic(mult_type  : string := "DEFAULT"); 
313       port(clk       : in  std_logic;
314            reset_in  : in  std_logic;
315            a, b      : in  std_logic_vector(31 downto 0);
316            mult_func : in  mult_function_type;
317            c_mult    : out std_logic_vector(31 downto 0);
318            pause_out : out std_logic); 
319    end component;
320
321    component pipeline
322       port(clk            : in  std_logic;
323            reset          : in  std_logic;
324            a_bus          : in  std_logic_vector(31 downto 0);
325            a_busD         : out std_logic_vector(31 downto 0);
326            b_bus          : in  std_logic_vector(31 downto 0);
327            b_busD         : out std_logic_vector(31 downto 0);
328            alu_func       : in  alu_function_type;
329            alu_funcD      : out alu_function_type;
330            shift_func     : in  shift_function_type;
331            shift_funcD    : out shift_function_type;
332            mult_func      : in  mult_function_type;
333            mult_funcD     : out mult_function_type;
334            reg_dest       : in  std_logic_vector(31 downto 0);
335            reg_destD      : out std_logic_vector(31 downto 0);
336            rd_index       : in  std_logic_vector(5 downto 0);
337            rd_indexD      : out std_logic_vector(5 downto 0);
338
339            rs_index       : in  std_logic_vector(5 downto 0);
340            rt_index       : in  std_logic_vector(5 downto 0);
341            pc_source      : in  pc_source_type;
342            mem_source     : in  mem_source_type;
343            a_source       : in  a_source_type;
344            b_source       : in  b_source_type;
345            c_source       : in  c_source_type;
346            c_bus          : in  std_logic_vector(31 downto 0);
347            pause_any      : in  std_logic;
348            pause_pipeline : out std_logic);
349    end component;
350
351    component mlite_cpu
352       generic(memory_type     : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_
353               mult_type       : string := "DEFAULT";
354               shifter_type    : string := "DEFAULT";
355               alu_type        : string := "DEFAULT";
356               pipeline_stages : natural := 2); --2 or 3
357       port(clk         : in std_logic;
358            reset_in    : in std_logic;
359            intr_in     : in std_logic;
360
361            address_next : out std_logic_vector(31 downto 2); --for synch ram
362            byte_we_next : out std_logic_vector(3 downto 0); 
363
364            address      : out std_logic_vector(31 downto 2);
365            byte_we      : out std_logic_vector(3 downto 0);
366            data_w       : out std_logic_vector(31 downto 0);
367            data_r       : in std_logic_vector(31 downto 0);
368            mem_pause    : in std_logic);
369    end component;
370
371    component cache
372       generic(memory_type : string := "DEFAULT");
373       port(clk            : in std_logic;
374            reset          : in std_logic;
375            address_next   : in std_logic_vector(31 downto 2);
376            byte_we_next   : in std_logic_vector(3 downto 0);
377            cpu_address    : in std_logic_vector(31 downto 2);
378            mem_busy       : in std_logic;
379
380            cache_access   : out std_logic;   --access 4KB cache
381            cache_checking : out std_logic;   --checking if cache hit
382            cache_miss     : out std_logic);  --cache miss
383    end component; --cache
384
385    component ram
386       generic(memory_type : string := "DEFAULT");
387       port(clk               : in std_logic;
388            enable            : in std_logic;
389            write_byte_enable : in std_logic_vector(3 downto 0);
390            address           : in std_logic_vector(31 downto 2);
391            data_write        : in std_logic_vector(31 downto 0);
392            data_read         : out std_logic_vector(31 downto 0));
393    end component; --ram
394    
395    component uart
396       generic(log_file : string := "UNUSED");
397       port(clk          : in std_logic;
398            reset        : in std_logic;
399            enable_read  : in std_logic;
400            enable_write : in std_logic;
401            data_in      : in std_logic_vector(7 downto 0);
402            data_out     : out std_logic_vector(7 downto 0);
403            uart_read    : in std_logic;
404            uart_write   : out std_logic;
405            busy_write   : out std_logic;
406            data_avail   : out std_logic);
407    end component; --uart
408
409    component eth_dma 
410       port(clk         : in std_logic;                      --25 MHz
411            reset       : in std_logic;
412            enable_eth  : in std_logic;
413            select_eth  : in std_logic;
414            rec_isr     : out std_logic;
415            send_isr    : out std_logic;
416
417            address     : out std_logic_vector(31 downto 2); --to DDR
418            byte_we     : out std_logic_vector(3 downto 0);
419            data_write  : out std_logic_vector(31 downto 0);
420            data_read   : in std_logic_vector(31 downto 0);
421            pause_in    : in std_logic;
422
423            mem_address : in std_logic_vector(31 downto 2);  --from CPU
424            mem_byte_we : in std_logic_vector(3 downto 0);
425            data_w      : in std_logic_vector(31 downto 0);
426            pause_out   : out std_logic;
427
428            E_RX_CLK    : in std_logic;                      --2.5 MHz receive
429            E_RX_DV     : in std_logic;                      --data valid
430            E_RXD       : in std_logic_vector(3 downto 0);   --receive nibble
431            E_TX_CLK    : in std_logic;                      --2.5 MHz transmit
432            E_TX_EN     : out std_logic;                     --transmit enable
433            E_TXD       : out std_logic_vector(3 downto 0)); --transmit nibble
434    end component; --eth_dma
435
436    component plasma
437       generic(memory_type : string := "XILINX_X16"; --"DUAL_PORT_" "ALTERA_LPM";
438               log_file    : string := "UNUSED";
439               ethernet    : std_logic := '0';
440               use_cache   : std_logic := '0');
441       port(clk          : in std_logic;
442            reset        : in std_logic;
443            uart_write   : out std_logic;
444            uart_read    : in std_logic;
445    
446            address      : out std_logic_vector(31 downto 2);
447            byte_we      : out std_logic_vector(3 downto 0); 
448            data_write   : out std_logic_vector(31 downto 0);
449            data_read    : in std_logic_vector(31 downto 0);
450            mem_pause_in : in std_logic;
451            no_ddr_start : out std_logic;
452            no_ddr_stop  : out std_logic;
453         
454            gpio0_out    : out std_logic_vector(31 downto 0);
455            gpioA_in     : in std_logic_vector(31 downto 0));
456    end component; --plasma
457
458    component ddr_ctrl
459       port(clk      : in std_logic;
460            clk_2x   : in std_logic;
461            reset_in : in std_logic;
462
463            address  : in std_logic_vector(25 downto 2);
464            byte_we  : in std_logic_vector(3 downto 0);
465            data_w   : in std_logic_vector(31 downto 0);
466            data_r   : out std_logic_vector(31 downto 0);
467            active   : in std_logic;
468            no_start : in std_logic;
469            no_stop  : in std_logic;
470            pause    : out std_logic;
471
472            SD_CK_P  : out std_logic;     --clock_positive
473            SD_CK_N  : out std_logic;     --clock_negative
474            SD_CKE   : out std_logic;     --clock_enable
475
476            SD_BA    : out std_logic_vector(1 downto 0);  --bank_address
477            SD_A     : out std_logic_vector(12 downto 0); --address(row or col)
478            SD_CS    : out std_logic;     --chip_select
479            SD_RAS   : out std_logic;     --row_address_strobe
480            SD_CAS   : out std_logic;     --column_address_strobe
481            SD_WE    : out std_logic;     --write_enable
482
483            SD_DQ    : inout std_logic_vector(15 downto 0); --data
484            SD_UDM   : out std_logic;     --upper_byte_enable
485            SD_UDQS  : inout std_logic;   --upper_data_strobe
486            SD_LDM   : out std_logic;     --low_byte_enable
487            SD_LDQS  : inout std_logic);  --low_data_strobe
488    end component; --ddr
489    
490 end; --package mlite_pack
491
492
493 package body mlite_pack is
494
495 function bv_adder(a     : in std_logic_vector;
496                   b     : in std_logic_vector;
497                   do_add: in std_logic) return std_logic_vector is
498    variable carry_in : std_logic;
499    variable bb       : std_logic_vector(a'length-1 downto 0);
500    variable result   : std_logic_vector(a'length downto 0);
501 begin
502    if do_add = '1' then
503       bb := b;
504       carry_in := '0';
505    else
506       bb := not b;
507       carry_in := '1';
508    end if;
509    for index in 0 to a'length-1 loop
510       result(index) := a(index) xor bb(index) xor carry_in;
511       carry_in := (carry_in and (a(index) or bb(index))) or
512                   (a(index) and bb(index));
513    end loop;
514    result(a'length) := carry_in xnor do_add;
515    return result;
516 end; --function
517
518
519 function bv_negate(a : in std_logic_vector) return std_logic_vector is
520    variable carry_in : std_logic;
521    variable not_a    : std_logic_vector(a'length-1 downto 0);
522    variable result   : std_logic_vector(a'length-1 downto 0);
523 begin
524    not_a := not a;
525    carry_in := '1';
526    for index in a'reverse_range loop
527       result(index) := not_a(index) xor carry_in;
528       carry_in := carry_in and not_a(index);
529    end loop;
530    return result;
531 end; --function
532
533
534 function bv_increment(a : in std_logic_vector(31 downto 2)
535                      ) return std_logic_vector is
536    variable carry_in : std_logic;
537    variable result   : std_logic_vector(31 downto 2);
538 begin
539    carry_in := '1';
540    for index in 2 to 31 loop
541       result(index) := a(index) xor carry_in;
542       carry_in := a(index) and carry_in;
543    end loop;
544    return result;
545 end; --function
546
547
548 function bv_inc(a : in std_logic_vector
549                 ) return std_logic_vector is
550    variable carry_in : std_logic;
551    variable result   : std_logic_vector(a'length-1 downto 0);
552 begin
553    carry_in := '1';
554    for index in 0 to a'length-1 loop
555       result(index) := a(index) xor carry_in;
556       carry_in := a(index) and carry_in;
557    end loop;
558    return result;
559 end; --function
560
561 end; --package body
562
563