module bit_repr_vector(input logic   clk,
    input logic  reset,
    input logic start,
    input logic [3:0]  width, // n <= 8
    input logic signed [31:0] c_i,
    input logic [7:0] ell, // l <= 32

    output logic [7:0]    output_length, // at most 256
    output logic signed [31:0]   data_out,
    output logic done);
    
    logic write_enable;
    logic read_enable;
    logic comp_enable;
    logic [7:0] write_index;
    logic [7:0] comp_index;
    logic [7:0] read_index;
    
    integer i;
    // initialize a DMEM to store input vector.
    logic signed [31:0] input_mem [7:0]; // n <= 8
    always_ff @(posedge clk) begin
        if (reset) begin
            for(i = 0; i <= 7; i = i+1)begin
                input_mem[i] <= 0;
            end
            write_enable <= 0;
            write_index <= 0;

        end else if (start || write_enable) begin
            if (write_index[3:0] < width) begin
                write_enable <= 1;
                input_mem[write_index[2:0]] <= c_i;
                write_index <= write_index + 1;

            end else if (write_index[3:0] == width) begin
                comp_enable <= 1;
                write_enable <= 0;
                write_index <= 0;
            end 
        end else if (read_enable) begin 
            // set computational flag to false
            comp_enable <= 0;
        end
    end	

    assign output_length = width * ell;
    
    logic signed [31:0] n; // corresponding to n-th element in the input vector
    logic signed [31:0] remaining_n;
    logic [7:0] comp_input_index;
    logic [7:0] expo_index;
    logic [31:0] bin_factor;
    logic signed [31:0] ratio;
    // initialize a DMEM to store output vector.
    logic signed [31:0] output_mem [255:0]; // n <= 256

    // do computations when computational flag is true
    always_ff @(posedge clk) begin
        if (comp_enable) begin
            if (comp_index < output_length) begin

                // perform bit-representation conversion for vector c
                // find the element to be converted to binary representation
                n <= input_mem[comp_input_index[2:0]];
                
                bin_factor <= 2**(ell-expo_index-1);
                // update the remining value for each input after subtraction
                       
                if (expo_index == 0) ratio <= input_mem[comp_input_index[2:0]] / 2**(ell-expo_index-1);
                else ratio <= remaining_n / 2**(ell-expo_index-1);
                if (expo_index == 0) remaining_n <= input_mem[comp_input_index[2:0]];
                if ((remaining_n / 2**(ell-expo_index-1)) == 1 && expo_index != 0) begin
                    remaining_n <= remaining_n - 2**(ell-expo_index-1);
                end else if ((remaining_n / 2**(ell-expo_index-1)) == -1 && expo_index != 0) begin
                    remaining_n <= remaining_n + 2**(ell-expo_index-1);
                end
                
                if (expo_index == ell - 1) expo_index <= 0;
                else expo_index <= expo_index + 1;

                output_mem[comp_index] <= ratio;

                comp_index <= comp_index + 1;
                comp_input_index <= (comp_index + 1) / ell;
        
            end else if (comp_index == output_length) begin
                comp_index <= 0;
                comp_input_index <= 0;
                // once finished, set read_enable to true
                read_enable <= 1;
            end
        end else if (done) begin
            // once finished, set read_enable to true
            read_enable <= 0;
        end
    end
    
    // read each element every clock cycle
    always_ff @(posedge clk) begin
        if (read_enable) begin
            if (read_index < output_length) begin
                // spitting out one element each cycle with appropriate index
                data_out <= output_mem[read_index];
                read_index <= read_index + 1;

            end else if (read_index == output_length) begin
                read_index <= 0;
                done <= 1;
            end
        end else begin
            done <= 0;
        end
        
    end
endmodule