📄 dcache.v
字号:
`timescale 1ns/10ps`include "pardef"/*****************************************************************************$RCSfile: dcache.v,v $$Revision: 1.15 $$Author: kohlere $$Date: 2000/05/04 16:31:08 $$State: Exp $$Source: /home/lefurgy/tmp/ISC-repository/isc/hardware/ARM10/behavioral/pipelined/fpga2/dcache.v,v $Description: D-Cache Controller Unit for the ARM Microprocessor. The cache is line addressable, so data writes use a read- modify-write protocol. Notes: DMAS 11 => double word 10 => word 01 => halfword 00 => byte DnWr 0 => data memory write 1 => data memory read Tag = D,V,tag*****************************************************************************/module dcache (nGCLK, nRESET, DA, DD, dmiss, DnMREQ, DMAS, DnWR, MMD, mmd_valid, istall, dwb, dmiss_addr, drive_mmd, doublehold, BIGEND, initializing, swic, swic_data, DABORT, decomp, flush);/*------------------------------------------------------------------------ Ports------------------------------------------------------------------------*/input [31:0] DA; //Instruction Address Businput [31:0] swic_data; //SWIC Word to Storeinput [1:0] DMAS; //Data Memory Access Sizeinput nGCLK; //Global Clockinput nRESET; //Global Resetinput DnMREQ; //Not Instruction Memory Requestinput DnWR; //Data Not Write, Readinput DABORT; //Data Access Abortinput BIGEND; //Endianness of Main Memoryinput mmd_valid; //MMD is Valid, Increment Counterinput drive_mmd; //Bus Granted via MMUinput istall; //ICache Missinput swic; //SWIC Requestedinput decomp; //Decompressor Runninginput flush; //Flush a line from Cacheinout [63:0] DD; //Data Data Businout [31:0] MMD; //Main Memory Data Busoutput [31:0] dmiss_addr; //Miss Addr to MMUoutput doublehold; //Hold for One Cycleoutput dmiss; //Instruction Cache Missoutput dwb; //Data Write Back Requiredoutput initializing; //Initializing Tags/*------------------------------------------------------------------------ Signal Declarations------------------------------------------------------------------------*/reg [`DLS-1:0] next_line; //Next Value for Buffer on Missreg [`DLS-1:0] din_cache; //Store Multiplexorreg [`DLS-1:0] comp_line; //Compression Line Bufferreg [31:0] lowword; //Low Order Word of Doublereg [63:0] to_DD; //Instruction Data Busreg [63:0] from_DD; //Data Bus Latchreg [31:0] to_MMD; //Main Memory Data Busreg [31:0] swic_d; //Latched SWIC Datareg [31:2] swic_a; //Latched SWIC Addrreg [`DTS-1:0] comp_tag; //Compression Tag Bufferreg [`DTS-1:0] din_tag; //Data to Write to Tagreg [`DPSH+1:0] page_sel; //Page Select Bits (tag)reg [`DLSS-1:0] line_sel; //Line Select Bitsreg [`DLSS-1:0] comp_tag_line; //Line Select Part of Tagreg [`DLSS-1:0] read_sel; //Line Select Muxreg [`DLSS-1:0] line_wb; //Line Address for WBreg [`DLSS-1:0] ls_mux; //Mux Between Line and SWICreg [7:0] dc0; //Cache Write Port Mux Byte 0reg [2:0] word_sel; //Word Select Bitsreg [2:0] word_cntr; //Which word?reg [1:0] byte_sel; //Byte Select Bitsreg disable_latch; //Disable Latch for DD busreg writecycle; //Write Block Next Cyclereg access; //Accessing DCachereg nMiss_active; //Miss is Active (active_low)reg drive_DD; //Drive DD this cyclereg drive_MMD; //Drive MMD this cyclereg held; //1Delay Takenreg init_on; //Initialization In Progressreg swic_store; //Store Enable for SWICreg wb_done; //Write Back Done reg flush_now; //Flush a Cache Linewire [255:0] cache_line; //Line Read from Cachewire [255:0] dc_line; //Read Port of D$wire [31:0] MMD; //Main Memory Data Buswire [31:0] dmiss_addr; //Address of Misswire [`DTS-1:0] tag_line; //Data from Tag$wire [`DTS-1:0] dt_line; //Read Port of Tag$wire [`DPSH+1:0] cache_tag; //Cache Tagwire init_done; //Initialization Completewire doublehold; //Hold for One Cyclewire swic_wb; //SWIC requires a Write Backwire flush_wb; //Flush requires a write backwire ls_and; //And of All Line Select Bitswire wr_ena_c; //Write Enable Cachewire wr_ena_t; //Write Enable Tagwire wr_ena_cc; //Write Enable Compression Cachewire wr_ena_ct; //Write Enable Compression Tagwire initializing; //Initializing Tag Ramwire dmiss; //Cache Misswire dwb; //Replacing Dirty Linewire dirty; //Dirtywire line_miss; //Line Miss/*------------------------------------------------------------------------ Memory Declarations------------------------------------------------------------------------*/ram2p xdcache (.nGCLK(nGCLK), .write_sel(ls_mux), .read_sel(read_sel), .write_port(din_cache), .read_port(dc_line), .wr_ena(wr_ena_c));dtag xdtag (.nGCLK(nGCLK), .write_sel(ls_mux), .read_sel(read_sel), .write_port(din_tag), .read_port(dt_line), .wr_ena(wr_ena_t));/*------------------------------------------------------------------------ Signal Assignments------------------------------------------------------------------------*///Set up The Drivers for Cache/Tag Linesassign cache_line = (decomp & ~swic_store) ? comp_line : {256{1'bz}};assign cache_line = (~decomp | swic_store) ? dc_line : {256{1'bz}}; assign tag_line = (~decomp | swic_store) ? dt_line : {`DTS{1'bz}};assign tag_line = (decomp & ~swic_store) ? comp_tag : {`DTS{1'bz}};assign dirty = tag_line[`DTS-1];//This is the Miss Logicassign cache_tag = tag_line[`DPSH+1:0];assign line_miss = (access & (comp_tag_line != line_sel) & decomp); assign dmiss = (access & ((cache_tag != page_sel) | line_miss) & ~swic_store) | swic_wb | flush_wb;assign swic_wb = (swic_store & (cache_tag != page_sel) & dirty);assign flush_wb = (flush_now & dirty);assign dwb = (dmiss & dirty) | swic_wb | flush_wb;//This is the Miss Address Control Logicassign dmiss_addr = (dwb) ? {tag_line[`DPSH:0],line_wb,5'h00} : {page_sel[`DPSH:0],line_wb,5'h00};assign doublehold = (DMAS == `DOUB) & (word_sel == 3'h7) & access & ~held;assign DD = (drive_DD) ? to_DD : {64{1'bz}};assign MMD = (drive_MMD) ? to_MMD : {32{1'bz}};//Check for All 1's, If so, may need to wrap around//to line 0 for double word load/storeassign ls_and = (& line_sel);//Assign the Cache Write Enable//1) Normal Write//2) While Loading Cache Lines from Memory//3) During a SWIC operationassign wr_ena_c = ((((writecycle & nMiss_active) | (mmd_valid)) & ~decomp) | swic_store);assign wr_ena_cc = (((((writecycle & nMiss_active) | (mmd_valid)) & decomp)) & ~swic_store);//Assign the Tag Write Enable//1) Normal Write//2) When Line has been Loaded from Memory//3) During a SWIC operation//4) After a Dirty Line has been Copied to Memory//5) During Initializationassign wr_ena_t = ((((writecycle & nMiss_active) | (word_cntr == 3'h7 & ~drive_MMD) | (wb_done) | (init_on)) & ~decomp) | (swic_store));assign wr_ena_ct = (((((writecycle & nMiss_active) | (word_cntr == 3'h7 & ~drive_MMD) | (wb_done) | (init_on)) & decomp)) & ~swic_store & ~doublehold);//Initialization Done when line select is All 1'sassign init_done = ls_and;assign initializing = init_on & ~init_done;/*------------------------------------------------------------------------ Combinational Always Block------------------------------------------------------------------------*///Mux Out the Proper Word to the I$ for SWIC always @(swic_store or swic_d or cache_line or swic_a or word_sel or next_line or from_DD or held or DMAS or nMiss_active or writecycle or BIGEND or byte_sel or lowword)begin if (swic_store) begin case(swic_a[4:2]) //synopsys full_case parallel_case 3'h0: din_cache = {cache_line[255:32],swic_d}; 3'h1: din_cache = {cache_line[255:64],swic_d,cache_line[31:0]}; 3'h2: din_cache = {cache_line[255:96],swic_d,cache_line[63:0]}; 3'h3: din_cache = {cache_line[255:128],swic_d,cache_line[95:0]}; 3'h4: din_cache = {cache_line[255:160],swic_d,cache_line[127:0]}; 3'h5: din_cache = {cache_line[255:192],swic_d,cache_line[159:0]}; 3'h6: din_cache = {cache_line[255:224],swic_d,cache_line[191:0]}; 3'h7: din_cache = {swic_d,cache_line[223:0]}; endcase end else begin if (nMiss_active & writecycle) begin case (word_sel) //synopsys full_case parallel_case 3'h0: begin case (DMAS) //synopsys full_case parallel_case `DOUB: din_cache = (held) ? {cache_line[255:32],lowword} : {cache_line[255:64],from_DD}; `WORD: din_cache = {cache_line[255:32],from_DD[31:0]}; `HALF: begin case ({BIGEND,byte_sel[1]}) //synopsys full_case parallel_case 2'b00, 2'b11: din_cache = {cache_line[255:16],from_DD[15:0]}; 2'b01, 2'b10: din_cache = {cache_line[255:32],from_DD[31:16],cache_line[15:0]}; endcase end `BYTE: begin case ({BIGEND,byte_sel}) //synopsys full_case parallel_case 3'b000,3'b111: din_cache = {cache_line[255:8],from_DD[7:0]}; 3'b001,3'b110: din_cache = {cache_line[255:16],from_DD[15:8],cache_line[7:0]}; 3'b010,3'b101: din_cache = {cache_line[255:24],from_DD[23:16],cache_line[15:0]}; 3'b011,3'b100: din_cache = {cache_line[255:32],from_DD[31:24],cache_line[23:0]}; endcase end endcase end 3'h1: begin case (DMAS) //synopsys full_case parallel_case `DOUB: din_cache = {cache_line[255:96],from_DD,cache_line[31:0]}; `WORD: din_cache = {cache_line[255:64],from_DD[31:0],cache_line[31:0]}; `HALF: begin case ({BIGEND,byte_sel[1]}) //synopsys full_case parallel_case 2'b00, 2'b11: din_cache = {cache_line[255:48],from_DD[15:0],cache_line[31:0]}; 2'b01, 2'b10: din_cache = {cache_line[255:64],from_DD[31:16],cache_line[47:0]}; endcase end `BYTE: begin case ({BIGEND,byte_sel}) //synopsys full_case parallel_case 3'b000,3'b111: din_cache = {cache_line[255:40],from_DD[7:0],cache_line[31:0]}; 3'b001,3'b110: din_cache = {cache_line[255:48],from_DD[15:8],cache_line[39:0]}; 3'b010,3'b101: din_cache = {cache_line[255:56],from_DD[23:16],cache_line[47:0]}; 3'b011,3'b100: din_cache = {cache_line[255:64],from_DD[31:24],cache_line[55:0]}; endcase end endcase end 3'h2: begin case (DMAS) //synopsys full_case parallel_case `DOUB: din_cache = {cache_line[255:128],from_DD,cache_line[63:0]}; `WORD: din_cache = {cache_line[255:96],from_DD[31:0],cache_line[63:0]}; `HALF: begin case ({BIGEND,byte_sel[1]}) //synopsys full_case parallel_case 2'b00, 2'b11: din_cache = {cache_line[255:80],from_DD[15:0],cache_line[63:0]}; 2'b01, 2'b10: din_cache = {cache_line[255:96],from_DD[31:16],cache_line[79:0]}; endcase end `BYTE: begin case ({BIGEND,byte_sel}) //synopsys full_case parallel_case 3'b000,3'b111: din_cache = {cache_line[255:72],from_DD[7:0],cache_line[63:0]}; 3'b001,3'b110: din_cache = {cache_line[255:80],from_DD[15:8],cache_line[71:0]}; 3'b010,3'b101: din_cache = {cache_line[255:88],from_DD[23:16],cache_line[79:0]}; 3'b011,3'b100: din_cache = {cache_line[255:96],from_DD[31:24],cache_line[87:0]}; endcase end endcase end 3'h3: begin case (DMAS) //synopsys full_case parallel_case `DOUB: din_cache = {cache_line[255:160],from_DD,cache_line[95:0]}; `WORD: din_cache = {cache_line[255:128],from_DD[31:0],cache_line[95:0]}; `HALF: begin case ({BIGEND,byte_sel[1]}) //synopsys full_case parallel_case 2'b00, 2'b11: din_cache = {cache_line[255:112],from_DD[15:0],cache_line[95:0]}; 2'b01, 2'b10: din_cache = {cache_line[255:128],from_DD[31:16],cache_line[111:0]}; endcase end `BYTE: begin case ({BIGEND,byte_sel}) //synopsys full_case parallel_case 3'b000,3'b111: din_cache = {cache_line[255:104],from_DD[7:0],cache_line[95:0]}; 3'b001,3'b110: din_cache = {cache_line[255:112],from_DD[15:8],cache_line[103:0]}; 3'b010,3'b101: din_cache = {cache_line[255:120],from_DD[23:16],cache_line[111:0]}; 3'b011,3'b100: din_cache = {cache_line[255:128],from_DD[31:24],cache_line[119:0]}; endcase end endcase end 3'h4: begin case (DMAS) //synopsys full_case parallel_case `DOUB: din_cache = {cache_line[255:192],from_DD,cache_line[127:0]}; `WORD: din_cache = {cache_line[255:160],from_DD[31:0],cache_line[127:0]}; `HALF: begin case ({BIGEND,byte_sel[1]}) //synopsys full_case parallel_case 2'b00, 2'b11: din_cache = {cache_line[255:144],from_DD[15:0],cache_line[127:0]}; 2'b01, 2'b10: din_cache = {cache_line[255:160],from_DD[31:16],cache_line[143:0]}; endcase end `BYTE: begin case ({BIGEND,byte_sel}) //synopsys full_case parallel_case 3'b000,3'b111: din_cache = {cache_line[255:136],from_DD[7:0],cache_line[127:0]}; 3'b001,3'b110: din_cache = {cache_line[255:144],from_DD[15:8],cache_line[135:0]}; 3'b010,3'b101: din_cache = {cache_line[255:152],from_DD[23:16],cache_line[143:0]}; 3'b011,3'b100: din_cache = {cache_line[255:160],from_DD[31:24],cache_line[151:0]}; endcase end endcase end 3'h5: begin case (DMAS) //synopsys full_case parallel_case `DOUB: din_cache = {cache_line[255:224],from_DD,cache_line[159:0]}; `WORD: din_cache = {cache_line[255:192],from_DD[31:0],cache_line[159:0]}; `HALF: begin case ({BIGEND,byte_sel[1]}) //synopsys full_case parallel_case 2'b00, 2'b11: din_cache = {cache_line[255:176],from_DD[15:0],cache_line[159:0]}; 2'b01, 2'b10: din_cache = {cache_line[255:192],from_DD[31:16],cache_line[175:0]}; endcase end `BYTE: begin case ({BIGEND,byte_sel}) //synopsys full_case parallel_case 3'b000,3'b111: din_cache = {cache_line[255:168],from_DD[7:0],cache_line[159:0]}; 3'b001,3'b110: din_cache = {cache_line[255:176],from_DD[15:8],cache_line[167:0]}; 3'b010,3'b101: din_cache = {cache_line[255:184],from_DD[23:16],cache_line[175:0]}; 3'b011,3'b100: din_cache = {cache_line[255:192],from_DD[31:24],cache_line[183:0]}; endcase end endcase
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -