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

module LED7_Display_Demo (
// Test for "LED7_Display" 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,

	o$LED1,		// Discrete LEDs (active high)
	o$LED2,
	o$LED3,
	o$LED4,
	o$LED5,
	o$LED6,
	o$LED7,
	o$LED8,

	o$LEDgate	// Hold high to enable discrete LED latch
);

// User-adjustable constants
parameter p$ClockFrequency = 50;	// Clock frequency in MHz
parameter p$UpdateFrequency = 10;	// Rate at which to activate segments (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;
output	o$LED1;
output	o$LED2;
output	o$LED3;
output	o$LED4;
output	o$LED5;
output	o$LED6;
output	o$LED7;
output	o$LED8;
output	o$LEDgate;


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

parameter p$ShifterBits = 5*8;// One bit for each LED on DIO1 board (including discretes)
reg	[p$ShifterBits-1:0]	r$Shifter;

// Frequency divider and shift register to activate each LED individually
always @ (posedge i$Clock50MHz or posedge i$MasterReset)
	if (i$MasterReset) begin
		r$Cycles <= 0;
		r$Shifter <= 255;
	end
	else
		if (r$Cycles == p$UpperLimit)	begin
			r$Cycles <= 0;
			r$Shifter <= {r$Shifter[0],r$Shifter[39:1]};
		end
		else
			r$Cycles <= r$Cycles + 1;

// Instantiate one display digit module
LED7_Display LED7_Display (

	// Inputs:
	.i$Clock50MHz (i$Clock50MHz),	// System clock (50 MHz)
	.i$MasterReset (i$MasterReset),	// Master reset (active high)
	.i$Right (r$Shifter[15:8]),			// Pattern to display on rightmost digit
	.i$MiddleRight (r$Shifter[23:16]),	// Pattern to display on middle right digit
	.i$MiddleLeft (r$Shifter[31:24]),	// Pattern to display on middle left digit
	.i$Left (r$Shifter[39:32]),	// Pattern to display on leftmost digit

	// Outputs:
	.o$Segment_a (o$Segment_a),	// LED segment a (active low)
	.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)
);

// Establish connections to discrete LEDs
assign o$LED8 = r$Shifter[7];
assign o$LED7 = r$Shifter[6];
assign o$LED6 = r$Shifter[5];
assign o$LED5 = r$Shifter[4];
assign o$LED4 = r$Shifter[3];
assign o$LED3 = r$Shifter[2];
assign o$LED2 = r$Shifter[1];
assign o$LED1 = r$Shifter[0];

// Permanently assert gate of LED latch
assign o$LEDgate = 1;
 
endmodule