OpenCores
URL https://opencores.org/ocsvn/hive/hive/trunk

Subversion Repositories hive

[/] [hive/] [trunk/] [v01.10/] [alu_add_sub.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module : alu_add_sub.v
5
 
6
--------------------------------------------------------------------------------
7
 
8
Function:
9
- Add & subtract unit for a processor ALU.
10
 
11
Instantiates:
12
- (4x) vector_sr.v
13
 
14
Notes:
15
- IN/MID/OUT/FLG optionally registered.
16
 
17
--------------------------------------------------------------------------------
18
*/
19
 
20
module alu_add_sub
21
        #(
22
        parameter       integer                                                 REGS_IN                 = 1,            // in register option
23
        parameter       integer                                                 REGS_MID                        = 1,            // mid register option
24
        parameter       integer                                                 REGS_OUT                        = 1,            // out register option
25
        parameter       integer                                                 REGS_FLG                        = 1,            // flag register option
26
        parameter       integer                                                 DATA_W                  = 3             // data width
27
        )
28
        (
29
        // clocks & resets
30
        input                   wire                                                            clk_i,                                          // clock
31
        input                   wire                                                            rst_i,                                          // async. reset, active high
32
        // control I/O
33
        input                   wire                                                            sgn_i,                                          // 1=signed
34
        input                   wire                                                            ext_i,                                          // 1=extended result
35
        input                   wire                                                            sub_i,                                          // 1=subtract; 0=add
36
        // data I/O
37
        input                   wire    [DATA_W-1:0]                     a_i,                                                    // operand
38
        input                   wire    [DATA_W-1:0]                     b_i,                                                    // operand
39
        output          wire    [DATA_W-1:0]                     result_o,                                       // = ( a +/- b )
40
        // flags
41
        output          wire                                                            ltz_o,                                          //      a < 0
42
        output          wire                                                            lt_o                                                    //      a < b
43
        );
44
 
45
 
46
        /*
47
        ----------------------
48
        -- internal signals --
49
        ----------------------
50
        */
51
        localparam      integer                                                 ZSX_W                           = DATA_W+1;  // +1 extra bit
52
        localparam      integer                                                 ADD_W                           = DATA_W+2;  // +2 extra bits
53
        localparam      integer                                                 DBL_W                           = DATA_W*2;  // double width
54
        //
55
        wire                                                                                            sgn, sub, ext, sub_r, ext_r;
56
        wire    signed          [DATA_W-1:0]                     a, b;
57
        wire    signed          [ZSX_W-1:0]                              a_zsx, b_zsx;
58
        wire    signed          [ADD_W-1:0]                              ab_add, ab_sub, ab_add_r, ab_sub_r;
59
        reg     signed          [DBL_W-1:0]                              res_dbl;
60
        reg     signed          [DATA_W-1:0]                     result;
61
        wire                                                                                            ltz, lt;
62
 
63
 
64
        /*
65
        ================
66
        == code start ==
67
        ================
68
        */
69
 
70
 
71
        // optional input regs
72
        vector_sr
73
        #(
74
        .REGS                   ( REGS_IN ),
75
        .DATA_W         ( DATA_W+DATA_W+3 ),
76
        .RESET_VAL      ( 0 )
77
        )
78
        in_regs
79
        (
80
        .clk_i          ( clk_i ),
81
        .rst_i          ( rst_i ),
82
        .data_i         ( { a_i, b_i, sub_i, ext_i, sgn_i } ),
83
        .data_o         ( { a,   b,   sub,   ext,   sgn } )
84
        );
85
 
86
 
87
        // zero|sign extend results
88
        assign a_zsx = { ( sgn & a[DATA_W-1] ), a };
89
        assign b_zsx = { ( sgn & b[DATA_W-1] ), b };
90
 
91
        // arithmetic results (signed)
92
        assign ab_add = a_zsx + b_zsx;
93
        assign ab_sub = a_zsx - b_zsx;
94
 
95
        // flags
96
        assign ltz = a[DATA_W-1];
97
        assign lt = ab_sub[ZSX_W-1];
98
 
99
 
100
        // optional flag regs
101
        vector_sr
102
        #(
103
        .REGS                   ( REGS_FLG ),
104
        .DATA_W         ( 2 ),
105
        .RESET_VAL      ( 0 )
106
        )
107
        regs_flags
108
        (
109
        .clk_i          ( clk_i ),
110
        .rst_i          ( rst_i ),
111
        .data_i         ( { ltz,   lt } ),
112
        .data_o         ( { ltz_o, lt_o } )
113
        );
114
 
115
 
116
        // optional mid regs
117
        vector_sr
118
        #(
119
        .REGS                   ( REGS_MID ),
120
        .DATA_W         ( ADD_W+ADD_W+2 ),
121
        .RESET_VAL      ( 0 )
122
        )
123
        mid_regs
124
        (
125
        .clk_i          ( clk_i ),
126
        .rst_i          ( rst_i ),
127
        .data_i         ( { ab_sub,   ab_add,   sub,   ext } ),
128
        .data_o         ( { ab_sub_r, ab_add_r, sub_r, ext_r } )
129
        );
130
 
131
 
132
        // multiplex
133
        always @ ( * ) begin
134
                case ( sub_r )
135
                        'b0 : res_dbl <= ab_add_r;
136
                        'b1 : res_dbl <= ab_sub_r;
137
                endcase
138
        end
139
 
140
        // multiplex & extend
141
        always @ ( * ) begin
142
                case ( ext_r )
143
                        'b0 : result <= res_dbl[DATA_W-1:0];
144
                        'b1 : result <= res_dbl[DBL_W-1:DATA_W];
145
                endcase
146
        end
147
 
148
 
149
        // optional output regs
150
        vector_sr
151
        #(
152
        .REGS                   ( REGS_OUT ),
153
        .DATA_W         ( DATA_W ),
154
        .RESET_VAL      ( 0 )
155
        )
156
        out_regs
157
        (
158
        .clk_i          ( clk_i ),
159
        .rst_i          ( rst_i ),
160
        .data_i         ( result ),
161
        .data_o         ( result_o )
162
        );
163
 
164
 
165
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.