summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-10-14 13:44:56 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-10-14 13:44:56 -0500
commit7997af3f4f6d8ca680e381cb1bee4ebe3b82e175 (patch)
treef88cd6c4fa54fdf8c9d76506b9cf03cfa0142763
parente9bed7d3af54c11f1174b73daa8d8b838448b27f (diff)
downloadulab-7997af3f4f6d8ca680e381cb1bee4ebe3b82e175.tar.gz
ulab-7997af3f4f6d8ca680e381cb1bee4ebe3b82e175.zip
Fix 7-segment LED display and add sample driver for the same
-rw-r--r--clients/tde/configure.in142
-rw-r--r--clients/tde/src/part/fpgaview/part.cpp51
-rw-r--r--clients/tde/src/part/fpgaview/part.h11
-rw-r--r--fpga/common/remote_access.v71
-rw-r--r--fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf6
-rw-r--r--fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v73
6 files changed, 150 insertions, 204 deletions
diff --git a/clients/tde/configure.in b/clients/tde/configure.in
deleted file mode 100644
index c8f9931..0000000
--- a/clients/tde/configure.in
+++ /dev/null
@@ -1,142 +0,0 @@
-dnl =======================================================
-dnl FILE: ./admin/configure.in.min
-dnl =======================================================
-
-dnl This file is part of the KDE libraries/packages
-dnl Copyright (C) 2001 Stephan Kulow (coolo@kde.org)
-
-dnl This file is free software; you can redistribute it and/or
-dnl modify it under the terms of the GNU Library General Public
-dnl License as published by the Free Software Foundation; either
-dnl version 2 of the License, or (at your option) any later version.
-
-dnl This library is distributed in the hope that it will be useful,
-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-dnl Library General Public License for more details.
-
-dnl You should have received a copy of the GNU Library General Public License
-dnl along with this library; see the file COPYING.LIB. If not, write to
-dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-dnl Boston, MA 02110-1301, USA.
-
-# Original Author was Kalle@kde.org
-# I lifted it in some mater. (Stephan Kulow)
-# I used much code from Janos Farkas
-
-dnl Process this file with autoconf to produce a configure script.
-
-AC_INIT(acinclude.m4) dnl a source file from your sub dir
-
-dnl This is so we can use kde-common
-AC_CONFIG_AUX_DIR(admin)
-
-dnl This ksh/zsh feature conflicts with `cd blah ; pwd`
-unset CDPATH
-
-dnl Checking host/target/build systems, for make, install etc.
-AC_CANONICAL_SYSTEM
-dnl Perform program name transformation
-AC_ARG_PROGRAM
-
-dnl Automake doc recommends to do this only here. (Janos)
-AM_INIT_AUTOMAKE(tde, "3.5.10") dnl searches for some needed programs
-
-KDE_SET_PREFIX
-
-dnl generate the config header
-AM_CONFIG_HEADER(config.h) dnl at the distribution this done
-
-dnl Checks for programs.
-AC_PROG_CC
-AC_PROG_CXX
-AC_CHECK_COMPILERS
-AC_ENABLE_SHARED(yes)
-AC_ENABLE_STATIC(no)
-KDE_PROG_LIBTOOL
-
-dnl for NLS support. Call them in this order!
-dnl WITH_NLS is for the po files
-AM_KDE_WITH_NLS
-
-KDE_USE_QT(3.2)
-AC_PATH_KDE
-dnl =======================================================
-dnl FILE: configure.in.in
-dnl =======================================================
-
-#MIN_CONFIG(3.2)
-CXXFLAGS="$CXXFLAGS $KDE_DEFAULT_CXXFLAGS"
-
-if test "$build_arts" = "yes"; then
- AC_DEFINE(USE_ARTS, 1, [If we use arts volume])
- LIB_ARTS="-lartskde"
- AC_SUBST(LIB_ARTS)
-fi
-
-KDE_INIT_DOXYGEN([The API Reference], [Version $VERSION])
-
-KDE_CREATE_SUBDIRSLIST
-AC_CONFIG_FILES([ Makefile ])
-AC_CONFIG_FILES([ doc/Makefile ])
-AC_CONFIG_FILES([ misc/Makefile ])
-AC_CONFIG_FILES([ po/Makefile ])
-AC_CONFIG_FILES([ src/Makefile ])
-AC_CONFIG_FILES([ src/app/Makefile ])
-AC_CONFIG_FILES([ src/app/views/Makefile ])
-AC_CONFIG_FILES([ src/dialogs/Makefile ])
-AC_CONFIG_FILES([ src/part/Makefile ])
-AC_CONFIG_FILES([ src/part/adminconsole/Makefile ])
-AC_CONFIG_FILES([ src/part/adminusermgmt/Makefile ])
-AC_CONFIG_FILES([ src/part/commanalyzer/Makefile ])
-AC_CONFIG_FILES([ src/part/fpgaprogram/Makefile ])
-AC_CONFIG_FILES([ src/part/fpgaview/Makefile ])
-AC_CONFIG_FILES([ src/part/scope/Makefile ])
-AC_CONFIG_FILES([ src/part/sensormonitor/Makefile ])
-AC_CONFIG_FILES([ src/widgets/Makefile ])
-AC_OUTPUT
-# Check if KDE_SET_PREFIX was called, and --prefix was passed to configure
-if test -n "$kde_libs_prefix" -a -n "$given_prefix"; then
- # And if so, warn when they don't match
- if test "$kde_libs_prefix" != "$given_prefix"; then
- # And if kde doesn't know about the prefix yet
- echo ":"`tde-config --path exe`":" | grep ":$given_prefix/bin/:" 2>&1 >/dev/null
- if test $? -ne 0; then
- echo ""
- echo "Warning: you chose to install this package in $given_prefix,"
- echo "but KDE was found in $kde_libs_prefix."
- echo "For this to work, you will need to tell KDE about the new prefix, by ensuring"
- echo "that TDEDIRS contains it, e.g. export TDEDIRS=$given_prefix:$kde_libs_prefix"
- echo "Then restart KDE."
- echo ""
- fi
- fi
-fi
-
-if test x$GXX = "xyes" -a x$kde_have_gcc_visibility = "xyes" -a x$kde_cv_val_qt_gcc_visibility_patched = "xno"; then
- echo ""
- echo "Your GCC supports symbol visibility, but the patch for Qt supporting visibility"
- echo "was not included. Therefore, GCC symbol visibility support remains disabled."
- echo ""
- echo "For better performance, consider including the Qt visibility supporting patch"
- echo "located at:"
- echo ""
- echo "http://bugs.kde.org/show_bug.cgi?id=109386"
- echo ""
- echo "and recompile all of Qt and KDE. Note, this is entirely optional and"
- echo "everything will continue to work just fine without it."
- echo ""
-fi
-
-if test "$all_tests" = "bad"; then
- if test ! "$cache_file" = "/dev/null"; then
- echo ""
- echo "Please remove the file $cache_file after changing your setup"
- echo "so that configure will find the changes next time."
- echo ""
- fi
-else
- echo ""
- echo "Good - your configure finished. Start make now"
- echo ""
-fi
diff --git a/clients/tde/src/part/fpgaview/part.cpp b/clients/tde/src/part/fpgaview/part.cpp
index c312c66..dc5c9d9 100644
--- a/clients/tde/src/part/fpgaview/part.cpp
+++ b/clients/tde/src/part/fpgaview/part.cpp
@@ -140,6 +140,7 @@ FPGA7Segment::~FPGA7Segment() {
void FPGA7Segment::init() {
setFrameStyle(TQFrame::Box | TQFrame::Raised);
+ prevSegments = 0;
val = 0;
smallPoint = TRUE;
setSegmentStyle(Flat);
@@ -147,34 +148,32 @@ void FPGA7Segment::init() {
m_currentSegments = (char*)malloc(sizeof(char)*9);
m_prevSegments[0] = 99;
m_currentSegments[0] = 99;
- d = 0;
setSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum));
}
-void FPGA7Segment::setLitSegments(unsigned int segs) {
+void FPGA7Segment::setLitSegments(unsigned char segs) {
// This produces an array of up to 10 chars, with each char being the number of a lit segment, and the list being terminated with the number 99
// The bit input in segs is active high
// The bit sequence, MSB to LSB, is dp a b c d e f g
// Segment letters are taken from ug130.pdf
- // 0: a
- // 1: f
- // 2: d
- // 3: g
- // 4: e
- // 5: c
- // 6: b
- // 7: dp
-
- int i = 0;
- if (segs & 0x80) { m_currentSegments[i] = 7; i++; }
- if (segs & 0x40) { m_currentSegments[i] = 0; i++; }
- if (segs & 0x20) { m_currentSegments[i] = 6; i++; }
- if (segs & 0x10) { m_currentSegments[i] = 5; i++; }
- if (segs & 0x08) { m_currentSegments[i] = 2; i++; }
- if (segs & 0x04) { m_currentSegments[i] = 4; i++; }
- if (segs & 0x02) { m_currentSegments[i] = 1; i++; }
- if (segs & 0x01) { m_currentSegments[i] = 3; i++; }
- m_currentSegments[i] = 99;
+
+ if (prevSegments != segs) {
+ int i = 0;
+ if (segs & 0x80) { m_currentSegments[i] = 7; i++; }
+ if (segs & 0x40) { m_currentSegments[i] = 0; i++; }
+ if (segs & 0x20) { m_currentSegments[i] = 2; i++; }
+ if (segs & 0x10) { m_currentSegments[i] = 5; i++; }
+ if (segs & 0x08) { m_currentSegments[i] = 6; i++; }
+ if (segs & 0x04) { m_currentSegments[i] = 4; i++; }
+ if (segs & 0x02) { m_currentSegments[i] = 1; i++; }
+ if (segs & 0x01) { m_currentSegments[i] = 3; i++; }
+
+ m_currentSegments[i] = 99;
+
+ update();
+ }
+
+ prevSegments = segs;
}
void FPGA7Segment::drawContents( TQPainter *p )
@@ -230,7 +229,7 @@ void FPGA7Segment::drawDigit(const TQPoint &pos, TQPainter &p, int segLen, const
const char erase = 0;
const char draw = 1;
- const char leaveAlone = 2;
+// const char leaveAlone = 2;
segs = m_prevSegments;
for ( nErases=0; segs[nErases] != 99; nErases++ ) {
@@ -242,8 +241,12 @@ void FPGA7Segment::drawDigit(const TQPoint &pos, TQPainter &p, int segLen, const
for(i = 0 ; segs[i] != 99 ; i++) {
for ( j=0; j<nErases; j++ ) {
if ( segs[i] == updates[j][1] ) { // Same segment ?
+// FIXME
+// Always redraw segments for now, as dragging windows in front of the LED display currently erases the occluded portion(s) of the display!
+#if 0
updates[j][0] = leaveAlone; // yes, already on screen
break;
+#endif
}
}
if ( j == nErases ) { // If not already on screen
@@ -584,8 +587,8 @@ K_EXPORT_COMPONENT_FACTORY(libremotelab_fpgaviewer, RemoteLab::Factory)
FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList&)
: RemoteInstrumentPart( parent, name ), m_base(NULL), m_interfaceMode(BasicInterfaceMode),
m_commHandlerState(0), m_commHandlerMode(0), m_commHandlerNextState(0), m_commHandlerNextMode(0), m_connectionActiveAndValid(false), m_tickerState(0), m_remoteInputModeEnabled(false), m_4bitInputValue(0), m_4bitOutputValue(0),
- m_8bitInputValue(0), m_8bitOutputValue(0), m_16bitInputValue(0), m_16bitOutputValue(0), m_7segDigit3OutputValue(0xffffffff),
- m_7segDigit2OutputValue(0xffffffff), m_7segDigit1OutputValue(0xffffffff), m_7segDigit0OutputValue(0xffffffff),
+ m_8bitInputValue(0), m_8bitOutputValue(0), m_16bitInputValue(0), m_16bitOutputValue(0), m_7segDigit3OutputValue(0xff),
+ m_7segDigit2OutputValue(0xff), m_7segDigit1OutputValue(0xff), m_7segDigit0OutputValue(0xff),
m_batchOutputFile(NULL), m_dataOutputFile(NULL),
m_inputImageViewer(NULL), m_outputImageViewer(NULL)
{
diff --git a/clients/tde/src/part/fpgaview/part.h b/clients/tde/src/part/fpgaview/part.h
index 26e70ec..b49ace2 100644
--- a/clients/tde/src/part/fpgaview/part.h
+++ b/clients/tde/src/part/fpgaview/part.h
@@ -105,7 +105,7 @@ class TQ_EXPORT FPGA7Segment : public TQFrame
SegmentStyle segmentStyle() const;
virtual void setSegmentStyle(SegmentStyle);
- void setLitSegments(unsigned int);
+ void setLitSegments(unsigned char);
TQSize sizeHint() const;
@@ -120,6 +120,7 @@ class TQ_EXPORT FPGA7Segment : public TQFrame
char* m_prevSegments;
char* m_currentSegments;
+ unsigned int prevSegments;
double val;
uint smallPoint : 1;
uint fill : 1;
@@ -231,10 +232,10 @@ namespace RemoteLab
unsigned int m_16bitInputValue;
unsigned int m_16bitOutputValue;
TQCString m_LCDOutputValue;
- unsigned int m_7segDigit3OutputValue;
- unsigned int m_7segDigit2OutputValue;
- unsigned int m_7segDigit1OutputValue;
- unsigned int m_7segDigit0OutputValue;
+ unsigned char m_7segDigit3OutputValue;
+ unsigned char m_7segDigit2OutputValue;
+ unsigned char m_7segDigit1OutputValue;
+ unsigned char m_7segDigit0OutputValue;
UnsignedIntegerList m_batchInputValueList;
UnsignedIntegerList m_batchOutputValueList;
diff --git a/fpga/common/remote_access.v b/fpga/common/remote_access.v
index 049b74f..668a6cc 100644
--- a/fpga/common/remote_access.v
+++ b/fpga/common/remote_access.v
@@ -43,7 +43,13 @@ module remote_access(
output sram_available,
input sram_processing_done,
input [7:0] led_segment_bus,
- input [3:0] led_digit_select);
+ input [3:0] led_digit_select,
+
+ // For use on Digilent Spartan 3E or compatible board only
+ output [3:0] remote_access_lcd_data_out,
+ output remote_access_lcd_rs_out,
+ output remote_access_lcd_rw_out,
+ output remote_access_lcd_enable_out);
reg [7:0] remote_access_4_bit_input_reg;
reg [7:0] remote_access_8_bit_input_reg;
@@ -57,7 +63,7 @@ module remote_access(
reg sram_available_reg;
reg startup_needed = 1;
- assign remote_access_4_bit_input = remote_access_4_bit_input_reg;
+ assign remote_access_4_bit_input = remote_access_4_bit_input_reg[3:0];
assign remote_access_8_bit_input = remote_access_8_bit_input_reg;
assign remote_access_16_bit_input = remote_access_16_bit_input_reg;
assign remote_access_lcd_data_out = remote_access_lcd_data_out_reg;
@@ -77,6 +83,7 @@ module remote_access(
reg four_mhz_clk;
reg clk_div_by_two;
+ reg clk_div_by_two_oneeighty;
reg clk_div_by_four;
reg clk_div_by_eight;
reg [3:0] fifty_clock_divider = 0;
@@ -92,8 +99,12 @@ module remote_access(
always @(posedge main_fifty_clock) begin
clk_div_by_two = !clk_div_by_two;
end
+
+ always @(negedge main_fifty_clock) begin
+ clk_div_by_two_oneeighty = !clk_div_by_two_oneeighty;
+ end
- always @(posedge clk_div_by_two) begin
+ always @(posedge clk_div_by_two_oneeighty) begin
clk_div_by_four = !clk_div_by_four;
end
@@ -108,45 +119,63 @@ module remote_access(
//-----------------------------------------------------------------------------------
reg [7:0] led_display_bytes [3:0];
- reg [4:0] digit_blanker_1 = 0;
- reg [4:0] digit_blanker_2 = 0;
- reg [4:0] digit_blanker_3 = 0;
- reg [4:0] digit_blanker_4 = 0;
+ reg [5:0] digit_blanker_1 = 0;
+ reg [5:0] digit_blanker_2 = 0;
+ reg [5:0] digit_blanker_3 = 0;
+ reg [5:0] digit_blanker_4 = 0;
+
+ reg [7:0] led_segment_bus_latch;
+ reg [3:0] led_digit_select_latch;
always @(negedge clk_div_by_eight) begin
- if (led_digit_select[0] == 0) begin
- led_display_bytes[0] = led_segment_bus;
+ led_segment_bus_latch = led_segment_bus;
+ led_digit_select_latch = led_digit_select;
+
+ if (led_digit_select_latch[0] == 0) begin
+ led_display_bytes[0] = led_segment_bus_latch;
digit_blanker_1 = 0;
+ digit_blanker_2 = digit_blanker_2 + 1;
+ digit_blanker_3 = digit_blanker_3 + 1;
+ digit_blanker_4 = digit_blanker_4 + 1;
end
- if (led_digit_select[1] == 0) begin
- led_display_bytes[1] = led_segment_bus;
+ if (led_digit_select_latch[1] == 0) begin
+ led_display_bytes[1] = led_segment_bus_latch;
+ digit_blanker_1 = digit_blanker_1 + 1;
digit_blanker_2 = 0;
+ digit_blanker_3 = digit_blanker_3 + 1;
+ digit_blanker_4 = digit_blanker_4 + 1;
end
- if (led_digit_select[2] == 0) begin
- led_display_bytes[2] = led_segment_bus;
+ if (led_digit_select_latch[2] == 0) begin
+ led_display_bytes[2] = led_segment_bus_latch;
+ digit_blanker_1 = digit_blanker_1 + 1;
+ digit_blanker_2 = digit_blanker_2 + 1;
digit_blanker_3 = 0;
+ digit_blanker_4 = digit_blanker_4 + 1;
end
- if (led_digit_select[3] == 0) begin
- led_display_bytes[3] = led_segment_bus;
+ if (led_digit_select_latch[3] == 0) begin
+ led_display_bytes[3] = led_segment_bus_latch;
+ digit_blanker_1 = digit_blanker_1 + 1;
+ digit_blanker_2 = digit_blanker_2 + 1;
+ digit_blanker_3 = digit_blanker_3 + 1;
digit_blanker_4 = 0;
end
-
- if (digit_blanker_1 > 30) begin
+
+ if (digit_blanker_1 > 60) begin
led_display_bytes[0] = 255;
end
- if (digit_blanker_2 > 30) begin
+ if (digit_blanker_2 > 60) begin
led_display_bytes[1] = 255;
end
- if (digit_blanker_3 > 30) begin
+ if (digit_blanker_3 > 60) begin
led_display_bytes[2] = 255;
end
- if (digit_blanker_4 > 30) begin
+ if (digit_blanker_4 > 60) begin
led_display_bytes[3] = 255;
end
end
@@ -245,7 +274,7 @@ module remote_access(
reg transmit_dsp_rx_complete = 0;
reg transmit_dsp_rx_complete_done = 0;
- // Transmit!
+ // Transmit!
always @(posedge clk_div_by_two) begin
transmitter_4_bit_state = remote_access_4_bit_output;
transmitter_8_bit_state = remote_access_8_bit_output;
diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf
index ab433e5..c9a68dd 100644
--- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf
+++ b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf
@@ -1,8 +1,8 @@
# (c) 2013 Timothy Pearson, Raptor Engineering
# Released into the Public Domain
-NET "clk" LOC = "V10";
+NET "clk" LOC = "V10" | IOSTANDARD = "LVCMOS33";
TIMESPEC TS_clk = PERIOD clk 100000 kHz;
-NET "serial_input" LOC = "T12";
-NET "serial_output" LOC = "M10";
+NET "serial_input" LOC = "T12" | IOSTANDARD = "LVCMOS33";
+NET "serial_output" LOC = "M10" | IOSTANDARD = "LVCMOS33";
diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v
index 801a9aa..6162ec1 100644
--- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v
+++ b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v
@@ -40,6 +40,9 @@ module main(
wire [5:0] lcd_data_in_address;
wire [7:0] lcd_data_in_data;
wire lcd_data_in_enable;
+
+ wire [7:0] led_segment_bus;
+ wire [3:0] led_digit_select;
//-------------------------------------------------------------------------------------------------------
//
@@ -69,9 +72,9 @@ module main(
//
// Inputs:
// .clk: 50MHz clock
- // .4_bit_input 4-bit input to the user program from the remote access module
- // .8_bit_input 8-bit input to the user program from the remote access module
- // .16_bit_input 16-bit input to the user program from the remote access module
+ // .four_bit_input 4-bit input to the user program from the remote access module
+ // .eight_bit_input 8-bit input to the user program from the remote access module
+ // .sixteen_bit_input 16-bit input to the user program from the remote access module
// .serial_port_receiver Input from the serial port's RxD (receive data) pin
// .remote_access_input_enable Toggle remote access input vs. local input mode
// .local_input Local input to the remote program
@@ -90,9 +93,9 @@ module main(
// .led_digit_select Connect directly to the 4 bits enabling the LED display digits
//
// Outputs:
- // .4_bit_output 4-bit output from the user program to the remote access module
- // .8_bit_output 8-bit output from the user program to the remote access module
- // .16_bit_output 16-bit output from the user program to the remote access module
+ // .four_bit_output 4-bit output from the user program to the remote access module
+ // .eight_bit_output 8-bit output from the user program to the remote access module
+ // .sixteen_bit_output 16-bit output from the user program to the remote access module
// .lcd_data_out Data output to the LCD
// .lcd_rs_out RS signal output to the LCD
// .lcd_rw_out RW signal output to the LCD
@@ -131,7 +134,7 @@ module main(
.lcd_data_in_address(lcd_data_in_address), .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable),
.sram_wren_in(sram_wren_in), .sram_clock_in(sram_clock_in), .sram_data_in(sram_data_in), .sram_address_in(sram_address_in),
.sram_data_out(sram_data_out), .sram_available(sram_available), .sram_processing_done(sram_processing_done),
- .led_segment_bus(255), .led_digit_select(15));
+ .led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select));
assign remote_access_local_input[7:4] = 0; // Local inputs
assign remote_access_local_input[3:0] = 0; // Local inputs
@@ -153,7 +156,8 @@ module main(
sample_demo sample_demo(.clk(clk_div_by_two), .four_bit_input(four_bit_input), .four_bit_output(four_bit_output),
.eight_bit_input(eight_bit_input), .eight_bit_output(eight_bit_output), .sixteen_bit_input(sixteen_bit_input),
.sixteen_bit_output(sixteen_bit_output), .lcd_data_in_address(lcd_data_in_address),
- .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable));
+ .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable),
+ .led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select));
//-------------------------------------------------------------------------------------------------------
//
@@ -174,7 +178,7 @@ endmodule
//
//-------------------------------------------------------------------------------------------------------
-module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_bit_output, sixteen_bit_input, sixteen_bit_output, lcd_data_in_address, lcd_data_in_data, lcd_data_in_enable);
+module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_bit_output, sixteen_bit_input, sixteen_bit_output, lcd_data_in_address, lcd_data_in_data, lcd_data_in_enable, led_segment_bus, led_digit_select);
input clk;
input [3:0] four_bit_input;
@@ -188,6 +192,9 @@ module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_
output reg [7:0] lcd_data_in_data;
output reg lcd_data_in_enable;
+ output reg [7:0] led_segment_bus;
+ output reg [3:0] led_digit_select;
+
reg [7:0] lcd_sample_counter = 48; // Create a sample LCD display counter register
reg [31:0] lcd_character_change_timer = 0; // Wait a certain number of cycles before loading a new character
reg [5:0] lcd_current_character = 0; // The current character's address
@@ -218,6 +225,54 @@ module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_
end
end
end
+
+ // 7-segment LED display driver clock generator
+ reg sseg_clock;
+ reg [4:0] sseg_clock_counter;
+
+ always @(posedge clk) begin
+ sseg_clock_counter = sseg_clock_counter + 1;
+ if (sseg_clock_counter > 16) begin
+ sseg_clock_counter = 0;
+ sseg_clock = ~sseg_clock;
+ end
+ end
+
+ // 7-segment LED display driver
+ // led_segment_bus and led_digit_select are active low
+ // The bit sequence, MSB to LSB, is dp a b c d e f g
+ // Segment letters are taken from ug130.pdf page 15
+
+ // 0: 8'b10000001
+ // 1: 8'b11001111
+ // 2: 8'b10010010
+ // 3: 8'b10000110
+ reg [2:0] current_anode;
+ always @(posedge sseg_clock) begin
+ current_anode = current_anode + 1;
+ if (current_anode > 3) begin
+ current_anode = 0;
+ end
+
+ case (current_anode)
+ 0: begin
+ led_digit_select = 4'b1110;
+ led_segment_bus = 8'b10000001;
+ end
+ 1: begin
+ led_digit_select = 4'b1101;
+ led_segment_bus = 8'b11001111;
+ end
+ 2: begin
+ led_digit_select = 4'b1011;
+ led_segment_bus = 8'b10010010;
+ end
+ 3: begin
+ led_digit_select = 4'b0111;
+ led_segment_bus = 8'b10000110;
+ end
+ endcase
+ end
endmodule
//-------------------------------------------------------------------------------------------------------