//----- Synthesizable Circuit -----

module DigitDisplay_Demo (
// Demonstration of "DigitDisplay" interface for Digilent Digital I/O 1 board

	// Inputs:
	i$Clock50MHz,	// System clock (50 MHz)
	i$MasterReset,	// Master reset (active high)

	// Outputs:
	o$Segment_a,	// LED segment a (active low)
	o$Segment_b,	// etc.
	o$Segment_c,
	o$Segment_d,
	o$Segment_e,
	o$Segment_f,
	o$Segment_g,
	o$Segment_dp,	// LED decimal point
	o$Digit_Right,	// Rightmost digit enable (active high)
	o$Digit_MiddleRight,	// etc.
	o$Digit_MiddleLeft,
	o$Digit_Left
);

// User-adjustable constants
parameter p$ClockFrequency = 50;	// Clock frequency in MHz
parameter p$UpdateFrequency = 2;	// Rate at which to update numerical values (in Hz)

// Upper limit for frequency divider counter
parameter p$UpperLimit = (p$ClockFrequency * 1000000) / (p$UpdateFrequency);
//parameter p$UpperLimit = 2; // for simulation only

// Number of bits for frequency divider counter (will accommodate 
// update frequencies down to 1 Hz)
parameter p$DividerCounterBits = 26;


// Port mode declarations:
	// Inputs:
input	i$Clock50MHz;
input	i$MasterReset;

	// Outputs:
output	o$Segment_a;
output	o$Segment_b;
output	o$Segment_c;
output	o$Segment_d;
output	o$Segment_e;
output	o$Segment_f;
output	o$Segment_g;
output	o$Segment_dp;
output	o$Digit_Right;
output	o$Digit_MiddleRight;
output	o$Digit_MiddleLeft;
output	o$Digit_Left;


// Registered identifiers:
reg [p$DividerCounterBits-1:0] r$Cycles;
reg	[7:0]	r$RightByte;
reg	[7:0]	r$LeftByte;

// Frequency divider and 8-bit counters for numerical display
always @ (posedge i$Clock50MHz or posedge i$MasterReset)
	if (i$MasterReset) begin
		r$Cycles <= 0;
		r$RightByte <= 8'h42;
		r$LeftByte <= 8'h5E;
	end
	else
		if (r$Cycles == p$UpperLimit)	begin
			r$Cycles <= 0;
			r$RightByte <= r$RightByte + 1;
			r$LeftByte <= r$LeftByte - 1;
		end
		else
			r$Cycles <= r$Cycles + 1;

// Instantiate one display digit module
DigitDisplay DigitDisplay (

	// Inputs:
	.i$Clock50MHz (i$Clock50MHz),	// System clock (50 MHz)
	.i$MasterReset (i$MasterReset),	// Master reset (active high)
	.i$RightByte (r$RightByte),	// Value to display on right two digits
	.i$LeftByte (r$LeftByte),	// Value to display on left two digits

	// Outputs:
	.o$Segment_a (o$Segment_a),	// LED segment a (active high)
	.o$Segment_b (o$Segment_b),	// etc.
	.o$Segment_c (o$Segment_c),
	.o$Segment_d (o$Segment_d),
	.o$Segment_e (o$Segment_e),
	.o$Segment_f (o$Segment_f),
	.o$Segment_g (o$Segment_g),
	.o$Segment_dp (o$Segment_dp),	// LED decimal point
	.o$Digit_Right (o$Digit_Right),	// Rightmost digit enable (active high)
	.o$Digit_MiddleRight (o$Digit_MiddleRight),	// etc.
	.o$Digit_MiddleLeft (o$Digit_MiddleLeft),
	.o$Digit_Left (o$Digit_Left)
);

endmodule