MBCtrl.v 3.72 KB
module	MBCtrl (
	memclk,
	Reset,
	Length,
	Addr,
	I,
	D,
	M36,
	Bk0StA2,
	Bk1StA2,
	Bk0LastStA3,
	Bk1LastStA3,
	Bk0LastCAS,
	Bk1LastCAS,

	StB0,
	StB1,
	nxt_StB1,
	StB2,
	StB5,
	Bk0MBAct,
	Bk1MBAct,
	Bk0MB1stAct,
	Bk1MB1stAct,
	SBSel
	
);

	input		memclk;
	input		Reset;
	input	[6:0]	Length;
	input	[6:3]	Addr;
	input		I;
	input		D;
	input		M36;
	input		Bk0StA2;
	input		Bk1StA2;
	input		Bk0LastStA3;
	input		Bk1LastStA3;
	input		Bk0LastCAS;
	input		Bk1LastCAS;

	output	[7:0]	StB0;
	output		StB1;
	output		nxt_StB1;
	output		StB2;
	output		StB5;
	output		Bk0MBAct;
	output		Bk1MBAct;
	output		Bk0MB1stAct;
	output		Bk1MB1stAct;
	output		SBSel;

	reg	SameBk0;
	reg	SameBk1;
	reg	[7:0]	StB0;
	reg	lStB0;

	wire		nxt_SameBk0 = lStB0 ? Bk0StA2 : SameBk0;
	wire		nxt_SameBk1 = lStB0 ? Bk1StA2 : SameBk1;

	always @(posedge memclk) begin
	if (Reset)	SameBk0 <= 1'b0;
	else		SameBk0 <= nxt_SameBk0;
	if (Reset)	SameBk1 <= 1'b0;
	else		SameBk1 <= nxt_SameBk1;
	end

	wire	SameLastStA3 = SameBk0 & Bk0LastStA3
			     | SameBk1 & Bk1LastStA3;
	
	wire	OppoLastStA3 = SameBk1 & Bk0LastStA3
			     | SameBk0 & Bk1LastStA3;

	// Compute B, 
	// same as BankCtrl.v

	// For M36:
	// B[7:6] = number of bank accesses (lenght + starting
	//	    address double word offset into bank (i.e. 64 byte 
	//	    alligned block)
	// EA[5:3] = ending adddress double word offset
	// For M64:
	// B[7]   = number of bank accesses (128 byte alligned block)
	// EA[6:3] = ending adddress double word offset

	wire	[7:3]	EAup =  Length[6:3] + (I ? 4'b0
					         : (M36 ? {1'b0,Addr[6:4]}
						        :       Addr[6:3]));

	wire	[7:3]	EAdn = ~Length[6:3] +  4'b1 + (M36 ? {1'b0,Addr[6:4]}
						           :       Addr[6:3]);

	wire	[7:6]	B    = D ? {(EAdn[7] ^ EAdn[6]),EAdn[6]} : EAup[7:6];

	// Multi-Bank State Machine

	reg	StB1;
	reg	StB2;
	reg	StB5;
	reg	StB6;

	wire	nxt_StB0 =          lStB0 & ~Bk0StA2 & ~Bk1StA2
			 |          lStB0 & (B[7:6]==2'h0) & M36
			 |          lStB0 & ~B[7] & ~M36
			 |          StB6 & Bk0LastCAS
			 |          StB6 & Bk1LastCAS
			 |  Reset;

	wire	nxt_StB1 = ~Reset & lStB0 & Bk0StA2 & ~(B[7:6]==2'h0) & M36
			 | ~Reset & lStB0 & Bk1StA2 & ~(B[7:6]==2'h0) & M36
			 | ~Reset & lStB0 & Bk0StA2 &  B[7] & ~M36
			 | ~Reset & lStB0 & Bk1StA2 &  B[7] & ~M36
			 | ~Reset & StB1 & ~SameLastStA3;

	wire	nxt_StB2 = ~Reset & StB1 &  SameLastStA3 & (B[7:6]==2'h2) & M36
			 | ~Reset & StB2 & ~OppoLastStA3;

	wire	nxt_StB5 = ~Reset & StB1 &  SameLastStA3 & (B[7:6]==2'h1) & M36
			 | ~Reset & StB1 &  SameLastStA3 &  B[7] & ~M36
			 | ~Reset & StB2 &  OppoLastStA3 & (B[7:6]==2'h2) & M36
			 | ~Reset & StB5 & ~SameLastStA3 & ~OppoLastStA3;

	wire	nxt_StB6 = ~Reset & StB5 &  OppoLastStA3 
			 | ~Reset & StB5 &  SameLastStA3 
			 | ~Reset & StB6 & ~Bk0LastCAS & ~Bk1LastCAS;

	always @(posedge memclk) begin
		lStB0 <= nxt_StB0;
		StB0 <= {8{nxt_StB0}};
		StB1 <= nxt_StB1;
		StB2 <= nxt_StB2;
		StB5 <= nxt_StB5;
		StB6 <= nxt_StB6;
	end

	wire	ActSame = OppoLastStA3 & StB2;
	wire	ActOppo = SameLastStA3 & StB1;

	wire	Bk0MBAct = SameBk0 & ActSame | SameBk1 & ActOppo;
	wire	Bk1MBAct = SameBk1 & ActSame | SameBk0 & ActOppo;

	wire	Bk0MB1stAct = SameBk1 & StB1 & SameLastStA3;
	wire	Bk1MB1stAct = SameBk0 & StB1 & SameLastStA3;

	reg	SBk0Sel;

	wire	nxt_SBk0Sel = ~SBk0Sel & lStB0 & Bk0StA2 & (B[7:6]==2'h0) & M36
			    | ~SBk0Sel & lStB0 & Bk0StA2 & ~B[7] & ~M36
			    |  SBk0Sel & ~Bk0LastCAS;

	always @(posedge memclk) 
	if (Reset)	SBk0Sel <= 1'b0;
	else		SBk0Sel <= nxt_SBk0Sel;

	reg	SBk1Sel;

	wire	nxt_SBk1Sel = ~SBk1Sel & lStB0 & Bk1StA2 & (B[7:6]==2'h0) & M36
			    | ~SBk1Sel & lStB0 & Bk1StA2 & ~B[7] & ~M36
			    |  SBk1Sel & ~Bk1LastCAS;

	always @(posedge memclk) 
	if (Reset)	SBk1Sel <= 1'b0;
	else		SBk1Sel <= nxt_SBk1Sel;

	wire	SBSel = SBk0Sel | SBk1Sel;

endmodule