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

Subversion Repositories hive

[/] [hive/] [trunk/] [v04.05/] [alu_add_sub.v] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 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) pipe.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                                                            flg_ne_o,                                       //      a != b
42
        output          wire                                                            flg_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_SUB_W               = DATA_W+2;  // +2 extra bits
53
        localparam      integer                                                 DBL_W                           = DATA_W*2;  // double width
54
        //
55
        wire                                                                                            sgn, sub, ext, sub_m, ext_m;
56
        wire    signed          [DATA_W-1:0]                     a, b;
57
        wire    signed          [ZSX_W-1:0]                              a_zsx, b_zsx;
58
        wire    signed          [ADD_SUB_W-1:0]          ab_add, ab_sub, ab_add_m, ab_sub_m;
59
        reg     signed          [DBL_W-1:0]                              res_dbl;
60
        reg     signed          [DATA_W-1:0]                     result;
61
        wire                                                                                            flg_ne, flg_lt;
62
 
63
 
64
        /*
65
        ================
66
        == code start ==
67
        ================
68
        */
69
 
70
 
71
        // optional input regs
72
        pipe
73
        #(
74
        .DEPTH          ( REGS_IN ),
75
        .WIDTH          ( 3+DATA_W+DATA_W ),
76
        .RESET_VAL      ( 0 )
77
        )
78
        in_regs
79
        (
80
        .clk_i          ( clk_i ),
81
        .rst_i          ( rst_i ),
82
        .data_i         ( { sub_i, ext_i, sgn_i, b_i, a_i } ),
83
        .data_o         ( { sub,   ext,   sgn,   b,   a   } )
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 flg_ne = ( a != b );
97
        assign flg_lt = ab_sub[ZSX_W-1];
98
 
99
 
100
        // optional flag regs
101
        pipe
102
        #(
103
        .DEPTH          ( REGS_FLG ),
104
        .WIDTH          ( 2 ),
105
        .RESET_VAL      ( 0 )
106
        )
107
        regs_flags
108
        (
109
        .clk_i          ( clk_i ),
110
        .rst_i          ( rst_i ),
111
        .data_i         ( { flg_ne,   flg_lt   } ),
112
        .data_o         ( { flg_ne_o, flg_lt_o } )
113
        );
114
 
115
 
116
        // optional mid regs
117
        pipe
118
        #(
119
        .DEPTH          ( REGS_MID ),
120
        .WIDTH          ( 2+ADD_SUB_W+ADD_SUB_W ),
121
        .RESET_VAL      ( 0 )
122
        )
123
        mid_regs
124
        (
125
        .clk_i          ( clk_i ),
126
        .rst_i          ( rst_i ),
127
        .data_i         ( { sub,   ext,   ab_sub,   ab_add   } ),
128
        .data_o         ( { sub_m, ext_m, ab_sub_m, ab_add_m } )
129
        );
130
 
131
 
132
        // multiplex
133
        always @ ( * ) begin
134
                case ( sub_m )
135
                        'b1     : res_dbl <= ab_sub_m;
136
                        default : res_dbl <= ab_add_m;
137
                endcase
138
        end
139
 
140
        // multiplex & extend
141
        always @ ( * ) begin
142
                case ( ext_m )
143
                        'b1     : result <= res_dbl[DBL_W-1:DATA_W];
144
                        default : result <= res_dbl[DATA_W-1:0];
145
                endcase
146
        end
147
 
148
 
149
        // optional output regs
150
        pipe
151
        #(
152
        .DEPTH          ( REGS_OUT ),
153
        .WIDTH          ( 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.