/*
 * Copyright (c) 2015-2016, Sumio Morioka
 * All rights reserved.
 *
 * This source code was originally written by Dr.Sumio Morioka for use in the 2015-2016 issues of 
 * "the Interface magazine", published by CQ publishing Co.Ltd in Japan (http://www.cqpub.co.jp).
 * The author has no responsibility on any results caused by using this code.
 *
 * - Author: Dr.Sumio Morioka (http://www002.upp.so-net.ne.jp/morioka, FB:Sumio Morioka)
 *
 *
 * IMPORTANT NOTICE:
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software/hardware without specific prior written permission.
 *
 * THIS SOFTWARE/HARDWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE/HARDWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

//////////////////////////////////////////////////////////////////////////
// clock (just for demo)
//////////////////////////////////////////////////////////////////////////
#include <ap_cint.h>
#include <ap_utils.h>

////////////////////////////////////////////
// port
////////////////////////////////////////////

volatile uint8	mem_addr	= 0;
volatile uint8	mem_dout	= 0;
volatile uint1	mem_wreq	= 0;
volatile uint1	mem_ack;

volatile uint1	dummy_tmr_out	= 0;

////////////////////////////////////////////
// main
////////////////////////////////////////////

void wait_tmr(uint32 tmr)	// unit 1us
{
#pragma HLS INLINE OFF
	uint8	u;
	uint32	t;
	for (u = 0; u < 100; u++) {	// for 100MHz clock
		for (t = 0; t < tmr; t++) {
			dummy_tmr_out	= 1- dummy_tmr_out;
		}
	}
}

void write_mem(uint8 addr, uint8 data)
{
#pragma HLS INLINE OFF
	ap_wait();
	mem_addr	= addr;
	mem_dout	= data;
	mem_wreq	= 0;
	ap_wait();

	do {
		mem_addr	= addr;
		mem_dout	= data;
		mem_wreq	= 1;
	} while (mem_ack == 0);
	ap_wait();

	mem_addr	= addr;
	mem_dout	= data;
	mem_wreq	= 0;
	ap_wait();
}

void clock_top()
{
#pragma HLS TOP
#pragma HLS INTERFACE ap_none port=dummy_tmr_out register

#pragma HLS INTERFACE ap_none port=mem_addr register
#pragma HLS INTERFACE ap_none port=mem_dout register
#pragma HLS INTERFACE ap_none port=mem_wreq register
#pragma HLS INTERFACE ap_none port=mem_ack

	uint8	pos;
	uint8	msec	= '0';
	uint8	sec1	= '0';
	uint8	sec10	= '0';
	uint8	min1	= '0';
	uint8	min10	= '0';

	for (pos = 0; pos < 32; pos++) {
		write_mem(pos, 0x20);
	}

	while (1) {
		write_mem(16, min10);
		write_mem(17, min1);
		write_mem(18, ':');
		write_mem(19, sec10);
		write_mem(20, sec1);
		write_mem(21, '.');
		write_mem(22, msec);

		wait_tmr(100000);		// 0.1sec

		// inc clock
		msec++;
		if (msec > '9') {
			msec	= '0';
			sec1++;
			if (sec1 > '9') {
				sec1	= '0';
				sec10++;
				if (sec10 > '5') {
					sec10	= '0';
					min1++;
					if (min1 > '9') {
						min1	= '0';
						min10++;
						if (min10 > '5') {
							min10	= '0';
						}
					}
				}
			}
		}
	}
}
