1 |
2 |
rehayes |
////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// Programable Interrupt Timer - Prescale Counter
|
4 |
|
|
//
|
5 |
|
|
// Author: Bob Hayes
|
6 |
|
|
// rehayes@opencores.org
|
7 |
|
|
//
|
8 |
|
|
// Downloaded from: http://www.opencores.org/projects/pit.....
|
9 |
|
|
//
|
10 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
11 |
|
|
// Copyright (c) 2009, Robert Hayes
|
12 |
|
|
//
|
13 |
|
|
// All rights reserved.
|
14 |
|
|
//
|
15 |
|
|
// Redistribution and use in source and binary forms, with or without
|
16 |
|
|
// modification, are permitted provided that the following conditions are met:
|
17 |
|
|
// * Redistributions of source code must retain the above copyright
|
18 |
|
|
// notice, this list of conditions and the following disclaimer.
|
19 |
|
|
// * Redistributions in binary form must reproduce the above copyright
|
20 |
|
|
// notice, this list of conditions and the following disclaimer in the
|
21 |
|
|
// documentation and/or other materials provided with the distribution.
|
22 |
|
|
// * Neither the name of the <organization> nor the
|
23 |
|
|
// names of its contributors may be used to endorse or promote products
|
24 |
|
|
// derived from this software without specific prior written permission.
|
25 |
|
|
//
|
26 |
|
|
// THIS SOFTWARE IS PROVIDED BY Robert Hayes ''AS IS'' AND ANY
|
27 |
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
28 |
|
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
29 |
|
|
// DISCLAIMED. IN NO EVENT SHALL Robert Hayes BE LIABLE FOR ANY
|
30 |
|
|
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
31 |
|
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
32 |
|
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
33 |
|
|
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
34 |
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
35 |
|
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
36 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
37 |
|
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
38 |
|
|
|
39 |
|
|
module pit_prescale #(parameter COUNT_SIZE = 15,
|
40 |
|
|
parameter DECADE_CNTR = 1,
|
41 |
|
|
parameter NO_PRESCALE = 0)
|
42 |
|
|
(
|
43 |
|
|
output prescale_out, //
|
44 |
|
|
output counter_sync, //
|
45 |
|
|
input async_rst_b, //
|
46 |
|
|
input sync_reset, // Syncronous reset signal
|
47 |
|
|
input bus_clk, // Reference Clock
|
48 |
|
|
input cnt_sync_o, // Syncronous counter enable
|
49 |
|
|
input ext_sync_i, // Enable from external PIT
|
50 |
|
|
input pit_slave, // PIT Slave Mode
|
51 |
|
|
input [3:0] divisor // Count Divisor
|
52 |
|
|
);
|
53 |
|
|
|
54 |
|
|
// Warning: This counter has no safety net if the divisor changes while the
|
55 |
|
|
// counter is active. There may need to be an addtional latch
|
56 |
|
|
// register for"divisor" that captures on the falling edge of
|
57 |
|
|
// "cnt_sync_o" or when "cnt_n" rolls over to eliminate this problem.
|
58 |
|
|
|
59 |
|
|
reg [COUNT_SIZE-1:0] cnt_n; // Div N counter
|
60 |
|
|
reg [COUNT_SIZE-1:0] end_count; // Psudo register for decoding
|
61 |
|
|
|
62 |
|
|
wire div_1; //
|
63 |
|
|
wire rollover; //
|
64 |
|
|
|
65 |
|
|
// This was going to be a "generate" block but iverilog does't support that
|
66 |
|
|
// command so we'll just have to trust the compiler to simplify the logic based
|
67 |
|
|
// on the setting of the constant "DECADE_CNTR"
|
68 |
|
|
always @*
|
69 |
|
|
if ( DECADE_CNTR )
|
70 |
|
|
case (divisor)
|
71 |
|
|
0: end_count = 1;
|
72 |
|
|
1: end_count = 2;
|
73 |
|
|
2: end_count = 4;
|
74 |
|
|
3: end_count = 8;
|
75 |
|
|
4: end_count = 10;
|
76 |
|
|
5: end_count = 100;
|
77 |
|
|
6: end_count = 1_000;
|
78 |
|
|
7: end_count = 10_000;
|
79 |
|
|
8: end_count = 20_000;
|
80 |
|
|
default: end_count = 20_000;
|
81 |
|
|
endcase
|
82 |
|
|
else
|
83 |
|
|
case (divisor)
|
84 |
|
|
0: end_count = 1;
|
85 |
|
|
1: end_count = 2;
|
86 |
|
|
2: end_count = 4;
|
87 |
|
|
3: end_count = 8;
|
88 |
|
|
4: end_count = 16;
|
89 |
|
|
5: end_count = 32;
|
90 |
|
|
6: end_count = 64;
|
91 |
|
|
7: end_count = 128;
|
92 |
|
|
8: end_count = 256;
|
93 |
|
|
9: end_count = 512;
|
94 |
|
|
10: end_count = 1024;
|
95 |
|
|
11: end_count = 2048;
|
96 |
|
|
12: end_count = 4096;
|
97 |
|
|
13: end_count = 8192;
|
98 |
|
|
14: end_count = 16384;
|
99 |
|
|
15: end_count = 32768;
|
100 |
|
|
endcase
|
101 |
|
|
|
102 |
|
|
assign counter_sync = pit_slave ? ext_sync_i : cnt_sync_o;
|
103 |
|
|
|
104 |
|
|
assign div_1 = (end_count == 1);
|
105 |
|
|
|
106 |
|
|
assign rollover = NO_PRESCALE || (cnt_n == end_count);
|
107 |
|
|
|
108 |
|
|
assign prescale_out = (pit_slave && div_1 && ext_sync_i) || rollover;
|
109 |
|
|
|
110 |
|
|
// Div N Counter
|
111 |
|
|
// If the "NO_PRESCALE" parameter is set the compiler should hopefully strip
|
112 |
|
|
// these counter bits when the module is compiled because the only place the
|
113 |
|
|
// register outputs go to drive a signal "rollover" that is already a constant.
|
114 |
|
|
always @(posedge bus_clk or negedge async_rst_b)
|
115 |
|
|
if ( !async_rst_b )
|
116 |
|
|
cnt_n <= 1;
|
117 |
|
|
else if ( !counter_sync || rollover)
|
118 |
|
|
cnt_n <= 1;
|
119 |
|
|
// else if ( rollover )
|
120 |
|
|
// cnt_n <= 1;
|
121 |
|
|
else
|
122 |
|
|
cnt_n <= cnt_n + 1;
|
123 |
|
|
|
124 |
|
|
|
125 |
|
|
endmodule // pit_prescale
|
126 |
|
|
|