//----- Synthesizable Circuit ----- module DigitDisplay ( // Digit display interface for Digilent Digital I/O 1 board // // - Accepts two 8-bit values on input, and displays the hexadecimal // representation of each value on the Digilent DIO1 peripheral board. // - 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: 21 Jan 2003 // Revised: // Inputs: i$Clock50MHz, // System clock (50 MHz) i$MasterReset, // Master reset (active high) i$RightByte, // Value to display on right two digits i$LeftByte, // Value to display on left two digits // 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$RightByte; input [7:0] i$LeftByte; // 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 [7:0] r$Nybble; reg [3:0] r$Digit; wire w$DecimalPoint; reg [6:0] r$Character; // 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 // Activate decimal point when left-middle digit is selected assign w$DecimalPoint = ~(r$DigitSelect == 2'b10); // MUX the four 4-bit inputs to a single 4-bit value always @ (r$DigitSelect or i$RightByte or i$LeftByte) case (r$DigitSelect) 2'b00 : r$Nybble <= i$RightByte[3:0]; 2'b01 : r$Nybble <= i$RightByte[7:4]; 2'b10 : r$Nybble <= i$LeftByte[3:0]; 2'b11 : r$Nybble <= i$LeftByte[7:4]; endcase // Convert 4-bit value to character always @ (r$Nybble) case (r$Nybble) // abcdefg 4'h0 : r$Character <= ~(7'b1111110); 4'h1 : r$Character <= ~(7'b0110000); 4'h2 : r$Character <= ~(7'b1101101); 4'h3 : r$Character <= ~(7'b1111001); 4'h4 : r$Character <= ~(7'b0110011); 4'h5 : r$Character <= ~(7'b1011011); 4'h6 : r$Character <= ~(7'b1011111); 4'h7 : r$Character <= ~(7'b1110000); 4'h8 : r$Character <= ~(7'b1111111); 4'h9 : r$Character <= ~(7'b1111011); 4'ha : r$Character <= ~(7'b1110111); 4'hb : r$Character <= ~(7'b0011111); 4'hc : r$Character <= ~(7'b1001110); 4'hd : r$Character <= ~(7'b0111101); 4'he : r$Character <= ~(7'b1001111); 4'hf : r$Character <= ~(7'b1000111); default : r$Character <= ~(7'b1001001); 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_a <= r$Character[6]; o$Segment_b <= r$Character[5]; o$Segment_c <= r$Character[4]; o$Segment_d <= r$Character[3]; o$Segment_e <= r$Character[2]; o$Segment_f <= r$Character[1]; o$Segment_g <= r$Character[0]; o$Segment_dp <= w$DecimalPoint; 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