//
// q_assm.V
// 
// Quadlet Assembler: used to assemble the incoming data from PHY into quadlets
//The purpose of this module is to form quadlets i.e. 32 bits word from data that is 
//provided by PHY according to the specified speed . Since all other modules can process 
//quadlets, therefore the data which ic received from PHY in the form of 2,4, or 8 bits 
//must be merged into a quadlet.

[Up: mashallah Q1]
module Q_ASSMIndex(   //Input
				 BCLK,		//Clock from transaction layer
                 SCLK,		//Clock from PHY (49.152 MHz)
                 D,			//Data from PHY
                 reset_n,	//reset signal to the LINK (active low)
				 pipe_en,	//enable signal to quadlet assembler from PLI
                 quad_fill,	//output signal to receiver for every quadlet 
                 ctl,		//control info from PHY
				 Q			//Assembled Quadlet (32)
				 );


input pipe_en,reset_n;
wire  pipe_en,reset_n;
input SCLK,BCLK;
wire  SCLK,BCLK;

input [7:0] D;
wire  [7:0] D;

input [1:0] ctl;
wire  [1:0] ctl;
 
output quad_fill;
reg    quad_fill;
output [31:0] Q;
reg    [31:0] Q;
reg [1:0] Sel_400; //indicates the data reception progress for the speed of 400 Mb/sec
reg [2:0] Sel_200; //indicates the data reception progress for the speed of 200 Mb/sec
reg [3:0] Sel_100; //indicates the data reception progress for the speed of 100 Mb/sec
reg [31:0] Q_100, Q_200, Q_400; //To store assembled quadlet
reg count_allow; 
reg [1:0] speedcode; //to store the speed code initially transferred from the PHY
reg En_100,En_200,En_400; //enable signals to the three sel counters used


always @(negedge SCLK or negedge reset_n)
begin
   if(!reset_n)
     speedcode <= 2'b11;
   else if(pipe_en && speedcode == 2'b11)  //pipe_en must be at logic 1 on positive edge 
										   //of SCLK by PLI.With pipe_en D contains speed code.        
	 speedcode <= D[1:0];                  

   else if(!pipe_en) 
     speedcode <= 2'b11;
end

//to enable any of the sel counters
always @(speedcode)
begin
  case(speedcode)
  2'b00:
      begin
        En_100 <= 1;
        En_200 <= 0;
        En_400 <= 0;                      
      end
  2'b01:
      begin
        En_100 <= 0;
        En_200 <= 1;
        En_400 <= 0;
        end
  2'b10:
      begin
        En_100 <= 0;
        En_200 <= 0;
        En_400 <= 1;
        end
  2'b11:
      begin
        En_100 <= 0;
        En_200 <= 0;
        En_400 <= 0;
        end
     endcase
end

//Quadlet Assembling
always @(negedge SCLK or negedge reset_n)
begin
   if(!reset_n)
   begin
     Q_100 = 32'h00000000;
     Q_200 = 32'h00000000;
     Q_400 = 32'h00000000;
   end
   else if(En_100 || ctl == 2'b01)
   begin
     Q_100 = Q_100 << 2;
     Q_100[1:0] = D[1:0];
   end
   else if(En_200)
   begin
     Q_200 = Q_200 << 4;
     Q_200[3:0] = D[3:0];
   end
   else if(En_400)
   begin
     Q_400 = Q_400 << 8;  
     Q_400[7:0] = D[7:0];
   end
end                                                    


always @(negedge SCLK or negedge reset_n)
begin
   if(!reset_n)
   begin
     Sel_100 <= 4'b1111;
     Sel_200 <= 3'b111;
     Sel_400 <= 2'b11;
     count_allow <= 1'b0;
   end
   else if(En_100 || ctl == 2'b01) // ctl == status
   begin  
     
	 Sel_100 <= Sel_100 + 1'b1;
     Sel_200 <= 3'b111;
	 Sel_400 <= 2'b11;	
	 count_allow <= 1'b1;
   end
   else if(En_200)
   begin
     Sel_100 <= 4'b1111;
	 Sel_200 <= Sel_200 + 1'b1;
     Sel_400 <= 2'b11;
	 count_allow <= 1'b1;
   end
   else if(En_400)
   begin
     Sel_100 <= 4'b1111;
	 Sel_200 <= 3'b111;
	 Sel_400 <= Sel_400 + 1'b1;
     count_allow <= 1'b1;
   end
   else
   begin  
     Sel_100 <= 4'b1111;
     Sel_200 <= 3'b111;
     Sel_400 <= 2'b11;
     count_allow <= 1'b0;
   end
end


always @(negedge BCLK or negedge reset_n)
begin
   if(!reset_n)
     quad_fill <= 1'b0;
   else if( ((Sel_100 == 4'b1111 && En_100) || (Sel_200 == 3'b111 && En_200) || (Sel_400 == 2'b11 && En_400)) && count_allow && !quad_fill)
     quad_fill <= 1'b1;
   else if(Sel_100 == 3 && ctl == 2'b01) // ctl == status
     quad_fill <= 1'b1;   
   else
     quad_fill <= 1'b0;
end                              


always @(posedge quad_fill)
begin
	if     (En_100 || Sel_100 == 3)   // to handle the status
		Q <= Q_100;
	else if(En_200)
		Q <= Q_200;
	else if(En_400)
		Q <= Q_400;
	else
		Q <= 32'h00000000;
end

endmodule












This page: Maintained by: firewire@linklayercontroller.com
Created:Sun Mar 11 19:19:00 2001
From: /mnt/c/windows/desktop/floppy/commen~1/q_assm.v

Verilog converted to html by v2html 6.0 (written by Costas Calamvokis).Help