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

Subversion Repositories quark

[/] [quark/] [trunk/] [01_SysRequirements/] [03_InternalRequirements/] [02_VerilogAlgorithmDesign/] [alu_8bit.v] - Blame information for rev 18

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

Line No. Rev Author Line
1 3 progman32
`timescale 1ns / 1ps
2
 
3
module ALU_8bit(
4
    clk,
5
         rst,
6
         en,
7
         ready,
8
         opcode,
9
         reg_in_1,
10
         reg_in_2,
11
         reg_out,
12
         reg_bank
13
    );
14
 
15
         input wire clk;
16
         input wire rst;
17
         input wire en;
18
         input wire [7:0] opcode;
19
         input wire [7:0] reg_in_1;
20
         input wire [7:0] reg_in_2;
21
 
22
         output reg ready;
23
         output reg [7:0] reg_out;
24
 
25
         /* ALU flags steps registers
26
                N
27
                Set when the result of the operation was Negative.
28
                Z
29
                Set when the result of the operation was Zero.
30
                C
31
                Set when the operation resulted in a Carry.
32
                V
33
                Set when the operation caused oVerflow.
34
 
35
                A carry occurs if the result of an add, subtract, or compare is greater than or equal to 232, or as the result of an inline barrel shifter operation in a move or logical instruction.
36
                Overflow occurs if the result of an add, subtract, or compare is greater than or equal to 231, or less than -231.
37
         */
38
    `define N 0:0
39
    `define Z 1:1
40
    `define C 2:2
41
    `define V 3:3
42
    output reg [3:0] reg_bank;
43
 
44
    reg [15:0] reg_out_temp;
45
 
46
        /* ROL and ROR steps and registers */
47
        `define R_FIRST_STEP  1'b0
48
        `define R_SECOND_STEP 1'b1
49
    reg rotation_step;
50
 
51
        /* math steps  and registers */
52
        `define M_FIRST_STEP  2'b00
53
        `define M_SECOND_STEP 2'b01
54
        `define M_THIRD_STEP  2'b10
55
        reg [1:0] math_step;
56
    reg [7:0] dividend;
57
    reg [7:0] denom;
58
    reg [7:0] current;
59
    reg [7:0] temp_result;
60
 
61
    always@(posedge clk) begin
62
        if (rst == 1'b1) begin
63
            reg_out_temp <= 16'b0000;
64
            reg_out <= 8'h00;
65
            ready <= 1'b0;
66
            rotation_step <= `R_FIRST_STEP;
67
            reg_bank <= 4'b0000;
68
            math_step <= `M_FIRST_STEP;
69
            current <= 8'h01;
70
            temp_result <= 8'h00;
71
            dividend <= 8'h00;
72
            denom <= 8'h00;
73
        end else if (en == 1'b1) begin
74
            ready <= 1'b0;
75
 
76
            case(opcode)
77
                8'h00:begin /* SUM(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 + reg_in_2]*/
78
                    reg_out <= reg_in_1 + reg_in_2;
79
                    ready <= 1'b1;
80
                end
81
 
82
                8'h01:begin /* SUB(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 - reg_in_2]*/
83
                    reg_out <= reg_in_1 - reg_in_2;
84
 
85
                    if (reg_in_2 > reg_in_1) begin
86
                        ready <= 1'b1;
87
                    end
88
 
89
                    if (reg_in_2 == reg_in_1) begin
90
                        ready <= 1'b1;
91
                    end
92
 
93
                    ready <= 1'b1;
94
                end
95
 
96
                8'h02:begin /* MUL(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 * reg_in_2]*/
97
 
98
                end
99
 
100
                8'h03:begin /* DIV(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 / reg_in_2]*/
101
                    case(math_step)
102
                        `M_FIRST_STEP:begin
103
                            dividend <= reg_in_1;
104
                            denom <= reg_in_2;
105
                            math_step <= `M_SECOND_STEP;
106
                        end
107
 
108
                        `M_SECOND_STEP:begin /* shift left to find first bit with value 1 */
109
                            if (denom <= dividend) begin
110
                                denom <= denom << 1;
111
                                current <= current << 1;
112
                            end else begin
113
                                denom <= denom >> 1; /* shift right reg_in_2 to align it with reg_in_1 */
114
                                current <= current >> 1;
115
                                math_step <= `M_THIRD_STEP;
116
                            end
117
                        end
118
 
119
                        `M_THIRD_STEP:begin
120
                            if (current != 0) begin
121
                                if (dividend >= denom) begin
122
                                    dividend <= dividend - denom;
123
                                    temp_result <= temp_result | current;
124
                                end
125
 
126
                                denom <= denom >> 1;
127
                                current <= current >> 1;
128
                            end else begin
129
                                reg_out <= temp_result;
130
                                                                current <= 8'h01;
131
                                temp_result <= 8'h00;
132
                                math_step <= `M_FIRST_STEP;
133
                                ready <= 1'b1;
134
                            end
135
                        end
136
                    endcase
137
                end
138
 
139
                8'h04:begin /* MOD(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 % reg_in_2]*/
140
 
141
                end
142
 
143
                8'h05:begin /* AND(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 & reg_in_2]*/
144
                    reg_out <= reg_in_1 & reg_in_2;
145
                    ready <= 1'b1;
146
                end
147
 
148
                8'h06:begin /* OR(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 | reg_in_2]*/
149
                    reg_out <= reg_in_1 | reg_in_2;
150
                    ready <= 1'b1;
151
                end
152
 
153
                8'h07:begin /* NOT(reg_out) reg_in_1 [reg_out = ~reg_in_1]*/
154
                    reg_out <= ~reg_in_1;
155
                    ready <= 1'b1;
156
                end
157
 
158
                8'h08:begin /* XOR(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 ^ reg_in_2]*/
159
                    reg_out <= reg_in_1 ^ reg_in_2;
160
                    ready <= 1'b1;
161
                end
162
 
163
                8'h09:begin /* SHL(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 << reg_in_2]*/
164
                    reg_out <= reg_in_1 << reg_in_2;
165
                    ready <= 1'b1;
166
                end
167
 
168
                8'h0A:begin /* SHR(reg_out) reg_in_1,reg_in_2 [reg_out = reg_in_1 >> reg_in_2]*/
169
                    reg_out <= reg_in_1 >> reg_in_2;
170
                    ready <= 1'b1;ready <= 1'b1;
171
                end
172
 
173
                8'h0B:begin /* ROL(reg_out) reg_in_1,reg_in_2 [reg_out = ??]*/
174 4 progman32
                    reg_out <= (reg_in_1 << (reg_in_2 & 8´h07)) | (reg_in_1 >> (8´h08 - (reg_in_2 & 8´h07));
175
                    ready <= 1'b1;
176 3 progman32
                end
177
 
178
                8'h0C:begin /* ROR(reg_out) reg_in_1,reg_in_2 [reg_out = ??]*/
179 4 progman32
                    reg_out <= (reg_in_1 >> (reg_in_2 & 8´h07)) | (reg_in_1 << (8´h08 - (reg_in_2 & 8´h07));
180 3 progman32
                end
181
            endcase
182
        end
183
    end
184
endmodule

powered by: WebSVN 2.1.0

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