//12-bit program counter for 4-bit CPU, comprising three 74163 chip modules

module Program_Counter
	(
	input [11:0] Address_In,  //12-bit input address for load
	input LOADn,  //Load (active low)
	input CLRn,  //Clear (active low)
	input CLK,
	input INCPC,
	output [11:0] Address_Out  //the 12-bit address output 
	);
	
	
	
//Counter #1
  wire [3:0] cnt1_out;  //Counter output
  wire [3:0] cnt1_in; //counter input
  wire cnt1_p=1;
  wire cnt1_t=1;
  wire cnt1_rco;
  
  assign cnt1_in = Address_In[3:0];
   
  CNT_74163 CNT_74163_inst1
  (//4-bit counter with load and carry
	//inputs
  	.A(cnt1_in),  //input A, B, C, D
	.LOADn(LOADn),  //Load (active low)
	.CLRn(CLRn),  //Clear (active low)
	.P(cnt1_p), //Enable
	.T(INCPC), //Enable
	.CLK(CLK),//.CLK(clk),
	//Outputs
	.Q(cnt1_out),  //the 4-bit output 
	.RCO(cnt1_rco)  //Ripple carry out
  );
  
    //Counter #2
  wire [3:0] cnt2_out;  //Counter output
  wire [3:0] cnt2_in; //counter input
  wire cnt2_p=1;
  //wire cnt2_t=1;  //This comes from counter #1's RCO
  wire cnt2_rco;
  
  assign cnt2_in = Address_In[7:4];
   
  CNT_74163 CNT_74163_inst2
  (//4-bit counter with load and carry
	//inputs
  	.A(cnt2_in),  //input A, B, C, D
	.LOADn(LOADn),  //Load (active low)
	.CLRn(CLRn),  //Clear (active low)
	.P(cnt2_p), //Enable
	.T(cnt1_rco), //RCO from Counter #1
	.CLK(CLK),//.CLK(clk),
	//Outputs
	.Q(cnt2_out),  //the 4-bit output 
	.RCO(cnt2_rco)  //Ripple carry out
  );
  
  //Counter #3
  wire [3:0] cnt3_out;  //Counter output
  wire [3:0] cnt3_in; //counter input

  wire cnt3_p=1;
  //wire cnt3_t=1;  //This comes from counter #2's RCO
  wire cnt3_rco;
  
  assign cnt3_in = Address_In[11:8];
   
  CNT_74163 CNT_74163_inst3
  (//4-bit counter with load and carry
	//inputs
  	.A(cnt3_in),  //input A, B, C, D
	.LOADn(LOADn),  //Load (active low)
	.CLRn(CLRn),  //Clear (active low)
	.P(cnt3_p), //Enable
	.T(cnt2_rco), //RCO from Counter #1
	.CLK(CLK),//.CLK(clk),
	//Outputs
	.Q(cnt3_out),  //the 4-bit output 
	.RCO(cnt3_rco)  //Ripple carry out
  );
  
  assign Address_Out = {cnt3_out, cnt2_out, cnt1_out};
  
  endmodule // Program_Counter