URL
https://opencores.org/ocsvn/s1_core/s1_core/trunk
Subversion Repositories s1_core
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 38 to Rev 39
- ↔ Reverse comparison
Rev 38 → Rev 39
/trunk/tools/src/bw_r_idct.v
0,0 → 1,32
// Empty module for cacheless Simply RISC S1 Core |
|
module bw_r_idct(rdtag_w0_y, rdtag_w1_y, rdtag_w2_y, rdtag_w3_y, so, rclk, se, |
si, reset_l, sehold, rst_tri_en, index0_x, index1_x, index_sel_x, |
dec_wrway_x, rdreq_x, wrreq_x, wrtag_w0_y, wrtag_w1_y, wrtag_w2_y, |
wrtag_w3_y, adj); |
|
input rclk; |
input se; |
input si; |
input reset_l; |
input sehold; |
input rst_tri_en; |
input [6:0] index0_x; |
input [6:0] index1_x; |
input index_sel_x; |
input [3:0] dec_wrway_x; |
input rdreq_x; |
input wrreq_x; |
input [32:0] wrtag_w0_y; |
input [32:0] wrtag_w1_y; |
input [32:0] wrtag_w2_y; |
input [32:0] wrtag_w3_y; |
input [3:0] adj; |
output [32:0] rdtag_w0_y; |
output [32:0] rdtag_w1_y; |
output [32:0] rdtag_w2_y; |
output [32:0] rdtag_w3_y; |
output so; |
|
endmodule |
|
/trunk/tools/src/bw_r_dcd.v
0,0 → 1,68
// Empty module for cacheless Simply RISC S1 Core |
|
module bw_r_dcd ( |
// Outputs |
so, dcache_rdata_wb, dcache_rparity_wb, dcache_rparity_err_wb, |
dcache_rdata_msb_w0_m, dcache_rdata_msb_w1_m, |
dcache_rdata_msb_w2_m, dcache_rdata_msb_w3_m, |
dcd_fuse_repair_value, dcd_fuse_repair_en, |
// Inputs |
dcache_rd_addr_e, dcache_alt_addr_e, dcache_rvld_e, dcache_wvld_e, |
dcache_wdata_e, dcache_wr_rway_e, dcache_byte_wr_en_e, |
dcache_alt_rsel_way_e, dcache_rsel_way_wb, dcache_alt_mx_sel_e, |
si, se, sehold, rst_tri_en, arst_l, rclk, dcache_alt_data_w0_m, |
dcache_arry_data_sel_m, efc_spc_fuse_clk1, fuse_dcd_wren, |
fuse_dcd_rid, fuse_dcd_repair_value, fuse_dcd_repair_en |
) ; |
|
input [10:3] dcache_rd_addr_e; // read cache index [10:4] + bit [3] offset |
input [10:3] dcache_alt_addr_e; // write/bist/diagnostic read cache index + offset |
|
input dcache_rvld_e; // read accesses d$. |
input dcache_wvld_e; // valid write setup to m-stage. |
|
input [143:0] dcache_wdata_e; // write data - 16Bx8 + 8b parity. |
input [3:0] dcache_wr_rway_e; // replacement way for load miss/store. |
input [15:0] dcache_byte_wr_en_e; // 16b byte wr enable for stores. |
|
input [3:0] dcache_alt_rsel_way_e ; // bist/diagnostic read way select |
input [3:0] dcache_rsel_way_wb; // load way select, connect to cache_way_hit |
input dcache_alt_mx_sel_e; |
|
input si; |
input se; |
input sehold; |
|
output so; |
|
input rst_tri_en ; |
|
input arst_l; // used for redundancy flops - do not reset on wrm reset. |
|
input rclk; |
|
output [63:0] dcache_rdata_wb; |
output [7:0] dcache_rparity_wb; |
output dcache_rparity_err_wb; |
|
input [63:0] dcache_alt_data_w0_m; //from qdp1 |
input dcache_arry_data_sel_m; //from dctl |
|
output [7:0] dcache_rdata_msb_w0_m; //to dcdp |
output [7:0] dcache_rdata_msb_w1_m; //to dcdp |
output [7:0] dcache_rdata_msb_w2_m; //to dcdp |
output [7:0] dcache_rdata_msb_w3_m; //to dcdp |
|
input efc_spc_fuse_clk1; |
|
input fuse_dcd_wren; //redundancy register write enable, qualified |
input [2:0] fuse_dcd_rid; //redundancy register id |
input [7:0] fuse_dcd_repair_value; //data in for redundancy register |
input [1:0] fuse_dcd_repair_en; //enable bits to turn on redundancy |
output [7:0] dcd_fuse_repair_value; //data out for redundancy register |
output [1:0] dcd_fuse_repair_en; //enable bits out |
|
|
endmodule |
|
|
/trunk/tools/src/bw_r_icd.v
0,0 → 1,41
// Empty module for cacheless Simply RISC S1 Core |
|
module bw_r_icd(icd_wsel_fetdata_s1, icd_wsel_topdata_s1, icd_fuse_repair_value, |
icd_fuse_repair_en, so, rclk, se, si, reset_l, sehold, fdp_icd_index_bf, |
ifq_icd_index_bf, fcl_icd_index_sel_ifq_bf, ifq_icd_wrway_bf, |
ifq_icd_worden_bf, ifq_icd_wrdata_i2, fcl_icd_rdreq_bf, |
fcl_icd_wrreq_bf, bist_ic_data, rst_tri_en, ifq_icd_data_sel_old_i2, |
ifq_icd_data_sel_fill_i2, ifq_icd_data_sel_bist_i2, fuse_icd_wren, |
fuse_icd_rid, fuse_icd_repair_value, fuse_icd_repair_en, |
efc_spc_fuse_clk1); |
|
input rclk; |
input se; |
input si; |
input reset_l; |
input sehold; |
input [11:2] fdp_icd_index_bf; |
input [11:2] ifq_icd_index_bf; |
input fcl_icd_index_sel_ifq_bf; |
input [1:0] ifq_icd_wrway_bf; |
input [3:0] ifq_icd_worden_bf; |
input [135:0] ifq_icd_wrdata_i2; |
input fcl_icd_rdreq_bf; |
input fcl_icd_wrreq_bf; |
input [7:0] bist_ic_data; |
input rst_tri_en; |
input ifq_icd_data_sel_old_i2; |
input ifq_icd_data_sel_fill_i2; |
input ifq_icd_data_sel_bist_i2; |
input fuse_icd_wren; |
input [3:0] fuse_icd_rid; |
input [7:0] fuse_icd_repair_value; |
input [1:0] fuse_icd_repair_en; |
input efc_spc_fuse_clk1; |
output [135:0] icd_wsel_fetdata_s1; |
output [135:0] icd_wsel_topdata_s1; |
output [7:0] icd_fuse_repair_value; |
output [1:0] icd_fuse_repair_en; |
output so; |
|
endmodule |
/trunk/hdl/rtl/sparc_core/bw_r_idct.v
1,54 → 1,5
// ========== Copyright Header Begin ========================================== |
// |
// OpenSPARC T1 Processor File: bw_r_idct.v |
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
// |
// The above named program is free software; you can redistribute it and/or |
// modify it under the terms of the GNU General Public |
// License version 2 as published by the Free Software Foundation. |
// |
// The above named program is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
// General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this work; if not, write to the Free Software |
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
// |
// ========== Copyright Header End ============================================ |
//////////////////////////////////////////////////////////////////////// |
/* |
// Module Name: bw_r_idct.v |
// Description: |
// Contains the RTL for the icache and dcache tag blocks. |
// This is a 1RW 512 entry X 33b macro, with 132b rd and 132b wr, |
// broken into 4 33b segments with its own write enable. |
// Address and Control inputs are available the stage before |
// array access, which is referred to as "_x". Write data is |
// available in the same stage as the write to the ram, referred |
// to as "_y". Read data is also read out and available in "_y". |
// |
// X | Y |
// index | ram access |
// index sel | write_tag |
// rd/wr req | -> read_tag |
// way enable | |
*/ |
// Empty module for cacheless Simply RISC S1 Core |
|
|
//////////////////////////////////////////////////////////////////////// |
// Local header file includes / local defines |
//////////////////////////////////////////////////////////////////////// |
|
//FPGA_SYN enables all FPGA related modifications |
`ifdef FPGA_SYN |
`define FPGA_SYN_IDCT |
`endif |
|
`ifdef FPGA_SYN_IDCT |
|
module bw_r_idct(rdtag_w0_y, rdtag_w1_y, rdtag_w2_y, rdtag_w3_y, so, rclk, se, |
si, reset_l, sehold, rst_tri_en, index0_x, index1_x, index_sel_x, |
dec_wrway_x, rdreq_x, wrreq_x, wrtag_w0_y, wrtag_w1_y, wrtag_w2_y, |
76,322 → 27,6
output [32:0] rdtag_w2_y; |
output [32:0] rdtag_w3_y; |
output so; |
|
wire clk; |
reg [6:0] index_y; |
reg rdreq_y; |
reg wrreq_y; |
reg [3:0] dec_wrway_y; |
wire [6:0] index_x; |
wire [3:0] we; |
|
reg [131:0] rdtag_sa_y; //for error_inject XMR |
|
assign clk = rclk; |
assign index_x = (index_sel_x ? index1_x : index0_x); |
assign we = ({4 {((wrreq_y & reset_l) & (~rst_tri_en))}} & dec_wrway_y); |
|
always @(posedge clk) begin |
if (~sehold) begin |
rdreq_y <= rdreq_x; |
wrreq_y <= wrreq_x; |
index_y <= index_x; |
dec_wrway_y <= dec_wrway_x; |
end |
end |
|
bw_r_idct_array ictag_ary_00( |
.we (we[0]), |
.clk (clk), |
.rd_data(rdtag_w0_y), |
.wr_data(wrtag_w0_y), |
.addr (index_y)); |
|
bw_r_idct_array ictag_ary_01( |
.we (we[1]), |
.clk (clk), |
.rd_data(rdtag_w1_y), |
.wr_data(wrtag_w1_y), |
.addr (index_y)); |
|
bw_r_idct_array ictag_ary_10( |
.we (we[2]), |
.clk (clk), |
.rd_data(rdtag_w2_y), |
.wr_data(wrtag_w2_y), |
.addr (index_y)); |
|
bw_r_idct_array ictag_ary_11( |
.we (we[3]), |
.clk (clk), |
.rd_data(rdtag_w3_y), |
.wr_data(wrtag_w3_y), |
.addr (index_y)); |
|
|
endmodule |
|
module bw_r_idct_array(we, clk, rd_data, wr_data, addr); |
|
input we; |
input clk; |
input [32:0] wr_data; |
input [6:0] addr; |
output [32:0] rd_data; |
reg [32:0] rd_data; |
|
reg [32:0] array[127:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
|
|
always @(negedge clk) begin |
if (we) array[addr] <= wr_data; |
else rd_data <= array[addr]; |
end |
endmodule |
|
`else |
|
module bw_r_idct(/*AUTOARG*/ |
// Outputs |
rdtag_w0_y, rdtag_w1_y, rdtag_w2_y, rdtag_w3_y, so, |
// Inputs |
rclk, se, si, reset_l, sehold, rst_tri_en, index0_x, index1_x, |
index_sel_x, dec_wrway_x, rdreq_x, wrreq_x, wrtag_w0_y, |
wrtag_w1_y, wrtag_w2_y, wrtag_w3_y, adj |
); |
|
input rclk, |
se, |
si, |
reset_l; // active LOW reset |
|
input sehold; |
input rst_tri_en; |
|
input [6:0] index0_x; // read/write address0 |
input [6:0] index1_x; // read/write address1 |
|
input index_sel_x; // selects between index1 and index0 |
|
input [3:0] dec_wrway_x; // way -- functions as a write enable |
// per 33b |
|
input rdreq_x, // read enable |
wrreq_x; // write enable |
|
// Don't use rdreq and wrreq to gate off the clock, since these are |
// critical. A separate power down signal can be supplied if |
// needed. |
|
input [32:0] wrtag_w0_y; // write data, not flopped |
input [32:0] wrtag_w1_y; // |
input [32:0] wrtag_w2_y; // |
input [32:0] wrtag_w3_y; // |
|
input [3:0] adj; |
|
|
output [32:0] rdtag_w0_y; // read data split into 4 ports |
output [32:0] rdtag_w1_y; // not flopped |
output [32:0] rdtag_w2_y; // |
output [32:0] rdtag_w3_y; // |
|
output so; |
|
|
// Declarations |
// local signals |
`ifdef DEFINE_0IN |
`else |
reg [32:0] ictag_ary [511:0]; |
reg [131:0] rdtag_bl_y, |
rdtag_sa_y; |
`endif |
|
wire clk; |
|
|
reg [6:0] index_y; |
reg rdreq_y, |
wrreq_y; |
reg [3:0] dec_wrway_y; |
|
wire [6:0] index_x; |
|
|
//---------------- |
// Code start here |
//---------------- |
|
assign clk = rclk; |
|
//------------------------- |
// 2:1 mux on address input |
//------------------------- |
// address inputs are critical and this mux needs to be merged with |
// the receiving flop. |
assign index_x = index_sel_x ? index1_x : |
index0_x; |
|
//------------------------ |
// input flops from x to y |
//------------------------ |
// these need to be scannable |
always @ (posedge clk) |
begin |
if (~sehold) |
begin |
rdreq_y <= rdreq_x; |
wrreq_y <= wrreq_x; |
index_y <= index_x; |
dec_wrway_y <= dec_wrway_x; |
end |
end |
|
`ifdef DEFINE_0IN |
wire [131:0] wm = { {33{(dec_wrway_y[3])}},{33{(dec_wrway_y[2])}},{33{(dec_wrway_y[1])}},{33{(dec_wrway_y[0])}} }; |
wire we = wrreq_y & ~se; |
|
l1_tag l1_tag ( .nclk(~clk), .adr(index_y[6:0]), .we(we), .wm(wm), |
.din ({wrtag_w3_y,wrtag_w2_y,wrtag_w1_y,wrtag_w0_y}), |
.dout({rdtag_w3_y,rdtag_w2_y,rdtag_w1_y,rdtag_w0_y}) ); |
`else |
|
//---------------------------------------------------------------------- |
// Read Operation |
//---------------------------------------------------------------------- |
|
always @(/*AUTOSENSE*/ /*memory or*/ index_y or rdreq_y or reset_l |
or wrreq_y) |
begin |
if (rdreq_y & reset_l) |
begin |
if (wrreq_y) // rd_wr conflict |
begin |
rdtag_bl_y = {132{1'bx}}; |
end |
|
else // no write, read only |
begin |
rdtag_bl_y[32:0] = ictag_ary[{index_y,2'b00}]; // way0 |
rdtag_bl_y[65:33] = ictag_ary[{index_y,2'b01}]; // way1 |
rdtag_bl_y[98:66] = ictag_ary[{index_y,2'b10}]; // way2 |
rdtag_bl_y[131:99] = ictag_ary[{index_y,2'b11}];// way3 |
end |
end |
else // no read |
begin |
rdtag_bl_y = {132{1'bx}}; |
end |
|
end // always @ (... |
|
|
// SA latch -- to make 0in happy |
always @ (/*AUTOSENSE*/clk or rdreq_y or rdtag_bl_y or reset_l) |
begin |
if (rdreq_y & ~clk & reset_l) |
begin |
rdtag_sa_y <= rdtag_bl_y; |
end |
end |
|
// Output is held the same if there is no read. This is not a |
// hard requirement, please let me know if the output has to |
// be something else for ease of implementation. |
|
// Output behavior during reset is currently not coded. |
// Functionally there is no preference, though it should be |
// unchanging to keep the power low. |
|
// Final Output |
assign rdtag_w0_y = rdtag_sa_y[32:0]; |
assign rdtag_w1_y = rdtag_sa_y[65:33]; |
assign rdtag_w2_y = rdtag_sa_y[98:66]; |
assign rdtag_w3_y = rdtag_sa_y[131:99]; |
|
|
//---------------------------------------------------------------------- |
// Write Operation |
//---------------------------------------------------------------------- |
// Writes should be blocked off during scan shift. |
always @ (negedge clk) |
begin |
if (wrreq_y & reset_l & ~rst_tri_en) |
begin |
if (dec_wrway_y[0]) |
ictag_ary[{index_y, 2'b00}] = wrtag_w0_y; |
if (dec_wrway_y[1]) |
ictag_ary[{index_y, 2'b01}] = wrtag_w1_y; |
if (dec_wrway_y[2]) |
ictag_ary[{index_y, 2'b10}] = wrtag_w2_y; |
if (dec_wrway_y[3]) |
ictag_ary[{index_y, 2'b11}] = wrtag_w3_y; |
end |
end |
|
// TBD: Need to model rd-wr contention |
`endif |
|
//****************************************************** |
// The stuff below is not part of the main functionality |
// and has no representation in the actual circuit. |
//****************************************************** |
|
// synopsys translate_off |
|
//----------------------- |
// Contention Monitor |
//----------------------- |
`ifdef INNO_MUXEX |
`else |
always @ (negedge clk) |
begin |
if (rdreq_y & wrreq_y & reset_l) |
begin |
// 0in <fire -message "FATAL ERROR: rd and wr contention in idct" |
//$display("IDtag Contention", "ERROR rd and wr contention in idct"); |
end |
end // always @ (negedge clk) |
|
`endif |
|
|
//-------------------------------- |
// // For dump_cache.v |
// //-------------------------------- |
// //fake to make dump_cache.v happy |
// reg [29:0] w0 [127:0]; |
// reg [29:0] w1 [127:0]; |
// reg [29:0] w2 [127:0]; |
// reg [29:0] w3 [127:0]; |
// |
// always @ (negedge clk) |
// begin |
// if (wrreq_y & ~se) |
// begin |
// if (rdreq_y) begin // rd/wr contention |
// case (dec_wrway_y) |
// 4'b0001 : w0[index_y[6:0]] ={30{1'bx}}; |
// 4'b0010 : w1[index_y[6:0]] ={30{1'bx}}; |
// 4'b0100 : w2[index_y[6:0]] ={30{1'bx}}; |
// 4'b1000 : w3[index_y[6:0]] ={30{1'bx}}; |
// endcase // case(wrway_y) |
// end |
// else begin |
// case (dec_wrway_y) |
// 4'b0001 : w0[index_y[6:0]] = wrtag_w0_y[29:0]; |
// 4'b0010 : w1[index_y[6:0]] = wrtag_w1_y[29:0]; |
// 4'b0100 : w2[index_y[6:0]] = wrtag_w2_y[29:0]; |
// 4'b1000 : w3[index_y[6:0]] = wrtag_w3_y[29:0]; |
// endcase // case(wrway_y) |
// end |
// end |
// end |
|
// synopsys translate_on |
|
endmodule // bw_r_idct |
|
`endif |
|
|
/trunk/hdl/rtl/sparc_core/bw_r_icd.v
1,63 → 1,5
// ========== Copyright Header Begin ========================================== |
// |
// OpenSPARC T1 Processor File: bw_r_icd.v |
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
// |
// The above named program is free software; you can redistribute it and/or |
// modify it under the terms of the GNU General Public |
// License version 2 as published by the Free Software Foundation. |
// |
// The above named program is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
// General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this work; if not, write to the Free Software |
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
// |
// ========== Copyright Header End ============================================ |
//////////////////////////////////////////////////////////////////////// |
/* |
// Module Name: bw_r_icd |
// Description: |
// The ICD contains the icache data. |
// 32B line size. |
// Write BW: 16B |
// Read BW: 16Bx2 (fetdata and topdata), collapsed to 4Bx2 |
// Associativity: 4 |
// Write boundary: 34b (32b inst + parity + predec bit) |
// NOTES: |
// 1. No clock enable. Rd/Wr enable is used to trigger the |
// operation. |
// 2. 2:1 mux on address input. Selects provided externally. |
// 3. 3:1 mux on data input. Selects provided and guaranteed |
// exclusive, externally. |
// |
*/ |
// Empty module for cacheless Simply RISC S1 Core |
|
|
//////////////////////////////////////////////////////////////////////// |
// Global header file includes |
//////////////////////////////////////////////////////////////////////// |
//`include "sys.h" // system level definition file which contains the |
// time scale definition |
|
|
//////////////////////////////////////////////////////////////////////// |
// Local header file includes / local defines |
//////////////////////////////////////////////////////////////////////// |
|
`include "ifu.h" |
|
//FPGA_SYN enables all FPGA related modifications |
`ifdef FPGA_SYN |
`define FPGA_SYN_ICD |
`endif |
|
`ifdef FPGA_SYN_ICD |
|
module bw_r_icd(icd_wsel_fetdata_s1, icd_wsel_topdata_s1, icd_fuse_repair_value, |
icd_fuse_repair_en, so, rclk, se, si, reset_l, sehold, fdp_icd_index_bf, |
ifq_icd_index_bf, fcl_icd_index_sel_ifq_bf, ifq_icd_wrway_bf, |
96,785 → 38,4
output [1:0] icd_fuse_repair_en; |
output so; |
|
reg [7:0] icd_fuse_repair_value; |
reg [1:0] icd_fuse_repair_en; |
reg [135:0] fetdata_f; |
reg [135:0] topdata_f; |
reg [135:0] fetdata_sa; |
reg [135:0] topdata_sa; |
reg [135:0] fetdata_s1; |
reg [135:0] topdata_s1; |
wire clk; |
wire [135:0] next_wrdata_bf; |
wire [135:0] wrdata_f; |
wire [135:0] bist_data_expand; |
wire [11:2] index_bf; |
reg [11:2] index_f; |
reg [11:0] wr_index0; |
reg [11:0] wr_index1; |
reg [11:0] wr_index2; |
reg [11:0] wr_index3; |
reg rdreq_f; |
reg wrreq_f; |
reg [3:0] worden_f; |
reg [1:0] wrway_f; |
|
reg [33:0] icdata_ary_00_00 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_00_01 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_00_10 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_00_11 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_01_00 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_01_01 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_01_10 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_01_11 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_10_00 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_10_01 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_10_10 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_10_11 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_11_00 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_11_01 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_11_10 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
reg [33:0] icdata_ary_11_11 [255:0] /* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; |
|
|
|
assign clk = rclk; |
assign index_bf = (fcl_icd_index_sel_ifq_bf ? ifq_icd_index_bf : |
fdp_icd_index_bf); |
wire [11:2] top_index = {index_f[11:3] , 1'b1}; |
|
assign bist_data_expand = {bist_ic_data[1:0], {4 {bist_ic_data[7:0]}}, |
bist_ic_data[1:0], {4 {bist_ic_data[7:0]}}, bist_ic_data[1:0], |
{4 {bist_ic_data[7:0]}}, bist_ic_data[1:0], {4 |
{bist_ic_data[7:0]}}}; |
assign icd_wsel_fetdata_s1 = fetdata_s1; |
assign icd_wsel_topdata_s1 = topdata_s1; |
|
mux3ds #(136) icden_mux( |
.dout (next_wrdata_bf), |
.in0 (wrdata_f), |
.in1 (ifq_icd_wrdata_i2), |
.in2 (bist_data_expand), |
.sel0 (ifq_icd_data_sel_old_i2), |
.sel1 (ifq_icd_data_sel_fill_i2), |
.sel2 (ifq_icd_data_sel_bist_i2)); |
dffe #(136) wrdata_reg( |
.din (next_wrdata_bf), |
.clk (clk), |
.q (wrdata_f), |
.en ((~sehold)), |
.se (se)); |
|
always @(posedge clk) begin |
if (~sehold) begin |
rdreq_f <= fcl_icd_rdreq_bf; |
wrreq_f <= fcl_icd_wrreq_bf; |
index_f <= index_bf; |
wrway_f <= ifq_icd_wrway_bf; |
worden_f <= ifq_icd_worden_bf; |
wr_index0 <= {index_bf[11:4], 2'b0, ifq_icd_wrway_bf}; |
wr_index1 <= {index_bf[11:4], 2'b1, ifq_icd_wrway_bf}; |
wr_index2 <= {index_bf[11:4], 2'b10, ifq_icd_wrway_bf}; |
wr_index3 <= {index_bf[11:4], 2'b11, ifq_icd_wrway_bf}; |
end |
fetdata_s1 <= fetdata_f; |
topdata_s1 <= topdata_f; |
end |
|
reg [33:0] fetch_00_00; |
reg [33:0] fetch_00_01; |
reg [33:0] fetch_00_10; |
reg [33:0] fetch_00_11; |
|
reg [33:0] fetch_01_00; |
reg [33:0] fetch_01_01; |
reg [33:0] fetch_01_10; |
reg [33:0] fetch_01_11; |
|
reg [33:0] fetch_10_00; |
reg [33:0] fetch_10_01; |
reg [33:0] fetch_10_10; |
reg [33:0] fetch_10_11; |
|
reg [33:0] fetch_11_00; |
reg [33:0] fetch_11_01; |
reg [33:0] fetch_11_10; |
reg [33:0] fetch_11_11; |
|
always @(posedge clk) begin |
fetch_00_00 <= icdata_ary_00_00[index_bf[11:4]]; |
fetch_00_01 <= icdata_ary_00_01[index_bf[11:4]]; |
fetch_00_10 <= icdata_ary_00_10[index_bf[11:4]]; |
fetch_00_11 <= icdata_ary_00_11[index_bf[11:4]]; |
|
fetch_01_00 <= icdata_ary_01_00[index_bf[11:4]]; |
fetch_01_01 <= icdata_ary_01_01[index_bf[11:4]]; |
fetch_01_10 <= icdata_ary_01_10[index_bf[11:4]]; |
fetch_01_11 <= icdata_ary_01_11[index_bf[11:4]]; |
|
fetch_10_00 <= icdata_ary_10_00[index_bf[11:4]]; |
fetch_10_01 <= icdata_ary_10_01[index_bf[11:4]]; |
fetch_10_10 <= icdata_ary_10_10[index_bf[11:4]]; |
fetch_10_11 <= icdata_ary_10_11[index_bf[11:4]]; |
|
fetch_11_00 <= icdata_ary_11_00[index_bf[11:4]]; |
fetch_11_01 <= icdata_ary_11_01[index_bf[11:4]]; |
fetch_11_10 <= icdata_ary_11_10[index_bf[11:4]]; |
fetch_11_11 <= icdata_ary_11_11[index_bf[11:4]]; |
end |
|
|
always @(index_f or rdreq_f or fetch_00_00 or fetch_01_00 or fetch_10_00 or fetch_11_00 |
or fetch_00_01 or fetch_01_01 or fetch_10_01 or fetch_11_01 |
or fetch_00_10 or fetch_01_10 or fetch_10_10 or fetch_11_10 |
or fetch_00_11 or fetch_01_11 or fetch_10_11 or fetch_11_11) begin |
if (rdreq_f) begin |
case(index_f[3:2]) |
2'b00: fetdata_f[33:0] = fetch_00_00; |
2'b01: fetdata_f[33:0] = fetch_01_00; |
2'b10: fetdata_f[33:0] = fetch_10_00; |
2'b11: fetdata_f[33:0] = fetch_11_00; |
endcase |
case(index_f[3:2]) |
2'b00: fetdata_f[67:34] = fetch_00_01; |
2'b01: fetdata_f[67:34] = fetch_01_01; |
2'b10: fetdata_f[67:34] = fetch_10_01; |
2'b11: fetdata_f[67:34] = fetch_11_01; |
endcase |
case(index_f[3:2]) |
2'b00: fetdata_f[101:68] = fetch_00_10; |
2'b01: fetdata_f[101:68] = fetch_01_10; |
2'b10: fetdata_f[101:68] = fetch_10_10; |
2'b11: fetdata_f[101:68] = fetch_11_10; |
endcase |
case(index_f[3:2]) |
2'b00: fetdata_f[135:102] = fetch_00_11; |
2'b01: fetdata_f[135:102] = fetch_01_11; |
2'b10: fetdata_f[135:102] = fetch_10_11; |
2'b11: fetdata_f[135:102] = fetch_11_11; |
endcase |
case(index_f[3]) |
1'b0: topdata_f[33:0] = fetch_01_00; |
1'b1: topdata_f[33:0] = fetch_11_00; |
endcase |
case(index_f[3]) |
1'b0: topdata_f[67:34] = fetch_01_01; |
1'b1: topdata_f[67:34] = fetch_11_01; |
endcase |
case(index_f[3]) |
1'b0: topdata_f[101:68] = fetch_01_10; |
1'b1: topdata_f[101:68] = fetch_11_10; |
endcase |
case(index_f[3]) |
1'b0: topdata_f[135:102] = fetch_01_11; |
1'b1: topdata_f[135:102] = fetch_11_11; |
endcase |
end |
else |
begin |
fetdata_f = 136'b0; |
topdata_f = 136'b0; |
end |
end |
|
always @(negedge clk) begin |
if (wrreq_f & (~rst_tri_en)) begin |
if (worden_f[0]) begin |
if (wr_index0[1:0] == 2'b0) begin |
icdata_ary_00_00[wr_index0[11:4]] <= wrdata_f[135:102]; |
end |
if (wr_index0[1:0] == 2'b1) begin |
icdata_ary_00_01[wr_index0[11:4]] <= wrdata_f[135:102]; |
end |
if (wr_index0[1:0] == 2'b10) begin |
icdata_ary_00_10[wr_index0[11:4]] <= wrdata_f[135:102]; |
end |
if (wr_index0[1:0] == 2'b11) begin |
icdata_ary_00_11[wr_index0[11:4]] <= wrdata_f[135:102]; |
end |
end |
if (worden_f[1]) begin |
if (wr_index1[1:0] == 2'b0) begin |
icdata_ary_01_00[wr_index1[11:4]] <= wrdata_f[101:68]; |
end |
if (wr_index1[1:0] == 2'b1) begin |
icdata_ary_01_01[wr_index1[11:4]] <= wrdata_f[101:68]; |
end |
if (wr_index1[1:0] == 2'b10) begin |
icdata_ary_01_10[wr_index1[11:4]] <= wrdata_f[101:68]; |
end |
if (wr_index1[1:0] == 2'b11) begin |
icdata_ary_01_11[wr_index1[11:4]] <= wrdata_f[101:68]; |
end |
end |
if (worden_f[2]) begin |
if (wr_index2[1:0] == 2'b0) begin |
icdata_ary_10_00[wr_index2[11:4]] <= wrdata_f[67:34]; |
end |
if (wr_index2[1:0] == 2'b1) begin |
icdata_ary_10_01[wr_index2[11:4]] <= wrdata_f[67:34]; |
end |
if (wr_index2[1:0] == 2'b10) begin |
icdata_ary_10_10[wr_index2[11:4]] <= wrdata_f[67:34]; |
end |
if (wr_index2[1:0] == 2'b11) begin |
icdata_ary_10_11[wr_index2[11:4]] <= wrdata_f[67:34]; |
end |
end |
if (worden_f[3]) begin |
if (wr_index3[1:0] == 2'b0) begin |
icdata_ary_11_00[wr_index3[11:4]] <= wrdata_f[33:0]; |
end |
if (wr_index3[1:0] == 2'b1) begin |
icdata_ary_11_01[wr_index3[11:4]] <= wrdata_f[33:0]; |
end |
if (wr_index3[1:0] == 2'b10) begin |
icdata_ary_11_10[wr_index3[11:4]] <= wrdata_f[33:0]; |
end |
if (wr_index3[1:0] == 2'b11) begin |
icdata_ary_11_11[wr_index3[11:4]] <= wrdata_f[33:0]; |
end |
end |
end |
end |
endmodule |
|
`else |
|
module bw_r_icd(/*AUTOARG*/ |
// Outputs |
icd_wsel_fetdata_s1, icd_wsel_topdata_s1, icd_fuse_repair_value, |
icd_fuse_repair_en, so, |
// Inputs |
rclk, se, si, reset_l, sehold, fdp_icd_index_bf, ifq_icd_index_bf, |
fcl_icd_index_sel_ifq_bf, ifq_icd_wrway_bf, ifq_icd_worden_bf, |
ifq_icd_wrdata_i2, fcl_icd_rdreq_bf, fcl_icd_wrreq_bf, |
bist_ic_data, rst_tri_en, ifq_icd_data_sel_old_i2, |
ifq_icd_data_sel_fill_i2, ifq_icd_data_sel_bist_i2, fuse_icd_wren, |
fuse_icd_rid, fuse_icd_repair_value, fuse_icd_repair_en, |
efc_spc_fuse_clk1 |
); |
|
input rclk, |
se, |
si, |
reset_l; |
input sehold; |
|
input [11:2] fdp_icd_index_bf, // index to write to/read from |
ifq_icd_index_bf; |
input fcl_icd_index_sel_ifq_bf; |
|
input [1:0] ifq_icd_wrway_bf; // way to write to |
input [3:0] ifq_icd_worden_bf; // word to write to (ignore index 1:0) |
input [135:0] ifq_icd_wrdata_i2; // 128b data, 4b sw, 4b parity |
|
input fcl_icd_rdreq_bf, |
fcl_icd_wrreq_bf; |
|
input [7:0] bist_ic_data; // needs to be expanded |
input rst_tri_en; |
|
// datain mux selects |
input ifq_icd_data_sel_old_i2, |
ifq_icd_data_sel_fill_i2, |
ifq_icd_data_sel_bist_i2; |
|
// efuse values for redundancy |
input fuse_icd_wren; |
input [3:0] fuse_icd_rid; |
input [7:0] fuse_icd_repair_value; |
input [1:0] fuse_icd_repair_en; |
|
// efuse non ovl clks |
input efc_spc_fuse_clk1; // use this clk to talk to fuse hdr |
// outputs |
output [135:0] icd_wsel_fetdata_s1, |
icd_wsel_topdata_s1; |
|
// redundancy reg read |
output [7:0] icd_fuse_repair_value; |
output [1:0] icd_fuse_repair_en; |
|
output so; |
|
|
//---------------------------------------------------------------------- |
// Declarations |
//---------------------------------------------------------------------- |
|
// local signals |
`ifdef DEFINE_0IN |
reg [135:0] fetdata_s1, |
topdata_s1; |
wire [135:0] fetdata_sa, |
topdata_sa; |
`else |
reg [33:0] icdata_ary [4095:0]; |
|
reg [135:0] fetdata_f, // way0 is lsb, way3 is msb |
topdata_f, |
fetdata_sa, |
topdata_sa, |
fetdata_s1, |
topdata_s1; |
`endif |
|
wire clk; |
|
wire [135:0] next_wrdata_bf, |
wrdata_f, |
bist_data_expand; |
|
wire [11:2] top_index, |
index_bf; |
|
reg [11:2] index_f; |
|
wire [11:0] wr_index0, |
wr_index1, |
wr_index2, |
wr_index3; |
|
reg rdreq_f, |
wrreq_f; |
reg [3:0] worden_f; |
reg [1:0] wrway_f; |
|
|
// redundancy crap |
reg [7:0] red0_ev_row, |
red0_od_row; |
reg [9:0] red0_ev_col, |
red0_od_col; |
reg [7:0] red1_ev_row, |
red1_od_row; |
reg [9:0] red1_ev_col, |
red1_od_col; |
reg [7:0] red2_ev_row, |
red2_od_row; |
reg [9:0] red2_ev_col, |
red2_od_col; |
reg [7:0] red3_ev_row, |
red3_od_row; |
reg [9:0] red3_ev_col, |
red3_od_col; |
|
reg [7:0] icd_fuse_repair_value; |
reg [1:0] icd_fuse_repair_en; |
|
|
// |
// Code start here |
// |
|
// clk header derives clk from rclk |
assign clk = rclk; |
|
|
// mux merged with flop |
assign index_bf = fcl_icd_index_sel_ifq_bf ? ifq_icd_index_bf : |
fdp_icd_index_bf; |
|
always @ (posedge clk) |
begin |
// input flops |
if (~sehold) |
begin |
rdreq_f <= fcl_icd_rdreq_bf; |
wrreq_f <= fcl_icd_wrreq_bf; |
index_f <= index_bf; |
wrway_f <= ifq_icd_wrway_bf; |
worden_f <= ifq_icd_worden_bf; |
end |
// S stage flops (for rd data) |
fetdata_s1 <= fetdata_sa; |
topdata_s1 <= topdata_sa; |
|
end // always @ (posedge clk) |
|
// BIST data |
assign bist_data_expand = {bist_ic_data[1:0], {4{bist_ic_data[7:0]}}, |
bist_ic_data[1:0], {4{bist_ic_data[7:0]}}, |
bist_ic_data[1:0], {4{bist_ic_data[7:0]}}, |
bist_ic_data[1:0], {4{bist_ic_data[7:0]}}}; |
|
|
// Mux + flop for write data input |
// ic data enable mux |
mux3ds #(136) icden_mux(.dout (next_wrdata_bf), |
.in0 (wrdata_f), |
.in1 (ifq_icd_wrdata_i2), |
.in2 (bist_data_expand), |
.sel0 (ifq_icd_data_sel_old_i2), |
.sel1 (ifq_icd_data_sel_fill_i2), |
.sel2 (ifq_icd_data_sel_bist_i2)); |
// write data regsiter |
// se hold is taken care of by external logic (in ifqctl) |
dffe #(136) wrdata_reg(.din (next_wrdata_bf), |
.clk (clk), |
.q (wrdata_f), |
.en (~sehold), |
.se (se), .si(), .so()); |
|
|
//---------------------------------------------------------------------- |
// Read Operation |
//---------------------------------------------------------------------- |
|
// The index has 2 parts. |
// 1. The 16B half-line index -- bits 11:4 |
// 2. The word offset -- bits 3:2 for reads, xx for writes |
// 3. The way -- wrway_f for writes, xx for reads |
// i.e. we read 1 word from each of 4 ways, but |
// we write 4 words to 1 way |
|
assign top_index = {index_f[11:3] , 1'b1}; |
|
`ifdef DEFINE_0IN |
// physical implmentation: ignore this and use else portion |
|
wire [15:0] we_wrd = ({ 3'b0,worden_f[3], 3'b0,worden_f[2], |
3'b0,worden_f[1], 3'b0,worden_f[0] }) << wrway_f; |
|
wire [543:0] we = (~wrreq_f ) ? 544'h0 : |
{ {34{we_wrd[15]}}, {34{we_wrd[14]}}, {34{we_wrd[13]}}, {34{we_wrd[12]}}, |
{34{we_wrd[11]}}, {34{we_wrd[10]}}, {34{we_wrd[ 9]}}, {34{we_wrd[ 8]}}, |
{34{we_wrd[ 7]}}, {34{we_wrd[ 6]}}, {34{we_wrd[ 5]}}, {34{we_wrd[ 4]}}, |
{34{we_wrd[ 3]}}, {34{we_wrd[ 2]}}, {34{we_wrd[ 1]}}, {34{we_wrd[ 0]}} }; |
|
wire [543:0] din = ({ {4{wrdata_f[ 33: 0]}}, {4{wrdata_f[ 67: 34]}}, |
{4{wrdata_f[101:68]}}, {4{wrdata_f[135:102]}} }); |
wire [543:0] dout; |
|
ic_data ic_data ( .nclk(~clk), .adr(index_f[11:4]), .we(we), .din(din), .dout(dout) ); |
|
wire [271:0] dout_l1 = index_f[3] ? dout[543:272] : dout[271:0]; |
|
assign fetdata_sa[135:0] = index_f[2] ? dout_l1[271:136] : dout_l1[135:0]; |
assign topdata_sa[135:0] = dout_l1[271:136]; |
|
|
`else |
|
// for physical implementation use this |
|
// read (inst[31:0] + sw bit + par bit) * 4 ways |
always @(/*AUTOSENSE*/ /*memory or*/ index_f or rdreq_f |
or top_index or wrreq_f) |
begin |
if (rdreq_f) |
begin |
if (wrreq_f) // rd-wr contention |
begin |
fetdata_f = 136'bx; |
topdata_f = 136'bx; |
end |
else |
begin // regular read |
fetdata_f[33:0] = icdata_ary[{index_f,2'b00}]; // way 0 |
fetdata_f[67:34] = icdata_ary[{index_f,2'b01}]; // way 1 |
fetdata_f[101:68] = icdata_ary[{index_f,2'b10}]; // way 2 |
fetdata_f[135:102] = icdata_ary[{index_f,2'b11}]; // way 3 |
|
topdata_f[33:0] = icdata_ary[{top_index, 2'b00}]; |
topdata_f[67:34] = icdata_ary[{top_index, 2'b01}]; |
topdata_f[101:68] = icdata_ary[{top_index, 2'b10}]; |
topdata_f[135:102] = icdata_ary[{top_index, 2'b11}]; |
end // else: !if(wrreq_f) |
end // if (rdreq_f) |
|
else // icache disabled or rd disabled |
begin |
// JC modified begin |
// fetdata_f = 136'bx; |
// topdata_f = 136'bx; |
fetdata_f = 136'b0; |
topdata_f = 136'b0; |
// JC modified end |
end // else: !if(rdreq_f) |
end // always @ (... |
|
|
// SA latch -- to make 0in happy |
always @ (clk or fetdata_f or topdata_f) |
begin |
if (~clk) |
begin |
fetdata_sa <= fetdata_f; |
topdata_sa <= topdata_f; |
end |
end |
`endif // !`ifdef DEFINE_0IN |
|
// final outputs (272bits) |
assign icd_wsel_fetdata_s1 = fetdata_s1; |
assign icd_wsel_topdata_s1 = topdata_s1; |
|
|
//---------------------------------------------------------------------- |
// Write Operation |
//---------------------------------------------------------------------- |
|
// The index has 3 parts. |
// 1. The 16B half-line index -- bits 11:4 of index_f |
// 2. The word offset -- bits 3:2 for reads, xx for writes |
// 3. The way -- wrway_f for writes, xx for reads |
|
// index word way |
// ----- ---- --- |
assign wr_index0 = {index_f[11:4], 2'b00, wrway_f}; |
assign wr_index1 = {index_f[11:4], 2'b01, wrway_f}; |
assign wr_index2 = {index_f[11:4], 2'b10, wrway_f}; |
assign wr_index3 = {index_f[11:4], 2'b11, wrway_f}; |
|
`ifdef DEFINE_0IN |
`else |
// assume write happens @ negedge clk (i.e. phase 1) |
always @ (negedge clk) |
begin |
if (wrreq_f & ~rst_tri_en) |
begin |
// instructions always Big Endian |
if (worden_f[0]) |
icdata_ary[wr_index0] <= wrdata_f[135:102]; |
if (worden_f[1]) |
icdata_ary[wr_index1] <= wrdata_f[101:68]; |
if (worden_f[2]) |
icdata_ary[wr_index2] <= wrdata_f[67:34]; |
if (worden_f[3]) |
icdata_ary[wr_index3] <= wrdata_f[33:0]; |
end // if (wrreq_f) |
end // always @ (... |
`endif // !`ifdef DEFINE_0IN |
|
|
//-------------------------------------------------------------- |
// Redundancy Registers |
//-------------------------------------------------------------- |
// |
// read red regs |
// 16:1 mux |
always @ (/*AUTOSENSE*/fuse_icd_rid or red0_ev_col or red0_ev_row |
or red0_od_col or red0_od_row or red1_ev_col |
or red1_ev_row or red1_od_col or red1_od_row |
or red2_ev_col or red2_ev_row or red2_od_col |
or red2_od_row or red3_ev_col or red3_ev_row |
or red3_od_col or red3_od_row) |
begin |
// sub array 0 |
if (fuse_icd_rid[3:0] == 4'b0) |
begin |
icd_fuse_repair_value = {2'b0, red0_ev_row[5:0]}; |
icd_fuse_repair_en = red0_ev_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b1) |
begin |
icd_fuse_repair_value = {2'b0, red0_od_row[5:0]}; |
icd_fuse_repair_en = red0_od_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b10) |
begin |
icd_fuse_repair_value = red0_ev_col[7:0]; |
icd_fuse_repair_en = red0_ev_col[9:8]; |
end |
else if (fuse_icd_rid[3:0] == 4'b11) |
begin |
icd_fuse_repair_value = red0_od_col[7:0]; |
icd_fuse_repair_en = red0_od_col[9:8]; |
end |
|
// sub array 1 |
else if (fuse_icd_rid[3:0] == 4'b100) |
begin |
icd_fuse_repair_value = {2'b0, red1_ev_row[5:0]}; |
icd_fuse_repair_en = red1_ev_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b101) |
begin |
icd_fuse_repair_value = {2'b0, red1_od_row[5:0]}; |
icd_fuse_repair_en = red1_od_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b110) |
begin |
icd_fuse_repair_value = red1_ev_col[7:0]; |
icd_fuse_repair_en = red1_ev_col[9:8]; |
end |
else if (fuse_icd_rid[3:0] == 4'b111) |
begin |
icd_fuse_repair_value = red1_od_col[7:0]; |
icd_fuse_repair_en = red1_od_col[9:8]; |
end |
|
// sub array 2 |
else if (fuse_icd_rid[3:0] == 4'b1000) |
begin |
icd_fuse_repair_value = {2'b0, red2_ev_row[5:0]}; |
icd_fuse_repair_en = red2_ev_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b1001) |
begin |
icd_fuse_repair_value = {2'b0, red2_od_row[5:0]}; |
icd_fuse_repair_en = red2_od_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b1010) |
begin |
icd_fuse_repair_value = red2_ev_col[7:0]; |
icd_fuse_repair_en = red2_ev_col[9:8]; |
end |
else if (fuse_icd_rid[3:0] == 4'b1011) |
begin |
icd_fuse_repair_value = red2_od_col[7:0]; |
icd_fuse_repair_en = red2_od_col[9:8]; |
end |
|
// sub array 3 |
else if (fuse_icd_rid[3:0] == 4'b1100) |
begin |
icd_fuse_repair_value = {2'b0, red3_ev_row[5:0]}; |
icd_fuse_repair_en = red3_ev_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b1101) |
begin |
icd_fuse_repair_value = {2'b0, red3_od_row[5:0]}; |
icd_fuse_repair_en = red3_od_row[7:6]; |
end |
else if (fuse_icd_rid[3:0] == 4'b1110) |
begin |
icd_fuse_repair_value = red3_ev_col[7:0]; |
icd_fuse_repair_en = red3_ev_col[9:8]; |
end |
else // if (fuse_icd_rid[3:0] == 4'b1111) |
begin |
icd_fuse_repair_value = red3_od_col[7:0]; |
icd_fuse_repair_en = red3_od_col[9:8]; |
end |
end // always @ (... |
|
|
// |
// write red regs |
// |
// use clk1 to latch anything to/from the hdr |
// |
// reset_l is an asynchronous reset. Only the the repair enables [9:8] |
// need to be reset. However, the actual circuit resets all the bits. |
always @ (posedge efc_spc_fuse_clk1 or negedge reset_l) |
begin |
if (~reset_l) |
begin // async reset |
red0_ev_row[7:0] <= 8'b0; |
red1_ev_row[7:0] <= 8'b0; |
red2_ev_row[7:0] <= 8'b0; |
red3_ev_row[7:0] <= 8'b0; |
|
red0_od_row[7:0] <= 8'b0; |
red1_od_row[7:0] <= 8'b0; |
red2_od_row[7:0] <= 8'b0; |
red3_od_row[7:0] <= 8'b0; |
|
red0_ev_col[9:0] <= 10'b0; |
red1_ev_col[9:0] <= 10'b0; |
red2_ev_col[9:0] <= 10'b0; |
red3_ev_col[9:0] <= 10'b0; |
|
red0_od_col[9:0] <= 10'b0; |
red1_od_col[9:0] <= 10'b0; |
red2_od_col[9:0] <= 10'b0; |
red3_od_col[9:0] <= 10'b0; |
end // if (~reset_l) |
|
else if (fuse_icd_wren & reset_l) |
begin // 4:16 decode |
if (fuse_icd_rid[3:0] == 4'b0) |
begin |
red0_ev_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b1) |
begin |
red0_od_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b10) |
begin |
red0_ev_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b11) |
begin |
red0_od_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
|
// sub array 1 |
else if (fuse_icd_rid[3:0] == 4'b100) |
begin |
red1_ev_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b101) |
begin |
red1_od_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b110) |
begin |
red1_ev_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b111) |
begin |
red1_od_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
|
// sub array 2 |
else if (fuse_icd_rid[3:0] == 4'b1000) |
begin |
red2_ev_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b1001) |
begin |
red2_od_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b1010) |
begin |
red2_ev_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b1011) |
begin |
red2_od_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
|
// sub array 2 |
else if (fuse_icd_rid[3:0] == 4'b1100) |
begin |
red3_ev_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b1101) |
begin |
red3_od_row <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[5:0]}; |
end |
else if (fuse_icd_rid[3:0] == 4'b1110) |
begin |
red3_ev_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
else // if (fuse_icd_rid[3:0] == 4'b1111) |
begin |
red3_od_col <= {fuse_icd_repair_en[1:0], |
fuse_icd_repair_value[7:0]}; |
end |
end // if (fuse_icd_wren) |
end // always @ (... |
|
endmodule // bw_r_icd |
|
`endif |
/trunk/hdl/rtl/sparc_core/bw_r_dcd.v
1,56 → 1,6
// ========== Copyright Header Begin ========================================== |
// |
// OpenSPARC T1 Processor File: bw_r_dcd.v |
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
// |
// The above named program is free software; you can redistribute it and/or |
// modify it under the terms of the GNU General Public |
// License version 2 as published by the Free Software Foundation. |
// |
// The above named program is distributed in the hope that it will be |
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
// General Public License for more details. |
// |
// You should have received a copy of the GNU General Public |
// License along with this work; if not, write to the Free Software |
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
// |
// ========== Copyright Header End ============================================ |
//////////////////////////////////////////////////////////////////////// |
/* |
// Module Name: |
// Description: LSU Data Cache. |
// - Physically-Indexed Physically Tagged (PIPT) |
// - 8KB |
// - 4 way set-associative. |
// - 16B lines |
// - 2:1 column select by choosing either lower |
// or upper half of 16B line. |
// - Parity protected on a byte basis. |
// - Byte enables for byte-wide stores. |
// |
*/ |
//////////////////////////////////////////////////////////////////////// |
// Global header file includes |
//////////////////////////////////////////////////////////////////////// |
//`include "sys.h" // system level definition file which contains the |
// time scale definition |
// Empty module for cacheless Simply RISC S1 Core |
|
//`include "iop.h" |
//`include "fabric.h" |
|
//FPGA_SYN enables all FPGA related modifications |
`ifdef FPGA_SYN |
`define FPGA_SYN_DCD |
`endif |
|
//////////////////////////////////////////////////////////////////////// |
// Local header file includes / local defines |
//////////////////////////////////////////////////////////////////////// |
|
module bw_r_dcd ( /*AUTOARG*/ |
module bw_r_dcd ( |
// Outputs |
so, dcache_rdata_wb, dcache_rparity_wb, dcache_rparity_err_wb, |
dcache_rdata_msb_w0_m, dcache_rdata_msb_w1_m, |
95,9 → 45,6
output [7:0] dcache_rparity_wb; |
output dcache_rparity_err_wb; |
|
//================================= |
// dc_fill critical path |
//================================= |
input [63:0] dcache_alt_data_w0_m; //from qdp1 |
input dcache_arry_data_sel_m; //from dctl |
|
106,10 → 53,6
output [7:0] dcache_rdata_msb_w2_m; //to dcdp |
output [7:0] dcache_rdata_msb_w3_m; //to dcdp |
|
//----------------------------------------------------------------------------- |
// 32KB block fuse inputs |
//----------------------------------------------------------------------------- |
// efuse non ovl clks |
input efc_spc_fuse_clk1; |
|
input fuse_dcd_wren; //redundancy register write enable, qualified |
119,518 → 62,7
output [7:0] dcd_fuse_repair_value; //data out for redundancy register |
output [1:0] dcd_fuse_repair_en; //enable bits out |
|
// Memory declaration. |
|
`ifdef DEFINE_0IN |
wire [143:0] temp_w0a; |
wire [143:0] temp_w1a; |
wire [143:0] temp_w2a; |
wire [143:0] temp_w3a; |
`else |
reg [143:0] w0 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity. |
reg [143:0] w1 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity. |
reg [143:0] w2 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity. |
reg [143:0] w3 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity. |
|
reg [143:0] temp_w0a_reg; |
reg [143:0] temp_w1a_reg; |
reg [143:0] temp_w2a_reg; |
reg [143:0] temp_w3a_reg; |
|
wire [143:0] temp_w0a; |
wire [143:0] temp_w1a; |
wire [143:0] temp_w2a; |
wire [143:0] temp_w3a; |
|
reg [143:0] temp_w0; |
reg [143:0] temp_w1; |
reg [143:0] temp_w2; |
reg [143:0] temp_w3; |
`endif |
reg [10:3] dcache_rwaddr_m ; |
reg [10:3] dcache_raddr_m ; |
reg dcache_rvld_m ; |
reg wvld_m ; |
reg [143:0] dcache_wdata_m ; |
reg [127:0] rw_wdline ; |
reg [3:0] dcache_wr_rway_m ; |
|
reg [63:0] dcache_rdata_w0_wb; // way0 64b data. |
reg [63:0] dcache_rdata_w1_wb; // way1 64b data. |
reg [63:0] dcache_rdata_w2_wb; // way2 64b data. |
reg [63:0] dcache_rdata_w3_wb; // way3 64b data. |
reg [15:0] byte_wr_enable ; |
reg [7:0] ctr; |
|
reg dcache_alt_mx_sel_m, dcache_alt_mx_sel_wb; |
reg [3:0] dcache_alt_rsel_way_m, dcache_alt_rsel_way_wb; |
|
integer i,j; |
|
wire dcache_wvld_m ; |
wire [63:0] dcache_rdata_w0_m; // way0 64b data. |
wire [63:0] dcache_rdata_w1_m; // way1 64b data. |
wire [63:0] dcache_rdata_w2_m; // way2 64b data. |
wire [63:0] dcache_rdata_w3_m; // way3 64b data. |
wire [7:0] dcache_rparity_w0_m; // way0 8b parity. |
wire [7:0] dcache_rparity_w1_m; // way1 8b parity. |
wire [7:0] dcache_rparity_w2_m; // way2 8b parity. |
wire [7:0] dcache_rparity_w3_m; // way3 8b parity. |
|
wire [7:0] rd_parity_err_w0_m; |
wire [7:0] rd_parity_err_w1_m; |
wire [7:0] rd_parity_err_w2_m; |
wire [7:0] rd_parity_err_w3_m; |
|
|
wire [143:0] way_mask ; |
wire [143:0] way_mask_inv ; |
|
wire [10:3] dcache_rwaddr_e ; |
wire [10:3] dcache_raddr_e ; |
|
//calculated parity based on read-out data |
wire [7:0] gen_dcache_parity_w0_m; |
wire [7:0] gen_dcache_parity_w1_m; |
wire [7:0] gen_dcache_parity_w2_m; |
wire [7:0] gen_dcache_parity_w3_m; |
|
wire clk; |
assign clk = rclk; |
|
//========================================================================================= |
// Staging |
//========================================================================================= |
|
// BIST Rd used fill address port. |
assign dcache_rwaddr_e[10:3] = |
(dcache_alt_mx_sel_e) ? dcache_alt_addr_e[10:3] : dcache_rd_addr_e[10:3] ; |
|
assign dcache_raddr_e[10:3] = |
(dcache_alt_mx_sel_e) ? dcache_alt_addr_e[10:3] : dcache_rd_addr_e[10:3] ; |
|
always @(posedge clk) |
begin |
dcache_alt_mx_sel_m <= sehold ? dcache_alt_mx_sel_m : dcache_alt_mx_sel_e; |
|
dcache_alt_rsel_way_m <= sehold ? dcache_alt_rsel_way_m : dcache_alt_rsel_way_e; |
|
dcache_rwaddr_m[10:3] <= sehold ? dcache_rwaddr_m[10:3] : dcache_rwaddr_e[10:3] ; |
|
dcache_raddr_m[10:3] <= sehold ? dcache_raddr_m[10:3] : dcache_raddr_e[10:3] ; |
|
dcache_rvld_m <= sehold ? dcache_rvld_m : dcache_rvld_e ; |
|
wvld_m <= sehold ? wvld_m : dcache_wvld_e ; |
|
dcache_wdata_m[143:0] <= sehold ? dcache_wdata_m[143:0] : dcache_wdata_e[143:0] ; |
|
dcache_wr_rway_m[3:0] <= sehold ? dcache_wr_rway_m[3:0] : dcache_wr_rway_e[3:0] ; |
|
byte_wr_enable[15:0] <= sehold ? byte_wr_enable[15:0] : dcache_byte_wr_en_e[15:0] ; |
|
end |
|
always @ (posedge clk) |
begin |
// JC modified begin |
// dcache_alt_mx_sel_wb <= dcache_alt_mx_sel_m; |
// dcache_alt_rsel_way_wb <= dcache_alt_rsel_way_m; |
dcache_alt_mx_sel_wb <= sehold ? dcache_alt_mx_sel_wb :dcache_alt_mx_sel_m; |
dcache_alt_rsel_way_wb <= sehold ? dcache_alt_rsel_way_wb :dcache_alt_rsel_way_m; |
// JC modified end |
end |
|
assign dcache_wvld_m = wvld_m & ~rst_tri_en ; |
|
|
`ifdef DEFINE_0IN |
wire [3:0] dc_we = dcache_wvld_m ? dcache_wr_rway_m : 4'b0; |
|
dc_data dc_data0 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]), |
.we(dc_we [0] ), .wm(way_mask [143:0]), |
.din(dcache_wdata_m[143:0]), .dout(temp_w0a[143:0]) ); |
dc_data dc_data1 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]), |
.we(dc_we [1] ), .wm(way_mask [143:0]), |
.din(dcache_wdata_m[143:0]), .dout(temp_w1a[143:0]) ); |
dc_data dc_data2 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]), |
.we(dc_we [2] ), .wm(way_mask [143:0]), |
.din(dcache_wdata_m[143:0]), .dout(temp_w2a[143:0]) ); |
dc_data dc_data3 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]), |
.we(dc_we [3] ), .wm(way_mask [143:0]), |
.din(dcache_wdata_m[143:0]), .dout(temp_w3a[143:0]) ); |
`else |
//========================================================================================= |
// generate wordlines |
//========================================================================================= |
|
// Generate at posedge of clk. |
// JC modified begin |
/* |
always @ (posedge clk) |
begin |
for (ctr=8'h00;ctr<128;ctr=ctr+1) |
begin |
if (clk & ({1'b0,dcache_rwaddr_e[10:4]} == ctr) & |
(dcache_rvld_e | dcache_wvld_e)) |
rw_wdline[ctr] = 1'b1; |
else |
rw_wdline[ctr] = 1'b0; |
end |
end |
*/ |
|
`ifdef FPGA_SYN_DCD |
`else |
always @ (clk or dcache_rwaddr_m or dcache_wvld_m or dcache_rvld_m) |
begin |
if (clk) begin |
for (ctr=8'h00;ctr<128;ctr=ctr+1) |
begin |
if (({1'b0,dcache_rwaddr_m[10:4]} == ctr) & |
(dcache_rvld_m | dcache_wvld_m)) |
rw_wdline[ctr] = 1'b1; |
else |
rw_wdline[ctr] = 1'b0; |
end |
end |
end |
// JC modified end |
`endif |
|
|
//========================================================================================= |
// Read from Memory. |
//========================================================================================= |
|
`ifdef FPGA_SYN_DCD |
always @(posedge clk) begin |
temp_w0a_reg[143:0] = w0[dcache_raddr_e[10:4]]; |
temp_w1a_reg[143:0] = w1[dcache_raddr_e[10:4]]; |
temp_w2a_reg[143:0] = w2[dcache_raddr_e[10:4]]; |
temp_w3a_reg[143:0] = w3[dcache_raddr_e[10:4]]; |
end |
`else |
// Read |
always @ (negedge clk) |
begin |
for (i=0;i<128;i=i+1) |
begin |
if (rw_wdline[i] & dcache_rvld_m) |
begin |
temp_w0a_reg[143:0] <= w0[i]; |
temp_w1a_reg[143:0] <= w1[i]; |
temp_w2a_reg[143:0] <= w2[i]; |
temp_w3a_reg[143:0] <= w3[i]; |
end |
end |
end |
`endif |
|
//removed stablizer, zero out without read |
assign temp_w0a[143:0] = dcache_rvld_m? temp_w0a_reg[143:0]: 144'b0; |
assign temp_w1a[143:0] = dcache_rvld_m? temp_w1a_reg[143:0]: 144'b0; |
assign temp_w2a[143:0] = dcache_rvld_m? temp_w2a_reg[143:0]: 144'b0; |
assign temp_w3a[143:0] = dcache_rvld_m? temp_w3a_reg[143:0]: 144'b0; |
|
`endif |
|
// Prior to SA, column mux (64(D)+8(P))x4 bits. Assume parity is |
// at the end of the 144b line. Entry is wX||Parity |
|
// Select either upper or lower 64b from each of the 4 ways. |
assign dcache_rdata_w0_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w0a[143:80] : temp_w0a[79:16] ; |
assign dcache_rdata_w1_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w1a[143:80] : temp_w1a[79:16] ; |
assign dcache_rdata_w2_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w2a[143:80] : temp_w2a[79:16] ; |
assign dcache_rdata_w3_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w3a[143:80] : temp_w3a[79:16] ; |
|
wire [7:0] dcache_msb_w0_m; |
wire [7:0] dcache_alt_data_w0_msb_m; |
|
//MSB sent out to dcdp in M stage |
assign dcache_msb_w0_m[7:0]= |
{dcache_rdata_w0_m[63], |
dcache_rdata_w0_m[55], |
dcache_rdata_w0_m[47], |
dcache_rdata_w0_m[39], |
dcache_rdata_w0_m[31], |
dcache_rdata_w0_m[23], |
dcache_rdata_w0_m[15], |
dcache_rdata_w0_m[07]} ; |
|
assign dcache_alt_data_w0_msb_m [7:0]= |
{dcache_alt_data_w0_m[63], |
dcache_alt_data_w0_m[55], |
dcache_alt_data_w0_m[47], |
dcache_alt_data_w0_m[39], |
dcache_alt_data_w0_m[31], |
dcache_alt_data_w0_m[23], |
dcache_alt_data_w0_m[15], |
dcache_alt_data_w0_m[07]} ; |
|
//2-to-1 mux |
assign dcache_rdata_msb_w0_m[7:0] = dcache_arry_data_sel_m ? |
dcache_msb_w0_m[7:0] : |
dcache_alt_data_w0_msb_m[7:0]; |
|
assign dcache_rdata_msb_w1_m[7:0]= |
{dcache_rdata_w1_m[63], |
dcache_rdata_w1_m[55], |
dcache_rdata_w1_m[47], |
dcache_rdata_w1_m[39], |
dcache_rdata_w1_m[31], |
dcache_rdata_w1_m[23], |
dcache_rdata_w1_m[15], |
dcache_rdata_w1_m[07]} ; |
|
assign dcache_rdata_msb_w2_m[7:0]= |
{dcache_rdata_w2_m[63], |
dcache_rdata_w2_m[55], |
dcache_rdata_w2_m[47], |
dcache_rdata_w2_m[39], |
dcache_rdata_w2_m[31], |
dcache_rdata_w2_m[23], |
dcache_rdata_w2_m[15], |
dcache_rdata_w2_m[07]} ; |
|
assign dcache_rdata_msb_w3_m[7:0]= |
{dcache_rdata_w3_m[63], |
dcache_rdata_w3_m[55], |
dcache_rdata_w3_m[47], |
dcache_rdata_w3_m[39], |
dcache_rdata_w3_m[31], |
dcache_rdata_w3_m[23], |
dcache_rdata_w3_m[15], |
dcache_rdata_w3_m[07]} ; |
|
wire [63:0] rdata_w0_m; |
wire [63:0] rdata_w1_m; |
wire [63:0] rdata_w2_m; |
wire [63:0] rdata_w3_m; |
|
//2-to-1 mux |
//dcache_alt_mx_sel default 0001 (way 0) when not in MBIST mode (logic in qdp2) |
assign rdata_w0_m[63:0] = dcache_arry_data_sel_m ? |
dcache_rdata_w0_m[63:0] : dcache_alt_data_w0_m[63:0]; |
|
//assign rdata_w0_m[63:0] = dcache_rdata_w0_m[63:0]; |
assign rdata_w1_m[63:0] = dcache_rdata_w1_m[63:0]; |
assign rdata_w2_m[63:0] = dcache_rdata_w2_m[63:0]; |
assign rdata_w3_m[63:0] = dcache_rdata_w3_m[63:0]; |
|
// Select upper half or lower half of parity. |
assign dcache_rparity_w0_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w0a[15:8] : temp_w0a[7:0] ; |
assign dcache_rparity_w1_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w1a[15:8] : temp_w1a[7:0] ; |
assign dcache_rparity_w2_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w2a[15:8] : temp_w2a[7:0] ; |
assign dcache_rparity_w3_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w3a[15:8] : temp_w3a[7:0] ; |
|
reg [7:0] dcache_rparity_w0_wb; |
reg [7:0] dcache_rparity_w1_wb; |
reg [7:0] dcache_rparity_w2_wb; |
reg [7:0] dcache_rparity_w3_wb; |
|
reg [7:0] rd_parity_err_w0_wb; |
reg [7:0] rd_parity_err_w1_wb; |
reg [7:0] rd_parity_err_w2_wb; |
reg [7:0] rd_parity_err_w3_wb; |
|
|
// Stage to WB |
always @(posedge clk) |
begin |
dcache_rdata_w0_wb[63:0] <= rdata_w0_m[63:0] ; |
dcache_rdata_w1_wb[63:0] <= rdata_w1_m[63:0] ; |
dcache_rdata_w2_wb[63:0] <= rdata_w2_m[63:0] ; |
dcache_rdata_w3_wb[63:0] <= rdata_w3_m[63:0] ; |
|
dcache_rparity_w0_wb[7:0] <= dcache_rparity_w0_m[7:0]; |
dcache_rparity_w1_wb[7:0] <= dcache_rparity_w1_m[7:0]; |
dcache_rparity_w2_wb[7:0] <= dcache_rparity_w2_m[7:0]; |
dcache_rparity_w3_wb[7:0] <= dcache_rparity_w3_m[7:0]; |
|
rd_parity_err_w0_wb [7:0] <= rd_parity_err_w0_m[7:0]; |
rd_parity_err_w1_wb [7:0] <= rd_parity_err_w1_m[7:0]; |
rd_parity_err_w2_wb [7:0] <= rd_parity_err_w2_m[7:0]; |
rd_parity_err_w3_wb [7:0] <= rd_parity_err_w3_m[7:0]; |
|
end |
|
//parity calculation and check are done in M stage for 4 way data |
wire rd_parity_err_w0; |
wire rd_parity_err_w1; |
wire rd_parity_err_w2; |
wire rd_parity_err_w3; |
|
lsu_dc_parity_gen #(8,8) parity_gen_w0 ( |
.data_in (dcache_rdata_w0_m[63:0]), |
.parity_out (gen_dcache_parity_w0_m[7:0]) |
); |
|
assign rd_parity_err_w0_m[7:0] = dcache_rvld_m ? (dcache_rparity_w0_m[7:0] ^ gen_dcache_parity_w0_m[7:0]) : |
8'hff; |
|
|
lsu_dc_parity_gen #(8,8) parity_gen_w1 ( |
.data_in (dcache_rdata_w1_m[63:0]), |
.parity_out (gen_dcache_parity_w1_m[7:0]) |
); |
|
assign rd_parity_err_w1_m[7:0] = dcache_rvld_m ? (dcache_rparity_w1_m[7:0] ^ gen_dcache_parity_w1_m[7:0]) : |
8'hff; |
|
lsu_dc_parity_gen #(8,8) parity_gen_w2 ( |
.data_in (dcache_rdata_w2_m[63:0]), |
.parity_out (gen_dcache_parity_w2_m[7:0]) |
); |
assign rd_parity_err_w2_m[7:0] = dcache_rvld_m ? (dcache_rparity_w2_m[7:0] ^ gen_dcache_parity_w2_m[7:0]) : |
8'hff; |
|
lsu_dc_parity_gen #(8,8) parity_gen_w3 ( |
.data_in (dcache_rdata_w3_m[63:0]), |
.parity_out (gen_dcache_parity_w3_m[7:0]) |
); |
assign rd_parity_err_w3_m[7:0] = dcache_rvld_m ? (dcache_rparity_w3_m[7:0] ^ gen_dcache_parity_w3_m[7:0]) : |
8'hff; |
|
|
// way select mux on READ |
// Select one of four ways from indexed cache set. |
|
wire [3:0] dcache_rd_sel_way_wb; |
assign dcache_rd_sel_way_wb[3:0] = dcache_alt_mx_sel_wb ? dcache_alt_rsel_way_wb[3:0] : |
dcache_rsel_way_wb[3:0]; |
|
assign dcache_rdata_wb[63:0] = |
(dcache_rd_sel_way_wb[0] ? dcache_rdata_w0_wb[63:0] : 64'b0) | |
(dcache_rd_sel_way_wb[1] ? dcache_rdata_w1_wb[63:0] : 64'b0) | |
(dcache_rd_sel_way_wb[2] ? dcache_rdata_w2_wb[63:0] : 64'b0) | |
(dcache_rd_sel_way_wb[3] ? dcache_rdata_w3_wb[63:0] : 64'b0); |
|
//parity err in W-stage, cache_way_hit may not be one-hot |
assign rd_parity_err_w0 = |(rd_parity_err_w0_wb[7:0]); |
assign rd_parity_err_w1 = |(rd_parity_err_w1_wb[7:0]); |
assign rd_parity_err_w2 = |(rd_parity_err_w2_wb[7:0]); |
assign rd_parity_err_w3 = |(rd_parity_err_w3_wb[7:0]); |
|
assign dcache_rparity_err_wb = rd_parity_err_w3 & dcache_rd_sel_way_wb[3] | |
rd_parity_err_w2 & dcache_rd_sel_way_wb[2] | |
rd_parity_err_w1 & dcache_rd_sel_way_wb[1] | |
rd_parity_err_w0 & dcache_rd_sel_way_wb[0] ; |
|
//mux4ds #(64) dcache_rdata_wb_mx ( |
// .in0 (dcache_rdata_w0_wb[63:0]), |
// .in1 (dcache_rdata_w1_wb[63:0]), |
// .in2 (dcache_rdata_w2_wb[63:0]), |
// .in3 (dcache_rdata_w3_wb[63:0]), |
// .sel0 (dcache_rd_sel_way_wb[0]), |
// .sel1 (dcache_rd_sel_way_wb[1]), |
// .sel2 (dcache_rd_sel_way_wb[2]), |
// .sel3 (dcache_rd_sel_way_wb[3]), |
// .dout (dcache_rdata_wb[63:0]) |
//); |
|
// dcache_rparity_wb only used by MBIST |
//mux4ds #(8) dcache_rparity_wb_mx ( |
// .in0 (dcache_rparity_w0_wb[7:0]), |
// .in1 (dcache_rparity_w1_wb[7:0]), |
// .in2 (dcache_rparity_w2_wb[7:0]), |
// .in3 (dcache_rparity_w3_wb[7:0]), |
// .sel0(dcache_alt_rsel_way_wb[0]), |
// .sel1(dcache_alt_rsel_way_wb[1]), |
// .sel2(dcache_alt_rsel_way_wb[2]), |
// .sel3(dcache_alt_rsel_way_wb[3]), |
// .dout(dcache_rparity_wb[7:0]) |
//); |
|
assign dcache_rparity_wb[7:0] = |
( dcache_rd_sel_way_wb[0] ? dcache_rparity_w0_wb[7:0] : 8'b0 ) | |
( dcache_rd_sel_way_wb[1] ? dcache_rparity_w1_wb[7:0] : 8'b0 ) | |
( dcache_rd_sel_way_wb[2] ? dcache_rparity_w2_wb[7:0] : 8'b0 ) | |
( dcache_rd_sel_way_wb[3] ? dcache_rparity_w3_wb[7:0] : 8'b0 ) ; |
|
|
//========================================================================================= |
// Write to Memory |
//========================================================================================= |
|
// Reads and writes are mutex as array is single-ported. |
|
|
// Includes data(128b)+parity(16b). |
assign way_mask[143:0] = |
{{8{byte_wr_enable[15]}},{8{byte_wr_enable[14]}},{8{byte_wr_enable[13]}}, |
{8{byte_wr_enable[12]}},{8{byte_wr_enable[11]}},{8{byte_wr_enable[10]}}, |
{8{byte_wr_enable[9]}}, {8{byte_wr_enable[8]}}, {8{byte_wr_enable[7]}}, |
{8{byte_wr_enable[6]}}, {8{byte_wr_enable[5]}}, {8{byte_wr_enable[4]}}, |
{8{byte_wr_enable[3]}}, {8{byte_wr_enable[2]}}, {8{byte_wr_enable[1]}}, |
{8{byte_wr_enable[0]}}, byte_wr_enable[15:0]} ; |
|
assign way_mask_inv[143:0] = ~way_mask[143:0]; |
|
|
always @ (negedge clk) |
begin |
|
`ifdef FPGA_SYN_DCD |
|
if(dcache_wvld_m & dcache_wr_rway_m[0]) begin |
w0[dcache_rwaddr_m[10:4]] = (temp_w0a_reg[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
if(dcache_wvld_m & dcache_wr_rway_m[1]) begin |
w1[dcache_rwaddr_m[10:4]] = (temp_w1a_reg[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
if(dcache_wvld_m & dcache_wr_rway_m[2]) begin |
w2[dcache_rwaddr_m[10:4]] = (temp_w2a_reg[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
if(dcache_wvld_m & dcache_wr_rway_m[3]) begin |
w3[dcache_rwaddr_m[10:4]] = (temp_w3a_reg[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
|
`else // !`ifdef FPGA_SYN_DCD |
|
for (j=0;j<128;j=j+1) |
begin |
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[0]) |
begin |
// read |
temp_w0[143:0] = w0[j]; |
// modify & write |
w0[j] = (temp_w0[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[1]) |
begin |
// read |
temp_w1[143:0] = w1[j]; |
// modify & write |
w1[j] = (temp_w1[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[2]) |
begin |
// read |
temp_w2[143:0] = w2[j]; |
// modify & write |
w2[j] = (temp_w2[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[3]) |
begin |
// read |
temp_w3[143:0] = w3[j]; |
// modify & write. |
w3[j] = (temp_w3[143:0] & way_mask_inv[143:0]) | |
(dcache_wdata_m[143:0] & way_mask[143:0]) ; |
end |
end |
`endif // !`ifdef FPGA_SYN_DCD |
|
end // always @ (negedge clk) |
|
endmodule |
|
|