Line 38... |
Line 38... |
// 3. DCA_CONTROL Data cache valid memory update and initalization controller
|
// 3. DCA_CONTROL Data cache valid memory update and initalization controller
|
// 4. MMU_MATCH MMU virtual address match detector
|
// 4. MMU_MATCH MMU virtual address match detector
|
// 5. CA_MATCH Cache tag match detector
|
// 5. CA_MATCH Cache tag match detector
|
// 6. DCACHE_SM Data cache state machine
|
// 6. DCACHE_SM Data cache state machine
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 1. DEBUG_AE Debug unit for address compare in data cache
|
// 1. 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;
|
|
|
input READ,WRITE;
|
input READ,WRITE;
|
Line 87... |
Line 87... |
& (VIRTUELL ? virt_adr : real_adr) & page_adr // address
|
& (VIRTUELL ? virt_adr : real_adr) & page_adr // address
|
& byte_en; // Byte Enable
|
& byte_en; // Byte Enable
|
|
|
endmodule
|
endmodule
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 2. MMU_UP MMU memory update and initalization controller
|
// 2. 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 );
|
|
|
input BCLK;
|
input BCLK;
|
input BRESET;
|
input BRESET;
|
Line 117... |
Line 117... |
wire [15:0] new_val;
|
wire [15:0] new_val;
|
|
|
assign WE_MV = wr_flag | WR_MRAM | IVAR; // write on falling edge BCLK
|
assign WE_MV = wr_flag | WR_MRAM | IVAR; // write on falling edge BCLK
|
assign RADR_MV = run_over ? count : VADR;
|
assign RADR_MV = run_over ? count : VADR;
|
assign WADR_MV = wr_flag ? (count - 4'b0001) : VADR_R;
|
assign WADR_MV = wr_flag ? (count - 4'b0001) : VADR_R;
|
assign DAT_MV = wr_flag ? {MVALID[31:16],new_val} : UPDATE; // Only the matching entries are clear
|
assign DAT_MV = wr_flag ? {MVALID[31:16],new_val} : UPDATE; // Only the matching entries are cleared : PTB0/PTB1
|
|
|
// [31:16] Address-Space memory, [15:0] Valid memory
|
// [31:16] Address-Space memory, [15:0] Valid memory
|
assign new_val = neue_ptb ? (PTB1 ? (MVALID[15:0] & ~MVALID[31:16]) : (MVALID[15:0] & MVALID[31:16]
|
assign new_val = neue_ptb ? (PTB1 ? (MVALID[15:0] & ~MVALID[31:16]) : (MVALID[15:0] & MVALID[31:16])) : 16'h0;
|
|
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) neue_ptb <= 1'b0;
|
if (!BRESET) neue_ptb <= 1'b0;
|
else neue_ptb <= NEW_PTB | (neue_ptb & run_over);
|
else neue_ptb <= NEW_PTB | (neue_ptb & run_over);
|
|
|
Line 138... |
Line 138... |
|
|
assign NEW_PTB_RUN = wr_flag; // Info to Op-Dec
|
assign NEW_PTB_RUN = wr_flag; // Info to Op-Dec
|
|
|
endmodule
|
endmodule
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 3. DCA_CONTROL Data cache valid memory update and initalization controller
|
// 3. 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,
|
module DCA_CONTROL ( BCLK, MCLK, BRESET, CUPDATE, DRAM_ACC, CA_SET, HIT_ALL, WRCFG, VADR_R, UPDATE, INVAL_A, WRITE,
|
WCTRL, KILL, WRCRAM0, WRCRAM1, WE_CV, WADR_CV, DAT_CV, INIT_CA_RUN, WRSET0, WRSET1 );
|
WCTRL, KILL, WRCRAM0, WRCRAM1, WE_CV, WADR_CV, DAT_CV, INIT_CA_RUN, WRSET0, WRSET1 );
|
|
|
input BCLK;
|
input BCLK;
|
input MCLK;
|
input MCLK;
|
input BRESET;
|
input BRESET;
|
Line 158... |
Line 158... |
input WRCFG; // static signal : GND or VDD
|
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 inh
|
input [1:0] WCTRL; // [1] : Read Burst Signal from DRAM controller, MCLK aligned. [0] : Cache inhibit
|
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 226... |
Line 226... |
// count at zero , ref Wert
|
// count at zero , ref Wert
|
// 1 : --- always on 5 : 100 001
|
// 1 : --- always on 5 : 100 001
|
// 2 : 001 000 6 : 101 010
|
// 2 : 001 000 6 : 101 010
|
// 3 : 010 010 7 : 110 011
|
// 3 : 010 010 7 : 110 011
|
// 4 : 011 000 8 : 111 100
|
// 4 : 011 000 8 : 111 100
|
always @(posedge MCLK) if (zero) refer <= {(count == 3'd7),((count == 3'd5) | (count[1:0] == 2'b10)
|
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;
|
always @(posedge MCLK) wr_puls <= (count == refer) | WRCFG;
|
|
|
endmodule
|
endmodule
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 4. MMU_MATCH MMU virtual address match detector
|
// 4. 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 );
|
|
|
input USER;
|
input USER;
|
input READ;
|
input READ;
|
Line 287... |
Line 287... |
4'hF : maske = 16'h8000;
|
4'hF : maske = 16'h8000;
|
endcase
|
endcase
|
|
|
assign VIRTUELL = USER ? MCR_FLAGS[0] : MCR_FLAGS[1];
|
assign VIRTUELL = USER ? MCR_FLAGS[0] : MCR_FLAGS[1];
|
|
|
assign adr_space = IVAR[1] ? IVAR[0] : (MCR_FLAGS[2] & USER); // adr_space = IVARx ? 1 or 0 : DualS
|
assign adr_space = IVAR[1] ? IVAR[0] : (MCR_FLAGS[2] & USER); // adr_space = IVARx ? 1 or 0 : DualSpace & TU
|
|
|
assign as_sorte = ((MVALID[31:16] & maske) != 16'h0);
|
assign as_sorte = ((MVALID[31:16] & maske) != 16'h0);
|
|
|
assign match = (VADR_R[31:20] == MMU_VA[31:20]) & (adr_space == as_sorte) & ((MVALID[15:0] & maske)
|
assign match = (VADR_R[31:20] == MMU_VA[31:20]) & (adr_space == as_sorte) & ((MVALID[15:0] & maske) != 16'h0000);
|
|
|
assign alles_ok = match & ( ~WRITE | MMU_VA[17] ) & ~PROT_ERROR; // Modified - Flag : reload the PT
|
assign alles_ok = match & ( ~WRITE | MMU_VA[17] ) & ~PROT_ERROR; // Modified - Flag : reload the PTE
|
|
|
// if MMU_HIT = 0 then there is no Write-Buffer access abd no update of cache !
|
// if MMU_HIT = 0 then there is no Write-Buffer access abd no update of cache !
|
assign MMU_HIT = zugriff ? ( VIRTUELL ? alles_ok : 1'b1 ) : 1'b0 ; // MMU off : then always HIT
|
assign MMU_HIT = zugriff ? ( VIRTUELL ? alles_ok : 1'b1 ) : 1'b0 ; // MMU off : then always HIT
|
|
|
assign val_bits = IVAR[1] ? (MVALID[15:0] & (match ? ~maske : 16'hFFFF)) : (MVALID[15:0] | maske);
|
assign val_bits = IVAR[1] ? (MVALID[15:0] & (match ? ~maske : 16'hFFFF)) : (MVALID[15:0] | maske);
|
assign as_bits = IVAR[1] ? MVALID[31:16] : (adr_space ? (MVALID[31:16] | maske) : (MVALID[31:16] &
|
assign as_bits = IVAR[1] ? MVALID[31:16] : (adr_space ? (MVALID[31:16] | maske) : (MVALID[31:16] & ~maske));
|
|
|
assign UPDATE = {as_bits,val_bits};
|
assign UPDATE = {as_bits,val_bits};
|
|
|
assign ena_prot = zugriff & VIRTUELL & match;
|
assign ena_prot = zugriff & VIRTUELL & match;
|
|
|
Line 319... |
Line 319... |
assign CI = VIRTUELL & MMU_VA[16];
|
assign CI = VIRTUELL & MMU_VA[16];
|
assign SEL_PTB1 = adr_space; // For PTE update
|
assign SEL_PTB1 = adr_space; // For PTE update
|
|
|
endmodule
|
endmodule
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 5. CA_MATCH Cache tag match detector
|
// 5. CA_MATCH Cache tag match detector
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module CA_MATCH ( CVALID, IOSEL, ADDR, TAG0, TAG1, CFG, WRITE, MMU_HIT, CI, INVAL_L, KDET, ENDRAM, D
|
module CA_MATCH ( CVALID, IOSEL, 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 [3:0] IOSEL;
|
input [3:0] IOSEL;
|
input [27:4] ADDR;
|
input [27:4] ADDR;
|
Line 378... |
Line 378... |
assign match_1 = ( TAG1 == ADDR[27:12] ); // 4KB
|
assign match_1 = ( TAG1 == ADDR[27: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];
|
|
|
// 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 f
|
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;
|
|
|
assign clear = INVAL_L | KDET; // INVAL_L is from CINV
|
assign clear = INVAL_L | KDET; // INVAL_L is from CINV
|
|
|
assign update_0 = CA_SET ? CVALID[7:0] : (clear ? (CVALID[7:0] & ~maske) : (CVALID[7:0] | maske));
|
assign update_0 = CA_SET ? CVALID[7:0] : (clear ? (CVALID[7:0] & ~maske) : (CVALID[7:0] | maske));
|
assign update_1 = CA_SET ? (clear ? (CVALID[15:8] & ~maske) : (CVALID[15:8] | maske)) : CVALID[15:8
|
assign update_1 = CA_SET ? (clear ? (CVALID[15:8] & ~maske) : (CVALID[15:8] | maske)) : CVALID[15:8];
|
|
|
assign lastinfo = CA_HIT ? (CA_SET ? (CVALID[23:16] | maske) : (CVALID[23:16] & ~maske)) : CVALID[2
|
assign lastinfo = CA_HIT ? (CA_SET ? (CVALID[23:16] | maske) : (CVALID[23:16] & ~maske)) : CVALID[23:16];
|
|
|
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
|
|
|
Line 400... |
Line 400... |
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
|
|
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
//
|
//
|
// 6. DCACHE_SM Data cache state machine
|
// 6. DCACHE_SM Data cache state machine
|
//
|
//
|
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
module DCACHE_SM ( BCLK, BRESET, IO_SPACE, MDONE, IO_READY, MMU_HIT, CA_HIT, READ, WRITE, ZTEST, RMW
|
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,
|
USE_CA, PTB_WR, PTB_SEL, SEL_PTB1, CPU_OUT, USER, PROT_ERROR, WB_ACC, ENWR, ADR_EQU, IC_PREQ, FILLRAM, ICTODC,
|
RWVAL, VIRTUELL,
|
RWVAL, VIRTUELL,
|
DRAM_ACC, DRAM_WR, IO_ACC, IO_RD, IO_WR, PTE_MUX, PD_MUX, PKEEP, PTE_ADR, PTE_DAT, HIT_ALL, A
|
DRAM_ACC, DRAM_WR, IO_ACC, IO_RD, IO_WR, PTE_MUX, PD_MUX, PKEEP, PTE_ADR, PTE_DAT, HIT_ALL, ACC_OK,
|
ABORT, PROTECT, IACC_STAT, ABO_LEVEL1, WR_MRAM, CUPDATE, AUX_DAT, NEW_PTB, PTB_ONE, MMU_DIN,
|
ABORT, PROTECT, IACC_STAT, ABO_LEVEL1, WR_MRAM, CUPDATE, AUX_DAT, NEW_PTB, PTB_ONE, MMU_DIN, IC_SIGS, KOMUX,
|
KDET, DMA_MUX, HLDA, RWVFLAG, PTE_STAT );
|
KDET, DMA_MUX, HLDA, RWVFLAG, PTE_STAT );
|
|
|
input BCLK;
|
input BCLK;
|
input BRESET;
|
input BRESET;
|
input IO_SPACE;
|
input IO_SPACE;
|
Line 516... |
Line 516... |
// 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
|
assign wr_req = WB_ACC & ((ENWR & ICTODC[0]) | (DRAM_WR & ADR_EQU)); // release done by DRAM signal
|
assign wr_req = WB_ACC & ((ENWR & ICTODC[0]) | (DRAM_WR & ADR_EQU)); // release done by DRAM signal ENWR
|
|
|
assign rd_ende = CA_HIT | rd_rdy; // CA_HIT only when Cache activ !
|
assign rd_ende = CA_HIT | rd_rdy; // CA_HIT only when Cache activ !
|
|
|
always @( zugriff // READ or WRITE or ZTEST , global control
|
always @( zugriff // READ or WRITE or ZTEST , global control
|
or PROT_ERROR // must not be
|
or PROT_ERROR // must not be
|
Line 539... |
Line 539... |
or IC_PREQ // PTE Request from ICACHE
|
or IC_PREQ // PTE Request from ICACHE
|
//
|
//
|
or dma // DMA Request
|
or dma // DMA Request
|
or dma_run ) // DMA running
|
or dma_run ) // DMA running
|
// #_# #_# #_# #_#
|
// #_# #_# #_# #_#
|
casex ({zugriff,PROT_ERROR,IO_SPACE,io_busy,mmu_hit_i,READ,wr_req,rd_ende,DRAM_ACC,pte_acc,IC_PREQ
|
casex ({zugriff,PROT_ERROR,IO_SPACE,io_busy,mmu_hit_i,READ,wr_req,rd_ende,DRAM_ACC,pte_acc,IC_PREQ,dma,dma_run})
|
// MMU Miss : PTE load from memory , valid too if WRITE and M=0
|
// MMU Miss : PTE load from memory , valid too if WRITE and M=0
|
13'b10_xx_0xxx_x0_x_x0 : new_state = 7'b0001010; // start PTE access
|
13'b10_xx_0xxx_x0_x_x0 : new_state = 7'b0001010; // start PTE access
|
// IO-Address selected : external access starts if not busy because of WRITE
|
// IO-Address selected : external access starts if not busy because of WRITE
|
13'b10_10_1xxx_x0_x_x0 : new_state = 7'b0000001;
|
13'b10_10_1xxx_x0_x_x0 : new_state = 7'b0000001;
|
// DRAM access : Cache Miss at READ :
|
// DRAM access : Cache Miss at READ :
|
13'b10_0x_1100_00_x_x0 : new_state = 7'b0010010;
|
13'b10_0x_1100_00_x_x0 : new_state = 7'b0010010;
|
// DRAM access : WRITE
|
// DRAM access : WRITE
|
13'b10_0x_101x_x0_x_x0 : new_state = 7'b0000100;
|
13'b10_0x_101x_x0_x_x0 : new_state = 7'b0000100;
|
// PTE Request ICACHE , IO access with WRITE is stored - parallel DRAM access possible
|
// PTE Request ICACHE , IO access with WRITE is stored - parallel DRAM access possible
|
13'b0x_xx_xxxx_x0_1_00 : new_state = 7'b0101010; // no access
|
13'b0x_xx_xxxx_x0_1_00 : new_state = 7'b0101010; // no access
|
13'b10_0x_1101_x0_1_x0 : new_state = 7'b0101010; // if successful READ a PTE access can happen i
|
13'b10_0x_1101_x0_1_x0 : new_state = 7'b0101010; // if successful READ a PTE access can happen in parallel
|
// DMA access. Attention : no IO-Write access in background and no ICACHE PTE access !
|
// DMA access. Attention : no IO-Write access in background and no ICACHE PTE access !
|
13'b0x_x0_xxxx_xx_0_10 : new_state = 7'b1000000; // DMA access is started
|
13'b0x_x0_xxxx_xx_0_10 : new_state = 7'b1000000; // DMA access is started
|
default : new_state = 7'b0;
|
default : new_state = 7'b0;
|
endcase
|
endcase
|
|
|
Line 568... |
Line 568... |
|
|
// 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 o
|
// 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])) :
|
always @(posedge BCLK) if (mem_done) rwv_bit <= level2 ? ~(cap_dat[2] & (~RWVAL[0] | cap_dat[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
|
assign zt_ok = mem_done & (RWVAL[1] ? (~cap_dat[2] | (RWVAL[0] & ~cap_dat[1]) | level2) // Level 2 always ok
|
: (cap_dat[0] & ~prot_i & level2) ); // "normal" access
|
: (cap_dat[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
|
|
|
Line 612... |
Line 612... |
|
|
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]) ? (cap_dat[2] & (cap_dat[1] | ~RWVAL[0]) & ~cap_dat[0] & level1)
|
: ~cap_dat[0]; // not do_zt because of icp_acc in ABORT
|
: ~cap_dat[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 Protec
|
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 & ~cap_dat[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;
|
|
|
Line 638... |
Line 638... |
assign PTE_MUX = pte_go | (pte_acc & ~pstate[1]);
|
assign PTE_MUX = pte_go | (pte_acc & ~pstate[1]);
|
|
|
assign pte_puls = mem_done & pte_acc & ~pstate[1];
|
assign pte_puls = mem_done & pte_acc & ~pstate[1];
|
assign PTE_STAT = {(pte_puls & icp_acc),(pte_puls & ~icp_acc)}; // only for statistic
|
assign PTE_STAT = {(pte_puls & icp_acc),(pte_puls & ~icp_acc)}; // only for statistic
|
|
|
assign PD_MUX = ((pstate == 3'd4) & mem_done & valid & ~refer) // switch data-MUX, write level 1
|
assign PD_MUX = ((pstate == 3'd4) & mem_done & valid & ~refer) // switch data-MUX, write level 1 too
|
| ((pstate == 3'd6) & mem_done & valid & (~refer | modi)) // write level 2
|
| ((pstate == 3'd6) & mem_done & valid & (~refer | modi)) // write level 2
|
| (((pstate == 3'd5) | (pstate == 3'd7)) & ~pte_run_wr);
|
| (((pstate == 3'd5) | (pstate == 3'd7)) & ~pte_run_wr);
|
|
|
assign pte_wr_sig = ENWR & PD_MUX;
|
assign pte_wr_sig = ENWR & PD_MUX;
|
|
|
always @(posedge BCLK) pte_run_wr <= pte_wr_sig; // Ok-Signal for pstate State-machine
|
always @(posedge BCLK) pte_run_wr <= pte_wr_sig; // Ok-Signal for pstate State-machine
|
|
|
assign PKEEP = (pstate == 3'd6) | ((pstate == 3'd7) & ~pte_run_wr); // keep the DRAM address
|
assign PKEEP = (pstate == 3'd6) | ((pstate == 3'd7) & ~pte_run_wr); // keep the DRAM address
|
|
|
// If there is a PTE still in the data cache it must be deleted. If MMU Bits are set by the pte eng
|
// If there is a PTE still in the data cache it must be deleted. If MMU Bits are set by the pte engine a following
|
// READ would deliver wrong data if cache hit. Therefore access of the Tags.
|
// READ would deliver wrong data if cache hit. Therefore access of the Tags.
|
always @(posedge BCLK or negedge BRESET)
|
always @(posedge BCLK or negedge BRESET)
|
if (!BRESET) ko_state <= 3'b000;
|
if (!BRESET) ko_state <= 3'b000;
|
else
|
else
|
casex ({kostart,ko_state})
|
casex ({kostart,ko_state})
|
Line 668... |
Line 668... |
|
|
assign run_dc = ~ko_state[2] & ~dma_run;
|
assign run_dc = ~ko_state[2] & ~dma_run;
|
assign KOMUX = ko_state[1] | DMA_MUX;
|
assign KOMUX = ko_state[1] | DMA_MUX;
|
assign KDET = ko_state[0] | dma_kdet;
|
assign KDET = ko_state[0] | dma_kdet;
|
|
|
assign HIT_ALL = MMU_HIT & CA_HIT & run_dc & ~pte_acc; // for Update "Last-Set" , MMU_HIT contains
|
assign HIT_ALL = MMU_HIT & CA_HIT & run_dc & ~pte_acc; // 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;
|
assign CUPDATE = card_flag & USE_CA & MDONE;
|
|
|
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 dat
|
// 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) DRAM_WR <= wr_dram | pte_wr_sig; // pulse
|
always @(posedge BCLK) DRAM_WR <= wr_dram | pte_wr_sig; // pulse
|
Line 695... |
Line 695... |
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;
|
if (IO_ACC) IO_WR <= WRITE; else IO_WR <= IO_WR & ~IO_READY & BRESET;
|
if (IO_ACC) IO_WR <= WRITE; else IO_WR <= IO_WR & ~IO_READY & BRESET;
|
end
|
end
|
|
|
assign io_busy = IO_RD | IO_WR | rd_done; // access is gone in next clock cycle, therefore blocked
|
assign io_busy = IO_RD | IO_WR | rd_done; // access is gone in next clock cycle, therefore blocked with "rd_done"
|
|
|
always @(posedge BCLK) rd_done <= IO_RD & IO_READY; // For READ one clock later for data to come th
|
always @(posedge BCLK) rd_done <= IO_RD & IO_READY; // For READ one clock later for data to come through
|
|
|
assign dma = ICTODC[2]; // external request HOLD after FF in ICACHE
|
assign dma = ICTODC[2]; // external request HOLD after FF in ICACHE
|
|
|
always @(posedge BCLK) dma_run <= (dma_go | (dma_run & dma)) & BRESET; // stops the data access unt
|
always @(posedge BCLK) dma_run <= (dma_go | (dma_run & dma)) & BRESET; // stops the data access until HOLD becomes inactive
|
|
|
assign HLDA = ~(ICTODC[1] & dma_run); // Signal for system that the CPU has stopped accesses
|
assign HLDA = ~(ICTODC[1] & dma_run); // Signal for system that the CPU has stopped accesses
|
|
|
always @(posedge BCLK) dma_kdet <= FILLRAM;
|
always @(posedge BCLK) dma_kdet <= FILLRAM;
|
assign DMA_MUX = FILLRAM | dma_kdet;
|
assign DMA_MUX = FILLRAM | dma_kdet;
|
|
|
// global feedback to ADDR_UNIT, early feedback to Op-Dec : you can continue
|
// global feedback to ADDR_UNIT, early feedback to Op-Dec : you can continue
|
|
|
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[27:12];
|
always @(posedge BCLK) if (PTB_WR && PTB_SEL) ptb1 <= CPU_OUT[27:12];
|
always @(posedge BCLK) if (PTB_WR && PTB_SEL) ptb1 <= CPU_OUT[27:12];
|
Line 731... |
Line 731... |
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
|
assign PTE_ADR = rd_level2 ? {CAPDAT[27: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;
|
always @(posedge BCLK) pte_modi = pte_dat_8;
|
assign PTE_DAT = {4'h3,CAPDAT[15:9],pte_modi,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
|
Line 755... |
Line 755... |
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 = cap_dat[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 allow
|
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})
|
3'b1_11 : write_ok = 1'b1;
|
3'b1_11 : write_ok = 1'b1;
|
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;
|