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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [T1-common/] [srams/] [bw_r_scm.v] - Rev 8

Compare with Previous | Blame | View Log

// ========== Copyright Header Begin ==========================================
// 
// OpenSPARC T1 Processor File: bw_r_scm.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 ============================================
////////////////////////////////////////////////////////////////////////
/*
//	Description:	Store Buffer of Load/Store Unit (CAM Side)
//		 - Physically divided into CAM and DATA RAMs.
//                              - CAM RAM has a single cam port and a single
//                              port for read/writes. The cam port is for loads,
//                              write for stores, read for test/diagnostic purposes.
//                              rd or write can be simultaneous with cam. can rd and cam
//                              a single entry simultaneously. cannot write and cam
//                              the same entry.
//                              - DATA RAM read occurs for a load raw match in the
//                              stb CAM RAM. DATA RAM write occurs a store. Both
//                              actions are architecturally guaranteed to be
//                              mutex.
//                              - Write occurs simultaneously to both arrays.
//                              - Reads are not necessarily simultaneous and are
//                              controlled by individual read signals.
//                              - Certain bits are maintained outside the array
//                              in the stb's control section, such as the valid
//                              bits.                	
//
*/
 
////////////////////////////////////////////////////////////////////////
// Local header file includes / local defines
////////////////////////////////////////////////////////////////////////
 
//FPGA_SYN enables all FPGA related modifications
`ifdef FPGA_SYN 
`define FPGA_SYN_SCM
`endif
 
module bw_r_scm (/*AUTOARG*/
   // Outputs
   stb_rdata_ramc, stb_ld_full_raw, stb_ld_partial_raw, 
   stb_cam_hit_ptr, stb_cam_hit, stb_cam_mhit, 
   // Inputs
   stb_cam_data, stb_alt_wr_data, stb_camwr_data, stb_alt_wsel, 
   stb_cam_vld, stb_cam_cm_tid, stb_cam_sqsh_msk, stb_cam_rw_ptr, 
   stb_cam_wptr_vld, stb_cam_rptr_vld, stb_cam_rw_tid, 
   stb_quad_ld_cam, rclk, rst_tri_en
   ) ;	
 
parameter NUMENTRIES = 32 ;				// number of entries in stb
 
input	[44:15]		stb_cam_data ;	  // data for compare; disjoint msb
input	[44:15]		stb_alt_wr_data ;	  // data for compare; disjoint msb
input	[14:0]		stb_camwr_data ;  // data for compare/write; common lsb
input			stb_alt_wsel ;
input			stb_cam_vld ;	  // cam is required.
input	[1:0]		stb_cam_cm_tid ;  // thread id for cam operation.
input	[7:0]		stb_cam_sqsh_msk; // mask for squashing cam results.
 
input 	[2:0]		stb_cam_rw_ptr ;  // wr pointer for single port.
input 	     		stb_cam_wptr_vld ;// write pointer vld
input 	     		stb_cam_rptr_vld ;// write pointer vld
input	[1:0]		stb_cam_rw_tid ;  // thread id for rw.
input 			stb_quad_ld_cam ; // quad-ld cam.
 
input			rclk ;		  // clock
 
//input			scan_ena ;	  // no longer required !
//input	[7:0]		adj ;
 
input			rst_tri_en ;
 
output	[44:0]		stb_rdata_ramc ;  // rd data from CAM RAM.
// raw output is muxed on a thread basis.
output	[7:0]		stb_ld_full_raw ; // ld with full raw.
output	[7:0]		stb_ld_partial_raw ; // ld with partial raw.
output	[2:0]		stb_cam_hit_ptr ;
output			stb_cam_hit ;	  // any hit in stb
output			stb_cam_mhit ;	  // multiple hits in stb	
 
 
/*UTOREG*/
// Beginning of automatic regs (for this module's undeclared outputs)
// End of automatics
reg [44:0]		stb_rdata_ramc ;
reg [31:0]		rw_wdline ;
reg [44:0]		stb_ramc [NUMENTRIES-1:0] /* synthesis syn_ramstyle = block_ram  syn_ramstyle = no_rw_check */;
reg [44:0]		ramc_entry ;
reg [36:0]		cam_tag ;
reg [31:0]		ptag_hit ;
reg [7:0]		cam_bmask ;
reg [31:0]		byte_match ;
reg [31:0]		byte_overlap ;
reg [31:0]		ld_full_raw ;
reg [31:0]		ld_partial_raw ;
reg [44:15]		alt_wr_data ;
wire [44:15]		pipe_wr_data ;
reg [14:0]		camwr_data ;
reg			wptr_vld ; 
reg			rptr_vld_tmp ; 
reg [1:0]	  	cam_tid ;
reg [1:0]	  	cam_vld ;
reg			alt_wsel ;
 
wire		rptr_vld ; 
wire 		ldq ;
wire	[7:0]	sqsh_msk ;
wire 	[7:0]	ld_full_raw_mx ;
wire    [7:0]	ld_partial_raw_mx ;
wire	[7:0]	ptag_hit_mx ;
wire	[7:0]	byte_overlap_mx ;
wire	[7:0]	byte_match_mx ;
wire	[7:0]	cam_hit ;
wire	[44:0]	wdata_ramc ;
wire	[44:0]	cam_data ;
wire	[44:15] wr_data ;
`ifdef FPGA_SYN_SCM
reg	[4:0]	stb_addr;
`endif
 
 
integer	i,j,k,l ;
 
 
wire	scan_ena ;
assign	scan_ena = 1'b0 ;
 
//=========================================================================================
//	generate wordlines
//=========================================================================================
 
assign	sqsh_msk[7:0]	= stb_cam_sqsh_msk[7:0]; 
 
// cam_vld and cam_tid_tmp are set-up a phase earlier. 
// Comment out - Now setup to posedge.
/*always @(negedge clk)
	begin
		cam_tid_tmp[1:0]	<= stb_cam_cm_tid[1:0] ;
		cam_vld_tmp		<= stb_cam_vld ;
	end */
 
`ifdef FPGA_SYN_SCM
`else
// Wordlines need to be generated locally 
always @ (posedge rclk)
        begin
                for (i=0;i<32;i=i+1)
                        begin
                        if ({stb_cam_rw_tid[1:0],stb_cam_rw_ptr[2:0]} == i)
                                rw_wdline[i]  <= 1'b1;
                        else
                                rw_wdline[i]  <= 1'b0;
                        end
        end
`endif
 
assign pipe_wr_data[44:15] = stb_cam_data[44:15];
 
always @(posedge rclk)
	begin
		alt_wr_data[44:15] <= stb_alt_wr_data[44:15];
		camwr_data[14:0] <= stb_camwr_data[14:0];
		wptr_vld 	<= stb_cam_wptr_vld ;
		rptr_vld_tmp 	<= stb_cam_rptr_vld ;
		cam_tid[1:0]	<= stb_cam_cm_tid[1:0] ;
		//cam_tid[1:0]	<= cam_tid_tmp[1:0] ;
 		//ldq 		<=  stb_quad_ld_cam ; Bug 2870
		alt_wsel 	<= stb_alt_wsel ;
`ifdef FPGA_SYN_SCM
                stb_addr	<= {stb_cam_rw_tid[1:0],stb_cam_rw_ptr[2:0]};
`endif
	end
 
assign 	ldq =  stb_quad_ld_cam ;
assign  rptr_vld = rptr_vld_tmp | rst_tri_en ;
 
//=========================================================================================
//	write or read to/from memory
//=========================================================================================
 
// For blk-st, select out-of-pipe.
assign	wr_data[44:15] = alt_wsel ? 
                alt_wr_data[44:15] : pipe_wr_data[44:15] ;	
 
assign	wdata_ramc[44:0] = {wr_data[44:15],camwr_data[14:0]};
 
// Write
always @ (negedge rclk)
	begin
`ifdef FPGA_SYN_SCM
	if(wptr_vld) begin
		if(~rst_tri_en) begin
			stb_ramc[stb_addr] <= wdata_ramc[44:0];
			stb_rdata_ramc[44:0] <=  wdata_ramc[44:0];
                end else begin
			stb_rdata_ramc[44:0] <=  stb_ramc[stb_addr];
		end
	end
`else
		for (j=0;j<NUMENTRIES;j=j+1)
			begin
			if (rw_wdline[j] & wptr_vld)
				begin
				if (~rst_tri_en)
					begin
					stb_ramc[j] <=  wdata_ramc[44:0];
					// write data is write-thru
					stb_rdata_ramc[44:0] <=  wdata_ramc[44:0];
					end
				else
					begin
					// INNO - default rd if wr squashed by scan_ena.
					stb_rdata_ramc[44:0] <=  stb_ramc[j];
					end
				end
			end
`endif
// Read
`ifdef FPGA_SYN_SCM
		if(rptr_vld & ~scan_ena) begin
			if (rptr_vld & wptr_vld & ~rst_tri_en) begin
				stb_rdata_ramc[44:0] <=  wdata_ramc[44:0];
			end
			else begin
				stb_rdata_ramc[44:0] <=  stb_ramc[stb_addr];
			end
		end
`else
		for (k=0;k<NUMENTRIES;k=k+1)
			begin
			if (rw_wdline[k] & rptr_vld & ~scan_ena)
				begin
				if (rptr_vld & wptr_vld & ~rst_tri_en) // INNO - write-thru
                                        stb_rdata_ramc[44:0] <=  wdata_ramc[44:0];
                                else
                                        stb_rdata_ramc[44:0] <=  stb_ramc[k];
				end
			end
`endif
	end
 
//=========================================================================================
//	CAM contents of CAM RAM
//=========================================================================================
 
// - Generate full/partial raw for incoming load.
// - Output signals need to be qualified with per entry
// vlds before causing any subsequent event, the read of
// the DATA RAM specifically.
// - full_raw & vld will cause rd of DATA RAM.
// - partial_raw & vld will cause ld to follow corresponding
// st on way out to xbar.
// - logic to generate partial and full raws may be done outside
// but that would require an additional signal per entry to
// be output.
 
// Mapping of cam/write data
// 
//	| 	40-3=37b(pa)	| 1b(stquad) 	|	8b(bytemask)	| <- use
//	|	45:9		| 8		|	7:0		| <- input port
//				**^ stquad rm'ed
 
reg [14:0] stb_camwr_data_d;
reg        ldq_d;
reg        stb_cam_vld_d;
reg        scan_ena_d;
reg [44:0]		stb_ramc_d [NUMENTRIES-1:0] /* synthesis syn_ramstyle = block_ram  syn_ramstyle = no_rw_check */;
 
always @(posedge rclk)
   begin
      stb_camwr_data_d[14:0]<=stb_camwr_data[14:0];
      ldq_d<=ldq;
      stb_cam_vld_d<=stb_cam_vld;
      scan_ena_d<=scan_ena;
		for (l=0;l<NUMENTRIES;l=l+1)
         stb_ramc_d[l]<=stb_ramc[l];
   end
 
assign	cam_data[44:0] = {stb_cam_data[44:15],stb_camwr_data_d[14:0]}; 
 
always @( * )
		for (l=0;l<NUMENTRIES;l=l+1)
         begin
				ramc_entry[44:0] = stb_ramc_d[l] ;
 
				cam_tag[36:0] = ramc_entry[44:8] ;
				cam_bmask[7:0] = ramc_entry[7:0] ;
            ptag_hit[l] = (cam_tag[36:1] == cam_data[44:9]) & 
						(((cam_tag[0] == cam_data[8]) & ~ldq_d) | ldq_d) & stb_cam_vld_d & ~scan_ena_d ;
				byte_match[l] = |(cam_bmask[7:0] & cam_data[7:0]) & stb_cam_vld_d & ~scan_ena_d ;
				// Simplification :
				byte_overlap[l] = |(~cam_bmask[7:0] & cam_data[7:0]) & stb_cam_vld_d & ~scan_ena_d ;
         end
 
 
// Mux the raw signals down to 8b quantities. Squash mask comes mid-way thru cycle.
 
 
assign	byte_overlap_mx[7:0] =
	(cam_tid[1:0] == 2'b00) ? byte_overlap[7:0] :
		(cam_tid[1:0] == 2'b01) ? byte_overlap[15:8] :
			(cam_tid[1:0] == 2'b10) ? byte_overlap[23:16] :
				(cam_tid[1:0] == 2'b11) ? byte_overlap[31:24] : 8'bxxxx_xxxx ;
 
assign	byte_match_mx[7:0] =
	(cam_tid[1:0] == 2'b00) ? byte_match[7:0] :
		(cam_tid[1:0] == 2'b01) ? byte_match[15:8] :
			(cam_tid[1:0] == 2'b10) ? byte_match[23:16] :
				(cam_tid[1:0] == 2'b11) ? byte_match[31:24] : 8'bxxxx_xxxx ;
 
assign	ptag_hit_mx[7:0] =
	(cam_tid[1:0] == 2'b00) ? ptag_hit[7:0] :
		(cam_tid[1:0] == 2'b01) ? ptag_hit[15:8] :
			(cam_tid[1:0] == 2'b10) ? ptag_hit[23:16] :
				(cam_tid[1:0] == 2'b11) ? ptag_hit[31:24] : 8'bxxxx_xxxx ;
 
assign	stb_ld_full_raw[7:0] =  
	ptag_hit_mx[7:0] & byte_match_mx[7:0] & ~byte_overlap_mx[7:0] & ~sqsh_msk[7:0] ;
assign	stb_ld_partial_raw[7:0] =  
	ptag_hit_mx[7:0] & byte_match_mx[7:0] &  byte_overlap_mx[7:0] & ~sqsh_msk[7:0] ;
 
assign	cam_hit[7:0] = 
	ptag_hit_mx[7:0] & byte_match_mx[7:0] & ~sqsh_msk[7:0] ;
assign	stb_cam_hit = |(cam_hit[7:0]);
 
// The stb data is meant to be read for single hit full raw case. It may actually be read
// for full raw, partial raw or multiple hit case but the read output will be ignored for
// partial and multiple hit case. Multiple hits will not cause a hazard as the ptr is first
// encoded and then decoded to form the wdline for the stb-data
// Use cam_hit result to void false hits.
assign	stb_cam_hit_ptr[0] 	=  cam_hit[1] | cam_hit[3] | cam_hit[5] | cam_hit[7] ;
assign	stb_cam_hit_ptr[1] 	=  cam_hit[2] | cam_hit[3] | cam_hit[6] | cam_hit[7] ;
assign	stb_cam_hit_ptr[2] 	=  cam_hit[4] | cam_hit[5] | cam_hit[6] | cam_hit[7] ;
 
//Generating multiple hits
assign  stb_cam_mhit            =  (cam_hit[0]  & cam_hit[1]) | (cam_hit[2] & cam_hit[3])  |
                                   (cam_hit[4]  & cam_hit[5]) | (cam_hit[6] & cam_hit[7])  |
                                   ((cam_hit[0] | cam_hit[1]) & (cam_hit[2] | cam_hit[3])) |
                                   ((cam_hit[4] | cam_hit[5]) & (cam_hit[6] | cam_hit[7])) |
                                   ((|cam_hit[3:0]) & (|cam_hit[7:4]));
 
//--------------------------------------------------------------
// Error Checking.
//--------------------------------------------------------------
 
// 1. simultaneous rd/wr on single port - terminate 
// 2. simultaneous cam and wr - terminate
// * PUT OUTSIDE OF SRAM RTL, AS RST NOT AVAILABLE. *
 
endmodule
 

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.