module DCA_CONTROL ( BCLK, BRESET, CUPDATE, DRAM_ACC, CA_SET, HIT_ALL, VADR_R, UPDATE, INVAL_A, WRITE, MDONE, USE_CA,
					 INHIBIT, KILL, WRCRAM0, WRCRAM1, WE_CV, WADR_CV, DAT_CV, INIT_CA_RUN, WRSET0, WRSET1 );

	input			BCLK;
	input			BRESET;
	input			CUPDATE;	// State CUPDATE : Cache is filled from DRAM
	input			DRAM_ACC;
	input			CA_SET;
	input			HIT_ALL;	// a complete cache hit !
	input	[11:7]	VADR_R;
	input	[23:0]	UPDATE;
	input			INVAL_A;
	input			WRITE;
	input			MDONE;		// Signal from DRAM : Access Done
	input			USE_CA;		// Signal use cache
	input	 		INHIBIT;	// Signal cache inhibit  - no write in cache
	input			KILL;		// valid Ram must be updated because of collision ... or CINV
	
	output			WRCRAM0,WRCRAM1;
	output			WE_CV;
	output	 [4:0]	WADR_CV;
	output	[23:0]	DAT_CV;
	output			INIT_CA_RUN;
	output			WRSET0,WRSET1;
	
	reg		 [1:0]	state;
	reg		 [4:0]	acount;
	reg				ca_set_d;

	wire			countf;
	
	always @(posedge BCLK) if (DRAM_ACC) ca_set_d <= CA_SET;	// Store for whole access

	// physical address is stored in TAG-RAM

	assign WRCRAM0 = (CUPDATE & ~INHIBIT) & ~ca_set_d;
	assign WRCRAM1 = (CUPDATE & ~INHIBIT) &  ca_set_d;
	
	// Load Valid RAM :
	
	assign WE_CV   = state[1] | HIT_ALL | (CUPDATE & ~INHIBIT) | KILL; // Hit All for "Last" Update
	assign WADR_CV = state[1] ? acount : VADR_R;
	assign DAT_CV  = state[1] ? 24'h0 : UPDATE;	

	// Clear of Cache-Valid RAMs : 32 clocks of BCLK
	
	assign countf = (acount == 5'h1F);
	
	always @(posedge BCLK)
		casex ({BRESET,INVAL_A,countf,state[1:0]})
		  5'b0xx_xx : state <= 2'b01;
		  5'b1xx_01 : state <= 2'b10;		// start counter
		  5'b10x_00 : state <= 2'b00;		// wait ...
		  5'b11x_00 : state <= 2'b10;
		  5'b1x0_10 : state <= 2'b10;
		  5'b1x1_10 : state <= 2'b00;
		  default   : state <= 2'b0;
		endcase
	
	always @(posedge BCLK) if (!state[1]) acount <= 5'h0; else acount <= acount + 5'h01;

	assign INIT_CA_RUN = state[1];
	
	// WRITE Control in data RAMs
	assign WRSET0 = ( ~CA_SET & WRITE & HIT_ALL) | (MDONE & USE_CA & ~ca_set_d);
	assign WRSET1 = (  CA_SET & WRITE & HIT_ALL) | (MDONE & USE_CA &  ca_set_d);
	
endmodule