OpenCores
URL https://opencores.org/ocsvn/blue/blue/trunk

Subversion Repositories blue

[/] [blue/] [trunk/] [blue8/] [io.v] - Rev 4

Go to most recent revision | Compare with Previous | Blame | View Log

/*
    This file is part of Blue8.
 
    These modules are from Ed Doering
 
 
*/
 
`timescale 1ns / 1ps
module DisplayHex (
// Digit display interface for Digilent DIO1, DIO4 and Spartan-3 boards
//
// - Accepts two 8-bit values on input, and displays the hexadecimal
//     representation of each value on the four-digit seven-segment display
// - 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)
//
// Instantiation template:
/*
DigitDisplay instancename (
	// System connections
    .gClock(  ), 
    .gReset(  ), 	 // Active high
 
    // Data inputs
    .iRight(  ),   // 8-bit value
    .iLeft(  ),    // 8-bit value
 
    // Direct connections to DIO1 or DIO4 board:
    // Segment selectors
    .oSegmentA(  ), 
    .oSegmentB(  ), 
    .oSegmentC(  ), 
    .oSegmentD(  ), 
    .oSegmentE(  ), 
    .oSegmentF(  ), 
    .oSegmentG(  ), 
    .oSegmentDP(  ),
 
    // Digit selectors 
    .oDigitRight(  ), 
    .oDigitMiddleRight(  ), 
    .oDigitMiddleLeft(  ), 
    .oDigitLeft(  )
    );
	// Use 0 for DIO4 and Spartan-3 boards, 1 for DIO1 board (parameter defaults to 0 
	// when 'defparam' line is omitted).
*/
// End of instantiation template
//
// Author: Ed Doering
// Created: 21 Jan 2003
// Revised: 16 Mar 2004 (added parameter to choose digit select assertion level)
// 	16 Aug 2005 (updated for Spartan-3; updated signal names)
 
	// Global system resources:
	input gClock,	// System clock (50 MHz)
	input gReset,	// Master reset (active high)
 
	// Inputs:
	input [7:0] iRight,	// Value to display on right two digits
	input [7:0] iLeft,	// Value to display on left two digits
	input [3:0] indp,    // input decimal points
 
	// Outputs:
	output reg oSegmentA,	// LED segment a (active low)
	output reg oSegmentB,	// etc.
	output reg oSegmentC,
	output reg oSegmentD,
	output reg oSegmentE,
	output reg oSegmentF,
	output reg oSegmentG,
	output reg oSegmentDP,	// LED decimal point
	output reg oDigitRight,	// Rightmost digit enable (active high)
	output reg oDigitMiddleRight,	// etc.
	output reg oDigitMiddleLeft,
	output reg oDigitLeft
);
 
// User-adjustable constants
parameter pClockFrequency = 50;	// Clock frequency in MHz
parameter pRefreshFrequency = 100;	// Display refresh rate (for entire display) in Hz
 
// Upper limit for frequency divider counter
parameter pUpperLimit = (pClockFrequency * 1000000) / (4 * pRefreshFrequency);
//parameter pUpperLimit = 2; // for simulation only
 
// Number of bits for frequency divider counter (will accommodate 
// refresh frequencies down to 1 Hz)
parameter pDividerCounterBits = 24;
 
 
// Registered identifiers:
reg [pDividerCounterBits-1:0] rCycles;
reg [1:0] rDigitSelect;
reg [7:0] rNybble;
reg [3:0] rDigit;
reg wDecimalPoint;
reg [6:0] rCharacter;
 
// Frequency divider and 2-bit counter for digit selector
always @ (posedge gClock or posedge gReset)
	if (gReset) begin
		rCycles <= 0;
		rDigitSelect <= 3;
	end
	else
		if (rCycles == pUpperLimit)	begin
			rCycles <= 0;
			rDigitSelect <= rDigitSelect - 1;
		end
		else
			rCycles <= rCycles + 1;
 
// Decode the digit selector to four control lines
always @ (rDigitSelect)
		case (rDigitSelect)
			2'b00 : rDigit <= 4'b1110;
			2'b01 : rDigit <= 4'b1101;
			2'b10 : rDigit <= 4'b1011; 
			2'b11 : rDigit <= 4'b0111;
		endcase
 
 
// MUX the four 4-bit inputs to a single 4-bit value
always @ (rDigitSelect or iRight or iLeft or indp)
	case (rDigitSelect)
		2'b00 : begin rNybble <= iRight[3:0]; wDecimalPoint <= indp[0]; end
		2'b01 : begin rNybble <= iRight[7:4]; wDecimalPoint <= indp[1]; end
		2'b10 : begin rNybble <= iLeft[3:0]; wDecimalPoint <= indp[2]; end
		2'b11 : begin rNybble <= iLeft[7:4]; wDecimalPoint <= indp[3]; end
	endcase
 
// Convert 4-bit value to character
always @ (rNybble)
	case (rNybble)       //     abcdefg
		4'h0 : rCharacter <= ~(7'b1111110);
		4'h1 : rCharacter <= ~(7'b0110000);
		4'h2 : rCharacter <= ~(7'b1101101);
		4'h3 : rCharacter <= ~(7'b1111001);
		4'h4 : rCharacter <= ~(7'b0110011);
		4'h5 : rCharacter <= ~(7'b1011011);
		4'h6 : rCharacter <= ~(7'b1011111);
		4'h7 : rCharacter <= ~(7'b1110000);
		4'h8 : rCharacter <= ~(7'b1111111);
		4'h9 : rCharacter <= ~(7'b1111011);
		4'ha : rCharacter <= ~(7'b1110111);
		4'hb : rCharacter <= ~(7'b0011111);
		4'hc : rCharacter <= ~(7'b1001110);
		4'hd : rCharacter <= ~(7'b0111101);
		4'he : rCharacter <= ~(7'b1001111);
		4'hf : rCharacter <= ~(7'b1000111);
		default : rCharacter <= ~(7'b1001001);	
	endcase
 
// Create registered outputs (for glitch-free output)
always @ (posedge gClock or posedge gReset)
	if (gReset) begin
		oSegmentA <= 0;
		oSegmentB <= 0;
		oSegmentC <= 0;
		oSegmentD <= 0;
		oSegmentE <= 0;
		oSegmentF <= 0;
		oSegmentG <= 0;
		oSegmentDP <= 0;
		oDigitRight <= 1'b1;
		oDigitMiddleRight <= 1'b1;
		oDigitMiddleLeft <= 1'b1;
		oDigitLeft <= 1'b1;
	end
	else begin
		oSegmentA <= rCharacter[6];
		oSegmentB <= rCharacter[5];
		oSegmentC <= rCharacter[4];
		oSegmentD <= rCharacter[3];
		oSegmentE <= rCharacter[2];
		oSegmentF <= rCharacter[1];
		oSegmentG <= rCharacter[0];
		oSegmentDP <= wDecimalPoint;
		oDigitRight <= rDigit[0];
		oDigitMiddleRight <= rDigit[1];
		oDigitMiddleLeft <= rDigit[2];
		oDigitLeft <= rDigit[3];
	end
 
endmodule
 
//-----------------------------------------------------------------------------
 
module Debouncer (
// Switch debouncer for Digilent FPGA boards
//
// Requires a 50MHz clock, and implements a 10ms wait period.
// Includes glitch suppression. Built-in synchronizer.
// Outputs include a debounced replica of the input signal, and
// single clock period pulse outputs to indicate rising edge and
// falling edge detected (of clean signal).
//
// 10ms at 50MHz is 500,000 master clock cycles, requiring 19 bits
// of register space.
 
	// Global system resources:
	input gClock,	// System clock (must be 50 MHz)
	input gReset,	// Master reset (asynchronous, active high)
 
	// Inputs:
	input iBouncy,	// Bouncy switch signal
 
	// Outputs:
	output reg oDebounced,	// Debounced replica of switch signal
	output reg oPulseOnRisingEdge,	// Single pulse to indicate rising edge detected
	output reg oPulseOnFallingEdge	// Single pulse to indicate falling edge detected
);
 
// Constant parameters
parameter pInitialValue = 0;
parameter pTimerWidth = 19;
parameter pInitialTimerValue = 19'd500_000; // for synthesis
//parameter pInitialTimerValue = 19'd2; // for simulation
 
// Registered identifiers:
reg	rInitializeTimer;
reg	rWaitForTimer;
reg	rSaveInput;
reg	rBouncy_Syncd;
reg	[pTimerWidth-1:0] rTimer;
 
// Wire identifiers:
wire	wTransitionDetected;
wire	wTimerFinished;
 
// Controller:
always @ (posedge gClock or posedge gReset)
	if (gReset)
		{rInitializeTimer,rWaitForTimer,rSaveInput} <= {3'b100};
	else begin
		rInitializeTimer <= rInitializeTimer && !wTransitionDetected ||
							rSaveInput;
		rWaitForTimer <= rInitializeTimer && wTransitionDetected ||
							rWaitForTimer && !wTimerFinished;
		rSaveInput <= rWaitForTimer && wTimerFinished;
	end		
 
// Datapath:
always @ (posedge gClock or posedge gReset)
	if (gReset) begin
		rBouncy_Syncd <= 0;
		oDebounced <= pInitialValue;
		oPulseOnRisingEdge <= 0;
		oPulseOnFallingEdge <= 0;
		rTimer <= pInitialTimerValue;
	end
	else begin
		rBouncy_Syncd <= iBouncy;
		oDebounced <= (rSaveInput) ? rBouncy_Syncd : oDebounced;
		oPulseOnRisingEdge <= (rSaveInput && rBouncy_Syncd);
		oPulseOnFallingEdge <= (rSaveInput && !rBouncy_Syncd);
		rTimer <= (rInitializeTimer) ? pInitialTimerValue : rTimer - 1;
	end
 
assign wTransitionDetected = rBouncy_Syncd ^ oDebounced;
assign wTimerFinished = (rTimer == 0);
 
endmodule

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.