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