CASFifo.v 5.25 KB
module	CASFifo (
	memclk,
	Reset,
	BankAddr,
	NLE,
	Pr0StB0,
	Pr1StB0,
	Pr0StB5,
	Pr1StB5,
	Bk0LastStA3,
	Bk1LastStA3,
	Bk2LastStA3,
	Bk3LastStA3,

	Bk0CASMatch,
	Bk1CASMatch,
	Bk2CASMatch,
	Bk3CASMatch
);

	input		memclk;
	input		Reset;
	input	[1:0]	BankAddr;
	input		NLE;
	input		Pr0StB0;
	input		Pr1StB0;
	input		Pr0StB5;
	input		Pr1StB5;
	input		Bk0LastStA3;
	input		Bk1LastStA3;
	input		Bk2LastStA3;
	input		Bk3LastStA3;

	output		Bk0CASMatch;
	output		Bk1CASMatch;
	output		Bk2CASMatch;
	output		Bk3CASMatch;


	// Eight Entry Next (to be CAS'd) Bank FIFO

	wire	Write = NLE;

	wire	Read  = Pr0StB0 & (Bk0LastStA3 | Bk1LastStA3)
		      | Pr0StB5 & (Bk0LastStA3 | Bk1LastStA3)
		      | Pr1StB0 & (Bk2LastStA3 | Bk3LastStA3)
		      | Pr1StB5 & (Bk2LastStA3 | Bk3LastStA3);

	wire	[1:0]	DataIn = BankAddr;

	reg	[2:0]	WrPntr;
	wire	[2:0]	nxt_WrPntr = Write ? WrPntr + 3'b001 : WrPntr;

	always @(posedge memclk)
	if (Reset)	WrPntr <= 3'b000;
	else 		WrPntr <= nxt_WrPntr;

	wire	[7:0]	WEn;

	assign	WEn[0] = Write & (WrPntr==3'h0);
	assign	WEn[1] = Write & (WrPntr==3'h1);
	assign	WEn[2] = Write & (WrPntr==3'h2);
	assign	WEn[3] = Write & (WrPntr==3'h3);
	assign	WEn[4] = Write & (WrPntr==3'h4);
	assign	WEn[5] = Write & (WrPntr==3'h5);
	assign	WEn[6] = Write & (WrPntr==3'h6);
	assign	WEn[7] = Write & (WrPntr==3'h7);

	reg	[1:0]	Entry0;
	reg	[1:0]	Entry1;
	reg	[1:0]	Entry2;
	reg	[1:0]	Entry3;
	reg	[1:0]	Entry4;
	reg	[1:0]	Entry5;
	reg	[1:0]	Entry6;
	reg	[1:0]	Entry7;

	wire	[1:0]	nxt_Entry0 = Reset ? 2'h0 : WEn[0] ? DataIn : Entry0;
	wire	[1:0]	nxt_Entry1 = Reset ? 2'h0 : WEn[1] ? DataIn : Entry1;
	wire	[1:0]	nxt_Entry2 = Reset ? 2'h0 : WEn[2] ? DataIn : Entry2;
	wire	[1:0]	nxt_Entry3 = Reset ? 2'h0 : WEn[3] ? DataIn : Entry3;
	wire	[1:0]	nxt_Entry4 = Reset ? 2'h0 : WEn[4] ? DataIn : Entry4;
	wire	[1:0]	nxt_Entry5 = Reset ? 2'h0 : WEn[5] ? DataIn : Entry5;
	wire	[1:0]	nxt_Entry6 = Reset ? 2'h0 : WEn[6] ? DataIn : Entry6;
	wire	[1:0]	nxt_Entry7 = Reset ? 2'h0 : WEn[7] ? DataIn : Entry7;

	always @(posedge memclk) begin
		Entry0 = nxt_Entry0;
		Entry1 = nxt_Entry1;
		Entry2 = nxt_Entry2;
		Entry3 = nxt_Entry3;
		Entry4 = nxt_Entry4;
		Entry5 = nxt_Entry5;
		Entry6 = nxt_Entry6;
		Entry7 = nxt_Entry7;
	end

	reg	[2:0]	RdPntr;

	wire	[2:0]	nxt_RdPntr = Reset ? 3'h0 
					   : Read ? RdPntr + 3'h1 
						  : RdPntr;
	
	always @(posedge memclk)
		RdPntr <= nxt_RdPntr;

	reg	[1:0]	DataOut;
	reg	[1:0]	nxt_DataOut;

	always @(nxt_Entry0 or nxt_Entry1 or nxt_Entry2 or nxt_Entry3 or
		 nxt_Entry4 or nxt_Entry5 or nxt_Entry6 or nxt_Entry7 or
		 nxt_RdPntr)
	casex(nxt_RdPntr)
	3'h0:	nxt_DataOut = nxt_Entry0;
	3'h1:	nxt_DataOut = nxt_Entry1;
	3'h2:	nxt_DataOut = nxt_Entry2;
	3'h3:	nxt_DataOut = nxt_Entry3;
	3'h4:	nxt_DataOut = nxt_Entry4;
	3'h5:	nxt_DataOut = nxt_Entry5;
	3'h6:	nxt_DataOut = nxt_Entry6;
	3'h7:	nxt_DataOut = nxt_Entry7;
	endcase

	always @(posedge memclk)
		DataOut <= nxt_DataOut;

	wire	Bk0CAS = (DataOut==2'b00);
	wire	Bk1CAS = (DataOut==2'b01);
	wire	Bk2CAS = (DataOut==2'b10);
	wire	Bk3CAS = (DataOut==2'b11);

	wire	Bk0CASMatch = Pr0StB0 ? Bk0CAS : (Bk0CAS | Bk1CAS);
	wire	Bk1CASMatch = Pr0StB0 ? Bk1CAS : (Bk0CAS | Bk1CAS);
	wire	Bk2CASMatch = Pr1StB0 ? Bk2CAS : (Bk2CAS | Bk3CAS);
	wire	Bk3CASMatch = Pr1StB0 ? Bk3CAS : (Bk2CAS | Bk3CAS);

	wire	empty = (WrPntr==RdPntr);

	wire one    = (RdPntr==3'b000) & (WrPntr==3'b001)
		    | (RdPntr==3'b001) & (WrPntr==3'b010)
		    | (RdPntr==3'b010) & (WrPntr==3'b011)
		    | (RdPntr==3'b011) & (WrPntr==3'b100)
		    | (RdPntr==3'b100) & (WrPntr==3'b101)
		    | (RdPntr==3'b101) & (WrPntr==3'b110)
		    | (RdPntr==3'b110) & (WrPntr==3'b111)
		    | (RdPntr==3'b111) & (WrPntr==3'b000);

	wire two =    (RdPntr==3'b000) & (WrPntr==3'b010)
		    | (RdPntr==3'b001) & (WrPntr==3'b011)
		    | (RdPntr==3'b010) & (WrPntr==3'b100)
		    | (RdPntr==3'b011) & (WrPntr==3'b101)
		    | (RdPntr==3'b100) & (WrPntr==3'b110)
		    | (RdPntr==3'b101) & (WrPntr==3'b111)
		    | (RdPntr==3'b110) & (WrPntr==3'b000)
		    | (RdPntr==3'b111) & (WrPntr==3'b001);

	wire three =  (RdPntr==3'b000) & (WrPntr==3'b011)
		    | (RdPntr==3'b001) & (WrPntr==3'b100)
		    | (RdPntr==3'b010) & (WrPntr==3'b101)
		    | (RdPntr==3'b011) & (WrPntr==3'b110)
		    | (RdPntr==3'b100) & (WrPntr==3'b111)
		    | (RdPntr==3'b101) & (WrPntr==3'b000)
		    | (RdPntr==3'b110) & (WrPntr==3'b001)
		    | (RdPntr==3'b111) & (WrPntr==3'b010);

	wire four =   (RdPntr==3'b000) & (WrPntr==3'b100)
		    | (RdPntr==3'b001) & (WrPntr==3'b101)
		    | (RdPntr==3'b010) & (WrPntr==3'b110)
		    | (RdPntr==3'b011) & (WrPntr==3'b111)
		    | (RdPntr==3'b100) & (WrPntr==3'b000)
		    | (RdPntr==3'b101) & (WrPntr==3'b001)
		    | (RdPntr==3'b110) & (WrPntr==3'b010)
		    | (RdPntr==3'b111) & (WrPntr==3'b011);

	wire five   = (RdPntr==3'b000) & (WrPntr==3'b101)
		    | (RdPntr==3'b001) & (WrPntr==3'b110)
		    | (RdPntr==3'b010) & (WrPntr==3'b111)
		    | (RdPntr==3'b011) & (WrPntr==3'b000)
		    | (RdPntr==3'b100) & (WrPntr==3'b001)
		    | (RdPntr==3'b101) & (WrPntr==3'b010)
		    | (RdPntr==3'b110) & (WrPntr==3'b011)
		    | (RdPntr==3'b111) & (WrPntr==3'b100);

	reg overflow;
	always @(posedge memclk)
	overflow = ~(empty | one | two | three | four | five);

	// synopsys translate_off
	always @(overflow)
	if (overflow) $display("ERROR: %t: CASFifo: overflow", $time);
	// synopsys translate_on

endmodule