Fri, 13 Aug 2010 10:49:23 +0100
Initial import, Timer v3.0
1 // =============================================================================
2 // COPYRIGHT NOTICE
3 // Copyright 2006 (c) Lattice Semiconductor Corporation
4 // ALL RIGHTS RESERVED
5 // This confidential and proprietary software may be used only as authorised by
6 // a licensing agreement from Lattice Semiconductor Corporation.
7 // The entire notice above must be reproduced on all authorized copies and
8 // copies may only be made to the extent permitted by a licensing agreement from
9 // Lattice Semiconductor Corporation.
10 //
11 // Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada)
12 // 5555 NE Moore Court 408-826-6000 (other locations)
13 // Hillsboro, OR 97124 web : http://www.latticesemi.com/
14 // U.S.A email: techsupport@latticesemi.com
15 // =============================================================================/
16 // FILE DETAILS
17 // Project : LM32 Timer
18 // File : timer.v
19 // Title : Timer component core file
20 // Dependencies : None
21 // Version : 7.0
22 // : Initial Release
23 // Version : 7.0SP2, 3.0
24 // : No Change
25 // =============================================================================
26 `ifndef TIMER_FILE
27 `define TIMER_FILE
28 module timer #(
29 parameter PERIOD_NUM = 20,//decimal
30 parameter PERIOD_WIDTH = 16,//decimal
31 parameter WRITEABLE_PERIOD = 1,
32 parameter READABLE_SNAPSHOT = 1,
33 parameter START_STOP_CONTROL = 1,
34 parameter TIMEOUT_PULSE = 1,
35 parameter WATCHDOG = 0)
36 (
37 //slave port
38 S_ADR_I, //32bits
39 S_DAT_I, //32bits
40 S_WE_I,
41 S_STB_I,
42 S_CYC_I,
43 S_CTI_I,
44 S_BTE_I,
45 S_LOCK_I,
46 S_SEL_I,
47 S_DAT_O, //32bits
48 S_ACK_O,
49 S_RTY_O,
50 S_ERR_O,
51 S_INT_O,
52 RSTREQ_O, //resetrequest, only used when WatchDog enabled
53 TOPULSE_O, //timeoutpulse, only used when TimeOutPulse enabled
54 //system clock and reset
55 CLK_I,
56 RST_I
57 );
59 input [31:0] S_ADR_I;
60 input [31:0] S_DAT_I;
61 input S_WE_I;
62 input S_STB_I;
63 input S_CYC_I;
64 input [2:0] S_CTI_I;
65 input S_LOCK_I;
66 input [3:0] S_SEL_I;
67 input [1:0] S_BTE_I;
68 output [31:0] S_DAT_O;
69 output S_ACK_O;
70 output S_INT_O;
71 output S_RTY_O;
72 output S_ERR_O;
73 output RSTREQ_O;
74 output TOPULSE_O;
76 input CLK_I;
77 input RST_I;
79 parameter UDLY = 1;
80 parameter ST_IDLE = 2'b00;
81 parameter ST_CNT = 2'b01;
82 parameter ST_STOP = 2'b10;
84 reg dw00_cs;
85 reg dw04_cs;
86 reg dw08_cs;
87 reg dw0c_cs;
88 reg reg_wr;
89 reg reg_rd;
90 reg [31:0] latch_s_data;
91 reg [1:0] reg_04_data;
92 reg reg_run;
93 reg reg_stop;
94 reg reg_start;
95 reg [1:0] status;
96 reg [PERIOD_WIDTH-1:0] internal_counter;
97 reg [PERIOD_WIDTH-1:0] reg_08_data;
98 reg s_ack_dly;
99 reg s_ack_2dly;
100 reg s_ack_pre;
101 reg RSTREQ_O;
102 reg TOPULSE_O;
103 reg reg_to;
105 wire reg_cont;
106 wire reg_ito;
107 wire [1:0] read_00_data;
108 wire [1:0] read_04_data;
109 wire [PERIOD_WIDTH-1:0] read_08_data;
110 wire [PERIOD_WIDTH-1:0] read_0c_data;
111 wire [PERIOD_WIDTH-1:0] reg_period;
112 wire S_ACK_O;
113 wire [31:0] S_DAT_O;
114 wire S_INT_O;
116 assign S_RTY_O = 1'b0;
117 assign S_ERR_O = 1'b0;
119 always @(posedge CLK_I or posedge RST_I)
120 if(RST_I)
121 latch_s_data <= #UDLY 32'h0;
122 else
123 latch_s_data <= #UDLY S_DAT_I;
125 always @(posedge CLK_I or posedge RST_I)
126 if(RST_I)
127 begin
128 dw00_cs <= #UDLY 1'b0;
129 dw04_cs <= #UDLY 1'b0;
130 dw08_cs <= #UDLY 1'b0;
131 dw0c_cs <= #UDLY 1'b0;
132 end
133 else
134 begin
135 dw00_cs <= #UDLY (!(|S_ADR_I[5:2]));
136 dw04_cs <= #UDLY (S_ADR_I[5:2] == 4'h1);
137 dw08_cs <= #UDLY (S_ADR_I[5:2] == 4'h2);
138 dw0c_cs <= #UDLY (S_ADR_I[5:2] == 4'h3);
139 end
141 always @(posedge CLK_I or posedge RST_I)
142 if(RST_I)
143 begin
144 reg_wr <= #UDLY 1'b0;
145 reg_rd <= #UDLY 1'b0;
146 end
147 else
148 begin
149 reg_wr <= #UDLY S_WE_I && S_STB_I && S_CYC_I;
150 reg_rd <= #UDLY !S_WE_I && S_STB_I && S_CYC_I;
151 end
153 generate
154 if (START_STOP_CONTROL == 1)
156 always @(posedge CLK_I or posedge RST_I)
157 if(RST_I)
158 begin
159 status <= #UDLY ST_IDLE;
160 internal_counter <= #UDLY 'h0;
161 end
162 else
163 case(status)
164 ST_IDLE:
165 begin
166 if(reg_wr && dw08_cs)
167 begin
168 internal_counter <= #UDLY (WRITEABLE_PERIOD == 1) ? latch_s_data : reg_period;
169 end
170 else if(reg_start && !reg_stop)
171 begin
172 status <= #UDLY ST_CNT;
173 if(|reg_period)
174 internal_counter <= #UDLY reg_period - 1;
175 end
176 end
177 ST_CNT:
178 begin
179 if(reg_stop && (|internal_counter))
180 status <= #UDLY ST_STOP;
181 else if(reg_wr && dw08_cs)
182 begin
183 internal_counter <= #UDLY (WRITEABLE_PERIOD == 1) ? latch_s_data : reg_period;
184 if(!(|internal_counter) && !reg_cont)
185 status <= #UDLY ST_IDLE;
186 end
187 else if(!(|internal_counter))
188 begin
189 if(!reg_cont)
190 begin
191 status <= #UDLY ST_IDLE;
192 end
193 internal_counter <= #UDLY reg_period;
194 end
195 else
196 internal_counter <= #UDLY internal_counter - 1;
197 end
198 ST_STOP:
199 begin
200 if(reg_start && !reg_stop)
201 status <= #UDLY ST_CNT;
202 else if(reg_wr && dw08_cs)
203 begin
204 internal_counter <= #UDLY (WRITEABLE_PERIOD == 1) ? latch_s_data : reg_period;
205 end
206 end
207 default:
208 begin
209 status <= #UDLY ST_IDLE;
210 internal_counter <= #UDLY 'h0;
211 end
212 endcase
213 endgenerate
216 generate
217 if (START_STOP_CONTROL == 0)
218 always @(posedge CLK_I or posedge RST_I)
219 if(RST_I)
220 internal_counter <= #UDLY 'h0;
221 else if ((reg_wr && dw08_cs) && (WATCHDOG == 1) || !(|internal_counter))
222 internal_counter <= #UDLY reg_period;
223 else
224 internal_counter <= #UDLY internal_counter - 1;
225 endgenerate
227 always @(posedge CLK_I or posedge RST_I)
228 if(RST_I)
229 reg_to <= #UDLY 1'b0;
230 else if(reg_wr && dw00_cs && (!latch_s_data[0]))
231 reg_to <= #UDLY 1'b0;
232 else if(!(|internal_counter) && reg_ito && ((START_STOP_CONTROL == 0) || reg_run))
233 reg_to <= #UDLY 1'b1;
235 generate
236 if (START_STOP_CONTROL == 1)
237 always @(posedge CLK_I or posedge RST_I)
238 if(RST_I)
239 reg_run <= #UDLY 1'b0;
240 else if(reg_stop)
241 reg_run <= #UDLY 1'b0;
242 else if(reg_start)
243 reg_run <= #UDLY 1'b1;
244 else
245 reg_run <= #UDLY (status !== ST_IDLE);
246 endgenerate
248 assign read_00_data = (START_STOP_CONTROL == 1) ? {reg_run,reg_to} : {1'b1,reg_to};
250 //reg_04:control
251 assign {reg_cont,reg_ito} = reg_04_data;
253 generate
254 if (START_STOP_CONTROL == 1)
255 always @(posedge CLK_I or posedge RST_I)
256 if(RST_I)
257 reg_stop <= #UDLY 1'b0;
258 else if(reg_wr && dw04_cs)
259 begin
260 if(latch_s_data[3] && !latch_s_data[2] && !reg_stop)
261 reg_stop <= #UDLY 1'b1;
262 else if(!latch_s_data[3] && latch_s_data[2] && reg_stop)
263 reg_stop <= #UDLY 1'b0;
264 end
266 always @(posedge CLK_I or posedge RST_I)
267 if(RST_I)
268 reg_start <= #UDLY 1'b0;
269 else if(reg_wr && dw04_cs && !reg_run)
270 reg_start <= #UDLY latch_s_data[2];
271 else
272 reg_start <= #UDLY 1'b0;
273 endgenerate
275 always @(posedge CLK_I or posedge RST_I)
276 if(RST_I)
277 reg_04_data <= #UDLY 2'h0;
278 else if(reg_wr && dw04_cs)
279 reg_04_data <= #UDLY latch_s_data[1:0];
281 assign read_04_data = reg_04_data;
283 generate
284 if (WRITEABLE_PERIOD == 1) begin
285 assign reg_period = reg_08_data;
286 assign read_08_data = reg_08_data;
287 always @(posedge CLK_I or posedge RST_I) begin
288 if (RST_I)
289 reg_08_data <= #UDLY PERIOD_NUM;
290 else if ((reg_wr && dw08_cs) && (START_STOP_CONTROL == 1))
291 reg_08_data <= #UDLY latch_s_data;
292 end
293 end
294 else
295 assign reg_period = PERIOD_NUM;
296 endgenerate
298 generate
299 if (READABLE_SNAPSHOT == 1)
300 assign read_0c_data = internal_counter;
301 endgenerate
303 always @(posedge CLK_I or posedge RST_I)
304 if(RST_I)
305 begin
306 s_ack_pre <= #UDLY 1'b0;
307 s_ack_dly <= #UDLY 1'b0;
308 s_ack_2dly <= #UDLY 1'b0;
309 end
310 else
311 begin
312 s_ack_pre <= #UDLY S_STB_I && S_CYC_I;
313 s_ack_dly <= #UDLY s_ack_pre;
314 s_ack_2dly <= #UDLY s_ack_dly;
315 end
317 assign S_ACK_O = s_ack_dly & !s_ack_2dly;
318 assign S_DAT_O = (dw00_cs & !S_WE_I & S_STB_I) ? read_00_data :
319 (dw04_cs & !S_WE_I & S_STB_I) ? read_04_data :
320 (dw08_cs & !S_WE_I & S_STB_I & WRITEABLE_PERIOD) ? read_08_data :
321 (dw0c_cs & !S_WE_I & S_STB_I & READABLE_SNAPSHOT) ? read_0c_data :
322 32'h0;
323 assign S_INT_O = reg_to;
325 generate
326 if (WATCHDOG == 1)
327 always @(posedge CLK_I or posedge RST_I) begin
328 if(RST_I)
329 RSTREQ_O <= #UDLY 1'b0;
330 else if(!(|internal_counter) && !RSTREQ_O && ((START_STOP_CONTROL == 0) || reg_run))
331 RSTREQ_O <= #UDLY 1'b1;
332 else
333 RSTREQ_O <= #UDLY 1'b0;
334 end
335 endgenerate
338 generate
339 if (TIMEOUT_PULSE == 1)
340 //TOPULSE_O
341 always @(posedge CLK_I or posedge RST_I)
342 if(RST_I)
343 TOPULSE_O <= #UDLY 1'b0;
344 else if(!(|internal_counter) && !TOPULSE_O && ((START_STOP_CONTROL == 0) || reg_run))
345 TOPULSE_O <= #UDLY 1'b1;
346 else
347 TOPULSE_O <= #UDLY 1'b0;
348 endgenerate
350 endmodule
351 `endif