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

Subversion Repositories next186mp3

[/] [next186mp3/] [trunk/] [HW/] [timer8253.v] - Blame information for rev 3

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

Line No. Rev Author Line
1 2 ndumitrach
//////////////////////////////////////////////////////////////////////////////////
2
//
3
// This file is part of the Next186 Soc PC project
4
// http://opencores.org/project,next186
5
//
6
// Filename: timer8253.v
7
// Description: Part of the Next186 SoC PC project, timer
8
//      8253 simplified timer (no gate, only counters 0 and 2, no read back command)
9
// Version 1.0
10
// Creation date: May2012
11
//
12
// Author: Nicolae Dumitrache 
13
// e-mail: ndumitrache@opencores.org
14
//
15
/////////////////////////////////////////////////////////////////////////////////
16
// 
17
// Copyright (C) 2012 Nicolae Dumitrache
18
// 
19
// This source file may be used and distributed without 
20
// restriction provided that this copyright statement is not 
21
// removed from the file and that any derivative work contains 
22
// the original copyright notice and the associated disclaimer.
23
// 
24
// This source file is free software; you can redistribute it 
25
// and/or modify it under the terms of the GNU Lesser General 
26
// Public License as published by the Free Software Foundation;
27
// either version 2.1 of the License, or (at your option) any 
28
// later version. 
29
// 
30
// This source is distributed in the hope that it will be 
31
// useful, but WITHOUT ANY WARRANTY; without even the implied 
32
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
33
// PURPOSE. See the GNU Lesser General Public License for more 
34
// details. 
35
// 
36
// You should have received a copy of the GNU Lesser General 
37
// Public License along with this source; if not, download it 
38
// from http://www.opencores.org/lgpl.shtml 
39
// 
40
///////////////////////////////////////////////////////////////////////////////////
41
// Additional Comments: 
42
// http://wiki.osdev.org/Programmable_Interval_Timer
43
//////////////////////////////////////////////////////////////////////////////////
44
 
45
`timescale 1ns / 1ps
46
 
47
module timer_8253(
48
    input CS,
49
         input WR,
50
    input [1:0]addr,
51
         input [7:0]din,
52
         output wire [7:0]dout,
53
         input CLK_25,
54
         input clk,             // cpu CLK
55
         output out0,
56
         output out2
57
    );
58
 
59
        reg [8:0]rclk = 0; // rclk[8] oscillates at 1193181.8181... Hz
60
        reg [1:0]cclk = 0;
61
 
62
        always @(posedge CLK_25) begin
63
                if(rclk[7:0] < 8'd208) rclk <= rclk + 21;
64
                else rclk <= rclk + 57;
65
        end
66
 
67
        always @ (posedge clk) begin
68
                cclk <= {cclk[0], rclk[8]};
69
        end
70
 
71
        wire a0 = addr == 0;
72
        wire a2 = addr == 2;
73
        wire a3 = addr == 3;
74
        wire cmd0 = a3 && din[7:6] == 0;
75
        wire cmd2 = a3 && din[7:6] == 2;
76
        wire [7:0]dout0;
77
        wire [7:0]dout2;
78
        wire [7:0]mode0;
79
        wire [7:0]mode2;
80
 
81
        counter counter0 (
82
                 .CS(CS && (a0 || cmd0)),
83
                 .WR(WR),
84
                 .clk(clk),
85
                 .cmd(cmd0),
86
                 .din(din),
87
                 .dout(dout0),
88
                 .mode(mode0),
89
                 .CE(cclk)
90
    );
91
 
92
        counter counter2 (
93
                 .CS(CS && (a2 || cmd2)),
94
                 .WR(WR),
95
                 .clk(clk),
96
                 .cmd(cmd2),
97
                 .din(din),
98
                 .dout(dout2),
99
                 .mode(mode2),
100
                 .CE(cclk)
101
                 );
102
 
103
        assign out0 = mode0[7];
104
        assign out2 = mode2[7];
105
        assign dout =   a0 ? dout0 : dout2;
106
 
107
endmodule
108
 
109
 
110
module counter(
111
         input CS,
112
    input WR,   // write cmd/data
113
         input clk,     // CPU clk
114
    input cmd,
115
         input [7:0]din,
116
         output [7:0]dout,
117
         output reg [7:0]mode,   // mode[7] = output
118
         input [1:0]CE   // count enable
119
    );
120
 
121
         reg [15:0]count = 0;
122
         reg [15:0]init = 0;
123
         reg [1:0]state = 0; // state[1] = init reg filled
124
         reg strobe = 0;
125
         reg rd = 0;
126
         reg latch = 0;
127
         reg newcmd = 0;
128
         wire c1 = count == 1;
129
         wire c2 = count == 2;
130
         reg CE1 = 0;
131
 
132
         assign dout = mode[5] & (~mode[4] | rd) ? count[15:8] : count[7:0];
133
 
134
        always @(posedge clk) begin
135
 
136
                if(CE == 2'b10) CE1 <= 1;
137
 
138
                if(CS) begin
139
                        if(WR) begin
140
                                mode[6] <= 1;
141
                                rd <= 0;
142
                                latch <= 0;
143
                                if(cmd) begin   // command
144
                                        if(|din[5:4]) begin
145
                                                mode[5:0] <= din[5:0];
146
                                                newcmd <= 1;
147
                                                state <= {1'b0, din[5] & ~din[4]};
148
                                        end else latch <= &mode[5:4];
149
                                end else begin  // data
150
                                        state <= state[0] + ^mode[5:4] + 1;
151
                                        if(state[0]) init[15:8] <= din;
152
                                        else init[7:0] <= din;
153
                                end
154
                        end else begin
155
                                rd <= ~rd;
156
                                if(rd) latch <= 0;
157
                        end
158
                end else if(state[1] && CE1 && !latch) begin
159
                        newcmd <= 0;
160
                        CE1 <= 0;
161
                        case(mode[3:1])
162
                                3'b000, 3'b001:
163
                                        if(mode[6]) begin
164
                                                mode[7:6] <= 2'b00;
165
                                                count <= init;
166
                                        end else begin
167
                                                count <= count - 1;
168
                                                if(c1) mode[7] <= 1;
169
                                        end
170
                                3'b010, 3'b110: begin
171
                                        mode[7] <= ~c2;
172
                                        if(c1 | newcmd) begin
173
                                                mode[6] <= 1'b0;
174
                                                count <= init;
175
                                        end else count <= count - 1;
176
                                end
177
                                3'b011, 3'b111: begin
178
                                        if(c1 | c2 | newcmd) begin
179
                                                mode[7:6] <= {~mode[7] | newcmd, 1'b0};
180
                                                count <= {init[15:1], (~mode[7] | newcmd) & init[0]};
181
                                        end else count <= count - 2;
182
                                end
183
                                3'b100, 3'b101:
184
                                        if(mode[6]) begin
185
                                                mode[7:6] <= 2'b10;
186
                                                count <= init;
187
                                                strobe <= 1;
188
                                        end else begin
189
                                                count <= count - 1;
190
                                                if(c1) begin
191
                                                        if(strobe) mode[7] <= 0;
192
                                                        strobe <= 0;
193
                                                end else mode[7] <= 1;
194
                                        end
195
                        endcase
196
                end
197
        end
198
 
199
endmodule

powered by: WebSVN 2.1.0

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