OpenCores
URL https://opencores.org/ocsvn/s1_core/s1_core/trunk

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [sparc_core/] [bw_r_icd.v] - Rev 113

Compare with Previous | Blame | View Log

// ========== 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 ============================================
`ifdef SIMPLY_RISC_TWEAKS
`define SIMPLY_RISC_SCANIN .si(0)
`else
`define SIMPLY_RISC_SCANIN .si()
`endif
////////////////////////////////////////////////////////////////////////
/*
 //  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.
 //    
 */
 
 
////////////////////////////////////////////////////////////////////////
// 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, 
	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;
 
	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;
    `ifdef FPGA_SYN_ALTERA
        reg	[11:2]		index_bf;
    `else
        wire [11:2]     index_bf;
    `endif
	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;
    `ifdef FPGA_SYN_ALTERA
 
        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 */ 
    `else
        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 */ ;
    `endif
 
 
 
 
 
	assign clk = rclk;
    `ifdef FPGA_SYN_ALTERA
    `else
        assign index_bf = (fcl_icd_index_sel_ifq_bf ? ifq_icd_index_bf : 
            fdp_icd_index_bf);
    `endif
//	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 = 136'b0;
	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_s #(136) wrdata_reg(
		.din				(next_wrdata_bf), 
		.clk				(clk), 
		.q				(wrdata_f), 
		.en				((~sehold)), 
    `SIMPLY_RISC_SCANIN,
		.se				(se));
 
	always @(posedge clk) begin
	  if (~sehold) begin
	    rdreq_f <= fcl_icd_rdreq_bf;
	    wrreq_f <= fcl_icd_wrreq_bf;
        `ifdef FPGA_SYN_ALTERA
        `else
            index_f <= index_bf;
        `endif
	    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;
    `ifdef FPGA_SYN_ALTERA
 
	reg [33:0] fetch_00_00_d;
	reg [33:0] fetch_00_01_d;
	reg [33:0] fetch_00_10_d;
	reg [33:0] fetch_00_11_d;
 
	reg [33:0] fetch_01_00_d;
	reg [33:0] fetch_01_01_d;
	reg [33:0] fetch_01_10_d;
	reg [33:0] fetch_01_11_d;
 
	reg [33:0] fetch_10_00_d;
	reg [33:0] fetch_10_01_d;
	reg [33:0] fetch_10_10_d;
	reg [33:0] fetch_10_11_d;
 
	reg [33:0] fetch_11_00_d;
	reg [33:0] fetch_11_01_d;
	reg [33:0] fetch_11_10_d;
	reg [33:0] fetch_11_11_d;
    reg        delay_half_cycle;
 
 
	always @(negedge clk) begin // Sandeep Changed this to negedge clock from posedge clock
        // Can we push the reads to the next negedge? Delay this read!! Looks
        // like the previous write does not get through
    `else
    always @(posedge clk) begin
    `endif
	  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]];
      `ifdef FPGA_SYN_ALTERA
          index_f <= index_bf; // Sandeep moved this logic 1/2 cycle forward for altera
          index_bf <= (fcl_icd_index_sel_ifq_bf ? ifq_icd_index_bf : // Moved this logic from a continuous assignment to a synchronous assignment
              fdp_icd_index_bf);
      `endif
	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 // Writes happening at the negedge
	  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_s #(136)  wrdata_reg(.din (next_wrdata_bf),
			                     .clk (clk),
			                     .q   (wrdata_f),
                           .en  (~sehold),
			                     .se  (se), `SIMPLY_RISC_SCANIN, .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
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.