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

Subversion Repositories rtf8088

[/] [rtf8088/] [trunk/] [rtl/] [verilog/] [ALU.v] - Blame information for rev 4

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

Line No. Rev Author Line
1 2 robfinch
// ============================================================================
2
//  ALU
3
//  - perform datapath operations
4
//
5
//
6
//  (C) 2009-2012  Robert Finch
7
//  robfinch[remove]@opencores.org
8
//
9
//
10
// This source file is free software: you can redistribute it and/or modify 
11
// it under the terms of the GNU Lesser General Public License as published 
12
// by the Free Software Foundation, either version 3 of the License, or     
13
// (at your option) any later version.                                      
14
//                                                                          
15
// This source file is distributed in the hope that it will be useful,      
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
18
// GNU General Public License for more details.                             
19
//                                                                          
20
// You should have received a copy of the GNU General Public License        
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
22
//
23
//
24
//  Verilog 
25
//
26
// ============================================================================
27
//
28
function carry;
29
        input op;
30
        input a;
31
        input b;
32
        input s;
33
 
34
        begin
35
                carry = op ? (~a&b)|(s&~a)|(s&b) : (a&b)|(a&~s)|(b&~s);
36
        end
37
 
38
endfunction
39
 
40
function overflow;
41
        input op;
42
        input a;
43
        input b;
44
        input s;
45
 
46
        begin
47
                overflow = (op ^ s ^ b) & (~op ^ a ^ b);
48
        end
49
 
50
endfunction
51
 
52
reg [15:0] alu_o;
53
reg [15:0] a;
54
reg [15:0] b;
55
wire amsb = w ? a[15] : a[7];
56
wire bmsb = w ? b[15] : b[7];
57
wire [15:0] as = {!a[15],a[14:0]};
58
wire [15:0] bs = {!b[15],b[14:0]};
59
wire signed [15:0] sa = a;
60
wire signed [15:0] sb = b;
61
wire signed [7:0] als = a[7:0];
62
wire signed [7:0] bls = b[7:0];
63
wire signed [15:0] p = als * bls;
64
wire signed [31:0] wp = sa * sb;
65
 
66
// Compute AL/10
67
// - multiply by 1/10 = 26/256
68
wire [15:0] al26 = {al,4'b0} + {al,3'b0} + {al,1'b0};    // * 26
69
wire [7:0] aldv10 = al26[15:8];  // 256
70
 
71
wire [15:0] cmp_o = a - b;
72
wire eq  = a == b;
73
wire ltu = a < b;
74
wire lt  = as < bs;
75
 
76 4 robfinch
wire [31:0] shlo = {16'h0000,b} << shftamt;
77
wire [31:0] shruo = {b,16'h0000} >> shftamt;
78
wire [15:0] shro = ~(~b >> shftamt);
79
wire [32:0] shlco = {16'h0000,b,cf} << shftamt;
80
wire [32:0] shrcuo = {cf,b,16'h0000} >> shftamt;
81
 
82
wire [15:0] shlo8 = {8'h00,b[7:0]} << shftamt;
83
wire [15:0] shruo8 = {b[7:0],8'h00} >> shftamt;
84
wire [ 7:0] shro8 = ~(~b[7:0] >> shftamt);
85
wire [16:0] shlco8 = {8'h00,b,cf} << shftamt;
86
wire [16:0] shrcuo8 = {cf,b[7:0],8'h00} >> shftamt;
87
 
88
 
89 2 robfinch
always @(ir or ir2 or a or b or cf or af or al or ah or aldv10 or TTT)
90
        begin
91
                casex(ir)
92
                `MOV_M2AL,`MOV_M2AX,`LDS,`LES:
93
                        alu_o <= a;
94
                `MOV_MR,`MOV_R2S,
95
                `MOV_RR8,`MOV_RR16,
96
                `MOV_I8M,`MOV_I16M,
97
                `MOV_I2AL,`MOV_I2DL,`MOV_I2CL,`MOV_I2BL,`MOV_I2AH,`MOV_I2DH,`MOV_I2CH,`MOV_I2BH,
98
                `MOV_I2AX,`MOV_I2DX,`MOV_I2CX,`MOV_I2BX,`MOV_I2SP,`MOV_I2BP,`MOV_I2SI,`MOV_I2DI:
99
                        alu_o <= b;
100
                `XCHG_MEM:
101
                        alu_o <= b;
102
                `ADD,`ADD_ALI8,`ADD_AXI16: alu_o <= a + b;
103
                `SUB,`SUB_ALI8,`SUB_AXI16: alu_o <= a - b;
104
                `ADC,`ADC_ALI8,`ADC_AXI16: alu_o <= a + b + cf;
105
                `SBB,`SBB_ALI8,`SBB_AXI16: alu_o <= a - b - cf;
106
                `AND,`AND_ALI8,`AND_AXI16: alu_o <= a & b;
107
                `OR, `OR_ALI8, `OR_AXI16:  alu_o <= a | b;
108
                `XOR,`XOR_ALI8,`XOR_AXI16: alu_o <= a ^ b;
109
                `CMP,`CMP_ALI8,`CMP_AXI16: alu_o <= a - b;
110
                `SCASB,`SCASW,`CMPSB,`CMPSW: alu_o <= a - b;
111
                `INC_REG: alu_o <= a + 16'd1;
112
                `DEC_REG: alu_o <= a - 16'd1;
113
                `IMUL: alu_o <= w ? p : wp[15:0];
114
                `ALU_I2R8:
115
                        case(TTT)
116
                        3'd0:   alu_o <= a + b;                 // ADD
117
                        3'd1:   alu_o <= a | b;                 // OR
118
                        3'd2:   alu_o <= a + b + cf;    // ADC
119
                        3'd3:   alu_o <= a - b - cf;    // SBB
120
                        3'd4:   alu_o <= a & b;                 // AND
121
                        3'd5:   alu_o <= a - b;                 // SUB
122
                        3'd6:   alu_o <= a ^ b;                 // XOR
123
                        default:        alu_o <= 16'h0000;
124
                        endcase
125
                // ToDo: fix sign extension / extra immediate byte ?
126
                `ALU_I2R16:
127
                        case(TTT)
128
                        3'd0:   alu_o <= a + b;                 // ADD
129
                        3'd1:   alu_o <= a | b;                 // OR
130
                        3'd2:   alu_o <= a + b + cf;    // ADC
131
                        3'd3:   alu_o <= a - b - cf;    // SBB
132
                        3'd4:   alu_o <= a & b;                 // AND
133
                        3'd5:   alu_o <= a - b;                 // SUB
134
                        3'd6:   alu_o <= a ^ b;                 // XOR
135
                        default:        alu_o <= 16'h0000;
136
                        endcase
137
                `AAA:
138
                        if (al[3:0]>4'h9 || af) begin
139
                                alu_o[3:0] <= al[3:0] + 4'd6;
140
                                alu_o[7:4] <= 4'h0;
141
                                alu_o[15:8] <= ah + 8'd1;
142
                        end
143
                        else
144
                                alu_o <= ax;
145
                `AAS:
146
                        if (al[3:0]>4'h9 || af) begin
147
                                alu_o[3:0] <= al[3:0] - 4'd6;
148
                                alu_o[7:4] <= 4'h0;
149
                                alu_o[15:8] <= ah - 8'd1;
150
                        end
151
                        else
152
                                alu_o <= ax;
153
// ToDo: fix +1 carry
154
                `DAA:
155
                        begin
156
                                alu_o <= 16'h0000;
157
                                if (al[3:0]>4'h9 || af) begin
158
                                        alu_o[3:0] <= al[3:0] + 4'd6;
159
                                end
160
                                if (al[7:4]>4'h9 || cf) begin
161
                                        alu_o[7:4] <= al[7:4] + 4'd6;
162
                                end
163
                        end
164
// ToDo: fix +1 carry
165
                `DAS:
166
                        begin
167
                                alu_o <= 16'h0000;
168
                                if (al[3:0]>4'h9 || af) begin
169
                                        alu_o[3:0] <= al[3:0] - 4'd6;
170
                                end
171
                                if (al[7:4]>4'h9 || cf) begin
172
                                        alu_o[7:4] <= al[7:4] - 4'd6;
173
                                end
174
                        end
175
 
176
                `MORE1:
177
                        casex(ir2)
178
                        `AAM:
179
                                begin
180
                                        alu_o[ 7:0] <= al - aldv10;
181
                                        alu_o[15:8] <= aldv10;
182
                                end
183
                        default:
184
                                alu_o <= 16'h0000;
185
                        endcase
186
                `MORE2:
187
                        casex(ir2)
188
                        `AAD:
189
                                begin
190
                                        alu_o[ 7:0] <= {ah,3'b0} + {ah,1'b0} + al;
191
                                        alu_o[15:8] <= 8'h00;
192
                                end
193
                        default:
194
                                alu_o <= 16'h0000;
195
                        endcase
196
                default: alu_o <= 16'h0000;
197
                endcase
198
        end
199
 
200
assign pres = ~^alu_o[7:0];
201
assign reszw = alu_o==16'h0000;
202
assign reszb = alu_o[7:0]==8'h00;
203
assign resnb = alu_o[7];
204
assign resnw = alu_o[15];
205
 
206
assign resz = w ? reszw : reszb;
207
assign resn = w ? resnw : resnb;
208
 

powered by: WebSVN 2.1.0

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