2021-02-17 00:05:46 +01:00
|
|
|
`include "cpu_pkg.svh"
|
|
|
|
|
|
|
|
import cpu_pkg::*;
|
|
|
|
|
|
|
|
module alu (
|
|
|
|
input logic clk_i,
|
|
|
|
input logic nreset_i,
|
|
|
|
|
|
|
|
input logic alu_op_valid_i,
|
|
|
|
input alu_op_t alu_op_i,
|
|
|
|
input logic [7:0] operand_i,
|
2021-02-19 22:53:13 +01:00
|
|
|
input logic [2:0] inx8_i, // Only used for bit/set/res
|
2021-02-17 00:05:46 +01:00
|
|
|
|
2022-02-08 17:14:57 +01:00
|
|
|
input logic rot_op_valid_i,
|
|
|
|
input rot_op_t rot_op_i,
|
|
|
|
|
2021-02-19 00:22:26 +01:00
|
|
|
input alu16_op_t alu16_op_i,
|
|
|
|
input logic [15:0] inx16_i,
|
|
|
|
input logic [15:0] iny16_i,
|
|
|
|
|
2021-02-17 00:05:46 +01:00
|
|
|
output logic [ 7:0] a_o,
|
2021-02-19 00:22:26 +01:00
|
|
|
output logic [ 7:0] f_o,
|
|
|
|
|
2022-02-08 17:14:57 +01:00
|
|
|
output logic [ 7:0] out8_o, // Only used for inc/dec reg8 and rot
|
2021-02-19 00:22:26 +01:00
|
|
|
output logic [15:0] out16_o
|
2021-02-17 00:05:46 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
logic a_we;
|
|
|
|
logic [ 7:0] a_r;
|
|
|
|
logic [ 7:0] a_next;
|
|
|
|
|
|
|
|
logic f_we;
|
|
|
|
logic [ 7:0] f_r;
|
|
|
|
logic [ 7:0] f_next;
|
|
|
|
|
2021-02-20 23:57:15 +01:00
|
|
|
logic [ 7:0] a_inc;
|
|
|
|
logic [ 7:0] f_inc;
|
|
|
|
|
2021-02-17 00:05:46 +01:00
|
|
|
logic [ 7:0] a_xor;
|
|
|
|
logic [ 7:0] f_xor;
|
|
|
|
|
2021-02-19 22:53:13 +01:00
|
|
|
logic [ 7:0] a_bit; // Never written, only to test
|
|
|
|
logic [ 7:0] f_bit;
|
|
|
|
|
2022-02-08 17:14:57 +01:00
|
|
|
|
|
|
|
logic [ 7:0] out8_incr;
|
2021-02-20 23:57:15 +01:00
|
|
|
logic [ 7:0] f_incr;
|
2022-02-08 17:14:57 +01:00
|
|
|
|
|
|
|
logic [ 7:0] out8_rl;
|
|
|
|
logic [ 7:0] f_rl;
|
2021-02-20 23:57:15 +01:00
|
|
|
|
2021-02-19 00:22:26 +01:00
|
|
|
logic [15:0] out16_inc;
|
|
|
|
logic [15:0] out16_dec;
|
|
|
|
|
2021-02-17 00:05:46 +01:00
|
|
|
`DEF_FF(a_r, a_next, a_we, '0);
|
|
|
|
`DEF_FF(f_r, f_next, f_we, '0);
|
|
|
|
|
|
|
|
assign a_we = alu_op_valid_i;
|
2022-02-08 17:14:57 +01:00
|
|
|
assign a_next = (alu_op_valid_i & (alu_op_i == ALU_OP_XOR)) ? a_xor :
|
|
|
|
(alu_op_valid_i & (alu_op_i == ALU_OP_NOP)) ? operand_i :
|
|
|
|
(alu_op_valid_i & (alu_op_i == ALU_OP_INC)) ? a_inc :
|
2022-02-09 00:53:02 +01:00
|
|
|
(alu_op_valid_i & (alu_op_i == ALU_OP_ROT) & (rot_op_i == ROT_OP_RL)) ? out8_rl :
|
|
|
|
a_r;
|
2022-02-08 17:14:57 +01:00
|
|
|
|
|
|
|
assign f_we = alu_op_valid_i | rot_op_valid_i;
|
|
|
|
assign f_next = (alu_op_valid_i & (alu_op_i == ALU_OP_XOR)) ? f_xor :
|
|
|
|
(alu_op_valid_i & (alu_op_i == ALU_OP_BIT)) ? f_bit :
|
|
|
|
(alu_op_valid_i & (alu_op_i == ALU_OP_INC)) ? f_inc :
|
|
|
|
(alu_op_valid_i & (alu_op_i == ALU_OP_INCR)) ? f_incr :
|
|
|
|
(rot_op_valid_i & (rot_op_i == ROT_OP_RL)) ? f_rl :
|
|
|
|
f_r;
|
2021-02-17 00:05:46 +01:00
|
|
|
|
|
|
|
assign a_xor = (a_r ^ operand_i);
|
|
|
|
assign f_xor = {~(|a_xor), 3'b0, f_r[3:0]};
|
|
|
|
|
2021-02-20 23:57:15 +01:00
|
|
|
assign a_inc = (a_r + 8'h01);
|
|
|
|
assign f_inc = {~(|a_inc), 1'b0, a_inc[4], f_r[3:0]};
|
|
|
|
|
2021-02-19 22:53:13 +01:00
|
|
|
assign a_bit = (operand_i - {4'b0, inx8_i});
|
|
|
|
assign f_bit = {~(|a_bit), 2'b10, f_r[4:0]};
|
|
|
|
|
2022-02-08 17:14:57 +01:00
|
|
|
assign out8_rl = {operand_i[6:0], f_r[4]};
|
|
|
|
assign f_rl = {~(|out8_rl), 2'b0, operand_i[7], f_r[3:0]};
|
|
|
|
|
2021-02-20 23:57:15 +01:00
|
|
|
|
2022-02-08 17:14:57 +01:00
|
|
|
assign out8_incr = (operand_i + 8'h01);
|
|
|
|
assign f_incr = {~(|out8_incr), 1'b0, out8_incr[4], f_r[3:0]};
|
2021-02-20 23:57:15 +01:00
|
|
|
|
2021-02-19 00:22:26 +01:00
|
|
|
assign out16_dec = (inx16_i - 16'h01);
|
|
|
|
|
2021-02-17 00:05:46 +01:00
|
|
|
assign a_o = a_r;
|
|
|
|
assign f_o = f_r;
|
|
|
|
|
2022-02-08 17:14:57 +01:00
|
|
|
assign out8_o = ({8{alu_op_valid_i}} & out8_incr) | {8{rot_op_valid_i}} & out8_rl;
|
2021-02-19 00:22:26 +01:00
|
|
|
assign out16_o = out16_dec;
|
|
|
|
|
2021-02-17 00:05:46 +01:00
|
|
|
endmodule : alu
|