| Line 2... | Line 2... | 
      
        | //
 | //
 | 
      
        | // 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:
 | // 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".
 | 
      
        | Line 20... | Line 20... | 
      
        | //              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.  Writing a '0' starts the timer, '1' stops it.
 | //              (Start_n/Stop.  This bit has been dropped.  Writing to this
 | 
      
        | //                      Thus, ignoring this bit sets it to start.
 | //                      timer any value but zero starts it.  Writing a zero
 | 
      
        |   | //                      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.
 | 
      
        | //              (COUNT: If set, the timer only ticks whenever an external
 |   | 
      
        | //                      line goes high.  What this external line is ... is
 |   | 
      
        | //                      not specified here.  This, however, breaks my 
 |   | 
      
        | //                      interface ideal of having our peripheral set not depend
 |   | 
      
        | //                      upon anything.  Hence, this is an advanced option
 |   | 
      
        | //                      enabled at compile time only.)
 |   | 
      
        | //              (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.)
 | 
      
        | Line 70... | Line 65... | 
      
        | //
 | //
 | 
      
        | 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-2);
 |         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
 | 
      
        | Line 84... | Line 79... | 
      
        |         // 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;
 | 
      
        |   |         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)
 | 
      
        |                 begin
 |   | 
      
        |                         r_running <= 1'b0;
 |                         r_running <= 1'b0;
 | 
      
        |                         r_auto_reload <= 1'b0;
 |                 else if (wb_write)
 | 
      
        |                 end else if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
 |                         r_running <= (|i_wb_data[(VW-1):0]);
 | 
      
        |                 begin
 |                 else if ((o_int)&&(~r_auto_reload))
 | 
      
        |                         r_running <= (~i_wb_data[(BW-1)])&&(|i_wb_data[(BW-2):0]);
 |                         r_running <= 1'b0;
 | 
      
        |                         r_auto_reload <= (i_wb_data[(BW-2)]);
 |  
 | 
      
        |   |  
 | 
      
        |   |         always @(posedge i_clk)
 | 
      
        |   |                 if (wb_write)
 | 
      
        |   |                         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
 | 
      
        |                         if ((i_wb_data[(BW-2)])&&(|i_wb_data[(BW-3):0]))
 |         always @(posedge i_clk)
 | 
      
        |                                 r_reload_value <= i_wb_data[(BW-3):0];
 |                 if ((wb_write)&&(i_wb_data[(BW-1)])&&(|i_wb_data[(VW-1):0]))
 | 
      
        |                 end
 |                         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 ((r_running)&&(|r_value)&&(i_ce))
 |                 if (wb_write)
 | 
      
        |                 begin
 |                         r_value <= i_wb_data[(VW-1):0];
 | 
      
        |   |                 else if ((r_running)&&(i_ce)&&(~o_int))
 | 
      
        |                         r_value <= r_value - 1;
 |                         r_value <= r_value - 1;
 | 
      
        |                 end else if ((r_running)&&(r_auto_reload))
 |                 else if ((r_running)&&(r_auto_reload)&&(o_int))
 | 
      
        |                         r_value <= r_reload_value;
 |                         r_value <= r_reload_value;
 | 
      
        |                 else if ((~r_running)&&(i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
 |   | 
      
        |                         r_value <= i_wb_data[(VW-1):0];
 |   | 
      
        |  
 |  
 | 
      
        |         // 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)
 | 
      
        | Line 126... | Line 128... | 
      
        |         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_running, r_auto_reload, r_value };
 |         assign  o_wb_data = { r_auto_reload, r_value };
 | 
      
        |  
 |  
 | 
      
        | endmodule
 | endmodule
 | 
      
        |  
 |  
 | 
      
        |  No newline at end of file
 |  No newline at end of file
 |