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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [peripherals/] [ziptimer.v] - Diff between revs 56 and 69

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 56 Rev 69
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// Filename:    ziptimer.v
// Filename:    ziptimer.v
//
//
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
//
//
// Purpose:     A lighter weight implementation of the Zip Timer.
// Purpose:     A lighter weight implementation of the Zip Timer.
//
//
// Interface:
// Interface:
//      Two options:
//      Two options:
//      1. One combined register for both control and value, and ...
//      1. One combined register for both control and value, and ...
//              The reload value is set any time the timer data value is "set".
//              The reload value is set any time the timer data value is "set".
//              Reading the register returns the timer value.  Controls are
//              Reading the register returns the timer value.  Controls are
//              set so that writing a value to the timer automatically starts
//              set so that writing a value to the timer automatically starts
//              it counting down.
//              it counting down.
//      2. Two registers, one for control one for value.
//      2. Two registers, one for control one for value.
//              The control register would have the reload value in it.
//              The control register would have the reload value in it.
//      On the clock when the interface is set to zero the interrupt is set.
//      On the clock when the interface is set to zero the interrupt is set.
//              Hence setting the timer to zero will disable the timer without
//              Hence setting the timer to zero will disable the timer without
//              setting any interrupts.  Thus setting it to five will count
//              setting any interrupts.  Thus setting it to five will count
//              5 clocks: 5, 4, 3, 2, 1, Interrupt.
//              5 clocks: 5, 4, 3, 2, 1, Interrupt.
//
//
//
//
//      Control bits:
//      Control bits:
//              (Start_n/Stop.  This bit has been dropped.  Writing to this
//              (Start_n/Stop.  This bit has been dropped.  Writing to this
//                      timer any value but zero starts it.  Writing a zero
//                      timer any value but zero starts it.  Writing a zero
//                      clears and stops it.)
//                      clears and stops it.)
//              AutoReload.  If set, then on reset the timer automatically
//              AutoReload.  If set, then on reset the timer automatically
//                      loads the last set value and starts over.  This is
//                      loads the last set value and starts over.  This is
//                      useful for distinguishing between a one-time interrupt
//                      useful for distinguishing between a one-time interrupt
//                      timer, and a repetitive interval timer.
//                      timer, and a repetitive interval timer.
//              (INTEN.  Interrupt enable--reaching zero always creates an
//              (INTEN.  Interrupt enable--reaching zero always creates an
//                      interrupt, so this control bit isn't needed.  The
//                      interrupt, so this control bit isn't needed.  The
//                      interrupt controller can be used to mask the interrupt.)
//                      interrupt controller can be used to mask the interrupt.)
//              (COUNT-DOWN/UP: This timer is *only* a count-down timer.
//              (COUNT-DOWN/UP: This timer is *only* a count-down timer.
//                      There is no means of setting it to count up.)
//                      There is no means of setting it to count up.)
//      WatchDog
//      WatchDog
//              This timer can be implemented as a watchdog timer simply by
//              This timer can be implemented as a watchdog timer simply by
//              connecting the interrupt line to the reset line of the CPU.
//              connecting the interrupt line to the reset line of the CPU.
//              When the timer then expires, it will trigger a CPU reset.
//              When the timer then expires, it will trigger a CPU reset.
//
//
//
//
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Tecnology, LLC
//              Gisselquist Technology, LLC
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// 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
// 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
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
//
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// License:     GPL, v3, as defined and found on www.gnu.org,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
//
module  ziptimer(i_clk, i_rst, i_ce,
module  ziptimer(i_clk, i_rst, i_ce,
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_data,
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_data,
                        o_wb_ack, o_wb_stall, o_wb_data,
                        o_wb_ack, o_wb_stall, o_wb_data,
                o_int);
                o_int);
        parameter       BW = 32, VW = (BW-1);
        parameter       BW = 32, VW = (BW-1);
        input                   i_clk, i_rst, i_ce;
        input                   i_clk, i_rst, i_ce;
        // Wishbone inputs
        // Wishbone inputs
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
        input   [(BW-1):0]       i_wb_data;
        input   [(BW-1):0]       i_wb_data;
        // Wishbone outputs
        // Wishbone outputs
        output  reg                     o_wb_ack;
        output  reg                     o_wb_ack;
        output  wire                    o_wb_stall;
        output  wire                    o_wb_stall;
        output  wire    [(BW-1):0]       o_wb_data;
        output  wire    [(BW-1):0]       o_wb_data;
        // Interrupt line
        // Interrupt line
        output  reg             o_int;
        output  reg             o_int;
 
 
        reg                     r_auto_reload, r_running;
        reg                     r_auto_reload, r_running;
        reg     [(VW-1):0]       r_reload_value;
        reg     [(VW-1):0]       r_reload_value;
 
 
        wire    wb_write;
        wire    wb_write;
        assign  wb_write = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we));
        assign  wb_write = ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we));
 
 
        initial r_running = 1'b0;
        initial r_running = 1'b0;
        initial r_auto_reload = 1'b0;
        initial r_auto_reload = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_rst)
                if (i_rst)
                        r_running <= 1'b0;
                        r_running <= 1'b0;
                else if (wb_write)
                else if (wb_write)
                        r_running <= (|i_wb_data[(VW-1):0]);
                        r_running <= (|i_wb_data[(VW-1):0]);
                else if ((o_int)&&(~r_auto_reload))
                else if ((o_int)&&(~r_auto_reload))
                        r_running <= 1'b0;
                        r_running <= 1'b0;
 
 
 
 
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (wb_write)
                if (wb_write)
                        r_auto_reload <= (i_wb_data[(BW-1)]);
                        r_auto_reload <= (i_wb_data[(BW-1)]);
 
 
        // If setting auto-reload mode, and the value to other
        // If setting auto-reload mode, and the value to other
        // than zero, set the auto-reload value
        // than zero, set the auto-reload value
        always @(posedge i_clk)
        always @(posedge i_clk)
                if ((wb_write)&&(i_wb_data[(BW-1)])&&(|i_wb_data[(VW-1):0]))
                if ((wb_write)&&(i_wb_data[(BW-1)])&&(|i_wb_data[(VW-1):0]))
                        r_reload_value <= i_wb_data[(VW-1):0];
                        r_reload_value <= i_wb_data[(VW-1):0];
 
 
 
 
        reg     [(VW-1):0]       r_value;
        reg     [(VW-1):0]       r_value;
        initial r_value = 0;
        initial r_value = 0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (wb_write)
                if (wb_write)
                        r_value <= i_wb_data[(VW-1):0];
                        r_value <= i_wb_data[(VW-1):0];
                else if ((r_running)&&(i_ce)&&(~o_int))
                else if ((r_running)&&(i_ce)&&(~o_int))
                        r_value <= r_value + {(VW){1'b1}}; // r_value - 1;
                        r_value <= r_value + {(VW){1'b1}}; // r_value - 1;
                else if ((r_running)&&(r_auto_reload)&&(o_int))
                else if ((r_running)&&(r_auto_reload)&&(o_int))
                        r_value <= r_reload_value;
                        r_value <= r_reload_value;
 
 
        // Set the interrupt on our last tick.
        // Set the interrupt on our last tick.
        initial o_int   = 1'b0;
        initial o_int   = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                if (i_ce)
                if (i_ce)
                o_int <= (r_running)&&(r_value == { {(VW-1){1'b0}}, 1'b1 });
                o_int <= (r_running)&&(r_value == { {(VW-1){1'b0}}, 1'b1 });
                else
                else
                        o_int <= 1'b0;
                        o_int <= 1'b0;
 
 
        initial o_wb_ack = 1'b0;
        initial o_wb_ack = 1'b0;
        always @(posedge i_clk)
        always @(posedge i_clk)
                o_wb_ack <= (i_wb_cyc)&&(i_wb_stb);
                o_wb_ack <= (i_wb_cyc)&&(i_wb_stb);
        assign  o_wb_stall = 1'b0;
        assign  o_wb_stall = 1'b0;
 
 
        assign  o_wb_data = { r_auto_reload, r_value };
        assign  o_wb_data = { r_auto_reload, r_value };
 
 
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

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