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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [pit/] [pit_counter.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
module pit_counter(
28
    input               clk,
29
    input               rst_n,
30
 
31
    input               clock,
32
    input               gate,
33
    output reg          out,
34
 
35
    input       [7:0]   data_in,
36
    input               set_control_mode,
37
    input               latch_count,
38
    input               latch_status,
39
    input               write,
40
    input               read,
41
 
42
    output      [7:0]   data_out
43
);
44
 
45
//------------------------------------------------------------------------------
46
 
47
reg [2:0] mode;
48
always @(posedge clk or negedge rst_n) begin
49
    if(rst_n == 1'b0)           mode <= 3'd2;
50
    else if(set_control_mode)   mode <= data_in[3:1];
51
end
52
 
53
reg bcd;
54
always @(posedge clk or negedge rst_n) begin
55
    if(rst_n == 1'b0)           bcd <= 1'd0;
56
    else if(set_control_mode)   bcd <= data_in[0];
57
end
58
 
59
reg [1:0] rw_mode;
60
always @(posedge clk or negedge rst_n) begin
61
    if(rst_n == 1'b0)           rw_mode <= 2'd1;
62
    else if(set_control_mode)   rw_mode <= data_in[5:4];
63
end
64
 
65
//------------------------------------------------------------------------------
66
 
67
reg [7:0] counter_l;
68
always @(posedge clk or negedge rst_n) begin
69
    if(rst_n == 1'b0)                                         counter_l <= 8'd0;
70
    else if(set_control_mode)                                 counter_l <= 8'd0;
71
    else if(write && rw_mode == 2'd3 && msb_write == 1'b0)    counter_l <= data_in;
72
    else if(write && rw_mode == 2'd1)                         counter_l <= data_in;
73
end
74
 
75
reg [7:0] counter_m;
76
always @(posedge clk or negedge rst_n) begin
77
    if(rst_n == 1'b0)                                         counter_m <= 8'd0;
78
    else if(set_control_mode)                                 counter_m <= 8'd0;
79
    else if(write && rw_mode == 2'd3 && msb_write == 1'b1)    counter_m <= data_in;
80
    else if(write && rw_mode == 2'd2)                         counter_m <= data_in;
81
end
82
 
83
reg [7:0] output_l;
84
always @(posedge clk or negedge rst_n) begin
85
    if(rst_n == 1'b0)                           output_l <= 8'd0;
86
    else if(latch_count && ~(output_latched))   output_l <= counter[7:0];
87
    else if(~(output_latched))                  output_l <= counter[7:0];
88
end
89
 
90
reg [7:0] output_m;
91
always @(posedge clk or negedge rst_n) begin
92
    if(rst_n == 1'b0)                           output_m <= 8'd0;
93
    else if(latch_count && ~(output_latched))   output_m <= counter[15:8];
94
    else if(~(output_latched))                  output_m <= counter[15:8];
95
end
96
 
97
reg output_latched;
98
always @(posedge clk or negedge rst_n) begin
99
    if(rst_n == 1'b0)                               output_latched <= 1'b0;
100
    else if(set_control_mode)                       output_latched <= 1'b0;
101
    else if(latch_count)                            output_latched <= 1'b1;
102
    else if(read && (rw_mode != 2'd3 || msb_read))  output_latched <= 1'b0;
103
end
104
 
105
reg null_counter;
106
always @(posedge clk or negedge rst_n) begin
107
    if(rst_n == 1'b0)                                   null_counter <= 1'b0;
108
    else if(set_control_mode)                           null_counter <= 1'b1;
109
    else if(write && (rw_mode != 2'd3 || msb_write))    null_counter <= 1'b1;
110
    else if(load)                                       null_counter <= 1'b0;
111
end
112
 
113
reg msb_write;
114
always @(posedge clk or negedge rst_n) begin
115
    if(rst_n == 1'b0)                   msb_write <= 1'b0;
116
    else if(set_control_mode)           msb_write <= 1'b0;
117
    else if(write && rw_mode == 2'd3)   msb_write <= ~(msb_write);
118
end
119
 
120
reg msb_read;
121
always @(posedge clk or negedge rst_n) begin
122
    if(rst_n == 1'b0)                   msb_read <= 1'b0;
123
    else if(set_control_mode)           msb_read <= 1'b0;
124
    else if(read && rw_mode == 2'd3)    msb_read <= ~(msb_read);
125
end
126
 
127
reg [7:0] status;
128
always @(posedge clk or negedge rst_n) begin
129
    if(rst_n == 1'b0)                           status <= 8'd0;
130
    else if(latch_status && ~(status_latched))  status <= { out, null_counter, rw_mode, mode, bcd };
131
end
132
 
133
reg status_latched;
134
always @(posedge clk or negedge rst_n) begin
135
    if(rst_n == 1'b0)           status_latched <= 1'b0;
136
    else if(set_control_mode)   status_latched <= 1'b0;
137
    else if(latch_status)       status_latched <= 1'b1;
138
    else if(read)               status_latched <= 1'b0;
139
end
140
 
141
assign data_out =
142
    (status_latched)?                           status :
143
    (rw_mode == 2'd3 && msb_read == 1'b0)?      output_l :
144
    (rw_mode == 2'd3 && msb_read == 1'b1)?      output_m :
145
    (rw_mode == 2'd1)?                          output_l :
146
                                                output_m;
147
 
148
//------------------------------------------------------------------------------
149
 
150
reg clock_last;
151
always @(posedge clk or negedge rst_n) begin
152
    if(rst_n == 1'b0)   clock_last <= 1'b0;
153
    else                clock_last <= clock;
154
end
155
 
156
reg clock_pulse;
157
always @(posedge clk or negedge rst_n) begin
158
    if(rst_n == 1'b0)                               clock_pulse <= 1'b0;
159
    else if(clock_last == 1'b1 && clock == 1'b0)    clock_pulse <= 1'b1;
160
    else                                            clock_pulse <= 1'b0;
161
end
162
 
163
reg gate_last;
164
always @(posedge clk or negedge rst_n) begin
165
    if(rst_n == 1'b0)   gate_last <= 1'b1;
166
    else                gate_last <= gate;
167
end
168
 
169
reg gate_sampled;
170
always @(posedge clk or negedge rst_n) begin
171
    if(rst_n == 1'b0)                               gate_sampled <= 1'b0;
172
    else if(clock_last == 1'b0 && clock == 1'b1)    gate_sampled <= gate;
173
end
174
 
175
reg trigger;
176
always @(posedge clk or negedge rst_n) begin
177
    if(rst_n == 1'b0)                               trigger <= 1'b0;
178
    else if(gate_last == 1'b0 && gate == 1'b1)      trigger <= 1'b1;
179
    else if(clock_last == 1'b0 && clock == 1'b1)    trigger <= 1'b0;
180
end
181
 
182
reg trigger_sampled;
183
always @(posedge clk or negedge rst_n) begin
184
    if(rst_n == 1'b0)                               trigger_sampled <= 1'b0;
185
    else if(clock_last == 1'b0 && clock == 1'b1)    trigger_sampled <= trigger;
186
end
187
 
188
//------------------------------------------------------------------------------
189
 
190
always @(posedge clk or negedge rst_n) begin
191
    if(rst_n == 1'b0)                                                           out <= 1'b1;
192
 
193
    else if(set_control_mode && data_in[3:1] == 3'd0)                           out <= 1'b0;
194
    else if(set_control_mode && data_in[3:1] == 3'd1)                           out <= 1'b1;
195
    else if(set_control_mode && data_in[2:1] == 2'd2)                           out <= 1'b1;
196
    else if(set_control_mode && data_in[2:1] == 2'd3)                           out <= 1'b1;
197
    else if(set_control_mode && data_in[3:1] == 3'd4)                           out <= 1'b1;
198
    else if(set_control_mode && data_in[3:1] == 3'd5)                           out <= 1'b1;
199
 
200
    else if(mode == 3'd0 && write && rw_mode == 2'd3 && msb_write == 1'b0)      out <= 1'b0;
201
    else if(mode == 3'd0 && written)                                            out <= 1'b0;
202
    else if(mode == 3'd0 && counter == 16'd1 && enable)                         out <= 1'b1;
203
 
204
    else if(mode == 3'd1 && load)                                               out <= 1'b0;
205
    else if(mode == 3'd1 && counter == 16'd1 && enable)                         out <= 1'b1;
206
 
207
    else if(mode[1:0] == 2'd2 && gate == 1'b0)                                  out <= 1'b1;
208
    else if(mode[1:0] == 2'd2 && counter == 16'd2 && enable)                    out <= 1'b0;
209
    else if(mode[1:0] == 2'd2 && load)                                          out <= 1'b1;
210
 
211
    else if(mode[1:0] == 2'd3 && gate == 1'b0)                                          out <= 1'b1;
212
    else if(mode[1:0] == 2'd3 && load && counter == 16'd2 && out && ~(counter_l[0]))    out <= 1'b0;
213
    else if(mode[1:0] == 2'd3 && load && counter == 16'd0 && out && counter_l[0])       out <= 1'b0;
214
    else if(mode[1:0] == 2'd3 && load)                                                  out <= 1'b1;
215
 
216
    else if(mode == 3'd4 && load)                                               out <= 1'b1;
217
    else if(mode == 3'd4 && counter == 16'd2 && enable)                         out <= 1'b0;
218
    else if(mode == 3'd4 && counter == 16'd1 && enable)                         out <= 1'b1;
219
 
220
    else if(mode == 3'd5 && counter == 16'd2 && enable)                         out <= 1'b0;
221
    else if(mode == 3'd5 && counter == 16'd1 && enable)                         out <= 1'b1;
222
end
223
 
224
//------------------------------------------------------------------------------
225
 
226
reg written;
227
always @(posedge clk or negedge rst_n) begin
228
    if(rst_n == 1'b0)                                       written <= 1'b0;
229
    else if(set_control_mode)                               written <= 1'b0;
230
    else if(write && rw_mode != 2'd3)                       written <= 1'b1;
231
    else if(write && rw_mode == 2'd3 && msb_write == 1'b1)  written <= 1'b1;
232
    else if(load)                                           written <= 1'b0;
233
end
234
 
235
reg loaded;
236
always @(posedge clk or negedge rst_n) begin
237
    if(rst_n == 1'b0)           loaded <= 1'b0;
238
    else if(set_control_mode)   loaded <= 1'b0;
239
    else if(load)               loaded <= 1'b1;
240
end
241
 
242
wire load = clock_pulse && (
243
    (mode == 3'd0 && written) ||
244
    (mode == 3'd1 && written && trigger_sampled) ||
245
    (mode[1:0] == 2'd2 && (written || trigger_sampled || (loaded && gate_sampled && counter == 16'd1))) ||
246
    (mode[1:0] == 2'd3 && (written || trigger_sampled || (loaded && gate_sampled && ((counter == 16'd2 && (~(counter_l[0]) || ~(out))) || (counter == 16'd0 && counter_l[0] && out))))) ||
247
    (mode == 3'd4 && written) ||
248
    (mode == 3'd5 && (written || loaded) && trigger_sampled)
249
);
250
 
251
wire load_even = load && mode[1:0] == 2'd3;
252
 
253
wire enable = ~(load) && loaded && clock_pulse && (
254
    (mode == 3'd0 && gate_sampled && msb_write == 1'b0) ||
255
    (mode == 3'd1) ||
256
    (mode[1:0] == 2'd2 && gate_sampled) ||
257
    (mode == 3'd4 && gate_sampled) ||
258
    (mode == 3'd5)
259
);
260
 
261
wire enable_double = ~(load) && loaded && clock_pulse && mode[1:0] == 2'd3 && gate_sampled;
262
 
263
//------------------------------------------------------------------------------
264
 
265
wire [3:0] bcd_3 = counter[15:12] - 4'd1;
266
wire [3:0] bcd_2 = counter[11:8] - 4'd1;
267
wire [3:0] bcd_1 = counter[7:4] - 4'd1;
268
 
269
wire [15:0] counter_minus_1 =
270
    (bcd && counter[15:0] == 16'd0)?    16'h9999 :
271
    (bcd && counter[11:0] == 12'd0)?    { bcd_3, 12'h999 } :
272
    (bcd && counter[7:0] == 8'd0)?      { counter[15:12], bcd_2, 8'h99 } :
273
    (bcd && counter[3:0] == 4'd0)?      { counter[15:8], bcd_1, 4'h9 } :
274
                                        counter - 16'd1;
275
 
276
wire [15:0] counter_minus_2 =
277
    (bcd && counter[15:0] == 16'd0)?    16'h9998 :
278
    (bcd && counter[11:0] == 12'd0)?    { bcd_3, 12'h998 } :
279
    (bcd && counter[7:0] == 8'd0)?      { counter[15:12], bcd_2, 8'h98 } :
280
    (bcd && counter[3:0] == 4'd0)?      { counter[15:8], bcd_1, 4'h8 } :
281
                                        counter - 16'd2;
282
 
283
reg [15:0] counter;
284
always @(posedge clk or negedge rst_n) begin
285
    if(rst_n == 1'b0)       counter <= 16'd0;
286
    else if(load_even)      counter <= { counter_m, counter_l[7:1], 1'b0 };
287
    else if(load)           counter <= { counter_m, counter_l };
288
    else if(enable_double)  counter <= counter_minus_2;
289
    else if(enable)         counter <= counter_minus_1;
290
end
291
 
292
//------------------------------------------------------------------------------
293
 
294
endmodule

powered by: WebSVN 2.1.0

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