//----- Synthesizable Circuit ----- module LED7_Display ( // Digit display interface for Digilent Digital I/O 1 board offering // individual control of each LED segment. // // - Accepts four 8-bit input values, where the most significant bit // corresponds to the decimal point, and the remaining seven bits // correspond to the segments "a" through "g". For example, the // value 8'b10010101 will activate the decimal point and segments // "c", "e" and "g". A "1" lights the segment, and a "0" turns it off. // - Uses multiplexed display scheme with 100 Hz refresh to minimize flicker. // - Requires 50MHz master clock // - Requires active-high master reset (all segments active on reset) // // Author: Ed Doering // Created: 22 Jan 2003 // Revised: // Inputs: i$Clock50MHz, // System clock (50 MHz) i$MasterReset, // Master reset (active high) i$Right, // Pattern to display on rightmost digit i$MiddleRight, // Pattern to display on middle right digit i$MiddleLeft, // Pattern to display on middle left digit i$Left, // Pattern to display on leftmost digit // 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$RefreshFrequency = 100; // Display refresh rate (for entire display) in Hz // Upper limit for frequency divider counter parameter p$UpperLimit = (p$ClockFrequency * 1000000) / (4 * p$RefreshFrequency); //parameter p$UpperLimit = 2; // for simulation only // Number of bits for frequency divider counter (will accommodate // refresh frequencies down to 1 Hz) parameter p$DividerCounterBits = 24; // Port mode declarations: // Inputs: input i$Clock50MHz; input i$MasterReset; input [7:0] i$Right; input [7:0] i$MiddleRight; input [7:0] i$MiddleLeft; input [7:0] i$Left; // 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 o$Segment_a; reg o$Segment_b; reg o$Segment_c; reg o$Segment_d; reg o$Segment_e; reg o$Segment_f; reg o$Segment_g; reg o$Segment_dp; reg o$Digit_Right; reg o$Digit_MiddleRight; reg o$Digit_MiddleLeft; reg o$Digit_Left; reg [p$DividerCounterBits-1:0] r$Cycles; reg [1:0] r$DigitSelect; reg [3:0] r$Digit; reg [7:0] r$Pattern; // Frequency divider and 2-bit counter for digit selector always @ (posedge i$Clock50MHz or posedge i$MasterReset) if (i$MasterReset) begin r$Cycles <= 0; r$DigitSelect <= 3; end else if (r$Cycles == p$UpperLimit) begin r$Cycles <= 0; r$DigitSelect <= r$DigitSelect - 1; end else r$Cycles <= r$Cycles + 1; // Decode the digit selector to four control lines always @ (r$DigitSelect) case (r$DigitSelect) 2'b00 : r$Digit <= 4'b0001; 2'b01 : r$Digit <= 4'b0010; 2'b10 : r$Digit <= 4'b0100; 2'b11 : r$Digit <= 4'b1000; endcase // MUX the four 8-bit inputs to a single 8-bit value, and bit-wise // complement to make active low always @ (r$DigitSelect or i$Right or i$MiddleRight or i$MiddleLeft or i$Left) case (r$DigitSelect) 2'b00 : r$Pattern <= ~i$Right; 2'b01 : r$Pattern <= ~i$MiddleRight; 2'b10 : r$Pattern <= ~i$MiddleLeft; 2'b11 : r$Pattern <= ~i$Left; endcase // Create registered outputs (for glitch-free output) always @ (posedge i$Clock50MHz or posedge i$MasterReset) if (i$MasterReset) begin o$Segment_a <= 0; o$Segment_b <= 0; o$Segment_c <= 0; o$Segment_d <= 0; o$Segment_e <= 0; o$Segment_f <= 0; o$Segment_g <= 0; o$Segment_dp <= 0; o$Digit_Right <= 1; o$Digit_MiddleRight <= 1; o$Digit_MiddleLeft <= 1; o$Digit_Left <= 1; end else begin o$Segment_dp <= r$Pattern[7]; o$Segment_a <= r$Pattern[6]; o$Segment_b <= r$Pattern[5]; o$Segment_c <= r$Pattern[4]; o$Segment_d <= r$Pattern[3]; o$Segment_e <= r$Pattern[2]; o$Segment_f <= r$Pattern[1]; o$Segment_g <= r$Pattern[0]; o$Digit_Right <= r$Digit[0]; o$Digit_MiddleRight <= r$Digit[1]; o$Digit_MiddleLeft <= r$Digit[2]; o$Digit_Left <= r$Digit[3]; end endmodule