// counter.v
`define addr_bits 19

/*
--****************************************************************************
-- IMPORTANT-READ THESE TERMS CAREFULLY BEFORE UTILIZING THE INFORMATION
-- CONTAINED IN THIS APPLICATION NOTE. 
--
-- NO SUPPORT/NO WARRANTY. THE DESIGN FILES AND DOCUMENTATION ARE PROVIDED
-- WITHOUT SUPPORT OR WARRANTY OF ANY KIND. ACTEL IS NOT OBLIGATED TO 
-- PROVIDE UPDATES, BUG FIXES, OR TECHNICAL SUPPORT AND DISCLAIMS ALL 
-- WARRANTIES INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE, AND WARRANTIES OF NON-INFRINGEMENT OF THE
-- RIGHTS OF THIRD PARTIES (INCLUDING, WITHOUT LIMITATION, RIGHTS UNDER PATENT,
-- COPYRIGHT, TRADE SECRET, OR OTHER INTELLECTUAL PROPERTY RIGHTS).  RECIPIENT
-- ACCEPTS THE APPLICATION NOTE DESIGN FILES AND DOCUMENTATION IN "AS-IS"
-- CONDITION.
--*****************************************************************************
*/

module counter(clk,init,load,term_cnt,Q);

//Inputs
input clk;
input init;

//outputs
output term_cnt;
reg term_cnt;
output load;
reg load;
output [(`addr_bits-1):0] Q;
reg [(`addr_bits-1):0] Q;

//internals
reg [(`addr_bits-1):0] address;
reg [2:0] cnt;
parameter term_cnt_int = {`addr_bits{1'b1}}; 

always @(posedge clk)
begin
	if (~init)
	  cnt = 0;
	else if (~term_cnt)
		cnt = cnt + 1;
end

always @(negedge clk)
begin
	if (~init)
	begin
	  address = 0;
	  load = 1'b1; 
	end
	else if (cnt[2] && cnt[1] && cnt[0])  //increment the address after 8 bits are sent
	  begin
	   address = address + 1;
	   load = 1'b1;
	  end
	else
	  begin
	   address = address;
	   load = 1'b0;
	  end
end

always @(cnt or address)
begin
	if (address == term_cnt_int)
	  term_cnt = 1'b1;
	else
	  term_cnt = 1'b0;
	Q = address;
end

endmodule  
