📄 mmu_new.v
字号:
`timescale 1ns/10ps`include "pardef"/*****************************************************************************$RCSfile: mmu_new.v,v $$Revision: 1.15 $$Author: kohlere $$Date: 2000/05/11 01:07:57 $$State: Exp $$Source: /home/lefurgy/tmp/ISC-repository/isc/hardware/ARM10/behavioral/pipelined/fpga2/mmu_new.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, 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, MM_New_Line, MM_CE, me_enbar, decomp, dflush, mispredicted, misp_rec, pc_touched, hold_next_ex, ptaken_ex, pt, put, eval, 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 nRESET; //Global Resetinput LATECANCEL; //Cancel Coprocessor Instinput PASS; //Execute Coprocessor Inst (Cond Passed)input InMREQ; //Instruction Requestedinput DnMREQ; //Data Requestedinput if_enbar; //Instruction Fetch Enableinput id_enbar; //Coprocessor Decode Enableinput ex_enbar; //Coprocessor Ex Enableinput me_enbar; //Coprocessor ME Enable input 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 Branch input 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 [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 MM_New_Line; //Used for FPGA to Initiate New Transfer output MM_CE; //Enable for Buffer Ramoutput 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 decomp; //Decompressingoutput dflush; //Flush a Line from Data Cache/*------------------------------------------------------------------------ Defines & Parameters------------------------------------------------------------------------*/parameter LATENCY = 1; //# of GCLK cyclesparameter BW = 1; //words/cycleparameter PENALTY = LATENCY + 8/BW; //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 MM_New_Line; //Start New Transferreg MM_CE; //Enable the Bufferreg 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] inst_count; //Number of Completed Instructionswire [31:0] cyc_count; //Number of Pipeline Cycleswire [31:0] time_count; //Number of all Clock Cycleswire [31:0] iaccesses; //Number of I$ Accesseswire [31:0] daccesses; //Number of D$ Accesseswire [31:0] imiss_count; //Number of I$ Misseswire [31:0] dmiss_count; //Number of D$ Misseswire [31:0] predicted; //Number of Predicted Brancheswire [31:0] pcorrect; //Number of Correctly Predicted Brancheswire [31:0] spec_iabort; //Number of Speculative IABORTSwire [31:0] spec_dabort; //Number of Speculative DABORTSwire [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 drive_mmd; //DCache Controller Drive MMDwire istall; //ICache Needs to Stall Pipelinewire decomp; //Decompressing/*------------------------------------------------------------------------ Component Instantiations------------------------------------------------------------------------*/counters xcounters (.nGCLK(nGCLK), .nWAIT(nWAIT), .IABORT(IABORT), .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), .DABORT(DABORT), .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), .predicted(predicted), .dmiss_count(dmiss_count), .pcorrect(pcorrect), .iaccesses(iaccesses), .daccesses(daccesses), .spec_iabort(spec_iabort), .spec_dabort(spec_dabort), .time_count(time_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 latency = LATENCY;assign drive_mmd = (dwb & go & (count < 4'h8));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 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 & go & (count < 4'h8)); 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; 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//Start a Memory to Buffer/Buffer to Memory Transferalways @(go or count or dwb or MMnWR or imiss or dmiss) begin if ((go & (count == 4'h0) & MMnWR & ~dwb & (imiss | dmiss)) | (go & (count == 4'h8) & dwb & dmiss)) MM_New_Line <= 1'b1; else MM_New_Line <= 1'b0; end//Enable the DPM Bufferalways @(negedge nGCLK or negedge nRESET) begin if (~nRESET) MM_CE <= 1'b0; else MM_CE <= go; end/*------------------------------------------------------------------------ MMU Coprocessor Begins Here (CP #15)------------------------------------------------------------------------*/reg [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 Storewire [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 flush_cid; //Flush in ID Stagewire 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 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 Cr5wire write_cr6; //Write to Cr6wire write_cr7; //Write to Cr7wire write_cr8; //Write to Cr8wire write_cr9; //Write to Cr9wire write_cr10; //Write to Cr10wire write_cr11; //Write to Cr11wire write_cr12; //Write to Cr12wire write_cr13; //Write to Cr13wire write_cr14; //Write to Cr14wire write_cr15; //Write to Cr15/*------------------------------------------------------------------------ MMU ID Stage------------------------------------------------------------------------*///synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (~nRESET) mmu_ir_id <= 32'h0; else if (nWAIT) begin if (~id_enbar) mmu_ir_id <= inst_if; end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -