- `include "defines.vh"
- module alu #(
- parameter DATA_WIDTH = 8
- )(
- input wire [`OPSEL_COUNT-1:0] opsel,
- input wire enable,
- input wire [DATA_WIDTH-1:0] rd,
- input wire [DATA_WIDTH-1:0] rr,
- output reg [DATA_WIDTH-1:0] out,
- input wire [DATA_WIDTH-1:0] flags_in,
- output reg [DATA_WIDTH-1:0] flags_out
- );
- /* flags_out a fost transformat in reg, pentru a putea
- * fi atribuit in interiorul unui bloc always, insa va fi
- * sintetizat tot combinational (UAL-ul nici macar nu are clk
- * drept input) */
- /* TODO: De codificat cateva operatii
- * in defines.vh si de implementat aici
- */
- always @* begin
- case (opsel)
- `OPSEL_ADD,
- `OPSEL_ADC:
- begin
- {flags_out[`FLAGS_C], out} = rd + rr + ((opsel == `OPSEL_ADC) && flags_in[`FLAGS_C]);
- flags_out[`FLAGS_V] = (rd[7] == 1 && rr[7] == 1 && out[7] == 0) ||
- (rd[7] == 0 && rr[7] == 0 && out[7] == 1);
- flags_out[`FLAGS_Z] = (out == 0);
- flags_out[`FLAGS_N] = out[7];
- flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V];
- flags_out[`FLAGS_H] = (rd[3] == 1 && rr[3] == 1 && out[3] == 0) ||
- (rd[3] == 0 && rr[3] == 0 && out[3] == 1);
- flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
- flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
- end
- `OPSEL_SUB:
- begin
- {flags_out[`FLAGS_C], out} = rd - rr - flags_in[`FLAGS_C];
- flags_out[`FLAGS_V] = (rd[7] == 1 && rr[7] == 1 && out[7] == 0) ||
- (rd[7] == 0 && rr[7] == 0 && out[7] == 1);
- flags_out[`FLAGS_Z] = (out == 0);
- flags_out[`FLAGS_N] = out[7];
- flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V];
- flags_out[`FLAGS_H] = (rd[3] == 1 && rr[3] == 1 && out[3] == 0) ||
- (rd[3] == 0 && rr[3] == 0 && out[3] == 1);
- flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
- flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
- end
- `OPSEL_AND:
- begin
- out = rd & rr;
- flags_out[`FLAGS_V] = 0;
- flags_out[`FLAGS_Z] = (out == 0);
- flags_out[`FLAGS_N] = out[7];
- flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V];
- flags_out[`FLAGS_H] = flags_in[`FLAGS_H];
- flags_out[`FLAGS_C] = flags_in[`FLAGS_C];
- flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
- flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
- end
- `OPSEL_EOR:
- begin
- out = rd ^ rr;
- flags_out[`FLAGS_V] = 0;
- flags_out[`FLAGS_Z] = (out == 0);
- flags_out[`FLAGS_N] = out[7];
- flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V];
- flags_out[`FLAGS_H] = flags_in[`FLAGS_H];
- flags_out[`FLAGS_C] = flags_in[`FLAGS_C];
- flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
- flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
- end
- `OPSEL_OR:
- begin
- out = rd | rr;
- flags_out[`FLAGS_V] = 0;
- flags_out[`FLAGS_Z] = (out == 0);
- flags_out[`FLAGS_N] = out[7];
- flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V];
- flags_out[`FLAGS_H] = flags_in[`FLAGS_H];
- flags_out[`FLAGS_C] = flags_in[`FLAGS_C];
- flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
- flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
- end
- `OPSEL_NEG:
- begin
- out = 0 -rd;
- flags_out[`FLAGS_V] = 0;
- flags_out[`FLAGS_Z] = (out == 0);
- flags_out[`FLAGS_N] = out[7];
- flags_out[`FLAGS_S] = flags_out[`FLAGS_N] ^ flags_out[`FLAGS_V];
- flags_out[`FLAGS_H] = flags_in[`FLAGS_H];
- flags_out[`FLAGS_C] = flags_in[`FLAGS_C];
- flags_out[`FLAGS_T] = flags_in[`FLAGS_T];
- flags_out[`FLAGS_I] = flags_in[`FLAGS_I];
- end
- /*TODO: add your ops here*/
- default: begin
- out = 8'bx;
- flags_out = flags_in;
- end
- endcase
- end
- endmodule