`include "../VX_define.v" module VX_cache_data #( parameter NUM_IND = 8, parameter NUM_WORDS_PER_BLOCK = 4, parameter TAG_SIZE_START = 0, parameter TAG_SIZE_END = 16, parameter IND_SIZE_START = 0, parameter IND_SIZE_END = 7 ) ( input wire clk, rst, // Clock // `ifdef PARAM // Addr input wire[IND_SIZE_END:IND_SIZE_START] addr, // WE input wire[NUM_WORDS_PER_BLOCK-1:0][3:0] we, input wire evict, // Data input wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_write, input wire[TAG_SIZE_END:TAG_SIZE_START] tag_write, output wire[TAG_SIZE_END:TAG_SIZE_START] tag_use, output wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_use, output wire valid_use, output wire dirty_use // `else // // Addr // input wire[7:0] addr, // // WE // input wire[NUM_WORDS_PER_BLOCK-1:0][3:0] we, // input wire evict, // // Data // input wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_write, // Update Data // input wire[16:0] tag_write, // output wire[16:0] tag_use, // output wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_use, // output wire valid_use, // output wire dirty_use // `endif ); //localparam NUMBER_BANKS = CACHE_BANKS; //localparam CACHE_BLOCK_PER_BANK = (CACHE_BLOCK / CACHE_BANKS); // localparam NUM_WORDS_PER_BLOCK = CACHE_BLOCK / (CACHE_BANKS*4); //localparam NUMBER_INDEXES = NUM_IND; wire currently_writing = (|we); wire update_dirty = ((!dirty_use) && currently_writing) || (evict); wire dirt_new = evict ? 0 : (|we); `ifndef SYN // (3:0) 4 bytes reg[NUM_WORDS_PER_BLOCK-1:0][3:0][7:0] data[NUM_IND-1:0]; // Actual Data reg[TAG_SIZE_END:TAG_SIZE_START] tag[NUM_IND-1:0]; reg valid[NUM_IND-1:0]; reg dirty[NUM_IND-1:0]; // 16 bytes assign data_use = data[addr]; // Read Port assign tag_use = tag[addr]; assign valid_use = valid[addr]; assign dirty_use = dirty[addr]; integer f; integer ini_ind; always @(posedge clk, posedge rst) begin : update_all if (rst) begin for (ini_ind = 0; ini_ind < NUM_IND; ini_ind=ini_ind+1) begin data[ini_ind] <= 0; tag[ini_ind] <= 0; valid[ini_ind] <= 0; dirty[ini_ind] <= 0; end end else begin if (update_dirty) dirty[addr] <= dirt_new; // WRite Port if (evict) tag[addr] <= tag_write; if (evict) valid[addr] <= 1; for (f = 0; f < NUM_WORDS_PER_BLOCK; f = f + 1) begin if (we[f][0]) data[addr][f][0] <= data_write[f][7 :0 ]; if (we[f][1]) data[addr][f][1] <= data_write[f][15:8 ]; if (we[f][2]) data[addr][f][2] <= data_write[f][23:16]; if (we[f][3]) data[addr][f][3] <= data_write[f][31:24]; end end end `else wire[IND_SIZE_END:IND_SIZE_START] use_addr = addr; wire cena = 1; wire cenb_d = (|we); wire[NUM_WORDS_PER_BLOCK-1:0][31:0] wdata_d = data_write; wire[NUM_WORDS_PER_BLOCK-1:0][31:0] write_bit_mask_d; wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_out_d; genvar cur_b; for (cur_b = 0; cur_b < NUM_WORDS_PER_BLOCK; cur_b=cur_b+1) begin assign write_bit_mask_d[cur_b] = {32{~we[cur_b]}}; end assign data_use = data_out_d; // Using ASIC MEM /* verilator lint_off PINCONNECTEMPTY */ rf2_32x128_wm1 data ( .CENYA(), .AYA(), .CENYB(), .WENYB(), .AYB(), .QA(data_out_d), .SOA(), .SOB(), .CLKA(clk), .CENA(cena), .AA(use_addr), .CLKB(clk), .CENB(cenb_d), .WENB(write_bit_mask_d), .AB(use_addr), .DB(wdata_d), .EMAA(3'b011), .EMASA(1'b0), .EMAB(3'b011), .TENA(1'b1), .TCENA(1'b0), .TAA(5'b0), .TENB(1'b1), .TCENB(1'b0), .TWENB(128'b0), .TAB(5'b0), .TDB(128'b0), .RET1N(1'b1), .SIA(2'b0), .SEA(1'b0), .DFTRAMBYP(1'b0), .SIB(2'b0), .SEB(1'b0), .COLLDISN(1'b1) ); /* verilator lint_on PINCONNECTEMPTY */ wire[16:0] old_tag; wire old_valid; wire old_dirty; wire[16:0] new_tag = evict ? tag_write : old_tag; wire new_valid = evict ? 1 : old_valid; wire new_dirty = update_dirty ? dirt_new : old_dirty; wire cenb_m = (evict || update_dirty); wire[19-1:0][31:0] write_bit_mask_m = cenb_m ? 19'b0 : 19'b1; // Try to fix the error in memory conneciton, modified by Lingjun Zhu on Oct. 28 2019 // wire[NUM_WORDS_PER_BLOCK-1:0][31:0] wdata_m = {new_tag, new_dirty, new_valid}; // wire[NUM_WORDS_PER_BLOCK-1:0][31:0] data_out_m; wire[19-1:0] wdata_m = {new_tag, new_dirty, new_valid}; wire[19-1:0] data_out_m; assign {old_tag, old_dirty, old_valid} = data_out_m; assign dirty_use = old_dirty; assign valid_use = old_valid; assign tag_use = old_tag; /* verilator lint_off PINCONNECTEMPTY */ rf2_32x19_wm0 meta ( .CENYA(), .AYA(), .CENYB(), // .WENYB(), .AYB(), .QA(data_out_m), .SOA(), .SOB(), .CLKA(clk), .CENA(cena), .AA(use_addr), .CLKB(clk), .CENB(cenb_m), // .WENB(write_bit_mask_m), .AB(use_addr), .DB(wdata_m), .EMAA(3'b011), .EMASA(1'b0), .EMAB(3'b011), .TENA(1'b1), .TCENA(1'b0), .TAA(5'b0), .TENB(1'b1), .TCENB(1'b0), // .TWENB(128'b0), .TAB(5'b0), .TDB(19'b0), .RET1N(1'b1), .SIA(2'b0), .SEA(1'b0), .DFTRAMBYP(1'b0), .SIB(2'b0), .SEB(1'b0), .COLLDISN(1'b1) ); /* verilator lint_on PINCONNECTEMPTY */ `endif endmodule