// Sumbission for ELEC4720 Assignment 1 Question 6
// Oliver Boutros (c3428958)
// Riley King-Saunders (c

`ifndef INSTRUCTION_CLASSIFIER_H_SV
`define INSTRUCTION_CLASSIFIER_H_SV
module instruction_classifier(input logic[5:0] op,
    output logic[0:0] R, output logic[0:0] B1, output logic[0:0] J,
    output logic[0:0] B2, output logic[0:0] I, output logic[0:0] F,
    output logic[0:0] M);

    always_comb begin
        // Performs a rolling equals check
        //  Uses an AND mask to mask off bits we don't care about
        //  And a equals operator to perform a bitwise XNOR followed by a horizontal AND 
        R = ( (op & 6'b111111) == 6'b000000);
        B1= ( (op & 6'b111111) == 6'b000001);
        J = ( (op & 6'b111110) == 6'b000010);
        B2= ( (op & 6'b111100) == 6'b000100);
        I = ( (op & 6'b111000) == 6'b001000);
        F = ( (op & 6'b110000) == 6'b010000);
        M = ( (op & 6'b100000) == 6'b100000);
    end
endmodule
`endif

// Testbench

module instruction_classifier_tb();
    logic [5:0] op;
    logic [6:0] C;
    logic [5:0] ops[12];
    logic [6:0] C_exp[12];

    instruction_classifier dut(op, C[0:0], C[1:1], C[2:2], C[3:3], C[4:4], C[5:5], C[6:6]);

    integer error_count;
    initial begin
        ops[0] = 6'b000000;
        C_exp[0] = 7'b0000001;
        ops[1] = 6'b000001;
        C_exp[1] = 7'b0000010;
        ops[2] = 6'b000010;
        C_exp[2] = 7'b0000100;
        ops[3] = 6'b000100;
        C_exp[3] = 7'b0001000;
        ops[4] = 6'b001000;
        C_exp[4] = 7'b0010000;
        ops[5] = 6'b010000;
        C_exp[5] = 7'b0100000;
        ops[6] = 6'b100000;
        C_exp[6] = 7'b1000000;

        ops[7] = 6'b000011;
        C_exp[7] = 7'b0000100;
        ops[8] = 6'b000101;
        C_exp[8] = 7'b0001000;
        ops[9] = 6'b001001;
        C_exp[9] = 7'b0010000;
        ops[10] = 6'b010001;
        C_exp[10] = 7'b0100000;
        ops[11] = 6'b100001;
        C_exp[11] = 7'b1000000;

        error_count = 0;
        $display("Beginning Instruction Classifier tests");
        for (integer N = 0; N < $size(ops); ++N) begin
            op = ops[N];
            #1;
            if (C != C_exp[N]) begin
                $display("\t\x1b[38;5;9mInstruction 0b%b produced 0b%b but 0b%b was expected\x1b[m", op, C, C_exp[N]);
                error_count = error_count + 1;
            end
        end
        if (error_count == 0) $display("\x1b[38;5;10mAll Instruction Classifier tests passing\x1b[m");
        else $display("\x1b[38;5;9m%0d Instruction Classifier test(s) failing\x1b[m", error_count);
    end

endmodule
