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

Subversion Repositories ecpu_alu

[/] [ecpu_alu/] [trunk/] [alu/] [rtl/] [verilog/] [alu_datapath.v] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 leonous
// ported from university project for alu in VHDL
2
module alu_datapath (
3
                      A                             ,
4
                      B                             ,
5
                      Y                             ,
6
 
7
                      add_AB                        ,
8
                      inc_A                         ,
9
                      inc_B                         ,
10
                      sub_AB                        ,
11
                      cmp_AB                        ,
12
                      sl_AB                         ,
13
                      sr_AB                         ,
14
                      clr                           ,
15
                      dec_A                         ,
16
                      dec_B                         ,
17
                      mul_AB                        ,
18
                      cpl_A                         ,
19
                      and_AB                        ,
20
                      or_AB                         ,
21
                      xor_AB                        ,
22
                      cpl_B                         ,
23
 
24
                      clr_Z                         ,
25
                      clr_V                         ,
26
                      clr_C                         ,
27
 
28
                      C                             ,
29
                      V                             ,
30
                      Z                             ,
31
 
32
                      load_inputs                   ,
33
                      load_outputs                  ,
34
 
35
                      reset                         ,
36
                      clk
37
                    );
38
 
39
  // data input/output width for the ALU
40
  parameter                           ALU_WIDTH = 8;
41
 
42
  input   [ALU_WIDTH - 1:0]  A           ;
43
  input   [ALU_WIDTH - 1:0]  B           ;
44
  output  [ALU_WIDTH - 1:0]  Y           ;
45
 
46
  input                      add_AB      ;  // ALU control commands   
47
  input                      inc_A       ;
48
  input                      inc_B       ;
49
  input                      sub_AB      ;
50
  input                      cmp_AB      ;
51
  input                      sl_AB       ;
52
  input                      sr_AB       ;
53
  input                      clr         ;
54
  input                      dec_A       ;
55
  input                      dec_B       ;
56
  input                      mul_AB      ; // Not yet implemented
57
  input                      cpl_A       ;
58
  input                      and_AB      ;
59
  input                      or_AB       ;
60
  input                      xor_AB      ;  // soft reset! via opcode 
61
  input                      cpl_B       ;
62
 
63
  input                      clr_Z       ;
64
  input                      clr_V       ;
65
  input                      clr_C       ;
66
 
67
  output                     C           ;  // carry flag             
68
  output                     V           ;  // overflow flag          
69
  output                     Z           ;  // ALU result = 0         
70
 
71
  input                      load_inputs ;
72
  input                      load_outputs;
73
 
74
  input                      reset       ;  // hard reset!            
75
 
76
  input                      clk         ;  // clk wire              
77
 
78
 
79
  wire  [ALU_WIDTH - 1:0] adder_in_a        ;
80
  wire  [ALU_WIDTH - 1:0] adder_in_b        ;
81
  wire  [ALU_WIDTH - 1:0] adder_out         ;
82
 
83
  wire  [ALU_WIDTH - 1:0] shifter_inA       ;
84
  wire  [ALU_WIDTH - 1:0] shifter_inB       ;
85
  wire  [ALU_WIDTH - 1:0] shifter_out       ;
86
 
87
  wire                    shifter_carry     ;
88
  wire                    shifter_direction ;
89
 
90
  wire                    carry_in          ;
91
  wire                    carry             ;
92
  wire                    adderORsel        ;
93
  wire                    adderXORsel       ;
94
 
95
  wire  [ALU_WIDTH    :0] carry_out         ;
96
 
97
  wire  [ALU_WIDTH - 1:0] AandB             ;
98
  wire  [ALU_WIDTH - 1:0] AxorB             ;
99
  wire  [ALU_WIDTH - 1:0] AorB              ;
100
 
101
  wire  [ALU_WIDTH - 1:0]        logic0            ;
102
  wire  [ALU_WIDTH - 1:0]        logic1            ;
103
 
104
 
105
  reg     [ALU_WIDTH - 1:0] Areg              ;
106
  reg     [ALU_WIDTH - 1:0] Breg              ;
107
  reg     [ALU_WIDTH - 1:0] Yreg              ;
108
  reg                             Zreg              ;
109
  reg                             Creg              ;
110
  reg                             Vreg              ;
111
 
112
  wire  [ALU_WIDTH - 1:0] alu_out           ;
113
 
114
 
115
        assign logic1           = 'd1   ;
116
        assign logic0           = 'd0   ;
117
 
118
        // assign registers to outputs
119
        assign Y = Yreg;
120
        assign Z = Zreg;
121
        assign C = Creg;
122
        assign V = Vreg;
123
 
124
        // inputs to adder
125
        assign adder_in_a       =       (cpl_B) ? 'd0 : ((cpl_A) ? ~Areg : ((inc_B) ? 1'b0 :((dec_B) ? {ALU_WIDTH{1'b1}} :Areg)) );
126
 
127
  assign  adder_in_b = (!sub_AB && !inc_A && !cpl_A && !cpl_B) ? ((dec_A) ? {ALU_WIDTH{1'b1}} : Breg) :
128
                          (((sub_AB && !inc_A) || cpl_B) ? ~Breg :
129
                            ((!sub_AB && inc_A && !cpl_B) ?'d0     :
130
                              ((cpl_A) ? 'd0 : adder_in_b)));
131
 
132
        // carry_in to adder is set to 1 during subtract and increment
133
        // operations
134
        assign  carry_in  = (sub_AB || inc_A || inc_B) ? 1'b1 : 1'b0;
135
 
136
        // select appropriate alu_output to go to Z depending
137
        // on control wires
138
 
139
  assign alu_out = ((and_AB || or_AB) && (!sl_AB && !sr_AB))  ? carry_out[ALU_WIDTH:1]
140
                                        : ((sl_AB || sr_AB) ? shifter_out
141
                                                            : adder_out);
142
 
143
        // selects use of the Adder as an OR gate
144
        assign adderORsel       = (or_AB) ? 'b1 : 'b0;
145
 
146
        // selects use of the Adder as an XOR gate
147
        // or as a compare [which uses the XOR function]
148
        assign adderXORsel      =       (xor_AB || cmp_AB) ? 'b0 : 'b1;
149
 
150
        // set/unset carry flag depending on relevant conditions
151
  assign carry = (add_AB && !and_AB && !or_AB && !xor_AB && !cpl_B && !clr) ?
152
                    carry_out[ALU_WIDTH] :
153
                      ((and_AB || or_AB || xor_AB || cpl_B || clr) ?
154
                        'b0 : ((sl_AB ||  sr_AB)  ? shifter_carry :carry));
155
 
156
 
157
        // barrel shifter wires
158
        assign shifter_direction        =       (sr_AB) ? 'b1   :       'b0;
159
 
160
        assign shifter_inA = Areg;
161
        assign shifter_inB = Breg;
162
 
163
        alu_adder #(ALU_WIDTH) adder            (
164
                                                                          .x                    (adder_in_a ) ,
165
                                                                          .y                        (adder_in_b )       ,
166
                                                                          .carry_in       (carry_in   ) ,
167
                                                                          .ORsel                  (adderORsel ) ,
168
                                                                          .XORsel                 (adderXORsel) ,
169
                                                                          .carry_out    (carry_out  )   ,
170
                                                                          .z                        (adder_out  )
171
                                                                  );
172
 
173
        alu_barrel_shifter #(ALU_WIDTH) shifter (
174
                                                                          .x                        (shifter_inA      ) ,
175
                                                                          .y                        (shifter_inB      ) ,
176
                                                                          .z                        (shifter_out      ) ,
177
                                                                          .c                        (shifter_carry    ) ,
178
                                                                          .clk              (clk              ) ,
179
                                                                          .direction    (shifter_direction)
180
                                                                        );
181
 
182
        //registered_ios
183
  always @(posedge clk or posedge reset)
184
                                                begin
185
                                                        if (reset)
186
              begin
187
                                                                Areg    <=      'd0;
188
                                                                Breg    <=      'd0;
189
                                                                Yreg    <=      'd0;
190
 
191
                                                                Zreg    <=      'b1;
192
                                                                Creg    <=      'b0;
193
                                                                Vreg    <=      'b0;
194
              end
195
                                                        else
196
              begin
197
                                                                if (load_inputs)
198
                begin
199
                                                                        Areg    <=      A;
200
                                                                        Breg    <=      B;
201
                end
202
                                                                if (load_outputs)
203
                                                                        Yreg    <= alu_out;
204
 
205
                                                                //// clear command clears all registers
206
                                                                //// and the carry bit
207
                                                                if (clr)
208
                begin
209
                                                                        Areg    <=      'd0;
210
                                                                        Breg    <=      'd0;
211
                                                                        Yreg    <=      'd0;
212
 
213
                                                                        Creg    <=      'b0;
214
                end
215
 
216
 
217
                                                                if (clr_Z)
218
                                                                        Zreg    <= 'b0;
219
                                                                if (clr_C)
220
                                                                        Creg    <= 'b0;
221
                                                                if (clr_V)
222
                                                                        Vreg    <= 'b0;
223
 
224
                                                                // set the Z register 
225
                                                                if              (alu_out == 'd0)
226
                                                                        Zreg    <= 'b1;
227
                                                                else
228
                                                                        Zreg    <= 'b0;
229
 
230
 
231
                                                                Creg    <= carry;
232
                                                        end
233
                                                end // end always registered IOs;
234
 
235
 
236
endmodule
237
 
238
 

powered by: WebSVN 2.1.0

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