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

Subversion Repositories m32632

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

Only display areas with differences | Details | Blame | View Log

Rev 23 Rev 29
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
// 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:       ICACHE_SM.v
//      Filename:       ICACHE_SM.v
//      Version:        2.0
//      Version:        3.0
//      History:        1.0 first release of 30 Mai 2015
//      History:        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.
// 
// 
// This source file is free software; you can redistribute it 
// This source file is free software; you can redistribute it 
// and/or modify it under the terms of the GNU Lesser General 
// and/or modify it under the terms of the GNU Lesser General 
// Public License as published by the Free Software Foundation;
// Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any 
// either version 2.1 of the License, or (at your option) any 
// later version. 
// later version. 
// 
// 
// This source is distributed in the hope that it will be 
// This source is distributed in the hope that it will be 
// useful, but WITHOUT ANY WARRANTY; without even the implied 
// useful, but WITHOUT ANY WARRANTY; without even the implied 
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
// PURPOSE. See the GNU Lesser General Public License for more 
// PURPOSE. See the GNU Lesser General Public License for more 
// details. 
// details. 
// 
// 
// 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. KOLDETECT    Collision Detection Unit
//      1. KOLDETECT    Collision Detection Unit
//      2. ICACHE_SM    Instruction Cache State Machine
//      2. DMUX                 Data Multiplexor
 
//      3. ICACHE_SM    Instruction Cache State Machine
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      1. KOLDETECT    Collision Detection Unit
//      1. KOLDETECT    Collision Detection Unit
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module KOLDETECT ( BCLK, BRESET, DRAM_WR, CVALID, ADDR, TAG0, TAG1 , CFG , C_VALID, READ_I, ACC_OK, HOLD, KDET, INVAL_A, ENA_HK,
module KOLDETECT ( BCLK, BRESET, DRAM_WR, CVALID, ADDR, TAG0, TAG1 , CFG , C_VALID, READ_I, ACC_OK, HOLD, KDET, INVAL_A, ENA_HK,
                                   NEWCVAL, KOLLISION, STOP_ICRD, RUN_ICRD, KILL, KILLADR, ICTODC, STOP_CINV );
                                   NEWCVAL, KOLLISION, STOP_ICRD, RUN_ICRD, KILL, KILLADR, ICTODC, STOP_CINV );
 
 
        input                   BCLK;
        input                   BCLK;
        input                   BRESET;
        input                   BRESET;
        input                   DRAM_WR;
        input                   DRAM_WR;
        input   [23:0]   CVALID;         // Data from master Valid RAM
        input   [23:0]   CVALID;         // Data from master Valid RAM
        input   [27:4]  ADDR;
        input   [28:4]  ADDR;
        input  [27:12]  TAG0,TAG1;
        input  [28:12]  TAG0,TAG1;
        input    [1:0]   CFG;
        input    [1:0]   CFG;
        input   [23:0]   C_VALID;        // Data from secondary Valid RAM
        input   [23:0]   C_VALID;        // Data from secondary Valid RAM
        input                   READ_I;
        input                   READ_I;
        input                   ACC_OK;
        input                   ACC_OK;
        input                   HOLD;           // active low
        input                   HOLD;           // active low
        input                   KDET;
        input                   KDET;
        input                   INVAL_A;        // Cache Invalidate All
        input                   INVAL_A;        // Cache Invalidate All
        input                   ENA_HK;         // Enable HOLD and Kohaerenz
        input                   ENA_HK;         // Enable HOLD and Kohaerenz
 
 
        output  [23:0]   NEWCVAL;
        output  [23:0]   NEWCVAL;
        output                  KOLLISION;
        output                  KOLLISION;
        output                  STOP_ICRD;
        output                  STOP_ICRD;
        output                  RUN_ICRD;
        output                  RUN_ICRD;
        output                  KILL;
        output                  KILL;
        output  [11:7]  KILLADR;
        output  [11:7]  KILLADR;
        output   [2:0]   ICTODC;
        output   [2:0]   ICTODC;
        output                  STOP_CINV;
        output                  STOP_CINV;
 
 
        reg             [27:4]  addr_r;
        reg             [28:4]  addr_r;
        reg              [7:0]   clear;
        reg              [7:0]   clear;
        reg                             do_koll;
        reg                             do_koll;
        reg              [2:0]   counter;
        reg              [2:0]   counter;
        reg              [1:0]   wpointer,rpointer;
        reg              [1:0]   wpointer,rpointer;
        reg             [35:0]   adrfifo;
        reg             [35:0]   adrfifo;
        reg              [8:0]   fifo_q,fifo_c;
        reg              [8:0]   fifo_q,fifo_c;
        reg              [1:0]   state;
        reg              [1:0]   state;
        reg                             pipe;
        reg                             pipe;
        reg                             do_kill;
        reg                             do_kill;
        reg                             dma;
        reg                             dma;
 
 
        wire    [7:0]    set_0,set_1;
        wire    [7:0]    set_0,set_1;
        wire                    match_0,match_1;
        wire                    match_0,match_1;
        wire                    valid_0,valid_1;
        wire                    valid_0,valid_1;
        wire                    found_0,found_1;
        wire                    found_0,found_1;
        wire                    kolli,dma_kolli;
        wire                    kolli,dma_kolli;
        wire                    last_match;
        wire                    last_match;
        wire                    wr_entry;
        wire                    wr_entry;
        wire    [23:0]   cdaten;
        wire    [23:0]   cdaten;
        wire     [8:0]   kaddr;
        wire     [8:0]   kaddr;
        wire     [7:0]   new_0,new_1;
        wire     [7:0]   new_0,new_1;
        wire                    dma_mode,ic_dma;
        wire                    dma_mode,ic_dma;
        wire                    free,ende;
        wire                    free,ende;
        wire                    init_b;
        wire                    init_b;
 
 
        always @(posedge BCLK) do_koll <= DRAM_WR & CFG[0];      // one cycle pulse, without Cache Enable no collision
        always @(posedge BCLK) do_koll <= DRAM_WR & CFG[0];      // one cycle pulse, without Cache Enable no collision
        always @(posedge BCLK) addr_r <= ADDR;
        always @(posedge BCLK) addr_r <= ADDR;
 
 
        // similar logic like in CA_MATCH
        // similar logic like in CA_MATCH
 
 
        assign set_0 = C_VALID[7:0];
        assign set_0 = C_VALID[7:0];
        assign set_1 = C_VALID[15:8];
        assign set_1 = C_VALID[15:8];
 
 
        assign valid_0 = set_0[addr_r[6:4]];
        assign valid_0 = set_0[addr_r[6:4]];
        assign valid_1 = set_1[addr_r[6:4]];
        assign valid_1 = set_1[addr_r[6:4]];
 
 
        assign match_0 = ( TAG0 == addr_r[27:12] );     // 4KB
        assign match_0 = ( TAG0 == addr_r[28:12] );     // 4KB
        assign match_1 = ( TAG1 == addr_r[27:12] );     // 4KB
        assign match_1 = ( TAG1 == addr_r[28:12] );     // 4KB
 
 
        assign found_0 = valid_0 & match_0;
        assign found_0 = valid_0 & match_0;
        assign found_1 = valid_1 & match_1;
        assign found_1 = valid_1 & match_1;
 
 
        assign kolli = (found_0 | found_1) & ~CFG[1] & do_koll; // Action only if ICACHE is not locked
        assign kolli = (found_0 | found_1) & ~CFG[1] & do_koll; // Action only if ICACHE is not locked
 
 
        assign KOLLISION = (found_0 | found_1) & do_koll;       // to Statistik Modul, Register there
        assign KOLLISION = (found_0 | found_1) & do_koll;       // to Statistik Modul, Register there
 
 
        assign dma_kolli = (found_0 | found_1) & ~CFG[1] & CFG[0];
        assign dma_kolli = (found_0 | found_1) & ~CFG[1] & CFG[0];
 
 
        // the FIFO with 4 entries :
        // the FIFO with 4 entries :
        assign init_b = CFG[0] & ~INVAL_A;       // initialise if CINV A too
        assign init_b = CFG[0] & ~INVAL_A;       // initialise if CINV A too
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
                if (!init_b) wpointer <= 2'b00;
                if (!init_b) wpointer <= 2'b00;
                        else
                        else
                                wpointer <= wpointer + {1'b0,wr_entry};
                                wpointer <= wpointer + {1'b0,wr_entry};
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
                if (!init_b) rpointer <= 2'b00;
                if (!init_b) rpointer <= 2'b00;
                        else
                        else
                                rpointer <= rpointer + {1'b0,do_kill};
                                rpointer <= rpointer + {1'b0,do_kill};
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
          begin
          begin
                if (wr_entry && (wpointer == 2'b00)) adrfifo[8:0]   <= {addr_r[11:4],found_1};
                if (wr_entry && (wpointer == 2'b00)) adrfifo[8:0]   <= {addr_r[11:4],found_1};
                if (wr_entry && (wpointer == 2'b01)) adrfifo[17:9]  <= {addr_r[11:4],found_1};
                if (wr_entry && (wpointer == 2'b01)) adrfifo[17:9]  <= {addr_r[11:4],found_1};
                if (wr_entry && (wpointer == 2'b10)) adrfifo[26:18] <= {addr_r[11:4],found_1};
                if (wr_entry && (wpointer == 2'b10)) adrfifo[26:18] <= {addr_r[11:4],found_1};
                if (wr_entry && (wpointer == 2'b11)) adrfifo[35:27] <= {addr_r[11:4],found_1};
                if (wr_entry && (wpointer == 2'b11)) adrfifo[35:27] <= {addr_r[11:4],found_1};
          end
          end
 
 
        always @(adrfifo or rpointer)
        always @(adrfifo or rpointer)
                case (rpointer)
                case (rpointer)
                  2'b00 : fifo_q = adrfifo[8:0];
                  2'b00 : fifo_q = adrfifo[8:0];
                  2'b01 : fifo_q = adrfifo[17:9];
                  2'b01 : fifo_q = adrfifo[17:9];
                  2'b10 : fifo_q = adrfifo[26:18];
                  2'b10 : fifo_q = adrfifo[26:18];
                  2'b11 : fifo_q = adrfifo[35:27];
                  2'b11 : fifo_q = adrfifo[35:27];
                endcase
                endcase
 
 
        always @(adrfifo or wpointer)   // for Match of last entry use wpointer
        always @(adrfifo or wpointer)   // for Match of last entry use wpointer
                case (wpointer)
                case (wpointer)
                  2'b01 : fifo_c = adrfifo[8:0];
                  2'b01 : fifo_c = adrfifo[8:0];
                  2'b10 : fifo_c = adrfifo[17:9];
                  2'b10 : fifo_c = adrfifo[17:9];
                  2'b11 : fifo_c = adrfifo[26:18];
                  2'b11 : fifo_c = adrfifo[26:18];
                  2'b00 : fifo_c = adrfifo[35:27];
                  2'b00 : fifo_c = adrfifo[35:27];
                endcase
                endcase
 
 
        // Control
        // Control
 
 
        assign last_match = counter[2] & (fifo_c == {addr_r[11:4],found_1});    // if Match with last Entry no new Entry
        assign last_match = counter[2] & (fifo_c == {addr_r[11:4],found_1});    // if Match with last Entry no new Entry
 
 
        assign wr_entry = kolli & ~last_match;
        assign wr_entry = kolli & ~last_match;
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
                casex ({init_b,wr_entry,do_kill,counter})
                casex ({init_b,wr_entry,do_kill,counter})
                  6'b0_xx_xxx : counter <= 3'b000;
                  6'b0_xx_xxx : counter <= 3'b000;
                  6'b1_00_xxx : counter <= counter;
                  6'b1_00_xxx : counter <= counter;
                  6'b1_11_xxx : counter <= counter;
                  6'b1_11_xxx : counter <= counter;
                  6'b1_10_000 : counter <= 3'b100;
                  6'b1_10_000 : counter <= 3'b100;
                  6'b1_10_1xx : counter <= (counter[1:0] == 2'b11) ? 3'b111 : {counter[2],(counter[1:0] + 2'b01)};        // Overflow avoid
                  6'b1_10_1xx : counter <= (counter[1:0] == 2'b11) ? 3'b111 : {counter[2],(counter[1:0] + 2'b01)};        // Overflow avoid
                  6'b1_01_1xx : counter <= (counter[1:0] == 2'b00) ? 3'b000 : {counter[2],(counter[1:0] + 2'b11)};
                  6'b1_01_1xx : counter <= (counter[1:0] == 2'b00) ? 3'b000 : {counter[2],(counter[1:0] + 2'b11)};
                  default         : counter <= counter;
                  default         : counter <= counter;
                endcase
                endcase
 
 
        // DMA Access
        // DMA Access
        always @(posedge BCLK) dma <= ~HOLD;    // there is only one FF for this , from here to DCACHE
        always @(posedge BCLK) dma <= ~HOLD;    // there is only one FF for this , from here to DCACHE
 
 
        // Controlling of ICACHE
        // Controlling of ICACHE
 
 
        assign free = (~READ_I | ACC_OK) & ENA_HK;      // switch off if CINV
        assign free = (~READ_I | ACC_OK) & ENA_HK;      // switch off if CINV
 
 
        always @(posedge BCLK)                                  //  state[1]  state[0]
        always @(posedge BCLK)                                  //  state[1]  state[0]
                casex ({BRESET,dma,counter[2],free,ende,STOP_ICRD,dma_mode})
                casex ({BRESET,dma,counter[2],free,ende,STOP_ICRD,dma_mode})
                  7'b0_xx_xx_xx : state <= 2'b00;
                  7'b0_xx_xx_xx : state <= 2'b00;
                  7'b1_00_xx_00 : state <= 2'b00;
                  7'b1_00_xx_00 : state <= 2'b00;
                  7'b1_01_1x_00 : state <= 2'b10;       // Start of DCACHE Kohaerenz
                  7'b1_01_1x_00 : state <= 2'b10;       // Start of DCACHE Kohaerenz
                  7'b1_1x_1x_00 : state <= 2'b11;       // Start of DMA
                  7'b1_1x_1x_00 : state <= 2'b11;       // Start of DMA
        //
        //
                  7'b1_xx_x0_10 : state <= 2'b10;       // without "ende" it stays as is
                  7'b1_xx_x0_10 : state <= 2'b10;       // without "ende" it stays as is
                  7'b1_0x_x1_10 : state <= 2'b00;       // DMA is not active
                  7'b1_0x_x1_10 : state <= 2'b00;       // DMA is not active
                  7'b1_1x_x1_10 : state <= 2'b11;       // to DMA !
                  7'b1_1x_x1_10 : state <= 2'b11;       // to DMA !
        //
        //
                  7'b1_00_xx_11 : state <= 2'b00;
                  7'b1_00_xx_11 : state <= 2'b00;
                  7'b1_01_xx_11 : state <= 2'b10;
                  7'b1_01_xx_11 : state <= 2'b10;
                  7'b1_1x_xx_11 : state <= 2'b11;
                  7'b1_1x_xx_11 : state <= 2'b11;
                  default               : state <= 2'b00;
                  default               : state <= 2'b00;
                endcase
                endcase
 
 
        assign STOP_ICRD = state[1];    // used for Multiplexer
        assign STOP_ICRD = state[1];    // used for Multiplexer
        assign dma_mode  = state[0];     // internal Multiplexer
        assign dma_mode  = state[0];     // internal Multiplexer
 
 
        assign STOP_CINV = state[1] & ~ENA_HK;  // stops CINV if DMA access or Kohaerenz access
        assign STOP_CINV = state[1] & ~ENA_HK;  // stops CINV if DMA access or Kohaerenz access
 
 
        assign ende = (counter[1:0] == 2'b00) & do_kill;
        assign ende = (counter[1:0] == 2'b00) & do_kill;
 
 
        assign ic_dma = STOP_ICRD & dma_mode;   // Signal to DCACHE that ICACHE has stoped
        assign ic_dma = STOP_ICRD & dma_mode;   // Signal to DCACHE that ICACHE has stoped
 
 
        always @(posedge BCLK) pipe <= STOP_ICRD;
        always @(posedge BCLK) pipe <= STOP_ICRD;
 
 
        assign RUN_ICRD = ~(STOP_ICRD | pipe);  // Release for IC_READ
        assign RUN_ICRD = ~(STOP_ICRD | pipe);  // Release for IC_READ
 
 
        always @(posedge BCLK) do_kill <= STOP_ICRD & ~dma_mode & ~do_kill;     // Write pulse in Cache Valid RAM, 1 cycle on, 1 cycle off
        always @(posedge BCLK) do_kill <= STOP_ICRD & ~dma_mode & ~do_kill;     // Write pulse in Cache Valid RAM, 1 cycle on, 1 cycle off
 
 
        assign KILL = do_kill | (KDET & dma_kolli);
        assign KILL = do_kill | (KDET & dma_kolli);
 
 
        // Valid Daten prepare : different sources for DMA and DCACHE Kohaerenz
        // Valid Daten prepare : different sources for DMA and DCACHE Kohaerenz
 
 
        assign cdaten = dma_mode ? C_VALID : CVALID;
        assign cdaten = dma_mode ? C_VALID : CVALID;
        assign kaddr  = dma_mode ? {addr_r[11:4],found_1} : fifo_q;
        assign kaddr  = dma_mode ? {addr_r[11:4],found_1} : fifo_q;
 
 
        assign KILLADR = kaddr[8:4];
        assign KILLADR = kaddr[8:4];
 
 
        always @(kaddr)
        always @(kaddr)
                case (kaddr[3:1])
                case (kaddr[3:1])
                  3'h0 : clear = 8'hFE;
                  3'h0 : clear = 8'hFE;
                  3'h1 : clear = 8'hFD;
                  3'h1 : clear = 8'hFD;
                  3'h2 : clear = 8'hFB;
                  3'h2 : clear = 8'hFB;
                  3'h3 : clear = 8'hF7;
                  3'h3 : clear = 8'hF7;
                  3'h4 : clear = 8'hEF;
                  3'h4 : clear = 8'hEF;
                  3'h5 : clear = 8'hDF;
                  3'h5 : clear = 8'hDF;
                  3'h6 : clear = 8'hBF;
                  3'h6 : clear = 8'hBF;
                  3'h7 : clear = 8'h7F;
                  3'h7 : clear = 8'h7F;
                endcase
                endcase
 
 
        assign new_0 = kaddr[0] ? cdaten[7:0] : (cdaten[7:0] & clear);
        assign new_0 = kaddr[0] ? cdaten[7:0] : (cdaten[7:0] & clear);
        assign new_1 = kaddr[0] ? (cdaten[15:8] & clear) : cdaten[15:8];
        assign new_1 = kaddr[0] ? (cdaten[15:8] & clear) : cdaten[15:8];
 
 
        assign NEWCVAL = {cdaten[23:16],new_1,new_0};
        assign NEWCVAL = {cdaten[23:16],new_1,new_0};
 
 
        // multiple signals are needed in DCACHE :
        // multiple signals are needed in DCACHE :
        assign ICTODC = {dma,ic_dma,~(counter[2:1] == 2'b11)};
        assign ICTODC = {dma,ic_dma,~(counter[2:1] == 2'b11)};
 
 
endmodule
endmodule
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//      2. ICACHE_SM    Instruction Cache State Machine
//      2. DMUX         Data Multiplexor
 
//
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
module DMUX ( DRAM_Q, ADDR, CAP_Q );
 
 
 
        input  [127:0]   DRAM_Q;
 
        input    [3:2]  ADDR;
 
 
 
        output  reg     [31:0]   CAP_Q;
 
 
 
        always @(ADDR or DRAM_Q)
 
          case (ADDR)
 
            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
 
 
 
endmodule
 
 
 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
//
 
//      3. ICACHE_SM    Instruction Cache State Machine
//
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
module ICACHE_SM ( BCLK, BRESET, IO_SPACE, MDONE, IO_READY, MMU_HIT, CA_HIT, READ, PTE_ACC,
module ICACHE_SM ( BCLK, BRESET, IO_SPACE, MDONE, IO_READY, MMU_HIT, CA_HIT, READ, PTE_ACC,
                                   USE_CA, PTB_WR, PTB_SEL, USER, PROT_ERROR,
                                   USE_CA, PTB_WR, PTB_SEL, USER, PROT_ERROR,
                                   DRAM_ACC, IO_RD, IO_ACC, IC_PREQ, ACC_OK, HIT_ALL, CUPDATE, AUX_DAT, NEW_PTB, PTB_ONE );
                                   DRAM_ACC, IO_RD, IO_ACC, IC_PREQ, ACC_OK, HIT_ALL, CUPDATE, AUX_DAT, NEW_PTB, PTB_ONE );
 
 
        input                   BCLK;
        input                   BCLK;
        input                   BRESET;
        input                   BRESET;
        input                   IO_SPACE;
        input                   IO_SPACE;
        input                   MDONE;          // Memory Done : Feedback from DRAM Controller, BCLK aligned
        input                   MDONE;          // Memory Done : Feedback from DRAM Controller, BCLK aligned
        input                   IO_READY;
        input                   IO_READY;
        input                   MMU_HIT,CA_HIT;
        input                   MMU_HIT,CA_HIT;
        input                   READ;
        input                   READ;
        input                   PTE_ACC;
        input                   PTE_ACC;
        input                   USE_CA;
        input                   USE_CA;
        input                   PTB_WR,PTB_SEL;
        input                   PTB_WR,PTB_SEL;
        input                   USER;
        input                   USER;
        input                   PROT_ERROR;
        input                   PROT_ERROR;
 
 
        output  reg             DRAM_ACC,IO_RD;
        output  reg             DRAM_ACC,IO_RD;
        output                  IO_ACC;
        output                  IO_ACC;
        output                  IC_PREQ;
        output                  IC_PREQ;
        output                  ACC_OK;
        output                  ACC_OK;
        output                  HIT_ALL;
        output                  HIT_ALL;
        output                  CUPDATE;
        output                  CUPDATE;
        output                  AUX_DAT;
        output                  AUX_DAT;
        output  reg             NEW_PTB,PTB_ONE;
        output  reg             NEW_PTB,PTB_ONE;
 
 
        reg              [3:0]   new_state;
        reg              [3:0]   new_state;
        reg                             rd_done;
        reg                             rd_done;
        reg                             card_flag;
        reg                             card_flag;
        reg                             rd_rdy;
        reg                             rd_rdy;
 
 
        wire                    io_busy;
        wire                    io_busy;
        wire                    dram_go;
        wire                    dram_go;
        wire                    rd_ende;
        wire                    rd_ende;
        wire                    do_ca_rd;
        wire                    do_ca_rd;
 
 
// Cycle :                      /-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_
// Cycle :                      /-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_/-\_
// Access :                     _/-----------------------------------\__
// Access :                     _/-----------------------------------\__
// State Machine :  ____/----------------------------\______
// State Machine :  ____/----------------------------\______
//                                                      Busy status ...
//                                                      Busy status ...
 
 
        assign rd_ende = CA_HIT | rd_rdy;       // CA_HIT only if Cache activ !
        assign rd_ende = CA_HIT | rd_rdy;       // CA_HIT only if Cache activ !
 
 
        always @(        READ           // only READ , global control
        always @(        READ           // only READ , global control
                          or PROT_ERROR // is not allowed !
                          or PROT_ERROR // is not allowed !
                        //
                        //
                          or IO_SPACE   // indicates access in the IO_WELT
                          or IO_SPACE   // indicates access in the IO_WELT
                          or io_busy    // is already active ?
                          or io_busy    // is already active ?
                        //
                        //
                          or MMU_HIT    // Hit in the MMU , now only a READ can be active
                          or MMU_HIT    // Hit in the MMU , now only a READ can be active
                          or rd_ende    // Cache Hit
                          or rd_ende    // Cache Hit
                          or DRAM_ACC   // DRAM Access running
                          or DRAM_ACC   // DRAM Access running
                        //
                        //
                          or PTE_ACC )  // PTE Access running
                          or PTE_ACC )  // PTE Access running
                        //                                #_#                      #_#                                          #_#
                        //                                #_#                      #_#                                          #_#
                casex ({READ,PROT_ERROR,IO_SPACE,io_busy,MMU_HIT,rd_ende,DRAM_ACC,PTE_ACC})
                casex ({READ,PROT_ERROR,IO_SPACE,io_busy,MMU_HIT,rd_ende,DRAM_ACC,PTE_ACC})
                // MMU Miss : PTE load from memory 
                // MMU Miss : PTE load from memory 
                  8'b10_xx_0xx_0 : new_state = 4'b0100; // start PTE access
                  8'b10_xx_0xx_0 : new_state = 4'b0100; // start PTE access
                // IO-Address selected : external access starts if not already BUSY
                // IO-Address selected : external access starts if not already BUSY
                  8'b10_10_1xx_x : new_state = 4'b0001;
                  8'b10_10_1xx_x : new_state = 4'b0001;
                // DRAM Access : Cache Miss at READ
                // DRAM Access : Cache Miss at READ
                  8'b10_0x_100_x : new_state = 4'b1010; // can start directly
                  8'b10_0x_100_x : new_state = 4'b1010; // can start directly
                  default                : new_state = 4'b0;
                  default                : new_state = 4'b0;
                endcase
                endcase
 
 
        assign IO_ACC   = new_state[0];  // to load the Register for Data and Addr
        assign IO_ACC   = new_state[0];  // to load the Register for Data and Addr
        assign dram_go  = new_state[1];
        assign dram_go  = new_state[1];
        assign IC_PREQ  = new_state[2]; // MMU to DCACHE !
        assign IC_PREQ  = new_state[2]; // MMU to DCACHE !
        assign do_ca_rd = new_state[3];
        assign do_ca_rd = new_state[3];
 
 
        assign HIT_ALL = MMU_HIT & CA_HIT;      // for Update "Last-Set" , MMU_HIT contains ZUGRIFF
        assign HIT_ALL = MMU_HIT & CA_HIT;      // for Update "Last-Set" , MMU_HIT contains ZUGRIFF
 
 
        always @(posedge BCLK or negedge BRESET)
        always @(posedge BCLK or negedge BRESET)
                if (!BRESET) card_flag <= 1'b0;
                if (!BRESET) card_flag <= 1'b0;
                        else card_flag <= (do_ca_rd & ~rd_rdy) | (card_flag & ~MDONE);
                        else card_flag <= (do_ca_rd & ~rd_rdy) | (card_flag & ~MDONE);
 
 
        assign CUPDATE = card_flag & USE_CA & MDONE;    // USE_CA = ~CI & ~LDC;
        assign CUPDATE = card_flag & USE_CA & MDONE;    // USE_CA = ~CI & ~LDC;
 
 
        always @(posedge BCLK) rd_rdy <= card_flag & MDONE;
        always @(posedge BCLK) rd_rdy <= card_flag & MDONE;
 
 
        // The cache RAM can not provide fast enough the data after an Update. In this case a secondary data path is activated
        // The cache RAM can not provide fast enough the data after an Update. In this case a secondary data path is activated
        assign AUX_DAT = rd_rdy;
        assign AUX_DAT = rd_rdy;
 
 
        // DRAM Interface :
        // DRAM Interface :
 
 
        always @(posedge BCLK) if (dram_go) DRAM_ACC <= 1'b1;
        always @(posedge BCLK) if (dram_go) DRAM_ACC <= 1'b1;
                                                         else
                                                         else
                                                                DRAM_ACC <= DRAM_ACC & ~MDONE & BRESET;
                                                                DRAM_ACC <= DRAM_ACC & ~MDONE & BRESET;
        // IO Interface :
        // IO Interface :
 
 
        always @(posedge BCLK)
        always @(posedge BCLK)
          begin
          begin
                if (IO_ACC) IO_RD <= READ;  else IO_RD <= IO_RD & ~IO_READY & BRESET;
                if (IO_ACC) IO_RD <= READ;  else IO_RD <= IO_RD & ~IO_READY & BRESET;
          end
          end
 
 
        assign io_busy = IO_RD | rd_done;       // access is gone in next clock cycle, therefore blocked with "rd_done"
        assign io_busy = IO_RD | rd_done;       // access is gone in next clock cycle, therefore blocked with "rd_done"
 
 
        always @(posedge BCLK) rd_done <= READ & IO_READY;      // For READ one clock later for data to come through
        always @(posedge BCLK) rd_done <= READ & IO_READY;      // For READ one clock later for data to come through
 
 
        // global feedback to opcode fetch unit : you can continue
        // global feedback to opcode fetch unit : you can continue
 
 
        assign ACC_OK = IO_SPACE ? rd_done : (READ & MMU_HIT & rd_ende);
        assign ACC_OK = IO_SPACE ? rd_done : (READ & MMU_HIT & rd_ende);
 
 
        // PTB1 und PTB0
        // PTB1 und PTB0
 
 
        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;
 
 
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

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