📄 mmu.v
字号:
`timescale 1ns/10ps/*****************************************************************************$RCSfile: mmu.v,v $$Revision: 1.20 $$Author: kohlere $$Date: 2000/05/04 15:26:24 $$State: Exp $$Source: /home/lefurgy/tmp/ISC-repository/isc/hardware/ARM10/behavioral/pipelined/mmu.v,v $Description: Memory Management Unit for the ARM Microprocessor. Notes: DMAS 11 => double word 10 => word 01 => halfword 00 => byte CHSD/E 11 => last 10 => absent 01 => go 00 => wait DnWr 0 => data memory write 1 => data memory read*****************************************************************************/module mmu (nGCLK, nECLK1, nECLK2, nECLK3, nECLK4, nECLK5, nECLK6, nRESET, nWAIT, CHSD, CHSE, id_enbar, BIGEND, LATECANCEL, PASS, IABORT, DABORT, MMA, MMnWR, DnMREQ, dmiss, dwb, DD, doublehold, dmiss_addr, imiss_addr, imiss, inst_if, ex_enbar, ic_read_mmd, dc_read_mmd, drive_mmd, IA, InMREQ, DA, useMini, iswic, dswic, swic_data, dc_init, ic_init, istall, mode, me_enbar, data_decomp, dflush, mispredicted, misp_rec, pc_touched, hold_next_ex, ptaken_ex, pt, put, eval, inst_count, inst_finished, if_enbar, stop_me);/*------------------------------------------------------------------------ Ports------------------------------------------------------------------------*/input [31:0] imiss_addr; //Instruction Address of Missinput [31:0] dmiss_addr; //Data Address of Missinput [31:0] inst_if; //Instr to ID stageinput [31:0] IA; //Instruction Address Businput [31:0] DA; //Data Address Businput [4:0] mode; //Processor Modeinput nGCLK; //Global Clockinput nECLK1; //Pipeline Clockinput nECLK2; //Pipeline Clockinput nECLK3; //Pipeline Clockinput nECLK4; //Pipeline Clockinput nECLK5; //Pipeline Clockinput nECLK6; //Pipeline Clockinput nRESET; //Global Resetinput LATECANCEL; //Cancel Coprocessor Instinput PASS; //Execute Coprocessor Inst (Cond Passed)input InMREQ; //Instruction Requestedinput DnMREQ; //Data Requestedinput if_enbar; //Fetch Enableinput id_enbar; //Coprocessor Decode Enableinput ex_enbar; //Coprocessor Ex Enable input me_enbar; //Coprocessor ME Enableinput imiss; //Instruction Cache Missinput doublehold; //Hold for One Cycleinput dmiss; //Data Cache Missinput dwb; //Data Write Back Neededinput dc_init; //Data Cache Initinginput ic_init; //Inst Cache Initinginput mispredicted; //Mispredicted a Branchinput misp_rec; //Have the IR Savedinput pc_touched; //PC Modified in EXinput hold_next_ex; //Multiply in EXinput ptaken_ex; //Predicted Takeninput pt; //Predicted Takeninput put; //Predicted Not Takeninput eval; //Evaluating a Branchinput stop_me; //Stop Executioninout [63:0] DD; //Data Data Busoutput [31:0] MMA; //Main Memory Address Busoutput [31:0] swic_data; //Data Word to Store in I$output [31:0] inst_count; //Number of Completed Instoutput [1:0] CHSD; //Coprocessor HandShakeoutput [1:0] CHSE; //Coprocessor HandShakeoutput nWAIT; //Memory System Stall Signaloutput BIGEND; //Give Processor Big/Little Endianessoutput DABORT; //Data Abortoutput IABORT; //Instruction Prefetch Abortoutput MMnWR; //Not Main Memory Write, Readoutput iswic; //SWIC Signal to I$ Controlleroutput dswic; //SWIC Signal to D$ Controlleroutput ic_read_mmd; //To I-Cache Controlleroutput dc_read_mmd; //To D-Cache Controlleroutput drive_mmd; //Permission to Dcache Controlleroutput useMini; //Do Not Store Line in Cacheoutput istall; //ICache Stalling Processoroutput data_decomp; //Data Decompression in Progressoutput dflush; //Flush a Line from Data Cacheoutput inst_finished; //Finished an Instruction/*------------------------------------------------------------------------ Defines & Parameters------------------------------------------------------------------------*/parameter LATENCY = 1; //# of GCLK cyclesparameter BW = 1; //words/cycleparameter PENALTY = LATENCY + 8/BW + 1; //Total Miss Penalty/*------------------------------------------------------------------------ Signal Declarations------------------------------------------------------------------------*/reg [31:0] MMA; //Main Memory Address Busreg [31:6] ia; //Latched Instruction Addrreg [31:0] da; //Latched Data Addrreg [3:0] count; //Cycle Count for Missreg swicInD; //Swic, Hi=>I, Lo=>Dreg nWAIT; //Stall Signal to Processorreg MMnWR; //Main Memory not Write Readreg drive_mmd; //DCache Controller Drive MMDreg srv_d; //Serving DCache=1/Icache=0reg go; //Servicing Missreg dwb_1; //DWB delayed by 1reg abort_id; //ABORT now in IDreg abort_ex; //ABORT now in EXreg abort_me; //ABORT now in MEwire [63:0] DD; //Data Data Buswire [31:0] MMD; //Main Memory Data Buswire [31:0] imiss_count; //Number of I$ Misseswire [31:0] dmiss_count; //Number of D$ Misseswire [31:0] inst_count; //Number of Instructionswire [31:0] cyc_count; //Number of Pipeline Cycleswire [3:0] penalty; //Cache Miss Penalty (cycles)wire [3:0] latency; //Main Memory Latencywire [3:0] next_count; //Next Count Valuewire BIGEND; //Endiannesswire DABORT; //Data Access Abortwire IABORT; //Inst Access Abortwire istall; //ICache Needs to Stall Pipelinewire data_decomp; //Data Decompression in Progresswire inst_finished; //Inst Completed/*------------------------------------------------------------------------ Component Instantiations------------------------------------------------------------------------*/counters xcounters (.nGCLK1(nECLK3), .nGCLK2(nECLK2), .nRESET(nRESET), .mispredicted(mispredicted), .if_enbar(if_enbar), .misp_rec(misp_rec), .pc_touched(pc_touched), .id_enbar(id_enbar), .ex_enbar(ex_enbar), .me_enbar(me_enbar), .hold_next_ex(hold_next_ex), .finished(inst_finished), .go(go), .ptaken_ex(ptaken_ex), .pt(pt), .put(put), .count(inst_count), .eval(eval), .cyc_count(cyc_count), .imiss(imiss), .dmiss(dmiss), .InMREQ(InMREQ), .DnMREQ(DnMREQ), .imiss_count(imiss_count), .dmiss_count(dmiss_count));/*------------------------------------------------------------------------ Signal Assignments------------------------------------------------------------------------*/assign next_count = ((count == penalty) | (DABORT & ~abort_id)) ? 4'h0 : count + 1;assign ic_read_mmd = (count > latency) & ~srv_d;assign dc_read_mmd = (count > latency) & srv_d & MMnWR & ~dwb_1;//assign penalty = (~MMnWR) ? (4'h7 + LATENCY) : PENALTY;assign penalty = (dwb_1) ? (4'h6 + LATENCY) : PENALTY;assign latency = LATENCY;//Write Back First (High Priority)//assign drive_mmd = dwb & (count >= (latency - 1));//assign drive_mmd = dwb & (count >= (latency));assign istall = imiss & ~nWAIT;/*------------------------------------------------------------------------ Sequential Always Block------------------------------------------------------------------------*///Stall the Processor on a cache miss//synopsys async_set_reset "nRESET"always @(nGCLK or imiss or IABORT or dmiss or DABORT or doublehold or nRESET or dc_init or ic_init or stop_me) begin if (~nRESET) nWAIT <= 1'b1; else if (~nGCLK) nWAIT <= ~((imiss & ~IABORT) | (dmiss & ~DABORT) | doublehold | ic_init | dc_init | stop_me); end//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) swicInD <= 1'b0; else if (IABORT) swicInD <= 1'b1; else if (DABORT) swicInD <= 1'b0; end/*------------------------------------------------------------------------ MMA Bus Controller------------------------------------------------------------------------*///Cache Miss Cycle Counter//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) count <= #1 4'h0; else if (~nWAIT & go) count <= #1 next_count; else count <= #1 4'h0; end//Want to Reset MMnWR after transferred//8 words, thus the < 4'h7//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) MMnWR <= #1 1'b1; else MMnWR <= #1 ~(dwb & (count < 4'h7) & !(dwb & drive_mmd & MMnWR)); end//Want to Drive Data bus two cycles after//MMnWR is asserted. Another cycle delay//in DCACHEalways @(posedge nGCLK or negedge nRESET) begin if (~nRESET) drive_mmd <= #1 1'b0; else drive_mmd <= ~MMnWR; end//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) srv_d <= #1 1'b0; else srv_d <= #1 ((dmiss & (count != penalty)) | dwb) & ~DABORT; end//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) go <= #1 1'b0; else go <= #1 (dmiss & ~DABORT) | (imiss & ~IABORT); endalways @(srv_d or dmiss_addr or count or imiss_addr) begin MMA <= (srv_d) ? {dmiss_addr[31:5],count[2:0],2'h0} : {imiss_addr[31:5],count[2:0],2'h0}; endalways @(posedge nGCLK or negedge nRESET) begin if (~nRESET) dwb_1 <= #1 1'b0; else dwb_1 <= #1 dwb; end/*------------------------------------------------------------------------ MMU Coprocessor Begins Here (CP #15)------------------------------------------------------------------------*/`define LAST (2'b11) //Coprocessor Last Cycle `define ABS (2'b10) //Coprocessor Absent`define GO (2'b01) //Coprocessor Working `define WAIT (2'b00) //Coprocessor Stallreg [31:0] mmu_ir_id; //MMU ID Instruction Registerreg [31:0] op1_cid; //Operand #1 (in ID)reg [31:0] op1_cex; //Operand #1 (in EX)reg [31:0] op2_cid; //Operand #2 (in ID)reg [31:0] op2_cex; //Operand #2 (in EX)reg [31:0] res_cex; //Muxed Result of EX Stagereg [31:0] res_cme; //Result (in ME)reg [31:0] res_to_wb; //Muxed Result in ME Stagereg [31:0] cr1; //Reg 1 -- Control Registerreg [31:0] cr2; //Reg 2 --reg [31:0] cr3; //Reg 3 --reg [31:0] cr4; //Reg 4 --reg [31:0] cr5; //Reg 5 --reg [31:0] cr6; //Reg 6 --reg [31:0] cr7; //Reg 7 --reg [31:0] cr8; //Reg 8 --reg [31:0] cr9; //Reg 9 --reg [31:0] cr10; //Reg 10 --reg [31:0] cr11; //Reg 11 --reg [31:0] cr12; //Reg 12 --reg [31:0] cr13; //Reg 13 --reg [31:0] cr14; //Reg 14 --reg [31:0] cr15; //Reg 15 --reg [31:0] rf_op1; //Register Operand #1reg [31:0] rf_op2; //Register Operand #2reg [31:0] perf_op1; //Performance Counter Muxreg [3:0] op2_index_cid; //Op2 Index into Reg Filereg [3:0] op1_index_cex; //Op1 Index in EX reg [3:0] CRd_cex; //Destination Register Indexreg [3:0] CRd_cme; //Destination Register Indexreg [1:0] CHSD; //MMU ID Handshake Signalreg [1:0] CHSE; //MMU EX Handshake Signalreg [1:0] next_chsd; //Input to CHSD Latchreg [1:0] next_chse; //Input to CHSE Latchreg mem_op_cex; //LDC/STC Operation (in EX)reg reg_op_cex; //MRC/MCR Operation (in EX)reg data_op_cex; //CDP Operation (in EX)reg drive_DD_cex; //To ARM (in EX)reg load_use_cex; //Load Use Bubble reg swic_cex; //SWIC in EXreg flush_cex; //FLUSH in EXreg mem_op_cme; //LDC/STC Operation (in ME)reg reg_op_cme; //MRC/MCR Operation (in ME)reg data_op_cme; //CDP Operation (in ME)reg drive_DD_cme; //To ARM (in ME)wire [31:0] to_DD; //Data to DD;wire [31:0] cr0; //Cr0 -- ID Register (Read Only)wire [31:0] swic_data; //SWIC Data to I/D$'swire [3:0] CRn_cid; //Cop Rnwire [3:0] Rd_cid; //ARM Rdwire [3:0] CRm_cid; //Cop Rmwire [3:0] op1_index_cid; //Op1 Index into Reg Filewire cop15; //Coprocessor 15 Selectedwire N; //N-Bit of Mem Inst.wire flush; //Opcode for Flush Instr.wire move_perf; //Move the Performance Counterswire must_wait_cid; //ID Stage Blockedwire must_wait_cex; //EX Stage Blockedwire load_use_op1; //Load Use Interlock wire mem_op_cid; //LDC/STC Operation wire reg_op_cid; //MRC/MCR Operationwire data_op_cid; //CDP Operationwire swic_cid; //SWIC Instwire flush_cid; //Flush a Cache Linewire swic_cme; //SWIC Instwire rfw_ena; //Write to a Regsiterwire write_cr0; //Write to Cr0wire write_cr1; //Write to Cr1wire write_cr2; //Write to Cr2wire write_cr3; //Write to Cr3wire write_cr4; //Write to Cr4wire write_cr5; //Write to Cr5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -