OpenCores
URL https://opencores.org/ocsvn/rtf65002/rtf65002/trunk

Subversion Repositories rtf65002

[/] [rtf65002/] [trunk/] [rtl/] [verilog/] [cache_controller.v] - Diff between revs 32 and 35

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 32 Rev 35
Line 1... Line 1...
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2013  Robert Finch, Stratford
//   \\__/ o\    (C) 2013  Robert Finch, Stratford
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@opencores.org
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
// This source file is free software: you can redistribute it and/or modify 
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// by the Free Software Foundation, either version 3 of the License, or     
Line 21... Line 21...
// ============================================================================
// ============================================================================
//
//
// Cache controller
// Cache controller
// Also takes care of loading the instruction buffer for non-cached access
// Also takes care of loading the instruction buffer for non-cached access
//
//
 
 
//IDLE:
 
//      begin
 
//              if (!cyc_o) begin
 
//`ifdef SUPPORT_DCACHE
 
//                      // A write to a cacheable address does not cause a cache load
 
//                      if (dmiss) begin
 
//                              isDataCacheLoad <= `TRUE;
 
//                              if (isRMW)
 
//                                      lock_o <= 1'b1;
 
//                              cti_o <= 3'b001;
 
//                              bl_o <= 6'd3;
 
//                              cyc_o <= 1'b1;
 
//                              stb_o <= 1'b1;
 
//                              sel_o <= 4'hF;
 
//                              adr_o <= {radr[31:2],4'h0};
 
//                              cstate <= LOAD_DCACHE;
 
//                      end
 
//                      else
 
//`endif
 
//`ifdef SUPPORT_ICACHE
 
//                      if (!unCachedInsn && imiss && !hit0) begin
 
//                              isInsnCacheLoad <= `TRUE;
 
//                              bte_o <= 2'b00;
 
//                              cti_o <= 3'd001;
 
//                              bl_o <= 6'd3;
 
//                              cyc_o <= 1'b1;
 
//                              stb_o <= 1'b1;
 
//                              sel_o <= 4'hF;
 
//                              adr_o <= {pc[31:4],4'h0};
 
//                              cstate <= LOAD_ICACHE;
 
//                      end
 
//                      else if (!unCachedInsn && imiss && !hit1) begin
 
//                              isInsnCacheLoad <= `TRUE;
 
//                              bte_o <= 2'b00;
 
//                              cti_o <= 3'd001;
 
//                              bl_o <= 6'd3;
 
//                              cyc_o <= 1'b1;
 
//                              stb_o <= 1'b1;
 
//                              sel_o <= 4'hF;
 
//                              adr_o <= {pcp8[31:4],4'h0};
 
//                              cstate <= LOAD_ICACHE;
 
//                      end
 
//                      else 
 
//`endif
 
//                      if (unCachedInsn && imiss) begin
 
//                              bte_o <= 2'b00;
 
//                              cti_o <= 3'b001;
 
//                              bl_o <= 6'd2;
 
//                              cyc_o <= 1'b1;
 
//                              stb_o <= 1'b1;
 
//                              sel_o <= 4'hf;
 
//                              adr_o <= {pc[31:2],2'b00};
 
//                              cstate <= LOAD_IBUF1;
 
//                      end
 
//              end
 
//      end
 
 
 
 
 
`ifdef SUPPORT_DCACHE
`ifdef SUPPORT_DCACHE
DCACHE1:
DCACHE1:
        begin
        begin
                isDataCacheLoad <= `TRUE;
                isDataCacheLoad <= `TRUE;
                if (isRMW)
                if (isRMW)
                        lock_o <= 1'b1;
                        lock_o <= 1'b1;
                cti_o <= 3'b001;
                wb_burst(6'd3,{radr[31:2],4'h0});
                bl_o <= 6'd3;
 
                cyc_o <= 1'b1;
 
                stb_o <= 1'b1;
 
                sel_o <= 4'hF;
 
                adr_o <= {radr[31:2],4'h0};
 
                state <= LOAD_DCACHE;
                state <= LOAD_DCACHE;
        end
        end
LOAD_DCACHE:
LOAD_DCACHE:
        if (ack_i) begin
        if (ack_i) begin
 
                if (adr_o[3:2]==2'b10)
 
                        cti_o <= 3'b111;
                if (adr_o[3:2]==2'b11) begin
                if (adr_o[3:2]==2'b11) begin
                        dmiss <= `FALSE;
                        dmiss <= `FALSE;
                        isDataCacheLoad <= `FALSE;
                        isDataCacheLoad <= `FALSE;
                        cti_o <= 3'b000;
                        wb_nack();
                        bl_o <= 6'd0;
 
                        cyc_o <= 1'b0;
 
                        stb_o <= 1'b0;
 
                        sel_o <= 4'h0;
 
                        adr_o <= 34'h0;
 
                        state <= retstate;
                        state <= retstate;
                end
                end
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
        end
        end
`ifdef SUPPORT_BERR
`ifdef SUPPORT_BERR
        else if (err_i) begin
        else if (err_i) begin
 
                if (adr_o[3:2]==2'b10)
 
                        cti_o <= 3'b111;
                if (adr_o[3:2]==2'b11) begin
                if (adr_o[3:2]==2'b11) begin
                        dmiss <= `FALSE;
                        dmiss <= `FALSE;
                        isDataCacheLoad <= `FALSE;
                        isDataCacheLoad <= `FALSE;
                        cti_o <= 3'b000;
                        wb_nack();
                        bl_o <= 6'd0;
 
                        cyc_o <= 1'b0;
 
                        stb_o <= 1'b0;
 
                        sel_o <= 4'h0;
 
                        adr_o <= 34'h0;
 
                        // The state machine will be waiting for a dhit.
                        // The state machine will be waiting for a dhit.
                        // Override the next state and send the processor to the bus error state.
                        // Override the next state and send the processor to the bus error state.
 
                        intno <= 9'd508;
                        state <= BUS_ERROR;
                        state <= BUS_ERROR;
                end
                end
 
                derr_address <= adr_o[33:2];
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
        end
        end
`endif
`endif
`endif
`endif
`ifdef SUPPORT_ICACHE
`ifdef SUPPORT_ICACHE
ICACHE1:
ICACHE1:
        if (!hit0) begin
        if (!hit0) begin
                isInsnCacheLoad <= `TRUE;
                isInsnCacheLoad <= `TRUE;
                bte_o <= 2'b00;
                wb_burst(6'd3,{pc[31:4],4'h0});
                cti_o <= 3'b001;
 
                bl_o <= 6'd3;
 
                cyc_o <= 1'b1;
 
                stb_o <= 1'b1;
 
                sel_o <= 4'hF;
 
                adr_o <= {pc[31:4],4'h0};
 
                state <= LOAD_ICACHE;
                state <= LOAD_ICACHE;
        end
        end
        else if (!hit1) begin
        else if (!hit1) begin
                isInsnCacheLoad <= `TRUE;
                isInsnCacheLoad <= `TRUE;
                bte_o <= 2'b00;
                wb_burst(6'd3,{pcp8[31:4],4'h0});
                cti_o <= 3'b001;
 
                bl_o <= 6'd3;
 
                cyc_o <= 1'b1;
 
                stb_o <= 1'b1;
 
                sel_o <= 4'hF;
 
                adr_o <= {pcp8[31:4],4'h0};
 
                state <= LOAD_ICACHE;
                state <= LOAD_ICACHE;
        end
        end
        else
        else
                state <= em ? BYTE_IFETCH : IFETCH;
                state <= em ? BYTE_IFETCH : IFETCH;
LOAD_ICACHE:
LOAD_ICACHE:
        if (ack_i) begin
        if (ack_i) begin
 
                if (adr_o[3:2]==2'b10)
 
                        cti_o <= 3'b111;
                if (adr_o[3:2]==2'b11) begin
                if (adr_o[3:2]==2'b11) begin
                        isInsnCacheLoad <= `FALSE;
                        isInsnCacheLoad <= `FALSE;
                        cti_o <= 3'b000;
                        wb_nack();
                        bl_o <= 6'd0;
 
                        cyc_o <= 1'b0;
 
                        stb_o <= 1'b0;
 
                        sel_o <= 4'h0;
 
                        adr_o <= 34'd0;
 
`ifdef ICACHE_2WAY
`ifdef ICACHE_2WAY
                        clfsr <= {clfsr,clfsr_fb};
                        clfsr <= {clfsr,clfsr_fb};
`endif
`endif
                        state <= ICACHE1;
                        state <= ICACHE1;
                end
                end
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
        end
        end
`ifdef SUPPORT_BERR
`ifdef SUPPORT_BERR
        else if (err_i) begin
        else if (err_i) begin
 
                if (adr_o[3:2]==2'b10)
 
                        cti_o <= 3'b111;
                if (adr_o[3:2]==2'b11) begin
                if (adr_o[3:2]==2'b11) begin
                        isInsnCacheLoad <= `FALSE;
                        isInsnCacheLoad <= `FALSE;
                        cti_o <= 3'b000;
                        wb_nack();
                        bl_o <= 6'd0;
                        derr_address <= 32'd0;
                        cyc_o <= 1'b0;
                        intno <= 9'd509;
                        stb_o <= 1'b0;
                        state <= BUS_ERROR;
                        sel_o <= 4'h0;
 
                        adr_o <= 34'd0;
 
                        state <= INSN_BUS_ERROR;
 
`ifdef ICACHE_2WAY
`ifdef ICACHE_2WAY
                        clfsr <= {clfsr,clfsr_fb};
                        clfsr <= {clfsr,clfsr_fb};
`endif
`endif
                end
                end
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
                adr_o[3:2] <= adr_o[3:2] + 2'd1;
        end
        end
`endif
`endif
`endif
`endif
//IBUF1:
 
//      begin
 
//              bte_o <= 2'b00;
 
//              cti_o <= 3'b001;
 
//              bl_o <= 6'd2;
 
//              cyc_o <= 1'b1;
 
//              stb_o <= 1'b1;
 
//              sel_o <= 4'hf;
 
//              adr_o <= {pc[31:2],2'b00};
 
//              state <= LOAD_IBUF1;
 
//      end
 
LOAD_IBUF1:
LOAD_IBUF1:
        if (!cyc_o) begin
        if (!cyc_o) begin
                bte_o <= 2'b00;
                // Emulation mode never needs to read more than two words.
                cti_o <= 3'b001;
                // Native mode might need up to three words.
                bl_o <= 6'd2;
                wb_burst((em ? 6'd1: 6'd2),{pc[31:2],2'b00});
                cyc_o <= 1'b1;
 
                stb_o <= 1'b1;
 
                sel_o <= 4'hF;
 
                adr_o <= {pc[31:2],2'b00};
 
        end
        end
        else if (ack_i|err_i) begin
        else if (ack_i|err_i) begin
 
                if (em)
 
                        cti_o <= 3'b111;
                case(pc[1:0])
                case(pc[1:0])
                2'd0:   ibuf <= dat_i;
                2'd0:   ibuf <= dat_i;
                2'd1:   ibuf <= dat_i[31:8];
                2'd1:   ibuf <= dat_i[31:8];
                2'd2:   ibuf <= dat_i[31:16];
                2'd2:   ibuf <= dat_i[31:16];
                2'd3:   ibuf <= dat_i[31:24];
                2'd3:   ibuf <= dat_i[31:24];
                endcase
                endcase
                state <= LOAD_IBUF2;
                state <= LOAD_IBUF2;
                adr_o <= adr_o + 34'd4;
 
        end
        end
LOAD_IBUF2:
LOAD_IBUF2:
        if (ack_i|err_i) begin
        if (ack_i|err_i) begin
                cyc_o <= 1'b0;
                state <= em ? BYTE_IFETCH : LOAD_IBUF3;
                stb_o <= 1'b0;
 
                sel_o <= 4'h0;
 
                case(pc[1:0])
                case(pc[1:0])
                2'd0:   ibuf[55:32] <= dat_i[23:0];
                2'd0:   ibuf[55:32] <= dat_i[23:0];
                2'd1:   ibuf[55:24] <= dat_i;
                2'd1:   ibuf[55:24] <= dat_i;
                2'd2:   ibuf[47:16] <= dat_i;
                2'd2:   ibuf[47:16] <= dat_i;
                2'd3:   ibuf[39:8] <= dat_i;
                2'd3:   ibuf[39:8] <= dat_i;
                endcase
                endcase
                state <= LOAD_IBUF3;
                if (em) begin
                adr_o <= adr_o + 34'd4;
                        wb_nack();
 
                        if (err_i) begin
 
                                derr_address <= 32'd0;
 
                                intno <= 9'd509;
 
                                state <= BUS_ERROR;
 
                        end
 
                        bufadr <= pc;   // clears the miss
 
                end
 
                else
 
                        cti_o <= 3'b111;
        end
        end
LOAD_IBUF3:
LOAD_IBUF3:
        if (ack_i) begin
        if (ack_i) begin
                cti_o <= 3'b000;
                wb_nack();
                cyc_o <= 1'b0;
 
                stb_o <= 1'b0;
 
                sel_o <= 4'h0;
 
                case(pc[1:0])
                case(pc[1:0])
                2'd0:   ;
                2'd0:   ;
                2'd1:   ;
                2'd1:   ;
                2'd2:   ibuf[55:48] <= dat_i[7:0];
                2'd2:   ibuf[55:48] <= dat_i[7:0];
                2'd3:   ibuf[55:40] <= dat_i[15:0];
                2'd3:   ibuf[55:40] <= dat_i[15:0];
                endcase
                endcase
                adr_o <= 34'd0;
 
                state <= IFETCH;
                state <= IFETCH;
                bufadr <= pc;   // clears the miss
                bufadr <= pc;   // clears the miss
        end
        end
`ifdef SUPPORT_BERR
`ifdef SUPPORT_BERR
        else if (err_i) begin
        else if (err_i) begin
 
                wb_nack();
                case(pc[1:0])
                case(pc[1:0])
                2'd0:   ;
                2'd0:   ;
                2'd1:   ;
                2'd1:   ;
                2'd2:   ibuf[55:48] <= dat_i[7:0];
                2'd2:   ibuf[55:48] <= dat_i[7:0];
                2'd3:   ibuf[55:40] <= dat_i[15:0];
                2'd3:   ibuf[55:40] <= dat_i[15:0];
                endcase
                endcase
                cti_o <= 3'b000;
                derr_address <= 32'd0;
                cyc_o <= 1'b0;
                intno <= 9'd509;
                stb_o <= 1'b0;
                state <= BUS_ERROR;
                sel_o <= 4'h0;
 
                adr_o <= 34'd0;
 
                state <= INSN_BUS_ERROR;
 
                bufadr <= pc;   // clears the miss
                bufadr <= pc;   // clears the miss
        end
        end
`endif
`endif
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.