`define DATA128Z 128'bZ `define DATA32Z 32'bZ `define W_0 127:96 `define W_1 95:64 `define W_2 63:32 `define W_3 31:0 //`define OP_add 5'd0 //`define OP_addi 5'd1 //`define OP_and 5'd2 //`define OP_mul 5'd3 //`define OP_sub 5'd4 //`define OP_lw 5'd5 //`define OP_sw 5'd6 //`define OP_bne 5'd7 //`define OP_blz 5'd7 //`define OP_vadd 5'd8 //`define OP_vsum 5'd9 //`define OP_vand 5'd10 //`define OP_vmul 5'd11 //`define OP_vxor 5'd12 //`define OP_vlw 5'd13 //`define OP_vmov 5'd14 //`define OP_vsw 5'd14 //`define OP_jalr 5'd15 `define OP_vec 5'b10000 `define OP_vlo0 5'b10001 `define OP_vhi0 5'b10010 `define OP_vlo1 5'b11001 `define OP_vhi1 5'b11010 module combined_ALU ( op5, alu1, alu2, bus ); input [4:0] op5; input [127:0] alu1; input [127:0] alu2; output [127:0] bus; wire [31:0] s_bus; wire [127:0] v_bus; wire [127:0] mov_bus; wire [3:0] op = op5[3:0]; wire is_vlo0 = (op5 == `OP_vlo0); wire is_vhi0 = (op5 == `OP_vhi0); wire is_vlo1 = (op5 == `OP_vlo1); wire is_vhi1 = (op5 == `OP_vhi1); wire is_vmov = is_vlo0 | is_vhi0 | is_vlo1 | is_vhi1; wire [127:0] extract_w0 = { 96'd0, alu1[31:0] }; wire [127:0] extract_w1 = { 96'd0, alu1[63:32] }; wire [127:0] extract_w2 = { 96'd0, alu1[95:64] }; wire [127:0] extract_w3 = { 96'd0, alu1[127:96] }; assign mov_bus = (op5 == `OP_vlo1) ? extract_w0 : `DATA128Z; assign mov_bus = (op5 == `OP_vlo0) ? extract_w1 : `DATA128Z; assign mov_bus = (op5 == `OP_vhi1) ? extract_w2 : `DATA128Z; assign mov_bus = (op5 == `OP_vhi0) ? extract_w3 : `DATA128Z; assign bus = is_vmov ? mov_bus : ((op == `OP_vadd) | (op == `OP_vand) | (op == `OP_vmul) | (op == `OP_vxor) | (op == `OP_vsum)) ? v_bus : { 96'b0, s_bus }; scalar_ALU SALU ( .op(op), .alu1(alu1[31:0]), .alu2(alu2[31:0]), .bus(s_bus) ); vector_ALU VALU ( .op5(op5), .alu1(alu1), .alu2(alu2), .bus(v_bus) ); endmodule // // POOR MAN'S ALU - scalar_ALU // module scalar_ALU ( op, alu1, alu2, bus ); input [3:0] op; input [31:0] alu1; input [31:0] alu2; output [31:0] bus; wire [31:0] add_function = alu1+alu2; wire [31:0] vaddr_function = alu1+{alu2[29:0],2'd0}; wire [31:0] and_function = alu1&alu2; wire [31:0] mul_function = alu1*alu2; wire [31:0] sub_function = alu1-alu2; assign bus = (op == `OP_add) ? add_function : `DATA32Z; assign bus = (op == `OP_addi) ? add_function : `DATA32Z; assign bus = (op == `OP_and) ? and_function : `DATA32Z; assign bus = (op == `OP_mul) ? mul_function : `DATA32Z; assign bus = (op == `OP_sub) ? sub_function : `DATA32Z; assign bus = (op == `OP_lw) ? add_function : `DATA32Z; assign bus = (op == `OP_sw) ? add_function : `DATA32Z; assign bus = (op == `OP_vlw) ? vaddr_function : `DATA32Z; assign bus = (op == `OP_vsw) ? vaddr_function : `DATA32Z; assign bus = (op == `OP_jalr) ? add_function : `DATA32Z; endmodule // // POOR MAN'S ALU - vector_ALU // module vector_ALU ( op5, alu1, alu2, bus ); input [4:0] op5; input [127:0] alu1; input [127:0] alu2; output [127:0] bus; wire [31:0] alu1_0 = alu1[`W_0]; wire [31:0] alu1_1 = alu1[`W_1]; wire [31:0] alu1_2 = alu1[`W_2]; wire [31:0] alu1_3 = alu1[`W_3]; wire [31:0] alu2_0 = alu2[`W_0]; wire [31:0] alu2_1 = alu2[`W_1]; wire [31:0] alu2_2 = alu2[`W_2]; wire [31:0] alu2_3 = alu2[`W_3]; wire [127:0] vadd_function = { alu1_0 + alu2_0, alu1_1 + alu2_1, alu1_2 + alu2_2, alu1_3 + alu2_3 }; wire [127:0] vand_function = { alu1_0 & alu2_0, alu1_1 & alu2_1, alu1_2 & alu2_2, alu1_3 & alu2_3 }; wire [127:0] vmul_function = { alu1_0 * alu2_0, alu1_1 * alu2_1, alu1_2 * alu2_2, alu1_3 * alu2_3 }; wire [127:0] vxor_function = { alu1_0 ^ alu2_0, alu1_1 ^ alu2_1, alu1_2 ^ alu2_2, alu1_3 ^ alu2_3 }; wire [127:0] vsum_function = { alu1_0 + alu1_1 + alu1_2 + alu1_3 }; assign bus = (op5 == {1'd0, `OP_vadd}) ? vadd_function : `DATA128Z; assign bus = (op5 == {1'd0, `OP_vand}) ? vand_function : `DATA128Z; assign bus = (op5 == {1'd0, `OP_vmul}) ? vmul_function : `DATA128Z; assign bus = (op5 == {1'd0, `OP_vxor}) ? vxor_function : `DATA128Z; assign bus = (op5 == {1'd0, `OP_vsum}) ? vsum_function : `DATA128Z; endmodule // // BRANCH TESTERS // module branch_checker ( arg1, arg2, bne_out, blz_out ); input [31:0] arg1; input [31:0] arg2; output bne_out; output blz_out; assign bne_out = ~(arg1==arg2); assign blz_out = arg2[31]; endmodule