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

Subversion Repositories rtcclock

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rtcclock
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/trunk/rtl/rtcclock.v
45,6 → 45,8
o_data, // multiplexed based upon i_wb_addr
// Output controls
o_sseg, o_led, o_interrupt,
//
o_ppd,
// Time setting hack(s)
i_hack);
input i_clk;
55,7 → 57,7
output reg [31:0] o_data;
output reg [31:0] o_sseg;
output wire [15:0] o_led;
output wire o_interrupt;
output wire o_interrupt, o_ppd;
input i_hack;
 
reg [31:0] clock, stopwatch, ckspeed;
124,8 → 126,9
clock[19:16] <= clock[19:16] + 4'h1;
end
end
// ppd <= (clock{15:8] == 8'h59);
ck_ppd <= (clock[21:0] == 22'h235959);
 
 
if ((ck_sel)&&(i_wb_we))
begin
if (8'hff != i_wb_data[7:0])
480,6 → 483,11
 
assign o_interrupt = tm_int || al_int;
 
// A once-per day strobe, on the last second of the day so that the
// the next clock is the first clock of the day. This is useful for
// connecting this module to a year/month/date date/calendar module.
assign o_ppd = (ck_ppd)&&(ck_pps);
 
always @(posedge i_clk)
case(i_wb_addr[2:0])
3'b000: o_data <= { clock[31:22], ck_last_clock };
/trunk/rtl/rtcdate.v
0,0 → 1,188
///////////////////////////////////////////////////////////////////////////
//
// Filename: rtcdate.v
//
// Project: A Wishbone Controlled Real--time Clock Core
//
// Purpose:
// This core provides a real-time date function that can be coupled with
// a real-time clock. The date provided is in Binary Coded Decimal (bcd)
// form, and available for reading and writing over the Wishbone Bus.
//
// WARNING: Race conditions exist when updating the date across the Wishbone
// bus at or near midnight. (This should be obvious, but it bears
// stating.) Specifically, if the update command shows up at the same
// clock as the ppd clock, then the ppd clock will be ignored and the
// new date will be the date of the day following midnight. However,
// if the update command shows up one clock before the ppd, then the date
// may be updated, but may have problems dealing with the last day of the
// month or year. To avoid race conditions, update the date sometime
// after the stroke of midnight and before 5 clocks before the next
// midnight. If you are concerned that you might hit a race condition,
// just read the clock again (5+ clocks later) to make certain you set
// it correctly.
//
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Tecnology, LLC
//
///////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
module rtcdate(i_clk, i_ppd, i_wb_cyc, i_wb_stb, i_wb_we, i_wb_data,
o_wb_ack, o_wb_stall, o_wb_data);
input i_clk;
// A one part per day signal, i.e. basically a clock enable line that
// controls when the beginning of the day happens. This line should
// be high on the very last second of any day in order for the rtcdate
// module to always have the right date.
input i_ppd;
// Wishbone inputs
input i_wb_cyc, i_wb_stb, i_wb_we;
input [31:0] i_wb_data;
// Wishbone outputs
output reg o_wb_ack;
output wire o_wb_stall;
output wire [31:0] o_wb_data;
 
 
reg [5:0] r_day;
reg [4:0] r_mon;
reg [13:0] r_year;
 
reg last_day_of_month, last_day_of_year, is_leap_year;
always @(posedge i_clk)
last_day_of_year <= (last_day_of_month) && (r_mon == 5'h12);
always @(posedge i_clk)
begin
case(r_mon)
5'h01: last_day_of_month <= (r_day >= 6'h31); // Jan
5'h02: last_day_of_month <= (r_day >= 6'h29)
||((~is_leap_year)&&(r_day == 6'h28));
5'h03: last_day_of_month <= (r_day >= 6'h31); // March
5'h04: last_day_of_month <= (r_day >= 6'h30); // April
5'h05: last_day_of_month <= (r_day >= 6'h31); // May
5'h06: last_day_of_month <= (r_day >= 6'h30); // June
5'h07: last_day_of_month <= (r_day >= 6'h31); // July
5'h08: last_day_of_month <= (r_day >= 6'h31); // August
5'h09: last_day_of_month <= (r_day >= 6'h30); // Sept
5'h10: last_day_of_month <= (r_day >= 6'h31); // October
5'h11: last_day_of_month <= (r_day >= 6'h30); // November
5'h12: last_day_of_month <= (r_day >= 6'h31); // December
default: last_day_of_month <= 1'b0;
endcase
end
 
reg year_divisible_by_four, century_year, four_century_year;
always @(posedge i_clk)
year_divisible_by_four<= ((~r_year[0])&&(r_year[4]==r_year[1]));
always @(posedge i_clk)
century_year <= (r_year[7:0] == 8'h00);
always @(posedge i_clk)
four_century_year <= ((~r_year[8])&&((r_year[12]==r_year[9])));
always @(posedge i_clk)
is_leap_year <= (year_divisible_by_four)&&((~century_year)
||((century_year)&&(four_century_year)));
 
 
// Adjust the day of month
initial r_day = 6'h01;
always @(posedge i_clk)
begin
if ((r_day == 0)||(r_day > 6'h31)||(r_day[3:0] > 4'h9))
r_day <= 6'h01;
else if ((i_ppd)&&(last_day_of_month))
r_day <= 6'h01;
else if ((i_ppd)&&(r_day[3:0] != 4'h9))
r_day[3:0] <= r_day[3:0] + 4'h1;
else if (i_ppd)
begin
r_day[3:0] <= 4'h0;
r_day[5:4] <= r_day[5:4] + 2'h1;
end
 
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we)&&(i_wb_data[7:0]!=8'hff))
r_day <= i_wb_data[5:0];
end
 
// Adjust the month of the year
initial r_mon = 5'h01;
always @(posedge i_clk)
begin
if ((r_mon == 0)||(r_mon > 5'h12)||(r_mon[3:0] > 4'h9))
r_mon <= 5'h01;
else if ((i_ppd)&&(last_day_of_year))
r_mon <= 5'h01;
else if ((i_ppd)&&(last_day_of_month)&&(r_mon[3:0] != 4'h9))
r_mon[3:0] <= r_mon[3:0] + 4'h1;
else if ((i_ppd)&&(last_day_of_month))
begin
r_mon[3:0] <= 4'h0;
r_mon[4] <= 1;
end
 
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we)&&(i_wb_data[15:8]!=8'hff))
r_mon <= i_wb_data[12:8];
end
 
// Adjust the year
initial r_year = 14'h2000;
always @(posedge i_clk)
begin
// Deal with any out of bounds conditions
if (r_year[3:0] > 4'h9)
r_year[3:0] <= 4'h0;
if (r_year[7:4] > 4'h9)
r_year[7:4] <= 4'h0;
if (r_year[11:8] > 4'h9)
r_year[11:8] <= 4'h0;
if ((i_ppd)&&(last_day_of_year))
begin
if (r_year[3:0] != 4'h9)
r_year[3:0] <= r_year[3:0] + 4'h1;
else begin
r_year[3:0] <= 4'h0;
if (r_year[7:4] != 4'h9)
r_year[7:4] <= r_year[7:4] + 4'h1;
else begin
r_year[7:4] <= 4'h0;
if (r_year[11:8] != 4'h9)
r_year[11:8] <= r_year[11:8]+4'h1;
else begin
r_year[11:8] <= 4'h0;
r_year[13:12] <= r_year[13:12]+2'h1;
end
end
end
end
 
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we)&&(i_wb_data[31:16]!=16'hffff))
r_year <= i_wb_data[29:16];
end
 
always @(posedge i_clk)
o_wb_ack <= ((i_wb_cyc)&&(i_wb_stb));
assign o_wb_stall = 1'b0;
assign o_wb_data = { 2'h0, r_year, 3'h0, r_mon, 2'h0, r_day };
endmodule
/trunk/doc/spec.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/trunk/doc/src/spec.tex
68,6 → 68,7
copy.
\end{license}
\begin{revisionhistory}
0.2 & 7/11/2015 & Gisselquist & Date interface added\\\hline
0.1 & 5/25/2015 & Gisselquist & First Draft \\\hline
\end{revisionhistory}
% Revision History
80,8 → 81,8
from simplicity, more and more complex cores can be built until an eventual
application comes from all the tiny details.
 
This real time clock is one such simple core. All of the pieces to this
clock are simple. Nothing is inherently complex. However, placing this
This real time clock began with one such simple core. All of the pieces to
this clock are simple. Nothing is inherently complex. However, placing this
clock into a larger FPGA structure requires a Wishbone bus, and being able
to command and control an FPGA over a wishbone bus is an achievement in
itself. Further, the clock produces seven segment display output values
97,26 → 98,29
\setcounter{page}{1}
 
This Real--Time Clock implements a twenty four hour clock, count-down timer,
stopwatch
and alarm. It is designed to be configurable to adjust to whatever clock
speed the underlying architecture is running on, so with only minor changes
should run on any fundamental clock rate from about 66~kHz on up to
stopwatch and alarm. It is designed to be configurable to adjust to whatever
clock speed the underlying architecture is running on, so with only minor
changes should run on any fundamental clock rate from about 66~kHz on up to
250~TeraHertz with varying levels of accuracy along the way.
 
This clock offers a fairly full feature set of capability: time, alarms,
a countdown timer and a stopwatch, all features which are available from the
wishbone bus.
Distributed with this clock is a similar Real--Time Date module. This
second module can track the day, month, and year while properly accounting
for varying days in each month and leap years, when they happen.
 
Together, the clock and date module offer a fairly full feature set of
capability: date, time, alarms, a countdown timer and a stopwatch, all
features which are available from the wishbone bus.
 
Other interfaces exist as well.
 
Should you wish to investigate your clock's
stability or try to guarantee it's fine precision accuracy, it is possible to
provide a time hack pulse to the clock and subsequently read what all of the
internal registers were set to at that time.
Should you wish to investigate your clock's stability or try to guarantee
its fine precision accuracy, it is possible to provide a time hack pulse to
the clock and subsequently read what all of the internal registers were set
to at that time.
 
When either the count--down timer reaches zero or the clock reaches the alarm
time (if set), the clock module will produce an impulse which can be used
as an interrupt trigger.
time (if set), the clock module will produce an impulse which can be used as
an interrupt trigger.
 
This clock will also provide outputs sufficient to drive an external seven
segment display driver and 16 LED's.
142,9 → 146,9
 
Central to this real time clock architecture is a 48~bit sub--second register.
This register is incremented every clock by a user defined 32~bit value,
{\tt CKSPEED}.
When the register turns over at the end of each second, a second has taken
place and all of the various clock registers are adjusted.
{\tt CKSPEED}. When the register turns over at the end of each second, a
second has taken place and all of the various clock (and date) registers are
adjusted.
 
Well, not quite but almost. The 48~bit register is actually split into a
lower 40~bit register that is common to all clock components, as well as
224,6 → 228,15
It is the users responsibility to read the time hack registers before a
subsequent time hack pulse sets them to new values.
 
\section{Date}
The Real--Time Date module is really a separate module from the Real--Time
Clock module, but that doesn't prevent it from working just like the others.
To set the date, just write the new date value to the address of the date.
Further, as with the clock time, setting any particular field of the date to
all ones, such as setting the month to {\tt 8'hff}, will cause that portion of
the date to retain it's current value. In this way, one part of the date
may be set and not others.
 
\chapter{Registers}\label{chap:regs}
This RTC clock module supports eight registers, as listed in
Tbl.~\ref{tbl:reglist}. Of these eight, the first four have been so placed
244,6 → 257,16
\end{center}\end{table}
Each register will be discussed in detail in this chapter.
 
The Date module supports an additional register, listed in
Tbl.~\ref{tbl:datereg}.
\begin{table}[htbp]
\begin{center}
\begin{reglist}
DATE & 0 & 32 & R/W & Calendar date register\\\hline
\end{reglist}\caption{Date Register}\label{tbl:datereg}
\end{center}\end{table}
This register will be discussed after we discuss the time registers.
 
\section{Clock Time Register}
The various bit fields associated with the current time may be found in
the {\tt CLOCK} register, shown in Tbl.~\ref{tbl:clockreg}.
413,6 → 436,24
upon information gleaned from the hack time. Implementation details have
to date prevented this portion of the design from being implemented.
 
\section{Date Register}
The year, month, and day of month fields may all be found within the
{\tt DATE} register of the Real--Time Date module, shown in
Tbl.~\ref{tbl:datebits}.
\begin{table}[htbp]\begin{center}
\begin{bitlist}
30--31 & R & Always return zero.\\\hline
16--29 & R/W & Four digit BCD year\\\hline
13--15 & R & Always return zero.\\\hline
8--12 & R/W & Two digit BCD month\\\hline
6--7 & R & Always return zero.\\\hline
0--5 & R/W & Two digit BCD day of month\\\hline
\end{bitlist}
\caption{Date Register Bit Definitions}\label{tbl:datebits}
\end{center}\end{table}
Further, according to the common calendar convention, the minimum day and month
are one and not zero.
 
\chapter{Wishbone Datasheet}\label{chap:wishbone}
Tbl.~\ref{tbl:wishbone}
\begin{table}[htbp]
441,9 → 482,10
\caption{Wishbone Datasheet}\label{tbl:wishbone}
\end{center}\end{table}
is required by the wishbone specification, and so
it is included here. The big thing to notice is that this real time clock
acts as a wishbone slave, and that all accesses to the
clock registers are 32--bit reads and writes. The address bus does not offer
it is included here. The big thing to notice is that both the real time clock
and the real time date modules act as wishbone slaves, and that all accesses
to the registers of either module are 32--bit reads and writes. The address
bus does not offer
byte level, but rather 32--bit word level resolution. Select lines are not
implemented. Bit ordering is the normal ordering where bit~31 is the most
significant bit and so forth. Although the stall line is implemented, it is
470,10 → 512,11
\fi
 
\chapter{I/O Ports}\label{chap:ioports}
The I/O ports for this core are shown in Tbls.~\ref{tbl:iowishbone}
The I/O ports for this clock are shown in Tbls.~\ref{tbl:iowishbone}
\begin{table}[htbp]
\begin{center}
\begin{portlist}
i\_clk & 1 & Input & System clock, used for time and wishbone interfaces.\\\hline
i\_wb\_cyc & 1 & Input & Wishbone bus cycle wire.\\\hline
i\_wb\_stb & 1 & Input & Wishbone strobe.\\\hline
i\_wb\_we & 1 & Input & Wishbone write enable.\\\hline
506,6 → 549,11
o\_interrupt & 1 & Output & A pulsed/strobed interrupt line. When the
clock needs to generate an interrupt, it will set this line
high for one clock cycle. \\\hline
o\_ppd & 1 & Output & A `pulse per day' signal which can be fed into the
real--time date module. This line will be high on the clock before
the stroke of midnight, allowing the date module to turn over to the
next day at exactly the same time the clock module turns over to the
next day.\\\hline
i\_hack & 1 & Input & When this line is raised, copies are made of the
internal state registers on the next clock. These registers can then
be used for an accurate time hack regarding the state of the clock
549,6 → 597,11
trigger once until cleared as will the alarm, but the alarm may trigger after
the timer has triggered and before the timer clears.
 
As a fourth additional line, the clock module produces a one pulse per day
signal, {\tt o\_ppd}. This signal is designed to be the only necessary
coordinated input between the clock and date module. Feeding it straight
into the date module will keep the two synchronized.
 
The final other I/O line is a simple input line. This line is expected to be
strobed for one clock cycle any time a time hack is required. For example,
should you wish to read and synchronize to a GPS PPS signal, strobe the device
555,6 → 608,32
with the PPS (after dealing with any metastability issues), and read the time
hacks that are produced.
 
The real--time date module has a similar set of I/O ports to the clock. These
are listed in Tbl.~\ref{tbl:iodate}.
\begin{table}[htbp]
\begin{center}
\begin{portlist}
i\_clk & 1 & Input & The system clock.\\\hline
i\_ppd & 1 & Input & The one pulse per day strobe from the clock module.\\\hline
i\_wb\_cyc & 1 & Input & Wishbone bus cycle.\\\hline
i\_wb\_stb & 1 & Input & Wishbone strobe.\\\hline
i\_wb\_we & 1 & Input & Wishbone write enable.\\\hline
i\_wb\_data & 32 & Input & Wishbone bus data register for use when writing
(configuring) the core from the bus.\\\hline
o\_wb\_ack & 1 & Output & Equal to the bus cycle line anded with the strobe
line, and delayed by one clock---essentially acknowledging any
wishbone access.\\\hline
o\_wb\_stall & 1 & Output & Fixed to zer.\\\hline
o\_wb\_data & 32 & Output & Wishbone data bus, returning data values read
from the interface.\\\hline
\end{portlist}
\caption{Wishbone I/O Ports}\label{tbl:iodate}
\end{center}\end{table}
There are two big things to notice. The first is the {\tt i\_ppd} signal.
This should be connected straight from the clock module's {\tt o\_ppd} signal
into this module. The second difference is the lack of any address lines.
This is appropriate since the date module provides a single register only.
 
% Appendices
% Index
\end{document}

powered by: WebSVN 2.1.0

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