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

Subversion Repositories pit

[/] [pit/] [trunk/] [rtl/] [sys_verilog/] [pit_prescale.sv] - Rev 24

Go to most recent revision | Compare with Previous | Blame | View Log

////////////////////////////////////////////////////////////////////////////////
//
//  Programable Interrupt Timer - Prescale Counter
//
//  Author: Bob Hayes
//          rehayes@opencores.org
//
//  Downloaded from: http://www.opencores.org/projects/pit.....
//
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Robert Hayes
//
// All rights reserved.
//
// 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 <organization> nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY Robert Hayes ''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 Robert Hayes 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, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////////////
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

module pit_prescale #(parameter COUNT_SIZE = 15,
                      parameter DECADE_CNTR = 1,
                      parameter NO_PRESCALE = 0)
  (
  output                      prescale_out,  // 
  output                      counter_sync,  // 
  input                       async_rst_b,   // 
  input                       sync_reset,    // Syncronous reset signal
  input                       bus_clk,       // Reference Clock
  input                       cnt_sync_o,    // Syncronous counter enable
  input                       ext_sync_i,    // Enable from external PIT
  input                       pit_slave,     // PIT Slave Mode
  input                 [3:0] divisor        // Count Divisor
  );
  
// Warning: This counter has no safety net if the divisor changes while the
//           counter is active. There may need to be an addtional latch
//           register for"divisor" that captures on the falling edge of
//           "cnt_sync_o" or when "cnt_n" rolls over to eliminate this problem.

logic  [COUNT_SIZE-1:0] cnt_n;         // Div N counter
logic  [COUNT_SIZE-1:0] end_count;     // Psudo register for decoding

logic                   div_1;         // 
logic                   rollover;      // 

// This was going to be a "generate" block but iverilog does't support that
//  command so we'll just have to trust the compiler to simplify the logic based
//  on the setting of the constant "DECADE_CNTR"
   always_comb
     if ( DECADE_CNTR )
       case (divisor)
          0: end_count = 1;
          1: end_count = 2;
          2: end_count = 4;
          3: end_count = 8;
          4: end_count = 10;
          5: end_count = 100;
          6: end_count = 1_000;
          7: end_count = 10_000;
          8: end_count = 20_000;
          default: end_count = 20_000;
        endcase
    else
        unique case (divisor)
           0: end_count = 1;
           1: end_count = 2;
           2: end_count = 4;
           3: end_count = 8;
           4: end_count = 16;
           5: end_count = 32;
           6: end_count = 64;
           7: end_count = 128;
           8: end_count = 256;
           9: end_count = 512;
          10: end_count = 1024;
          11: end_count = 2048;
          12: end_count = 4096;
          13: end_count = 8192;
          14: end_count = 16384;
          15: end_count = 32768;
        endcase

assign counter_sync = pit_slave ? ext_sync_i : cnt_sync_o;

assign div_1 = (end_count == 1);

assign rollover = NO_PRESCALE || (cnt_n == end_count);

assign prescale_out = (pit_slave && div_1 && ext_sync_i) || rollover; 

// Div N Counter
// If the "NO_PRESCALE" parameter is set the compiler should hopefully strip
//  these counter bits when the module is compiled because the only place the
//  register outputs go to drive a signal "rollover" that is already a constant.
always_ff @(posedge bus_clk or negedge async_rst_b)
  if ( !async_rst_b )
    cnt_n  <= 1;
  else if ( !counter_sync || rollover)
    cnt_n  <= 1;
  else
    cnt_n  <= cnt_n + 1;


endmodule  // pit_prescale

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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