WISC-SP22-5-Stage-Pipelined-Processor / verilog / controller.v
controller.v
Raw
module controller(clk, rst, enable0, enable1, enable_select, cache_rdy, hit_cache, user_data_sel, comp, write, offset_cache, soff_cache, offset_mem, soff_mem, valid_in, rd, wr, done, stag, hit0, hit1, valid0, valid1, dirty0, dirty1, busy_0, MemRead, MemWrite);
    
    input clk, rst, hit0, hit1, valid0, valid1, dirty0, dirty1, busy_0, MemRead, MemWrite;
    output reg enable0, enable1, comp, write, soff_cache, soff_mem, rd, wr, done, stag, valid_in, cache_rdy, hit_cache, user_data_sel, enable_select;
    output reg [1:0] offset_cache;
    output reg [1:0] offset_mem;
    
    wire [12:0] state;
    reg [12:0] next_state;
    wire VW;
    wire VW_mux;
    reg hit_valid;
    reg [12:0] dirty_or_not;
    reg write_check;
    reg dirty;
    
    parameter IDLE = 5'b00000;
    parameter COMP_TAG = 5'b00001;
    parameter A_BANK0 = 5'b00010;
    parameter A_BANK1 = 5'b00011;
    parameter A_BANK2 = 5'b00100;
    parameter A_BANK3 = 5'b00101;
    parameter WRITTEN_W1 = 5'b00110;
    parameter WRITTEN_W2 = 5'b00111;
    parameter W_BANK0 = 5'b01000;
    parameter W_BANK1 = 5'b01001;
    parameter W_BANK2 = 5'b01010;
    parameter W_BANK3 = 5'b01011;
    parameter STALL = 5'b01100;
    parameter AFTER_A = 5'b01101;
    
    assign VW_mux = ((MemRead|MemWrite) & (state == IDLE)) ? ~VW : VW;
    
    register #(.WIDTHSELECT(1)) VW_reg(.clk(clk), .rst(rst), .read(VW), .write(VW_mux));
    
    register #(.WIDTHSELECT(13)) state_reg(.clk(clk), .rst(rst), .read(state), .write(next_state));
    
    always@(hit0, hit1, valid0, valid1, dirty0, dirty1, busy_0, MemRead, MemWrite, state) begin
        
        enable0 = 0;
        enable1 = 0;
        comp = 0;
        write = 0;
        soff_cache = 0;
        soff_mem = 0;
        offset_mem = 2'b00;
        offset_cache = 2'b00;
        rd = 0;
        wr = 0;
        done = 0;
        stag = 0;
        valid_in = 0;
        next_state = state;
        dirty_or_not = 13'b0;
        hit_valid = 0;
        cache_rdy = 0;
        user_data_sel = 0;
        dirty = 0;
        case(state)
            COMP_TAG: begin
                          comp = 1;
                          write = write_check;
                          user_data_sel = write_check ? 1 : 0;
                          enable0 = 1;
                          enable1 = 1;
                          //if hit0 = 1 & valid0 = 1 | hit1 = 1 & valid1 = 1:
                          hit_valid = (hit0&valid0) | (hit1&valid1);
                          //if !(hit_valid):
                          //if(!valid0 & !valid1):
                          //else if(valid0):
                          //else if(valid1):
                          //else victimway:
                          enable_select = (!hit_valid) ? ((!valid0 & !valid1) ? 1'b0 : ((valid0 & ~valid1) ? 1'b1 : ((valid1 & ~valid0) ? 1'b0 : VW))) : ((hit1&valid1) ? 1'b1 : 1'b0);
                          dirty = enable_select ? dirty1 : dirty0;
                          done = hit_valid ? 1'b1 : 1'b0;
                          dirty_or_not = dirty ? W_BANK0: A_BANK0;
                          next_state = hit_valid ? IDLE : dirty_or_not;
                          
                      end
            A_BANK0: begin
                         rd = 1;
                         wr = 0;
                         offset_mem = 2'b00;
                         soff_mem = 1;
                         hit_cache = 1'b0;
                         next_state = A_BANK1;
                     end
            A_BANK1: begin
                         rd = 1;
                         wr = 0;
                         offset_mem = 2'b01;
                         soff_mem = 1;
                         next_state = A_BANK2;
                     end
            A_BANK2: begin
                         rd = 1;
                         wr = 0;
                         offset_mem = 2'b10;
                         soff_mem = 1;
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 1;
                         valid_in = 1;
                         offset_cache = 2'b00;
                         soff_cache = 1;
                         next_state = A_BANK3;
                     end
            
            A_BANK3: begin
                         rd = 1;
                         wr = 0;
                         offset_mem = 2'b11;
                         soff_mem = 1;
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 1;
                         offset_cache = 2'b01;
                         valid_in = 1;
                         soff_cache = 1;
                         next_state = WRITTEN_W1;
                     end  
            WRITTEN_W1: begin
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 1;
                         offset_cache = 2'b10;
                         valid_in = 1;
                         soff_cache = 1;
                         next_state = WRITTEN_W2;
                     end
            WRITTEN_W2: begin
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 1;
                         offset_cache = 2'b11;
                         valid_in = 1;
                         soff_cache = 1;
                         next_state = write_check ? AFTER_A : COMP_TAG;
                     end
            AFTER_A: begin
                         comp = 1;
                         write = 1;
                         user_data_sel = 1;
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         next_state = COMP_TAG;
                     end
            W_BANK0: begin
                         rd = 0;
                         wr = 1;
                         offset_mem = 2'b00;
                         soff_mem = 1;
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 0;
                         offset_cache = 2'b00;
                         soff_cache = 1;
                         stag = 1;
                         hit_cache = 1'b0;
                         next_state = W_BANK1;
                     end
            W_BANK1: begin
                         rd = 0;
                         wr = 1;
                         offset_mem = 2'b01;
                         soff_mem = 1;
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 0;
                         offset_cache = 2'b01;
                         soff_cache = 1;
                         stag = 1;
                         next_state = W_BANK2;
                     end
            W_BANK2: begin
                         rd = 0;
                         wr = 1;
                         offset_mem = 2'b10;
                         soff_mem = 1;
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 0;
                         offset_cache = 2'b10;
                         soff_cache = 1;
                         stag = 1;
                         next_state = W_BANK3;
                     end
            W_BANK3: begin
                         rd = 0;
                         wr = 1;
                         offset_mem = 2'b11;
                         soff_mem = 1;
                         enable0 = enable_select ? 1'b0 : 1'b1;
                         enable1 = enable_select ? 1'b1 : 1'b0;
                         comp = 0;
                         write = 0;
                         offset_cache = 2'b11;
                         soff_cache = 1;
                         stag = 1;
                         next_state = STALL;
                     end
            STALL: begin
                       next_state = busy_0 ? STALL : A_BANK0;
                   end
            
            default: begin
                         next_state = (MemRead|MemWrite) ? COMP_TAG : IDLE;
                         cache_rdy = (MemRead|MemWrite) ? 0 : 1;
                         hit_cache = 1'b1;
                         write_check = MemWrite;
                     end 
            
        endcase
        
    end
    
endmodule