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

Subversion Repositories spacewire

[/] [spacewire/] [trunk/] [rtl/] [SwitchMatrix.v] - Rev 27

Compare with Previous | Blame | View Log

//File name=Module=SwitchMatrix  2005-04-10      btltz@mail.china.com    btltz from CASIC  
//Description:     buffered digital SwitchMatrix  to simplify design, avoid HOL.
//                 * 16 x 16 switch connecting sixteen 9-bit FIFO I/O ports to 
//                      sixteen 10-bit output ports with  16 x 16 (x depth) = 256 syn buffers. buffered each point
//Abbreviations: 	 crd  --- credit
//						 alw  --- allow
//Origin:  SpaceWire Std - Draft-1(Clause 8)of ECSS(European Cooperation for Space Standardization),ESTEC,ESA.
//         SpaceWire Router Requirements Specification Issue 1 Rev 5. Astrium & University of Dundee 
//TODO:	  make rtl faster
////////////////////////////////////////////////////////////////////////////////////
//
/*synthesis translate_off*/
`include "timescale.v"
/*synthesis translate_on */
`define reset  1	        // WISHBONE standard reset
`define TOOL_NOTSUP_PORT_ARRAY //if the tool's support port array declaration  
 
module SwitchMatrix #(parameter BW=10, PORTNUM=16, AW=4,  // (1byte + 1)Byte-WIDTH 16x16 crossbar swith
                                CellDepth =255,           // 16x16 beffers x (255Byte x 10-bit / Cell) 
										  WCCNT = (CellDepth ==255 ? 8 :
										           (CellDepth ==511 ? 9  :
													   (CellDepth == 1023 ? 10 : 'bx  )) ),
										  WIDTH_CRD = (CellDepth ==255 && PORTNUM ==16) ? 12 :  //255depth x16ports = 4080 Bbytes/column
						    							   (CellDepth ==511 && PORTNUM ==16 ? 13 : //511depth x 16ports = 8176	Bbytes/column
															 (CellDepth == 1023 && PORTNUM == 16 ? 14 :
                                            (CellDepth ==255 && PORTNUM ==8 ? 11 :
														   (CellDepth ==511 && PORTNUM ==8 ? 12 :
															 (CellDepth ==1023 && PORTNUM ==8 ? 13 :'bx )))))
							 ) 						
		( // Byte width data input(output) from(to) FIFO
		                  `ifdef TOOL_NOTSUP_PORT_ARRAY 
								 output [BW-1:0] do0,do1,do2,do3,do4,do5,do6,do7,
								                 do8,do9,do10,do11,d12,do13,do14,do15,
                         input  [BW-1:0] di0,di1,di2,di3,di4,di5,di6,di7,
								                 di8,di9,di10,di11,di12,di13,di14,di15,
                         `else
							    output reg [BW-1:0] do [0:PORTNUM-1],
							    input  [BW-1:0] di [0:PORTNUM-1],								 
								`endif
 
								 output [PORTNUM-1:0] PHasData_o,   //a output port has data to transmit
		 // Configuration Port
		                  //output [WIDTH_CRD-1:0] crd_o [0:PORTNUM-1], // credit output back to each in line
		                   output reg [PORTNUM-1:0] sop_ack_o,       //level
								 input [PORTNUM-1:0] sop_req_i,       //pulse 								
								 input [PORTNUM-1:0]	eop_i,		     //pulse
								`ifdef TOOL_NOTSUP_PORT_ARRAY 
								 input cfg_data0_i,  cfg_data1_i,  cfg_data2_i,  cfg_data3_i,
										 cfg_data4_i,  cfg_data5_i,  cfg_data6_i,  cfg_data7_i,
										 cfg_data8_i,  cfg_data9_i,  cfg_data10_i, cfg_data11_i,
										 cfg_data12_i, cfg_data13_i, cfg_data14_i, cfg_data15_i,
                        `else
								 input [PORTNUM-1:0] cfg_data_i [0:PORTNUM-1],
                        `endif
 
								`ifdef TOOL_NOTSUP_PORT_ARRAY	 	
								 input [AW-1:0] out_addr0_i,out_addr1_i,out_addr2_i,out_addr3_i,
								                out_addr4_i,out_addr5_i,out_addr6_i,out_addr7_i,
													 out_addr8_i,out_addr9_i,out_addr10_i,out_addr11_i,
													 out_addr12_i,out_addr13_i,out_addr14_i,out_addr15_i,
								`else					 	   				
								 input [AW-1:0] out_addr_i [0:PORTNUM],	//select output column								 
								`endif
							    //input [PORTNUM-1:0] ld_inaddr_i, ld_outaddr_i,
       // System interface
								 input reset, gclk
							  );	
							      parameter True  = 1;
							      parameter False = 0;
 
`ifdef TOOL_NOTSUP_PORT_ARRAY
reg [BW-1:0] do [0:PORTNUM-1];
wire [BW-1:0] di [0:PORTNUM-1];	 
assign di0 = di[0],   di1 = di[1],   di2 = di[2],   di3 = di[3], 
       di4 = di[4],   di5 = di[5],   di6 = di[6],   di7 = di[7],
		 di8 = di[9],   di9 = di[9],   di10 = di[10], di11 = di[11],
		 di12 = di[12], di13 = di[13], di14 = di[14], di15 = di[15];
assign do0 = do[0],   do1 = do[1],   do2 = do[2],   do3 = do[3], 
       do4 = do[4],   do5 = do[5],   do6 = do[6],   do7 = do[7],
		 do8 = do[9],   do9 = do[9],   do10 = do[10], do11 = do[11],
		 do12 = do[12], do13 = do[13], do14 = do[14], do15 = do[15];
`endif
 
// Register to provide address when write(read) line(column).
// Each output port = 1 column
reg [AW-1:0] SelColumn [0:PORTNUM-1];       // for line cells selection//bit width ,depth
reg [AW-1:0] SelColine [0:PORTNUM-1];	     // for MUXes	 select lines in a column 
wire [PORTNUM-1:0] ld_SelColumn = sop_req_i;            
wire [PORTNUM-1:0] ld_SelColine;             // load select lines in a column
 
wire [AW-1:0] ScheOut;  //output from the schedule.Determine which line in a column has priority 
 
							  //opposite line| each column
wire [BW-1:0] CellOut    [0:PORTNUM]    [0:PORTNUM];	 //16x16 *9 from cell fifo to MUXes	                      
wire [WCCNT-1:0] CellCnt [0:PORTNUM]    [0:PORTNUM];  //data num(vectors) in each switch cell     
// Cell Control Lines
reg [PORTNUM-1:0] wr_en  [0:PORTNUM-1];
reg [PORTNUM-1:0] rd_en  [0:PORTNUM-1];
wire [PORTNUM-1:0] clrCell[0:PORTNUM-1]; 
wire [PORTNUM-1:0] CellEmpty [0:PORTNUM-1];
wire [PORTNUM-1:0] CellFull  [0:PORTNUM-1];	
wire [PORTNUM-1:0] CellAfull  [0:PORTNUM-1];                    // buffer cell almost full 
wire [PORTNUM-1:0] CellAempty  [0:PORTNUM-1];						  // buffer cell almost empty
 
wire [PORTNUM-1:0] CellHasData [0:PORTNUM-1] = ~CellEmpty;      //? is the syntax right ?	
wire [PORTNUM-1:0] CellHasSpc  [0:PORTNUM-1] = ~CellFull;  
 
 
// signal for Matrix Output management
reg [PORTNUM-1:0] columnHasData;
wire [PORTNUM-1:0] ColumnOE = columnHasData;
assign PHasData_o           = columnHasData; //Port Has Data.Synchronous output to write Tx FIFO
 
// reg [WIDTH_CRD-1:0] crdcnt [0:PORTNUM-1];//credit counter
// assign crd_o = crdcnt;
 
/////////////////////////////////////
// Config input/output address REGs
//  
always @(posedge gclk)
begin
integer i=0;
if(reset)
     begin
     SelColumn <= 0;
     SelLine <= 0;
     end
else begin
     for (i=0; i<PORTNUM; i=i+1 )
       begin 
		 if( ld_SelColumn[i] == True )	    // ld_SelColumn = sop_req_i; Note taht the addr must be valid.
	      SelColumn[i] <= out_addr_i[i];	 //   Address Vector load
	    if( ld_SelColine[i] == True )	    // if the scheduler load output address.
	      SelColine[i] <= ScheOut [i];	    //   Address Vector load
	    end
     end
end
 
///////////////////////
// Matrix Cell buffers
//
// note: should select devices that have true dual port RAM	  
 
generate
begin:GEN_Cell
genvar i,k;
for (i=0; i<PORTNUM; i=i+1)       // i : each column
begin
   for (k=0; k<PORTNUM; k=k+1)	 // k : in a column(sel line)
	begin
	eth_fifo  #(parameter DATA_WIDTH=BW, DEPTH=CellDepth)	  // byte width=9, depth=? undetermined
	         Cell_Fifo_Array
	         (.data_in ( di[k] ),	       // different colum has same data input line
				 .data_out( CellOut[i][k] ),// k assign to 1 column,i assign to n columns.L<-R			 
				 .write   ( wr_en[i][k] ), 
				 .read    ( rd_en[i][k] ),
				 .clear   ( clrCell[i][k] ), 
				 .almost_full ( CellAfull[i][k] ), 
				 .full        ( CellFull[i][k] ), 
				 .almost_empty( CellAempty[i][k] ), 
				 .empty       ( CellEmpty[i][k] ), 
				 .gclk  ( gclk ), 
				 .reset( reset ),
				 .cnt( CellCnt[i][k] )      //may be usable
				 );
    end  //end 1 column (16x1 )
end	   //end 1 array  (16x16) 
end      //end GEN_Cell 
 
 
 
/////////////////////////////////////////
// Distribute lines data 
//     to the Matrix Cell	
reg [PORTNUM-1:0] wpen ;     // Write Packages Enable
 
//register sop_req_i or eop_i pulse
always @(posedge gclk)
begin
integer k;
if(reset==`reset)
  wpen <= 0;
else begin
     for(k=0; k<PORTNUM; k=k+1)
   	  begin
	      if(eop_i[k])
	  	     wpen[k] <= 1'b0;
         else if(sop_req_i[k])
		     wpen[k] <= 1'b1;
        end
	   end
end
 
reg [PORTNUM-1:0] wr__;		  // level signal
 
always @(*)
begin
 for (k =0; k <PORTNUM; k =k+1)
  wr__[k] =  ( wpen[k] ==False || eop_i[k])  ?   0   :
             ( ( wpen[k] ==True && eop_i[k] ==False )  ?   1'b1 : 'bx	    );       
end 			
 
//decode config addr according to the external controller
//(and the package addr head). Generate cell "we" signals array.
always @(*)
begin
integer i,k;
  for (i=0; i<PORTNUM; i=i+1)       // i : each column
  begin
    for (k=0; k<PORTNUM; k=k+1)	   // k : lines in a column(sel line)
	 begin
      wr_en[i][k] = ( wr__[i]                     // write to x column 
		                &&  SelColine[i] ==k    	  // select a line in a column
							 &&  CellHasSpc[i][k] ==True // that cell is not full
						   )					        
							   ?   1'b1  :  1'b0;
     sop_ack_o[i] = (SelColine[i] ==k    	        // "select a line" must has been configed
							 &&  CellHasSpc[i][k] ==True // that cell is not full
							)
							   ?   1'b1  :  1'b0;         
	 end
  end
end 
 
 
/////////////////////////
// Read enable to Tx Fifo
//
////////////////////
// Credit collecting credit information to The Input Line
// Output Schedulers	are responsible for selecting eligible 
 
always @ (*)
begin
integer m;
  for(m=0; m<PORTNUM; m=m+1)
  	columnHasData[m] = | celHasData[m];           
	// cellHasData[m][0] || cellHasData[m][1] || ...|| cellHasData[m][15] 	  					
end
 
 
//////////////////////////////
// 16 outputs Column Schedulers 
//
//////////////////////////////
// 1 scheduler is responsible to 32 cell in a column
 
generate
begin:GEN_CSers
genvar i, k;
 for (i=0; i<PORTNUM; i=i+1)       // i : each column
 begin:inst_column
   for (k=0; k<PORTNUM; k=k+1)	  // k : in a column(sel line)
	begin:inst_line
     CSer    inst_CSer
	             ( .ld_SelCoLine_o( ld_SelColine ),
					   .empty_i(CellEmpty[i][k] ),      // one-hot input
						.Aempty_i(CellAfull[i][k]),		// one-hot
					   .addr_o( ScheOut[i] ),						
						.reset(reset)
						.gclk(gclk)						 
					  );
   end  // end lines in a column
 end    // end columns
end
endgenerate
 
////////////////////////////
//	16 outputs
// 
always @(*)
begin
integer n;
 for (n=0; n<PORTNUM; n=n+1) 
    begin
	 if(columOE)
	 do[n] = CellOut[SelLine][n];	  // n : (port0 -> port15)
	 else 
	 do[n] = 'b0;                   //       10'b p0_0000_0000  
    end									  // EOP = 10'b p1_0000_0000
end
 
 
/*///////////////
// Functions
//
function [15:0] greyiDEC4_16;  //Grey code input decoder
input [3:0] in;
begin
case (in)
	4'b0000 : greyiDEC4_16 = 16'h1;
	4'b0001 : greyiDEC4_16 = 16'h2;
	4'b0011 : greyiDEC4_16 = 16'h4;
	4'b0010 : greyiDEC4_16 = 16'h8;
	4'b0110 : greyiDEC4_16 = 16'h10;
	4'b0111 : greyiDEC4_16 = 16'h20;
	4'b0101 : greyiDEC4_16 = 16'h40;
	4'b0100 : greyiDEC4_16 = 16'h80;
	4'b1100 : greyiDEC4_16 = 16'h100;
	4'b1101 : greyiDEC4_16 = 16'h200;
	4'b1111 : greyiDEC4_16 = 16'h400;
	4'b1110 : greyiDEC4_16 = 16'h800;
	4'b1010 : greyiDEC4_16 = 16'h1000;
	4'b1011 : greyiDEC4_16 = 16'h2000;
	4'b1001 : greyiDEC4_16 = 16'h4000;
	4'b1000 : greyiDEC4_16 = 16'h8000;
	default : greyiDEC4_16 = 'bx;	
endcase
end
endfunction	*/
 
endmodule
 
`undef reset
`undef TOOL_NOTSUP_PORT_ARRAY
 

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.