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

Subversion Repositories m32632

[/] [m32632/] [trunk/] [rtl/] [CACHE_LOGIK.v] - Diff between revs 23 and 29

Show entire file | Details | Blame | View Log

Rev 23 Rev 29
Line 1... Line 1...
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
// This file is part of the M32632 project
// This file is part of the M32632 project
// http://opencores.org/project,m32632
// http://opencores.org/project,m32632
//
//
//      Filename:       CACHE_LOGIK.v
//      Filename:       CACHE_LOGIK.v
//      Version:        2.0
//  Version:    3.0
//      History:        1.1 bug fix of 7 October 2015
//      History:        2.0 of 11 August 2016
 
//                              1.1 bug fix of 7 October 2015
//                              1.0 first release of 30 Mai 2015
//                              1.0 first release of 30 Mai 2015
//      Date:           14 August 2016
//      Date:           2 December 2018
//
//
// Copyright (C) 2016 Udo Moeller
// Copyright (C) 2018 Udo Moeller
// 
// 
// This source file may be used and distributed without 
// This source file may be used and distributed without 
// restriction provided that this copyright statement is not 
// restriction provided that this copyright statement is not 
// removed from the file and that any derivative work contains 
// removed from the file and that any derivative work contains 
// the original copyright notice and the associated disclaimer.
// the original copyright notice and the associated disclaimer.
Line 30... Line 31...
// 
// 
// You should have received a copy of the GNU Lesser General 
// You should have received a copy of the GNU Lesser General 
// Public License along with this source; if not, download it 
// Public License along with this source; if not, download it 
// from http://www.opencores.org/lgpl.shtml 
// from http://www.opencores.org/lgpl.shtml 
// 
// 
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      Modules contained in this file:
//      Modules contained in this file:
//      1. NEU_VALID    Cache Valid RAM
//      1. WRPORT               Write Port
//      2. DEBUG_AE     Debug unit for address compare in data cache
//      2. NEU_VALID    Cache Valid RAM
//      3. MMU_UP               MMU memory update and initalization controller
//      3. DEBUG_AE     Debug unit for address compare in data cache
//      4. DCA_CONTROL  Data cache valid memory update and initalization controller
//      4. MMU_UP               MMU memory update and initalization controller
//      5. MMU_MATCH    MMU virtual address match detector
//      5. DCA_CONTROL  Data cache valid memory update and initalization controller
//      6. CA_MATCH             Cache tag match detector
//      6. MMU_MATCH    MMU virtual address match detector
//      7. FILTCMP              Address Filter and Comparator
//      7. CA_MATCH             Cache tag match detector
//      8. DCACHE_SM    Data cache state machine
//      8. FILTCMP              Address Filter and Comparator
 
//      9. DCACHE_SM    Data cache state machine
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      1. NEU_VALID    Cache Valid RAM
//      1. WRPORT       Write Port
 
//
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
module WRPORT ( WRITE, DRAM_Q, WRDATA, ENBYTE, VADDR, DADDR, WDAT, CAP_Q, ENB );
 
 
 
        input                   WRITE;
 
        input  [127:0]   DRAM_Q;
 
        input   [31:0]   WRDATA;
 
        input    [3:0]   ENBYTE;
 
        input    [3:2]  VADDR;
 
        input    [3:2]  DADDR;
 
 
 
        output [127:0]   WDAT;
 
 
 
        output  reg     [31:0]   CAP_Q;
 
        output  reg     [15:0]   ENB;
 
 
 
        assign WDAT = WRITE ? {WRDATA,WRDATA,WRDATA,WRDATA} : DRAM_Q;
 
 
 
        always @(DADDR or DRAM_Q)
 
          case (DADDR)
 
            2'b00 : CAP_Q = DRAM_Q[31:0];
 
                2'b01 : CAP_Q = DRAM_Q[63:32];
 
                2'b10 : CAP_Q = DRAM_Q[95:64];
 
                2'b11 : CAP_Q = DRAM_Q[127:96];
 
          endcase
 
 
 
        always @(WRITE or VADDR or ENBYTE)
 
          case ({WRITE,VADDR})
 
             3'b100 : ENB = {4'd0  ,4'd0  ,4'd0  ,ENBYTE};
 
             3'b101 : ENB = {4'd0  ,4'd0  ,ENBYTE,4'd0  };
 
             3'b110 : ENB = {4'd0  ,ENBYTE,4'd0  ,4'd0  };
 
             3'b111 : ENB = {ENBYTE,4'd0  ,4'd0  ,4'd0  };
 
                default : ENB = 16'hFFFF;
 
          endcase
 
 
 
endmodule
 
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
//
 
//      2. NEU_VALID    Cache Valid RAM
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module NEU_VALID ( BCLK, VALIN, WADR, WREN, RADR, VALOUT );
module NEU_VALID ( BCLK, VALIN, WADR, WREN, RADR, VALOUT );
 
 
        input                   BCLK;
        input                   BCLK;
Line 76... Line 118...
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      2. DEBUG_AE     Debug unit for address compare in data cache
//      3. DEBUG_AE     Debug unit for address compare in data cache
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DEBUG_AE ( DBG_IN, READ, WRITE, USER, VIRTUELL, ACC_OK, VADR_R, MMU_Q, ENBYTE, DBG_HIT );
module DEBUG_AE ( DBG_IN, READ, WRITE, USER, VIRTUELL, ACC_OK, VADR_R, MMU_Q, ENBYTE, DBG_HIT );
 
 
        input   [40:2]  DBG_IN;
        input   [40:2]  DBG_IN;
Line 123... Line 165...
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      3. MMU_UP               MMU memory update and initalization controller
//      4. MMU_UP               MMU memory update and initalization controller
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module MMU_UP ( BCLK, BRESET, NEW_PTB, PTB1, IVAR, WR_MRAM, VADR, VADR_R, MVALID, UPDATE,
module MMU_UP ( BCLK, BRESET, NEW_PTB, PTB1, IVAR, WR_MRAM, VADR, VADR_R, MVALID, UPDATE,
                                WE_MV, WADR_MV, RADR_MV, DAT_MV, NEW_PTB_RUN );
                                WE_MV, WADR_MV, RADR_MV, DAT_MV, NEW_PTB_RUN );
 
 
Line 174... Line 216...
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      4. DCA_CONTROL  Data cache valid memory update and initalization controller
//      5. DCA_CONTROL  Data cache valid memory update and initalization controller
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DCA_CONTROL ( BCLK, MCLK, BRESET, CUPDATE, DRAM_ACC, CA_SET, HIT_ALL, WRCFG, VADR_R, UPDATE, INVAL_A, WRITE,
module DCA_CONTROL ( BCLK, BRESET, CUPDATE, DRAM_ACC, CA_SET, HIT_ALL, VADR_R, UPDATE, INVAL_A, WRITE, MDONE, USE_CA,
                                         WCTRL, KILL, WRCRAM0, WRCRAM1, WE_CV, WADR_CV, DAT_CV, INIT_CA_RUN, WRSET0, WRSET1 );
                                         INHIBIT, KILL, WRCRAM0, WRCRAM1, WE_CV, WADR_CV, DAT_CV, INIT_CA_RUN, WRSET0, WRSET1 );
 
 
        input                   BCLK;
        input                   BCLK;
        input                   MCLK;
 
        input                   BRESET;
        input                   BRESET;
        input                   CUPDATE;        // State CUPDATE : Cache is filled from DRAM
        input                   CUPDATE;        // State CUPDATE : Cache is filled from DRAM
        input                   DRAM_ACC;
        input                   DRAM_ACC;
        input                   CA_SET;
        input                   CA_SET;
        input                   HIT_ALL;        // a complete cache hit !
        input                   HIT_ALL;        // a complete cache hit !
        input                   WRCFG;          // static signal : GND or VDD
 
        input   [11:7]  VADR_R;
        input   [11:7]  VADR_R;
        input   [23:0]   UPDATE;
        input   [23:0]   UPDATE;
        input                   INVAL_A;
        input                   INVAL_A;
        input                   WRITE;
        input                   WRITE;
        input    [1:0]   WCTRL;          // [1] : Read Burst Signal from DRAM controller, MCLK aligned. [0] : Cache inhibit
        input                   MDONE;          // Signal from DRAM : Access Done
 
        input                   USE_CA;         // Signal use cache
 
        input                   INHIBIT;        // Signal cache inhibit  - no write in cache
        input                   KILL;           // valid Ram must be updated because of collision ... or CINV
        input                   KILL;           // valid Ram must be updated because of collision ... or CINV
 
 
        output                  WRCRAM0,WRCRAM1;
        output                  WRCRAM0,WRCRAM1;
        output                  WE_CV;
        output                  WE_CV;
        output   [4:0]   WADR_CV;
        output   [4:0]   WADR_CV;
Line 206... Line 248...
 
 
        reg              [1:0]   state;
        reg              [1:0]   state;
        reg              [4:0]   acount;
        reg              [4:0]   acount;
        reg                             ca_set_d;
        reg                             ca_set_d;
 
 
        reg                             dly_bclk,zero,wr_puls;
 
        reg              [2:0]   count,refer;
 
 
 
        wire                    countf;
        wire                    countf;
 
 
        always @(posedge BCLK) if (DRAM_ACC) ca_set_d <= CA_SET;        // Store for whole access
        always @(posedge BCLK) if (DRAM_ACC) ca_set_d <= CA_SET;        // Store for whole access
 
 
        // physical address is stored in TAG-RAM
        // physical address is stored in TAG-RAM
 
 
        assign WRCRAM0 = (CUPDATE & ~WCTRL[0]) & ~ca_set_d;
        assign WRCRAM0 = (CUPDATE & ~INHIBIT) & ~ca_set_d;
        assign WRCRAM1 = (CUPDATE & ~WCTRL[0]) &  ca_set_d;
        assign WRCRAM1 = (CUPDATE & ~INHIBIT) &  ca_set_d;
 
 
        // Load Valid RAM :
        // Load Valid RAM :
 
 
        assign WE_CV   = state[1] | HIT_ALL | (CUPDATE & ~WCTRL[0]) | KILL; // Hit All for "Last" Update
        assign WE_CV   = state[1] | HIT_ALL | (CUPDATE & ~INHIBIT) | KILL; // Hit All for "Last" Update
        assign WADR_CV = state[1] ? acount : VADR_R;
        assign WADR_CV = state[1] ? acount : VADR_R;
        assign DAT_CV  = state[1] ? 24'h0 : UPDATE;
        assign DAT_CV  = state[1] ? 24'h0 : UPDATE;
 
 
        // Clear of Cache-Valid RAMs : 32 clocks of BCLK
        // Clear of Cache-Valid RAMs : 32 clocks of BCLK
 
 
Line 244... Line 283...
        always @(posedge BCLK) if (!state[1]) acount <= 5'h0; else acount <= acount + 5'h01;
        always @(posedge BCLK) if (!state[1]) acount <= 5'h0; else acount <= acount + 5'h01;
 
 
        assign INIT_CA_RUN = state[1];
        assign INIT_CA_RUN = state[1];
 
 
        // WRITE Control in data RAMs
        // WRITE Control in data RAMs
        assign WRSET0 = ( ~CA_SET & WRITE & HIT_ALL & wr_puls) | (WCTRL[1] & ~ca_set_d);
        assign WRSET0 = ( ~CA_SET & WRITE & HIT_ALL) | (MDONE & USE_CA & ~ca_set_d);
        assign WRSET1 = (  CA_SET & WRITE & HIT_ALL & wr_puls) | (WCTRL[1] &  ca_set_d);
        assign WRSET1 = (  CA_SET & WRITE & HIT_ALL) | (MDONE & USE_CA &  ca_set_d);
 
 
        // ++++++++++++ Special circuit for Timing of write pulse for data RAM of data cache +++++++++
 
 
 
        always @(negedge MCLK) dly_bclk <= BCLK;
 
 
 
        always @(negedge MCLK) zero <= BCLK & ~dly_bclk;
 
 
 
        always @(posedge MCLK) if (zero) count <= 3'd0; else count <= count + 3'd1;
 
 
 
        //    count at zero , ref Wert
 
        // 1 : --- always on    5 : 100  001
 
        // 2 : 001  000                 6 : 101  010
 
        // 3 : 010  010                 7 : 110  011
 
        // 4 : 011  000                 8 : 111  100
 
        always @(posedge MCLK) if (zero) refer <= {(count == 3'd7),((count == 3'd5) | (count[1:0] == 2'b10)),(count[2] & ~count[0])};
 
 
 
        always @(posedge MCLK) wr_puls <= (count == refer) | WRCFG;
 
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      5. MMU_MATCH    MMU virtual address match detector
//      6. MMU_MATCH    MMU virtual address match detector
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module MMU_MATCH ( USER, READ, WRITE, RMW, MCR_FLAGS, MVALID, VADR_R, MMU_VA, IVAR,
module MMU_MATCH ( USER, READ, WRITE, RMW, MCR_FLAGS, MVALID, VADR_R, MMU_VA, IVAR,
                                   VIRTUELL, MMU_HIT , UPDATE, PROT_ERROR, CI, SEL_PTB1 );
                                   VIRTUELL, MMU_HIT , UPDATE, PROT_ERROR, CI, SEL_PTB1 );
 
 
Line 355... Line 377...
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      6. CA_MATCH             Cache tag match detector
//      7. CA_MATCH             Cache tag match detector
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module CA_MATCH ( CVALID, DRAMSZ, ADDR, TAG0, TAG1, CFG, WRITE, MMU_HIT, CI, INVAL_L, KDET, ENDRAM, DC_ILO,
module CA_MATCH ( CVALID, DRAMSZ, ADDR, TAG0, TAG1, CFG, WRITE, MMU_HIT, CI, INVAL_L, KDET, ENDRAM, DC_ILO,
                                  CA_HIT, CA_SET, UPDATE, IO_SPACE, USE_CA, WB_ACC, KILL );
                                  CA_HIT, CA_SET, UPDATE, IO_SPACE, USE_CA, WB_ACC, KILL );
 
 
        input   [23:0]   CVALID;
        input   [23:0]   CVALID;
        input    [2:0]   DRAMSZ;
        input    [2:0]   DRAMSZ;
        input   [31:4]  ADDR;
        input   [31:4]  ADDR;
        input  [27:12]  TAG0,TAG1;
        input  [28:12]  TAG0,TAG1;
        input    [1:0]   CFG;    // LDC , DC
        input    [1:0]   CFG;    // LDC , DC
        input                   WRITE;
        input                   WRITE;
        input                   MMU_HIT;
        input                   MMU_HIT;
        input                   CI;
        input                   CI;
        input                   INVAL_L;        // invalid cache line
        input                   INVAL_L;        // invalid cache line
Line 383... Line 405...
        output                  USE_CA;
        output                  USE_CA;
        output                  WB_ACC;
        output                  WB_ACC;
        output                  KILL;
        output                  KILL;
 
 
        reg              [7:0]   maske;
        reg              [7:0]   maske;
        reg              [4:0]   szmaske;
        reg                             acc_dram;
 
 
        wire                    match_0,match_1;
        wire                    match_0,match_1;
        wire                    valid_0,valid_1;
        wire                    valid_0,valid_1;
        wire                    select;
        wire                    select;
        wire                    clear;
        wire                    clear;
        wire     [7:0]   update_0,update_1,lastinfo;
        wire     [7:0]   update_0,update_1,lastinfo;
        wire                    sel_dram,filter;
        wire                    sel_dram;
 
 
        always @(ADDR)
        always @(ADDR)
                case (ADDR[6:4])
                case (ADDR[6:4])
                  3'h0 : maske = 8'h01;
                  3'h0 : maske = 8'h01;
                  3'h1 : maske = 8'h02;
                  3'h1 : maske = 8'h02;
Line 407... Line 429...
                endcase
                endcase
 
 
        assign valid_0 = (( CVALID[7:0] & maske) != 8'h00);
        assign valid_0 = (( CVALID[7:0] & maske) != 8'h00);
        assign valid_1 = ((CVALID[15:8] & maske) != 8'h00);
        assign valid_1 = ((CVALID[15:8] & maske) != 8'h00);
 
 
        assign match_0 = ( TAG0 == ADDR[27:12] );       // 4KB
        assign match_0 = ( TAG0 == ADDR[28:12] );       // 4KB
        assign match_1 = ( TAG1 == ADDR[27:12] );       // 4KB
        assign match_1 = ( TAG1 == ADDR[28:12] );       // 4KB
 
 
        assign CA_HIT = ((valid_0 & match_0) | (valid_1 & match_1)) & ~DC_ILO & CFG[0];
        assign CA_HIT = ((valid_0 & match_0) | (valid_1 & match_1)) & ~DC_ILO & CFG[0] & (sel_dram | KDET);
 
 
        // which SET is written in cache miss ? If both are valid the last used is not taken
        // which SET is written in cache miss ? If both are valid the last used is not taken
        assign select = (valid_1 & valid_0) ? ~((CVALID[23:16] & maske) != 8'h00) : valid_0;    // Last-used field = CVALID[23:16]
        assign select = (valid_1 & valid_0) ? ~((CVALID[23:16] & maske) != 8'h00) : valid_0;    // Last-used field = CVALID[23:16]
 
 
        assign CA_SET = CA_HIT ? (valid_1 & match_1) : select;
        assign CA_SET = CA_HIT ? (valid_1 & match_1) : select;
Line 428... Line 450...
 
 
        assign UPDATE = {lastinfo,update_1,update_0};
        assign UPDATE = {lastinfo,update_1,update_0};
 
 
        assign KILL = clear & CA_HIT & ~CFG[1];         // only if cache is not locked
        assign KILL = clear & CA_HIT & ~CFG[1];         // only if cache is not locked
 
 
        always @(DRAMSZ)        // Size of DRAM
        always @(DRAMSZ or ADDR)        // Size of DRAM
                casex (DRAMSZ)
                case (DRAMSZ)
                   3'b00x : szmaske = 5'h1F;    //   8 MB 32016 Second Processor
                  3'b000 : acc_dram = (ADDR[28:23] == 6'd0);    //   8 MB 32016 Second Processor
        //         3'b001 reserved for Ceres III
                  3'b001 : acc_dram = (ADDR[28:24] == 5'd0);    //  16 MB
                   3'b01x : szmaske = 5'h10;    // 128 MB MCUBE
                  3'b010 : acc_dram = (ADDR[28:25] == 4'd0);    //  32 MB
                default   : szmaske = 5'h00;    // 256 MB NetBSD
                  3'b011 : acc_dram = (ADDR[28:26] == 3'd0);    //  64 MB
 
                  3'b100 : acc_dram = (ADDR[28:27] == 2'd0);    // 128 MB
 
                  3'b101 : acc_dram = ~ADDR[28];                                // 256 MB
 
                  3'b110 : acc_dram =   1'b1;                                   // 512 MB
 
                  3'b111 : acc_dram = ~(ADDR[28:27] == 2'b10);  // 256 MB NetBSD + 128 MB
                endcase
                endcase
 
 
        assign filter   = ((ADDR[27:23] & szmaske) == 5'd0);
        assign sel_dram =  (ADDR[31:29] == 3'd0) & acc_dram & ENDRAM;
        assign sel_dram =  (ADDR[31:28] == 4'd0) & filter & ENDRAM;
 
        assign IO_SPACE = ~sel_dram;                                    // not DRAM or DRAM ist off
        assign IO_SPACE = ~sel_dram;                                    // not DRAM or DRAM ist off
 
 
        assign USE_CA   = ~CI & ~DC_ILO & CFG[0] & ~CFG[1];      // CI ? ILO ? Cache on ? Locked Cache ? 
        assign USE_CA   = ~CI & ~DC_ILO & CFG[0] & ~CFG[1];      // CI ? ILO ? Cache on ? Locked Cache ? 
        assign WB_ACC   = WRITE & MMU_HIT & sel_dram;
        assign WB_ACC   = WRITE & MMU_HIT & sel_dram;
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      7. FILTCMP              Address Filter and Comparator
//      8. FILTCMP              Address Filter and Comparator
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module FILTCMP ( DRAMSZ, RADR, DRAM_A, ADR_EQU, TAGDAT );
module FILTCMP ( DRAMSZ, RADR, DRAM_A, ADR_EQU, TAGDAT );
 
 
        input    [2:0]   DRAMSZ;
        input    [2:0]   DRAMSZ;
        input   [27:4]  RADR,DRAM_A;
        input   [28:4]  RADR,DRAM_A;
 
 
        output                  ADR_EQU;
        output                  ADR_EQU;
        output reg      [27:12] TAGDAT;
        output reg      [28:12] TAGDAT;
 
 
        reg        [27:23]      adram;
        reg        [28:23]      adram;
 
 
        always @(DRAMSZ or RADR)
        always @(DRAMSZ or RADR)
                casex (DRAMSZ)
                casex (DRAMSZ)
                  3'b00x : TAGDAT = {5'd0,RADR[22:12]}; //   8 MB
                  3'b000 : TAGDAT = {6'd0,RADR[22:12]}; //   8 MB
                  3'bx10 : TAGDAT = {3'd0,RADR[24:12]}; //  32 MB
                  3'b001 : TAGDAT = {5'd0,RADR[23:12]}; //  16 MB
                  3'bx11 : TAGDAT = {2'd0,RADR[25:12]}; //  64 MB
                  3'b010 : TAGDAT = {4'd0,RADR[24:12]}; //  32 MB
                  3'b100 : TAGDAT = {1'd0,RADR[26:12]}; // 128 MB
                  3'b011 : TAGDAT = {3'd0,RADR[25:12]}; //  64 MB
                  3'b101 : TAGDAT =       RADR[27:12] ; // 256 MB
                  3'b100 : TAGDAT = {2'd0,RADR[26:12]}; // 128 MB
 
                  3'b101 : TAGDAT = {1'b0,RADR[27:12]}; // 256 MB
 
                  3'b11x : TAGDAT =       RADR[28:12] ; // 512 MB
                endcase
                endcase
 
 
        always @(DRAMSZ or DRAM_A)      // The address comparator is only used in the data cache.
        always @(DRAMSZ or DRAM_A)      // The address comparator is only used in the data cache.
                casex (DRAMSZ)
                casex (DRAMSZ)
                  3'b00x : adram =  5'd0;                                       //   8 MB
                  3'b000 : adram =  6'd0;                                       //   8 MB
                  3'bx10 : adram = {3'd0,DRAM_A[24:23]};        //  32 MB
                  3'b001 : adram = {5'd0,DRAM_A[23]};           //  16 MB
                  3'bx11 : adram = {2'd0,DRAM_A[25:23]};        //  64 MB
                  3'b010 : adram = {4'd0,DRAM_A[24:23]};        //  32 MB
                  3'b100 : adram = {1'd0,DRAM_A[26:23]};        // 128 MB
                  3'b011 : adram = {3'd0,DRAM_A[25:23]};        //  64 MB
                  3'b101 : adram =       DRAM_A[27:23] ;        // 256 MB
                  3'b100 : adram = {2'd0,DRAM_A[26:23]};        // 128 MB
 
                  3'b101 : adram = {1'd0,DRAM_A[27:23]};        // 256 MB
 
                  3'b11x : adram =       DRAM_A[28:23] ;        // 512 MB
                endcase
                endcase
 
 
        assign ADR_EQU = {TAGDAT,RADR[11:4]} == {adram,DRAM_A[22:4]};
        assign ADR_EQU = {TAGDAT,RADR[11:4]} == {adram,DRAM_A[22:4]};
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      8. DCACHE_SM    Data cache state machine
//      9. DCACHE_SM    Data cache state machine
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module DCACHE_SM ( BCLK, BRESET, IO_SPACE, MDONE, IO_READY, MMU_HIT, CA_HIT, READ, WRITE, ZTEST, RMW, CAPDAT, VADR_R, IC_VA,
module DCACHE_SM ( BCLK, BRESET, IO_SPACE, MDONE, IO_READY, MMU_HIT, CA_HIT, READ, WRITE, ZTEST, RMW, CAPDAT, VADR_R, IC_VA,
                                   USE_CA, PTB_WR, PTB_SEL, SEL_PTB1, CPU_OUT, USER, PROT_ERROR, WB_ACC, ENWR, ADR_EQU, IC_PREQ, DMA_CHK, ICTODC,
                                   USE_CA, PTB_WR, PTB_SEL, SEL_PTB1, CPU_OUT, USER, PROT_ERROR, WB_ACC, ENWR, ADR_EQU, IC_PREQ, DMA_CHK, ICTODC,
                                   RWVAL, VIRTUELL, QWATWO,
                                   RWVAL, VIRTUELL, QWATWO,
Line 506... Line 535...
        input   [31:0]   CAPDAT;
        input   [31:0]   CAPDAT;
        input  [31:12]  VADR_R,IC_VA;
        input  [31:12]  VADR_R,IC_VA;
        input                   USE_CA;
        input                   USE_CA;
        input                   PTB_WR,PTB_SEL;
        input                   PTB_WR,PTB_SEL;
        input                   SEL_PTB1;
        input                   SEL_PTB1;
        input  [27:12]  CPU_OUT;        // used for PTB0/1
        input  [28:12]  CPU_OUT;        // used for PTB0/1
        input                   USER;
        input                   USER;
        input                   PROT_ERROR;
        input                   PROT_ERROR;
        input                   WB_ACC;
        input                   WB_ACC;
        input                   ENWR;           // Enable WRITE from DRAM
        input                   ENWR;           // Enable WRITE from DRAM
        input                   ADR_EQU;
        input                   ADR_EQU;
Line 522... Line 551...
        input                   QWATWO;
        input                   QWATWO;
 
 
        output  reg             DRAM_ACC,DRAM_WR;
        output  reg             DRAM_ACC,DRAM_WR;
        output                  IO_ACC,IO_RD,IO_WR;
        output                  IO_ACC,IO_RD,IO_WR;
        output                  PTE_MUX,PD_MUX,PKEEP;
        output                  PTE_MUX,PD_MUX,PKEEP;
        output  [27:0]   PTE_ADR;
        output  [28:0]   PTE_ADR;
        output  [19:0]   PTE_DAT;
        output  [19:0]   PTE_DAT;
        output                  HIT_ALL;
        output                  HIT_ALL;
        output                  ACC_OK;
        output                  ACC_OK;
        output                  ABORT,PROTECT;
        output                  ABORT,PROTECT;
        output   [3:1]  IACC_STAT;
        output   [3:1]  IACC_STAT;
Line 546... Line 575...
        output   [1:0]   PTE_STAT;
        output   [1:0]   PTE_STAT;
 
 
        reg                             IO_WR,IO_RD;
        reg                             IO_WR,IO_RD;
        reg              [1:0]   pl_dat;
        reg              [1:0]   pl_dat;
        reg              [6:0]   new_state;
        reg              [6:0]   new_state;
        reg              [2:0]   cap_dat;        // only for analyse of timing
 
        reg                             mem_done;
        reg                             mem_done;
        reg                             rd_done;
        reg                             rd_done;
        reg              [2:0]   pstate;
        reg              [2:0]   pstate;
        reg                             pte_run_wr;
        reg                             pte_run_wr;
        reg              [1:0]   prot_level1;
        reg              [1:0]   prot_level1;
        reg                             card_flag;
        reg                             card_flag;
        reg        [27:12]      ptb0,ptb1;
        reg        [28:12]      ptb0,ptb1;
        reg                             write_ok;
        reg                             write_ok;
        reg                             icp_acc;
        reg                             icp_acc;
        reg                             pte_modi;
 
        reg              [2:0]   ko_state;
        reg              [2:0]   ko_state;
        reg                             dma_run;
        reg                             dma_run;
        reg                             dma_kdet;
        reg                             dma_kdet;
        reg                             rwv_bit;
        reg                             rwv_bit;
        reg                             prot_i;
        reg                             prot_i;
        reg                             rd_rdy;
        reg                             rd_rdy;
 
 
        wire   [27:12]  ptb10;
        wire   [28:12]  ptb10;
        wire   [31:12]  virtual_adr;
        wire   [31:12]  virtual_adr;
        wire                    io_busy;
        wire                    io_busy;
        wire                    dram_go;
        wire                    dram_go;
        wire                    pte_sel;
        wire                    pte_sel;
        wire                    pte_acc;
        wire                    pte_acc;
Line 592... Line 619...
        wire                    zt_ok;
        wire                    zt_ok;
        wire     [1:0]   acc_level;
        wire     [1:0]   acc_level;
        wire                    user_ptw,wr_ptw;
        wire                    user_ptw,wr_ptw;
        wire                    pte_puls;
        wire                    pte_puls;
 
 
        always @(posedge BCLK) cap_dat <= CAPDAT[2:0];
 
 
 
        // if USER not virtual then ZTEST is quickly done
        // if USER not virtual then ZTEST is quickly done
        assign zugriff = READ | WRITE | (ZTEST & VIRTUELL);
        assign zugriff = READ | WRITE | (ZTEST & VIRTUELL);
        assign mmu_hit_i = MMU_HIT & ~ZTEST;
        assign mmu_hit_i = MMU_HIT & ~ZTEST;
 
 
        // WB_ACC is a successful WRITE access, ICTODC[0] is coherent Logik release : >=3 entries in FIFO
        // WB_ACC is a successful WRITE access, ICTODC[0] is coherent Logik release : >=3 entries in FIFO
Line 652... Line 677...
        // ZTEST logic is for the special case when a write access is crossing page boundaries
        // ZTEST logic is for the special case when a write access is crossing page boundaries
 
 
        assign do_zt = ZTEST & ~icp_acc;
        assign do_zt = ZTEST & ~icp_acc;
 
 
        // 0 is pass , 1 is blocked. RWVAL[0] is 1 if WRVAL. Level 1 can only be blocked, otherwise ABORT or Level 2 is following.
        // 0 is pass , 1 is blocked. RWVAL[0] is 1 if WRVAL. Level 1 can only be blocked, otherwise ABORT or Level 2 is following.
        always @(posedge BCLK) if (mem_done) rwv_bit <= level2 ? ~(cap_dat[2] & (~RWVAL[0] | cap_dat[1])) : 1'b1;
        always @(posedge BCLK) if (mem_done) rwv_bit <= level2 ? ~(CAPDAT[2] & (~RWVAL[0] | CAPDAT[1])) : 1'b1;
 
 
        assign RWVFLAG = VIRTUELL & rwv_bit;
        assign RWVFLAG = VIRTUELL & rwv_bit;
 
 
        assign zt_ok = mem_done & (RWVAL[1] ? (~cap_dat[2] | (RWVAL[0] & ~cap_dat[1]) | level2)  // Level 2 always ok
        assign zt_ok = mem_done & (RWVAL[1] ? (~CAPDAT[2] | (RWVAL[0] & ~CAPDAT[1]) | level2)    // Level 2 always ok
                                                                                : (cap_dat[0] & ~prot_i & level2) );     // "normal" access
                                                                                : (CAPDAT[0] & ~prot_i & level2) );      // "normal" access
 
 
        // PTE access logic, normal state machine
        // PTE access logic, normal state machine
        // Updates to the PTEs are normal WRITE request to DRAM, therefore no MDONE at Write
        // Updates to the PTEs are normal WRITE request to DRAM, therefore no MDONE at Write
 
 
        assign modi  = ~CAPDAT[8] & WRITE & write_ok & ~icp_acc;        // is "1" if the Modified Bit must be set
        assign modi  = ~CAPDAT[8] & WRITE & write_ok & ~icp_acc;        // is "1" if the Modified Bit must be set
        assign refer = CAPDAT[7] | do_zt;       // Assumption "R" Bit is set if RDVAL/WRVAL and page border test
        assign refer = CAPDAT[7] | do_zt;       // Assumption "R" Bit is set if RDVAL/WRVAL and page border test
        assign valid = (do_zt & RWVAL[1]) ? (cap_dat[2] & (cap_dat[1] | ~RWVAL[0]) & cap_dat[0] & level1)
        assign valid = (do_zt & RWVAL[1]) ? (CAPDAT[2] & (CAPDAT[1] | ~RWVAL[0]) & CAPDAT[0] & level1)
                                                                          : (cap_dat[0] & ~prot_i);
                                                                          : (CAPDAT[0] & ~prot_i);
 
 
        always @(posedge BCLK) mem_done <= MDONE & pte_acc;
        always @(posedge BCLK) mem_done <= MDONE & pte_acc;
 
 
        always @(posedge BCLK or negedge BRESET)
        always @(posedge BCLK or negedge BRESET)
                if (!BRESET) pstate <= 3'h0;
                if (!BRESET) pstate <= 3'h0;
Line 695... Line 720...
 
 
        assign pte_acc =  pstate[2];
        assign pte_acc =  pstate[2];
        assign level1  = ~pstate[1];
        assign level1  = ~pstate[1];
        assign level2  =  pstate[1];
        assign level2  =  pstate[1];
 
 
        assign valid_a = (ZTEST & RWVAL[1]) ? (cap_dat[2] & (cap_dat[1] | ~RWVAL[0]) & ~cap_dat[0] & level1)
        assign valid_a = (ZTEST & RWVAL[1]) ? (CAPDAT[2] & (CAPDAT[1] | ~RWVAL[0]) & ~CAPDAT[0] & level1)
                                                                                : ~cap_dat[0];   // not do_zt because of icp_acc in ABORT
                                                                                : ~CAPDAT[0];    // not do_zt because of icp_acc in ABORT
 
 
        assign ABORT   =   mem_done & valid_a & ~icp_acc;
        assign ABORT   =   mem_done & valid_a & ~icp_acc;
        assign PROTECT = ((mem_done & prot_i  & ~icp_acc) | PROT_ERROR) & ~(ZTEST & RWVAL[1]);  // no Protection-Error at RDVAL/WRVAL
        assign PROTECT = ((mem_done & prot_i  & ~icp_acc) | PROT_ERROR) & ~(ZTEST & RWVAL[1]);  // no Protection-Error at RDVAL/WRVAL
 
 
        assign IACC_STAT[1] = mem_done & ~cap_dat[0] & icp_acc;
        assign IACC_STAT[1] = mem_done & ~CAPDAT[0] & icp_acc;
        assign IACC_STAT[2] = level1;
        assign IACC_STAT[2] = level1;
        assign IACC_STAT[3] = mem_done & prot_i & icp_acc;
        assign IACC_STAT[3] = mem_done & prot_i & icp_acc;
 
 
        assign ABO_LEVEL1 = level1;     // is stored in case of ABORT in ADDR_UNIT
        assign ABO_LEVEL1 = level1;     // is stored in case of ABORT in ADDR_UNIT
 
 
Line 799... Line 824...
        assign ACC_OK = ZTEST ? (~VIRTUELL | zt_ok)
        assign ACC_OK = ZTEST ? (~VIRTUELL | zt_ok)
                                                  : (IO_SPACE ? ((IO_ACC & WRITE) | rd_done) : (wr_dram | (READ & MMU_HIT & rd_ende & run_dc)) );
                                                  : (IO_SPACE ? ((IO_ACC & WRITE) | rd_done) : (wr_dram | (READ & MMU_HIT & rd_ende & run_dc)) );
 
 
        // PTB1 and PTB0
        // PTB1 and PTB0
 
 
        always @(posedge BCLK) if (PTB_WR && !PTB_SEL) ptb0 <= CPU_OUT[27:12];
        always @(posedge BCLK) if (PTB_WR && !PTB_SEL) ptb0 <= CPU_OUT;
        always @(posedge BCLK) if (PTB_WR &&  PTB_SEL) ptb1 <= CPU_OUT[27:12];
        always @(posedge BCLK) if (PTB_WR &&  PTB_SEL) ptb1 <= CPU_OUT;
 
 
        always @(posedge BCLK) NEW_PTB <= PTB_WR;                       // to MMU Update Block
        always @(posedge BCLK) NEW_PTB <= PTB_WR;                       // to MMU Update Block
        always @(posedge BCLK) if (PTB_WR) PTB_ONE <= PTB_SEL;
        always @(posedge BCLK) if (PTB_WR) PTB_ONE <= PTB_SEL;
 
 
        assign ptb10 = SEL_PTB1 ? ptb1 : ptb0;
        assign ptb10 = SEL_PTB1 ? ptb1 : ptb0;
Line 815... Line 840...
        assign pte_sel = pte_go ? do_ic_p : icp_acc;
        assign pte_sel = pte_go ? do_ic_p : icp_acc;
 
 
        assign virtual_adr = pte_sel ? IC_VA : VADR_R;
        assign virtual_adr = pte_sel ? IC_VA : VADR_R;
 
 
        // The 2 Address-LSB's : no full access : USE_CA = 0    
        // The 2 Address-LSB's : no full access : USE_CA = 0    
        assign PTE_ADR = rd_level2 ? {CAPDAT[27:12],virtual_adr[21:12],2'b00} : {ptb10,virtual_adr[31:22],2'b00};
        assign PTE_ADR = rd_level2 ? {CAPDAT[28:12],virtual_adr[21:12],2'b00} : {ptb10,virtual_adr[31:22],2'b00};
 
 
        // PTE_DAT[8] is used for update of MMU_RAM.
        // PTE_DAT[8] is used for update of MMU_RAM.
        assign pte_dat_8 = (level2 & WRITE & write_ok & ~icp_acc) | CAPDAT[8];
        assign pte_dat_8 = (level2 & WRITE & write_ok & ~icp_acc) | CAPDAT[8];
        always @(posedge BCLK) pte_modi = pte_dat_8;
        assign PTE_DAT = {4'h3,CAPDAT[15:9],pte_dat_8,1'b1,CAPDAT[6:0]}; // the top 4 bits are Byte-Enable
        assign PTE_DAT = {4'h3,CAPDAT[15:9],pte_modi,1'b1,CAPDAT[6:0]};  // the top 4 bits are Byte-Enable
 
 
 
        // The data for the MMU-RAM : 24 Bits , [6]=Cache Inhibit
        // The data for the MMU-RAM : 24 Bits , [6]=Cache Inhibit
        assign MMU_DIN = {pl_dat,pte_dat_8,CAPDAT[6],CAPDAT[31:12]};
        assign MMU_DIN = {pl_dat,pte_dat_8,CAPDAT[6],CAPDAT[31:12]};
 
 
        // Protection field
        // Protection field
 
 
        always @(posedge BCLK) if (mem_done && (pstate[2:0] == 3'd4)) prot_level1 <= cap_dat[2:1];
        always @(posedge BCLK) if (mem_done && (pstate[2:0] == 3'd4)) prot_level1 <= CAPDAT[2:1];
 
 
        always @(prot_level1 or cap_dat)
        always @(prot_level1 or CAPDAT)
                casex ({prot_level1,cap_dat[2]})
                casex ({prot_level1,CAPDAT[2]})
                  3'b11_x : pl_dat = cap_dat[2:1];
                  3'b11_x : pl_dat = CAPDAT[2:1];
                  3'b10_1 : pl_dat = 2'b10;
                  3'b10_1 : pl_dat = 2'b10;
                  3'b10_0 : pl_dat = cap_dat[2:1];
                  3'b10_0 : pl_dat = CAPDAT[2:1];
                  3'b01_1 : pl_dat = 2'b01;
                  3'b01_1 : pl_dat = 2'b01;
                  3'b01_0 : pl_dat = cap_dat[2:1];
                  3'b01_0 : pl_dat = CAPDAT[2:1];
                  3'b00_x : pl_dat = 2'b00;
                  3'b00_x : pl_dat = 2'b00;
                endcase
                endcase
 
 
        always @(USER or pl_dat)        // is used if no PTE update is neccesary for M-Bit if writing is not allowed
        always @(USER or pl_dat)        // is used if no PTE update is neccesary for M-Bit if writing is not allowed
                casex ({USER,pl_dat})
                casex ({USER,pl_dat})
Line 847... Line 871...
                  3'b0_1x : write_ok = 1'b1;
                  3'b0_1x : write_ok = 1'b1;
                  3'b0_01 : write_ok = 1'b1;
                  3'b0_01 : write_ok = 1'b1;
                  default : write_ok = 1'b0;
                  default : write_ok = 1'b0;
                endcase
                endcase
 
 
        assign acc_level = level2 ? pl_dat : cap_dat[2:1];
        assign acc_level = level2 ? pl_dat : CAPDAT[2:1];
        assign user_ptw = icp_acc ? ICTODC[3] : USER;
        assign user_ptw = icp_acc ? ICTODC[3] : USER;
        assign wr_ptw = ~icp_acc & (WRITE | RMW | (ZTEST & ~RWVAL[1])); // only data cache can write
        assign wr_ptw = ~icp_acc & (WRITE | RMW | (ZTEST & ~RWVAL[1])); // only data cache can write
 
 
        always @(acc_level or user_ptw or wr_ptw)
        always @(acc_level or user_ptw or wr_ptw)
                case (acc_level)
                case (acc_level)

powered by: WebSVN 2.1.0

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