§ Описание входов модуля
- alumode - режим работы АЛУ
- opsize - размер входящих данных (16/32)
- isize - размер данных (8/16)
- op1 - первый операнд
- op2 - второй операнд
- flags - входящие флаги
- result - результат
- flags_o - исходящие флаги
- daa_r - результат десятичных коррекции (daa/das/aaa/aas)
- flags_d - исходящие флаги для десятичной коррекции
§ Код модуля
1module alu
2(
3
4 input wire isize,
5 input wire opsize,
6 input wire [ 2:0] alumode,
7 input wire [31:0] op1,
8 input wire [31:0] op2,
9 input wire [11:0] flags,
10
11
12 output wire [31:0] result,
13 output reg [11:0] flags_o,
14 output reg [15:0] daa_r,
15 output reg [11:0] flags_d
16);
17
18assign result = isize ? (opsize ? res[31:0] : res[15:0]) : res[7:0];
19
20reg [32:0] res;
21
22
23wire [4:0] signx = isize ? (opsize ? 31 : 15) : 7;
24
25wire parity = ~^res[7:0];
26wire zerof = isize ? (opsize ? ~|res : ~|res[15:0]) : ~|res[7:0];
27wire carryf = res[signx + 1];
28wire signf = res[signx];
29wire auxf = op1[4]^op2[4]^res[4];
30
31
32wire add_o = (op1[signx] == op2[signx]) & (op1[signx] ^ res[signx]);
33wire sub_o = (op1[signx] != op2[signx]) & (op1[signx] ^ res[signx]);
34
35
36reg daa_a;
37reg daa_c;
38reg daa_x;
39reg [8:0] daa_i;
40reg [7:0] daa_h;
41
42
43always @* begin
44
45 case (alumode)
46
47 0: res = op1 + op2;
48 1: res = op1 | op2;
49 2: res = op1 + op2 + flags[0];
50 3: res = op1 - op2 - flags[0];
51 4: res = op1 & op2;
52 5,
53 7: res = op1 - op2;
54 6: res = op1 ^ op2;
55
56 endcase
57
58 case (alumode)
59
60
61 0, 2: flags_o = {
62
63 add_o,
64 flags[10],
65 flags[9],
66 flags[8],
67 signf,
68 zerof,
69 1'b0,
70 auxf,
71 1'b0,
72 parity,
73 1'b1,
74 carryf
75 };
76
77
78 3, 5, 7: flags_o = {
79
80 sub_o,
81 flags[10],
82 flags[9],
83 flags[8],
84 signf,
85 zerof,
86 1'b0,
87 auxf,
88 1'b0,
89 parity,
90 1'b1,
91 carryf
92 };
93
94
95 1, 4, 6: flags_o = {
96
97 1'b0,
98 flags[10],
99 flags[9],
100 flags[8],
101 signf,
102 zerof,
103 1'b0,
104 1'b0,
105 1'b0,
106 parity,
107 1'b1,
108 1'b0
109 };
110
111 endcase
112
113
114end
115
116
117always @* begin
118
119 daa_r = op1[7:0];
120 flags_d = flags;
121
122 case (alumode)
123
124
125 0, 1: begin
126
127 daa_c = flags[0];
128 daa_a = flags[4];
129 daa_i = op1[7:0];
130
131
132 if (op1[3:0] > 9 || flags[4]) begin
133 daa_i = alumode[0] ? op1[7:0]-6 : op1[7:0]+6;
134 daa_c = daa_i[8];
135 daa_a = 1;
136 end
137
138 daa_r = daa_i[7:0];
139 daa_x = daa_c;
140
141
142 if (daa_c || daa_i[7:0] > 8'h9F) begin
143 daa_r = alumode[0] ? daa_i[7:0]-8'h60 : daa_i[7:0]+8'h60;
144 daa_x = 1;
145 end
146
147 flags_d[7] = daa_r[7];
148 flags_d[6] = ~|daa_r[7:0];
149 flags_d[4] = daa_a;
150 flags_d[2] = ~^daa_r[7:0];
151 flags_d[0] = daa_x;
152
153 end
154
155
156 2, 3: begin
157
158 daa_i = op1[ 7:0];
159 daa_r = op1[15:0];
160
161 if (flags[4] || op1[3:0] > 9) begin
162
163 daa_i = alumode[0] ? op1[ 7:0] - 6 : op1[ 7:0] + 6;
164 daa_h = alumode[0] ? op1[15:8] - 1 : op1[15:8] + 1;
165 daa_r = {daa_h, 4'h0, daa_i[3:0]};
166
167 flags_d[4] = 1;
168 flags_d[0] = 1;
169
170 end
171 else begin flags_d[4] = 0; flags_d[0] = 0; end
172
173 end
174
175 endcase
176
177end
178
179endmodule