1.1 diff -r 000000000000 -r 396b0bd970d3 rtl/verilog/timer.v 1.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 +++ b/rtl/verilog/timer.v Fri Aug 13 10:49:23 2010 +0100 1.4 @@ -0,0 +1,351 @@ 1.5 +// ============================================================================= 1.6 +// COPYRIGHT NOTICE 1.7 +// Copyright 2006 (c) Lattice Semiconductor Corporation 1.8 +// ALL RIGHTS RESERVED 1.9 +// This confidential and proprietary software may be used only as authorised by 1.10 +// a licensing agreement from Lattice Semiconductor Corporation. 1.11 +// The entire notice above must be reproduced on all authorized copies and 1.12 +// copies may only be made to the extent permitted by a licensing agreement from 1.13 +// Lattice Semiconductor Corporation. 1.14 +// 1.15 +// Lattice Semiconductor Corporation TEL : 1-800-Lattice (USA and Canada) 1.16 +// 5555 NE Moore Court 408-826-6000 (other locations) 1.17 +// Hillsboro, OR 97124 web : http://www.latticesemi.com/ 1.18 +// U.S.A email: techsupport@latticesemi.com 1.19 +// =============================================================================/ 1.20 +// FILE DETAILS 1.21 +// Project : LM32 Timer 1.22 +// File : timer.v 1.23 +// Title : Timer component core file 1.24 +// Dependencies : None 1.25 +// Version : 7.0 1.26 +// : Initial Release 1.27 +// Version : 7.0SP2, 3.0 1.28 +// : No Change 1.29 +// ============================================================================= 1.30 +`ifndef TIMER_FILE 1.31 +`define TIMER_FILE 1.32 +module timer #( 1.33 + parameter PERIOD_NUM = 20,//decimal 1.34 + parameter PERIOD_WIDTH = 16,//decimal 1.35 + parameter WRITEABLE_PERIOD = 1, 1.36 + parameter READABLE_SNAPSHOT = 1, 1.37 + parameter START_STOP_CONTROL = 1, 1.38 + parameter TIMEOUT_PULSE = 1, 1.39 + parameter WATCHDOG = 0) 1.40 + ( 1.41 + //slave port 1.42 + S_ADR_I, //32bits 1.43 + S_DAT_I, //32bits 1.44 + S_WE_I, 1.45 + S_STB_I, 1.46 + S_CYC_I, 1.47 + S_CTI_I, 1.48 + S_BTE_I, 1.49 + S_LOCK_I, 1.50 + S_SEL_I, 1.51 + S_DAT_O, //32bits 1.52 + S_ACK_O, 1.53 + S_RTY_O, 1.54 + S_ERR_O, 1.55 + S_INT_O, 1.56 + RSTREQ_O, //resetrequest, only used when WatchDog enabled 1.57 + TOPULSE_O, //timeoutpulse, only used when TimeOutPulse enabled 1.58 + //system clock and reset 1.59 + CLK_I, 1.60 + RST_I 1.61 + ); 1.62 + 1.63 + input [31:0] S_ADR_I; 1.64 + input [31:0] S_DAT_I; 1.65 + input S_WE_I; 1.66 + input S_STB_I; 1.67 + input S_CYC_I; 1.68 + input [2:0] S_CTI_I; 1.69 + input S_LOCK_I; 1.70 + input [3:0] S_SEL_I; 1.71 + input [1:0] S_BTE_I; 1.72 + output [31:0] S_DAT_O; 1.73 + output S_ACK_O; 1.74 + output S_INT_O; 1.75 + output S_RTY_O; 1.76 + output S_ERR_O; 1.77 + output RSTREQ_O; 1.78 + output TOPULSE_O; 1.79 + 1.80 + input CLK_I; 1.81 + input RST_I; 1.82 + 1.83 + parameter UDLY = 1; 1.84 + parameter ST_IDLE = 2'b00; 1.85 + parameter ST_CNT = 2'b01; 1.86 + parameter ST_STOP = 2'b10; 1.87 + 1.88 + reg dw00_cs; 1.89 + reg dw04_cs; 1.90 + reg dw08_cs; 1.91 + reg dw0c_cs; 1.92 + reg reg_wr; 1.93 + reg reg_rd; 1.94 + reg [31:0] latch_s_data; 1.95 + reg [1:0] reg_04_data; 1.96 + reg reg_run; 1.97 + reg reg_stop; 1.98 + reg reg_start; 1.99 + reg [1:0] status; 1.100 + reg [PERIOD_WIDTH-1:0] internal_counter; 1.101 + reg [PERIOD_WIDTH-1:0] reg_08_data; 1.102 + reg s_ack_dly; 1.103 + reg s_ack_2dly; 1.104 + reg s_ack_pre; 1.105 + reg RSTREQ_O; 1.106 + reg TOPULSE_O; 1.107 + reg reg_to; 1.108 + 1.109 + wire reg_cont; 1.110 + wire reg_ito; 1.111 + wire [1:0] read_00_data; 1.112 + wire [1:0] read_04_data; 1.113 + wire [PERIOD_WIDTH-1:0] read_08_data; 1.114 + wire [PERIOD_WIDTH-1:0] read_0c_data; 1.115 + wire [PERIOD_WIDTH-1:0] reg_period; 1.116 + wire S_ACK_O; 1.117 + wire [31:0] S_DAT_O; 1.118 + wire S_INT_O; 1.119 + 1.120 + assign S_RTY_O = 1'b0; 1.121 + assign S_ERR_O = 1'b0; 1.122 + 1.123 + always @(posedge CLK_I or posedge RST_I) 1.124 + if(RST_I) 1.125 + latch_s_data <= #UDLY 32'h0; 1.126 + else 1.127 + latch_s_data <= #UDLY S_DAT_I; 1.128 + 1.129 + always @(posedge CLK_I or posedge RST_I) 1.130 + if(RST_I) 1.131 + begin 1.132 + dw00_cs <= #UDLY 1'b0; 1.133 + dw04_cs <= #UDLY 1'b0; 1.134 + dw08_cs <= #UDLY 1'b0; 1.135 + dw0c_cs <= #UDLY 1'b0; 1.136 + end 1.137 + else 1.138 + begin 1.139 + dw00_cs <= #UDLY (!(|S_ADR_I[5:2])); 1.140 + dw04_cs <= #UDLY (S_ADR_I[5:2] == 4'h1); 1.141 + dw08_cs <= #UDLY (S_ADR_I[5:2] == 4'h2); 1.142 + dw0c_cs <= #UDLY (S_ADR_I[5:2] == 4'h3); 1.143 + end 1.144 + 1.145 + always @(posedge CLK_I or posedge RST_I) 1.146 + if(RST_I) 1.147 + begin 1.148 + reg_wr <= #UDLY 1'b0; 1.149 + reg_rd <= #UDLY 1'b0; 1.150 + end 1.151 + else 1.152 + begin 1.153 + reg_wr <= #UDLY S_WE_I && S_STB_I && S_CYC_I; 1.154 + reg_rd <= #UDLY !S_WE_I && S_STB_I && S_CYC_I; 1.155 + end 1.156 + 1.157 + generate 1.158 + if (START_STOP_CONTROL == 1) 1.159 + 1.160 + always @(posedge CLK_I or posedge RST_I) 1.161 + if(RST_I) 1.162 + begin 1.163 + status <= #UDLY ST_IDLE; 1.164 + internal_counter <= #UDLY 'h0; 1.165 + end 1.166 + else 1.167 + case(status) 1.168 + ST_IDLE: 1.169 + begin 1.170 + if(reg_wr && dw08_cs) 1.171 + begin 1.172 + internal_counter <= #UDLY (WRITEABLE_PERIOD == 1) ? latch_s_data : reg_period; 1.173 + end 1.174 + else if(reg_start && !reg_stop) 1.175 + begin 1.176 + status <= #UDLY ST_CNT; 1.177 + if(|reg_period) 1.178 + internal_counter <= #UDLY reg_period - 1; 1.179 + end 1.180 + end 1.181 + ST_CNT: 1.182 + begin 1.183 + if(reg_stop && (|internal_counter)) 1.184 + status <= #UDLY ST_STOP; 1.185 + else if(reg_wr && dw08_cs) 1.186 + begin 1.187 + internal_counter <= #UDLY (WRITEABLE_PERIOD == 1) ? latch_s_data : reg_period; 1.188 + if(!(|internal_counter) && !reg_cont) 1.189 + status <= #UDLY ST_IDLE; 1.190 + end 1.191 + else if(!(|internal_counter)) 1.192 + begin 1.193 + if(!reg_cont) 1.194 + begin 1.195 + status <= #UDLY ST_IDLE; 1.196 + end 1.197 + internal_counter <= #UDLY reg_period; 1.198 + end 1.199 + else 1.200 + internal_counter <= #UDLY internal_counter - 1; 1.201 + end 1.202 + ST_STOP: 1.203 + begin 1.204 + if(reg_start && !reg_stop) 1.205 + status <= #UDLY ST_CNT; 1.206 + else if(reg_wr && dw08_cs) 1.207 + begin 1.208 + internal_counter <= #UDLY (WRITEABLE_PERIOD == 1) ? latch_s_data : reg_period; 1.209 + end 1.210 + end 1.211 + default: 1.212 + begin 1.213 + status <= #UDLY ST_IDLE; 1.214 + internal_counter <= #UDLY 'h0; 1.215 + end 1.216 + endcase 1.217 + endgenerate 1.218 + 1.219 + 1.220 + generate 1.221 + if (START_STOP_CONTROL == 0) 1.222 + always @(posedge CLK_I or posedge RST_I) 1.223 + if(RST_I) 1.224 + internal_counter <= #UDLY 'h0; 1.225 + else if ((reg_wr && dw08_cs) && (WATCHDOG == 1) || !(|internal_counter)) 1.226 + internal_counter <= #UDLY reg_period; 1.227 + else 1.228 + internal_counter <= #UDLY internal_counter - 1; 1.229 + endgenerate 1.230 + 1.231 + always @(posedge CLK_I or posedge RST_I) 1.232 + if(RST_I) 1.233 + reg_to <= #UDLY 1'b0; 1.234 + else if(reg_wr && dw00_cs && (!latch_s_data[0])) 1.235 + reg_to <= #UDLY 1'b0; 1.236 + else if(!(|internal_counter) && reg_ito && ((START_STOP_CONTROL == 0) || reg_run)) 1.237 + reg_to <= #UDLY 1'b1; 1.238 + 1.239 + generate 1.240 + if (START_STOP_CONTROL == 1) 1.241 + always @(posedge CLK_I or posedge RST_I) 1.242 + if(RST_I) 1.243 + reg_run <= #UDLY 1'b0; 1.244 + else if(reg_stop) 1.245 + reg_run <= #UDLY 1'b0; 1.246 + else if(reg_start) 1.247 + reg_run <= #UDLY 1'b1; 1.248 + else 1.249 + reg_run <= #UDLY (status !== ST_IDLE); 1.250 + endgenerate 1.251 + 1.252 + assign read_00_data = (START_STOP_CONTROL == 1) ? {reg_run,reg_to} : {1'b1,reg_to}; 1.253 + 1.254 + //reg_04:control 1.255 + assign {reg_cont,reg_ito} = reg_04_data; 1.256 + 1.257 + generate 1.258 + if (START_STOP_CONTROL == 1) 1.259 + always @(posedge CLK_I or posedge RST_I) 1.260 + if(RST_I) 1.261 + reg_stop <= #UDLY 1'b0; 1.262 + else if(reg_wr && dw04_cs) 1.263 + begin 1.264 + if(latch_s_data[3] && !latch_s_data[2] && !reg_stop) 1.265 + reg_stop <= #UDLY 1'b1; 1.266 + else if(!latch_s_data[3] && latch_s_data[2] && reg_stop) 1.267 + reg_stop <= #UDLY 1'b0; 1.268 + end 1.269 + 1.270 + always @(posedge CLK_I or posedge RST_I) 1.271 + if(RST_I) 1.272 + reg_start <= #UDLY 1'b0; 1.273 + else if(reg_wr && dw04_cs && !reg_run) 1.274 + reg_start <= #UDLY latch_s_data[2]; 1.275 + else 1.276 + reg_start <= #UDLY 1'b0; 1.277 + endgenerate 1.278 + 1.279 + always @(posedge CLK_I or posedge RST_I) 1.280 + if(RST_I) 1.281 + reg_04_data <= #UDLY 2'h0; 1.282 + else if(reg_wr && dw04_cs) 1.283 + reg_04_data <= #UDLY latch_s_data[1:0]; 1.284 + 1.285 + assign read_04_data = reg_04_data; 1.286 + 1.287 + generate 1.288 + if (WRITEABLE_PERIOD == 1) begin 1.289 + assign reg_period = reg_08_data; 1.290 + assign read_08_data = reg_08_data; 1.291 + always @(posedge CLK_I or posedge RST_I) begin 1.292 + if (RST_I) 1.293 + reg_08_data <= #UDLY PERIOD_NUM; 1.294 + else if ((reg_wr && dw08_cs) && (START_STOP_CONTROL == 1)) 1.295 + reg_08_data <= #UDLY latch_s_data; 1.296 + end 1.297 + end 1.298 + else 1.299 + assign reg_period = PERIOD_NUM; 1.300 + endgenerate 1.301 + 1.302 + generate 1.303 + if (READABLE_SNAPSHOT == 1) 1.304 + assign read_0c_data = internal_counter; 1.305 + endgenerate 1.306 + 1.307 + always @(posedge CLK_I or posedge RST_I) 1.308 + if(RST_I) 1.309 + begin 1.310 + s_ack_pre <= #UDLY 1'b0; 1.311 + s_ack_dly <= #UDLY 1'b0; 1.312 + s_ack_2dly <= #UDLY 1'b0; 1.313 + end 1.314 + else 1.315 + begin 1.316 + s_ack_pre <= #UDLY S_STB_I && S_CYC_I; 1.317 + s_ack_dly <= #UDLY s_ack_pre; 1.318 + s_ack_2dly <= #UDLY s_ack_dly; 1.319 + end 1.320 + 1.321 + assign S_ACK_O = s_ack_dly & !s_ack_2dly; 1.322 + assign S_DAT_O = (dw00_cs & !S_WE_I & S_STB_I) ? read_00_data : 1.323 + (dw04_cs & !S_WE_I & S_STB_I) ? read_04_data : 1.324 + (dw08_cs & !S_WE_I & S_STB_I & WRITEABLE_PERIOD) ? read_08_data : 1.325 + (dw0c_cs & !S_WE_I & S_STB_I & READABLE_SNAPSHOT) ? read_0c_data : 1.326 + 32'h0; 1.327 + assign S_INT_O = reg_to; 1.328 + 1.329 + generate 1.330 + if (WATCHDOG == 1) 1.331 + always @(posedge CLK_I or posedge RST_I) begin 1.332 + if(RST_I) 1.333 + RSTREQ_O <= #UDLY 1'b0; 1.334 + else if(!(|internal_counter) && !RSTREQ_O && ((START_STOP_CONTROL == 0) || reg_run)) 1.335 + RSTREQ_O <= #UDLY 1'b1; 1.336 + else 1.337 + RSTREQ_O <= #UDLY 1'b0; 1.338 + end 1.339 + endgenerate 1.340 + 1.341 + 1.342 + generate 1.343 + if (TIMEOUT_PULSE == 1) 1.344 + //TOPULSE_O 1.345 + always @(posedge CLK_I or posedge RST_I) 1.346 + if(RST_I) 1.347 + TOPULSE_O <= #UDLY 1'b0; 1.348 + else if(!(|internal_counter) && !TOPULSE_O && ((START_STOP_CONTROL == 0) || reg_run)) 1.349 + TOPULSE_O <= #UDLY 1'b1; 1.350 + else 1.351 + TOPULSE_O <= #UDLY 1'b0; 1.352 + endgenerate 1.353 + 1.354 +endmodule 1.355 +`endif