rtl/verilog/timer.v

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