§ Описание входов модуля
- alumode - режим работы АЛУ
- opsize - размер входящих данных (16/32)
- isize - размер данных (8/16)
- op1 - первый операнд
- op2 - второй операнд
- flags - входящие флаги
- result - результат
- flags_o - исходящие флаги
- daa_r - результат десятичных коррекции (daa/das/aaa/aas)
- flags_d - исходящие флаги для десятичной коррекции
§ Код модуля
module alu
(
input wire isize,
input wire opsize,
input wire [ 2:0] alumode,
input wire [31:0] op1,
input wire [31:0] op2,
input wire [11:0] flags,
output wire [31:0] result,
output reg [11:0] flags_o,
output reg [15:0] daa_r,
output reg [11:0] flags_d
);
assign result = isize ? (opsize ? res[31:0] : res[15:0]) : res[7:0];
reg [32:0] res;
wire [4:0] signx = isize ? (opsize ? 31 : 15) : 7;
wire parity = ~^res[7:0];
wire zerof = isize ? (opsize ? ~|res : ~|res[15:0]) : ~|res[7:0];
wire carryf = res[signx + 1];
wire signf = res[signx];
wire auxf = op1[4]^op2[4]^res[4];
wire add_o = (op1[signx] == op2[signx]) & (op1[signx] ^ res[signx]);
wire sub_o = (op1[signx] != op2[signx]) & (op1[signx] ^ res[signx]);
reg daa_a;
reg daa_c;
reg daa_x;
reg [8:0] daa_i;
reg [7:0] daa_h;
always @* begin
case (alumode)
0: res = op1 + op2;
1: res = op1 | op2;
2: res = op1 + op2 + flags[0];
3: res = op1 - op2 - flags[0];
4: res = op1 & op2;
5,
7: res = op1 - op2;
6: res = op1 ^ op2;
endcase
case (alumode)
0, 2: flags_o = {
add_o,
flags[10],
flags[9],
flags[8],
signf,
zerof,
1'b0,
auxf,
1'b0,
parity,
1'b1,
carryf
};
3, 5, 7: flags_o = {
sub_o,
flags[10],
flags[9],
flags[8],
signf,
zerof,
1'b0,
auxf,
1'b0,
parity,
1'b1,
carryf
};
1, 4, 6: flags_o = {
1'b0,
flags[10],
flags[9],
flags[8],
signf,
zerof,
1'b0,
1'b0,
1'b0,
parity,
1'b1,
1'b0
};
endcase
end
always @* begin
daa_r = op1[7:0];
flags_d = flags;
case (alumode)
0, 1: begin
daa_c = flags[0];
daa_a = flags[4];
daa_i = op1[7:0];
if (op1[3:0] > 9 || flags[4]) begin
daa_i = alumode[0] ? op1[7:0]-6 : op1[7:0]+6;
daa_c = daa_i[8];
daa_a = 1;
end
daa_r = daa_i[7:0];
daa_x = daa_c;
if (daa_c || daa_i[7:0] > 8'h9F) begin
daa_r = alumode[0] ? daa_i[7:0]-8'h60 : daa_i[7:0]+8'h60;
daa_x = 1;
end
flags_d[7] = daa_r[7];
flags_d[6] = ~|daa_r[7:0];
flags_d[4] = daa_a;
flags_d[2] = ~^daa_r[7:0];
flags_d[0] = daa_x;
end
2, 3: begin
daa_i = op1[ 7:0];
daa_r = op1[15:0];
if (flags[4] || op1[3:0] > 9) begin
daa_i = alumode[0] ? op1[ 7:0] - 6 : op1[ 7:0] + 6;
daa_h = alumode[0] ? op1[15:8] - 1 : op1[15:8] + 1;
daa_r = {daa_h, 4'h0, daa_i[3:0]};
flags_d[4] = 1;
flags_d[0] = 1;
end
else begin flags_d[4] = 0; flags_d[0] = 0; end
end
endcase
end
endmodule