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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [testbench/] [timer.v] - Blame information for rev 43

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 43 Revanth
`default_nettype none
2
 
3
// -----------------------------------------------------------------------------
4
// --                                                                         --
5
// --                   (C) 2016-2018 Revanth Kamaraj.                        --
6
// --                                                                         -- 
7
// -- --------------------------------------------------------------------------
8
// --                                                                         --
9
// -- This program is free software; you can redistribute it and/or           --
10
// -- modify it under the terms of the GNU General Public License             --
11
// -- as published by the Free Software Foundation; either version 2          --
12
// -- of the License, or (at your option) any later version.                  --
13
// --                                                                         --
14
// -- This program is distributed in the hope that it will be useful,         --
15
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of          --
16
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           --
17
// -- GNU General Public License for more details.                            --
18
// --                                                                         --
19
// -- You should have received a copy of the GNU General Public License       --
20
// -- along with this program; if not, write to the Free Software             --
21
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA           --
22
// -- 02110-1301, USA.                                                        --
23
// --                                                                         --
24
// -----------------------------------------------------------------------------
25
//                                                                            --
26
// This is a Wishbone timer peripheral with simple controls.                  --
27
//                                                                            --
28
// Registers:
29
// 0x0 (DEVEN) - 0x1 to enable the timer unit. 0x0 to disable the unit.       --
30
// 0x4 (DEVPR) - Timer length in number of Wishbone clocks.                   --
31
// 0x8 (DEVAK) - Write: 0x1 to acknowledge interrupt. Read: 0x1 reveals timer --
32
//               interrupt occured.                                           --
33
// 0xC (DEVST) - 0x1 to start the timer. Write only. Always reads 0x0.        --
34
//                                                                            --
35
// ------------------------------------------------------------------------------
36
 
37
module timer #(
38
 
39
        // Register addresses.
40
        parameter       [31:0]  TIMER_ENABLE_REGISTER = 32'h0,
41
        parameter       [31:0]  TIMER_LIMIT_REGISTER  = 32'h4,
42
        parameter       [31:0]  TIMER_INTACK_REGISTER = 32'h8,
43
        parameter       [31:0]  TIMER_START_REGISTER  = 32'hC
44
 
45
) (
46
 
47
// Clock and reset.
48
input wire                  i_clk,
49
input wire                  i_rst,
50
 
51
// Wishbone interface.
52
input wire  [31:0]          i_wb_dat,
53
input wire   [3:0]          i_wb_adr,
54
input wire                  i_wb_stb,
55
input wire                  i_wb_cyc,
56
input wire                  i_wb_wen,
57
input wire  [3:0]           i_wb_sel,
58
output reg [31:0]           o_wb_dat,
59
output reg                  o_wb_ack,
60
 
61
 
62
// Interrupt output. Level interrupt.
63
output  reg                 o_irq
64
 
65
);
66
 
67
// Timer registers.
68
reg [31:0] DEVEN;
69
reg [31:0] DEVPR;
70
reg [31:0] DEVAK;
71
reg [31:0] DEVST;
72
 
73
`ifndef ZAP_SOC_TIMER
74
`define ZAP_SOC_TIMER
75
        `define DEVEN TIMER_ENABLE_REGISTER
76
        `define DEVPR TIMER_LIMIT_REGISTER
77
        `define DEVAK TIMER_INTACK_REGISTER
78
        `define DEVST TIMER_START_REGISTER
79
`endif
80
 
81
// Timer core.
82
reg [31:0] ctr;         // Core counter.
83
reg        start;       // Pulse to start the timer. Done signal is cleared.
84
reg        done;        // Asserted when timer is done.
85
reg        clr;         // Clears the done signal.
86
reg [31:0] state;       // State
87
reg        enable;      // 1 to enable the timer.
88
reg [31:0] finalval;    // Final value to count.
89
reg [31:0] wbstate;
90
 
91
localparam IDLE         = 0;
92
localparam COUNTING     = 1;
93
localparam DONE         = 2;
94
 
95
localparam WBIDLE       = 0;
96
localparam WBREAD       = 1;
97
localparam WBWRITE      = 2;
98
localparam WBACK        = 3;
99
localparam WBDONE       = 4;
100
 
101
always @ (*)
102
        o_irq    = done;
103
 
104
always @ (*)
105
begin
106
        start    = DEVST[0];
107
        enable   = DEVEN[0];
108
        finalval = DEVPR;
109
        clr      = DEVAK[0];
110
end
111
 
112
always @ ( posedge i_clk )
113
begin
114
        DEVST <= 0;
115
 
116
        if ( i_rst )
117
        begin
118
                DEVEN <= 0;
119
                DEVPR <= 0;
120
                DEVAK <= 0;
121
                DEVST <= 0;
122
                wbstate  <= WBIDLE;
123
                o_wb_dat <= 0;
124
                o_wb_ack <= 0;
125
        end
126
        else
127
        begin
128
                case(wbstate)
129
                        WBIDLE:
130
                        begin
131
                                o_wb_ack <= 1'd0;
132
 
133
                                if ( i_wb_stb && i_wb_cyc )
134
                                begin
135
                                        if ( i_wb_wen )
136
                                                wbstate <= WBWRITE;
137
                                        else
138
                                                wbstate <= WBREAD;
139
                                end
140
                        end
141
 
142
                        WBWRITE:
143
                        begin
144
                                case(i_wb_adr)
145
                                `DEVEN: // DEVEN
146
                                begin
147
                                        $display($time, " - %m :: Writing register DEVEN...");
148
                                        if ( i_wb_sel[0] ) DEVEN[7:0]   <= i_wb_dat >> 0;
149
                                        if ( i_wb_sel[1] ) DEVEN[15:8]  <= i_wb_dat >> 8;
150
                                        if ( i_wb_sel[2] ) DEVEN[23:16] <= i_wb_dat >> 16;
151
                                        if ( i_wb_sel[3] ) DEVEN[31:24] <= i_wb_dat >> 24;
152
                                end
153
 
154
                                `DEVPR: // DEVPR
155
                                begin
156
                                        $display($time, " - %m :: Writing register DEVPR...");
157
                                        if ( i_wb_sel[0] ) DEVPR[7:0]   <= i_wb_dat >> 0;
158
                                        if ( i_wb_sel[1] ) DEVPR[15:8]  <= i_wb_dat >> 8;
159
                                        if ( i_wb_sel[2] ) DEVPR[23:16] <= i_wb_dat >> 16;
160
                                        if ( i_wb_sel[3] ) DEVPR[31:24] <= i_wb_dat >> 24;
161
 
162
                                end
163
 
164
                                `DEVAK: // DEVAK
165
                                begin
166
                                        $display($time, " - %m :: Writing register DEVAK...");
167
                                        if ( i_wb_sel[0] ) DEVPR[7:0]   <= i_wb_dat >> 0;
168
                                        if ( i_wb_sel[1] ) DEVPR[15:8]  <= i_wb_dat >> 8;
169
                                        if ( i_wb_sel[2] ) DEVPR[23:16] <= i_wb_dat >> 16;
170
                                        if ( i_wb_sel[3] ) DEVPR[31:24] <= i_wb_dat >> 24;
171
                                end
172
 
173
                                `DEVST: // DEVST
174
                                begin
175
                                        $display($time, " - %m :: Writing register DEVST...");
176
                                        if ( i_wb_sel[0] ) DEVST[7:0]   <= i_wb_dat >> 0;
177
                                        if ( i_wb_sel[1] ) DEVST[15:8]  <= i_wb_dat >> 8;
178
                                        if ( i_wb_sel[2] ) DEVST[23:16] <= i_wb_dat >> 16;
179
                                        if ( i_wb_sel[3] ) DEVST[31:24] <= i_wb_dat >> 24;
180
                                end
181
 
182
                                endcase
183
 
184
                                wbstate <= WBACK;
185
                        end
186
 
187
                        WBREAD:
188
                        begin
189
                                case(i_wb_adr)
190
                                `DEVEN: o_wb_dat <= DEVEN;
191
                                `DEVPR: o_wb_dat <= DEVPR;
192
                                `DEVAK: o_wb_dat <= done;
193
                                `DEVST: o_wb_dat <= 32'd0;
194
                                endcase
195
 
196
                                wbstate <= WBACK;
197
                        end
198
 
199
                        WBACK:
200
                        begin
201
                                o_wb_ack   <= 1'd1;
202
                                wbstate    <= WBDONE;
203
                        end
204
 
205
                        WBDONE:
206
                        begin
207
                                o_wb_ack  <= 1'd0;
208
                                wbstate   <= IDLE;
209
                        end
210
                endcase
211
        end
212
end
213
 
214
always @ (posedge i_clk)
215
begin
216
        if ( i_rst || !enable )
217
        begin
218
                ctr     <= 0;
219
                done    <= 0;
220
                state   <= IDLE;
221
        end
222
        else // if enabled
223
        begin
224
                case(state)
225
                IDLE:
226
                begin
227
                        if ( start )
228
                        begin
229
                                $display($time," - %m :: Timer started counting...");
230
                                state <= COUNTING;
231
                        end
232
                end
233
 
234
                COUNTING:
235
                begin
236
                        ctr <= ctr + 1;
237
 
238
                        if ( ctr == finalval )
239
                        begin
240
                                $display($time, " - %m :: Timer done counting...");
241
                                state <= DONE;
242
                        end
243
                end
244
 
245
                DONE:
246
                begin
247
                        done <= 1;
248
 
249
                        if ( start )
250
                        begin
251
                                $display($time, " - %m :: Timer got START from DONE state...");
252
                                done  <= 0;
253
                                state <= COUNTING;
254
                                ctr   <= 0;
255
                        end
256
                        else if ( clr ) // Acknowledge. 
257
                        begin
258
                                $display($time, " - %m :: Timer got done in ACK state...");
259
                                done  <= 0;
260
                                state <= IDLE;
261
                                ctr   <= 0;
262
                        end
263
                end
264
                endcase
265
        end
266
end
267
 
268
endmodule
269
 
270
`default_nettype wire

powered by: WebSVN 2.1.0

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