123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- `timescale 1ns / 1ps
- //////////////////////////////////////////////////////////////////////////////////
- // Company:
- // Engineer:
- //
- // Create Date: 23:32:12 01/08/2011
- // Design Name:
- // Module Name: rtc_srtc
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies:
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //////////////////////////////////////////////////////////////////////////////////
- module rtc (
- input clkin,
- input pgm_we,
- input [55:0] rtc_data_in,
- input we1,
- input [59:0] rtc_data_in1,
- output [59:0] rtc_data
- );
- reg [59:0] rtc_data_r;
- reg [59:0] rtc_data_out_r;
- reg [1:0] pgm_we_sreg;
- always @(posedge clkin) pgm_we_sreg <= {pgm_we_sreg[0], pgm_we};
- wire pgm_we_rising = (pgm_we_sreg[1:0] == 2'b01);
- reg [2:0] we1_sreg;
- always @(posedge clkin) we1_sreg <= {we1_sreg[1:0], we1};
- wire we1_rising = (we1_sreg[2:1] == 2'b01);
- reg [31:0] tick_cnt;
- always @(posedge clkin) begin
- tick_cnt <= tick_cnt + 1;
- if((tick_cnt == 22000000) || pgm_we_rising) tick_cnt <= 0;
- end
- assign rtc_data = rtc_data_out_r;
- reg [21:0] rtc_state;
- reg carry;
- reg [3:0] dom1[11:0];
- reg [3:0] dom10[11:0];
- reg [3:0] month;
- reg [1:0] year;
- reg [4:0] dow_day;
- reg [3:0] dow_month;
- reg [13:0] dow_year;
- reg [6:0] dow_year1;
- reg [6:0] dow_year100;
- reg [15:0] dow_tmp;
- parameter [21:0]
- STATE_SEC1 = 22'b0000000000000000000001,
- STATE_SEC10 = 22'b0000000000000000000010,
- STATE_MIN1 = 22'b0000000000000000000100,
- STATE_MIN10 = 22'b0000000000000000001000,
- STATE_HOUR1 = 22'b0000000000000000010000,
- STATE_HOUR10 = 22'b0000000000000000100000,
- STATE_DAY1 = 22'b0000000000000001000000,
- STATE_DAY10 = 22'b0000000000000010000000,
- STATE_MON1 = 22'b0000000000000100000000,
- STATE_MON10 = 22'b0000000000001000000000,
- STATE_YEAR1 = 22'b0000000000010000000000,
- STATE_YEAR10 = 22'b0000000000100000000000,
- STATE_YEAR100 = 22'b0000000001000000000000,
- STATE_YEAR1000 = 22'b0000000010000000000000,
- STATE_DOW0 = 22'b0000000100000000000000,
- STATE_DOW1 = 22'b0000001000000000000000,
- STATE_DOW2 = 22'b0000010000000000000000,
- STATE_DOW3 = 22'b0000100000000000000000,
- STATE_DOW4 = 22'b0001000000000000000000,
- STATE_DOW5 = 22'b0010000000000000000000,
- STATE_LATCH = 22'b0100000000000000000000,
- STATE_IDLE = 22'b1000000000000000000000;
- initial begin
- rtc_state = STATE_IDLE;
- dom1[0] = 1; dom10[0] = 3;
- dom1[1] = 8; dom10[1] = 2;
- dom1[2] = 1; dom10[2] = 3;
- dom1[3] = 0; dom10[3] = 3;
- dom1[4] = 1; dom10[4] = 3;
- dom1[5] = 0; dom10[5] = 3;
- dom1[6] = 1; dom10[6] = 3;
- dom1[7] = 1; dom10[7] = 3;
- dom1[8] = 0; dom10[8] = 3;
- dom1[9] = 1; dom10[9] = 3;
- dom1[10] = 0; dom10[10] = 3;
- dom1[11] = 1; dom10[11] = 3;
- month = 0;
- rtc_data_r = 60'h220110301000000;
- tick_cnt = 0;
- end
- wire is_leapyear_feb = (month == 1) && (year[1:0] == 2'b00);
- always @(posedge clkin) begin
- if(!tick_cnt) begin
- rtc_state <= STATE_SEC1;
- end else begin
- case (rtc_state)
- STATE_SEC1:
- rtc_state <= STATE_SEC10;
- STATE_SEC10:
- rtc_state <= STATE_MIN1;
- STATE_MIN1:
- rtc_state <= STATE_MIN10;
- STATE_MIN10:
- rtc_state <= STATE_HOUR1;
- STATE_HOUR1:
- rtc_state <= STATE_HOUR10;
- STATE_HOUR10:
- rtc_state <= STATE_DAY1;
- STATE_DAY1:
- rtc_state <= STATE_DAY10;
- STATE_DAY10:
- rtc_state <= STATE_MON1;
- STATE_MON1:
- rtc_state <= STATE_MON10;
- STATE_MON10:
- rtc_state <= STATE_YEAR1;
- STATE_YEAR1:
- rtc_state <= STATE_YEAR10;
- STATE_YEAR10:
- rtc_state <= STATE_YEAR100;
- STATE_YEAR100:
- rtc_state <= STATE_YEAR1000;
- STATE_YEAR1000:
- rtc_state <= STATE_DOW0;
- STATE_DOW0:
- rtc_state <= STATE_DOW1;
- STATE_DOW1:
- rtc_state <= STATE_DOW2;
- STATE_DOW2:
- rtc_state <= STATE_DOW3;
- STATE_DOW3:
- rtc_state <= STATE_DOW4;
- STATE_DOW4:
- if(dow_tmp > 13)
- rtc_state <= STATE_DOW4;
- else
- rtc_state <= STATE_DOW5;
- STATE_DOW5:
- rtc_state <= STATE_LATCH;
- STATE_LATCH:
- rtc_state <= STATE_IDLE;
- default:
- rtc_state <= STATE_IDLE;
- endcase
- end
- end
- always @(posedge clkin) begin
- if(pgm_we_rising) begin
- rtc_data_r[55:0] <= rtc_data_in;
- end else if (we1_rising) begin
- rtc_data_r <= rtc_data_in1;
- end else begin
- case(rtc_state)
- STATE_SEC1: begin
- if(rtc_data_r[3:0] == 9) begin
- rtc_data_r[3:0] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[3:0] <= rtc_data_r[3:0] + 1;
- carry <= 0;
- end
- end
- STATE_SEC10: begin
- if(carry) begin
- if(rtc_data_r[7:4] == 5) begin
- rtc_data_r[7:4] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[7:4] <= rtc_data_r[7:4] + 1;
- carry <= 0;
- end
- end
- end
- STATE_MIN1: begin
- if(carry) begin
- if(rtc_data_r[11:8] == 9) begin
- rtc_data_r[11:8] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[11:8] <= rtc_data_r[11:8] + 1;
- carry <= 0;
- end
- end
- end
- STATE_MIN10: begin
- if(carry) begin
- if(rtc_data_r[15:12] == 5) begin
- rtc_data_r[15:12] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[15:12] <= rtc_data_r[15:12] + 1;
- carry <= 0;
- end
- end
- end
- STATE_HOUR1: begin
- if(carry) begin
- if(rtc_data_r[23:20] == 2 && rtc_data_r[19:16] == 3) begin
- rtc_data_r[19:16] <= 0;
- carry <= 1;
- end else if (rtc_data_r[19:16] == 9) begin
- rtc_data_r[19:16] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[19:16] <= rtc_data_r[19:16] + 1;
- carry <= 0;
- end
- end
- end
- STATE_HOUR10: begin
- if(carry) begin
- if(rtc_data_r[23:20] == 2) begin
- rtc_data_r[23:20] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[23:20] <= rtc_data_r[23:20] + 1;
- carry <= 0;
- end
- end
- end
- STATE_DAY1: begin
- if(carry) begin
- if(rtc_data_r[31:28] == dom10[month]
- && rtc_data_r[27:24] == dom1[month] + is_leapyear_feb) begin
- rtc_data_r[27:24] <= 0;
- carry <= 1;
- end else if (rtc_data_r[27:24] == 9) begin
- rtc_data_r[27:24] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[27:24] <= rtc_data_r[27:24] + 1;
- carry <= 0;
- end
- end
- end
- STATE_DAY10: begin
- if(carry) begin
- if(rtc_data_r[31:28] == dom10[month]) begin
- rtc_data_r[31:28] <= 0;
- rtc_data_r[27:24] <= 1;
- carry <= 1;
- end else begin
- rtc_data_r[31:28] <= rtc_data_r[31:28] + 1;
- carry <= 0;
- end
- end
- end
- STATE_MON1: begin
- if(carry) begin
- if(rtc_data_r[39:36] == 1 && rtc_data_r[35:32] == 2) begin
- rtc_data_r[35:32] <= 1;
- carry <= 1;
- end else if (rtc_data_r[35:32] == 9) begin
- rtc_data_r[35:32] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[35:32] <= rtc_data_r[35:32] + 1;
- carry <= 0;
- end
- end
- end
- STATE_MON10: begin
- if(carry) begin
- if(rtc_data_r[39:36] == 1) begin
- rtc_data_r[39:36] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[39:36] <= rtc_data_r[39:36] + 1;
- carry <= 0;
- end
- end
- end
- STATE_YEAR1: begin
- month <= rtc_data_r[35:32] + (rtc_data_r[36] ? 10 : 0) - 1;
- if(carry) begin
- if(rtc_data_r[43:40] == 9) begin
- rtc_data_r[43:40] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[43:40] <= rtc_data_r[43:40] + 1;
- carry <= 0;
- end
- end
- end
- STATE_YEAR10: begin
- if(carry) begin
- if(rtc_data_r[47:44] == 9) begin
- rtc_data_r[47:44] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[47:44] <= rtc_data_r[47:44] + 1;
- carry <= 0;
- end
- end
- end
- STATE_YEAR100: begin
- if(carry) begin
- if(rtc_data_r[51:48] == 9) begin
- rtc_data_r[51:48] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[51:48] <= rtc_data_r[51:48] + 1;
- carry <= 0;
- end
- end
- end
- STATE_YEAR1000: begin
- if(carry) begin
- if(rtc_data_r[55:52] == 9) begin
- rtc_data_r[55:52] <= 0;
- carry <= 1;
- end else begin
- rtc_data_r[55:52] <= rtc_data_r[55:52] + 1;
- carry <= 0;
- end
- end
- end
- STATE_DOW0: begin
- dow_year1 <= rtc_data_r[43:40]
- +(rtc_data_r[47:44] << 1) + (rtc_data_r[47:44] << 3);
- dow_year100 <= rtc_data_r[51:48]
- +(rtc_data_r[55:52] << 1) + (rtc_data_r[55:52] << 3);
- dow_month <= month + 1;
- dow_day <= rtc_data_r[27:24]
- + (rtc_data_r[31:28] << 1)
- + (rtc_data_r[31:28] << 3);
- end
- STATE_DOW1: begin
- year <= dow_year1[1:0];
- if(dow_month <= 2) begin
- dow_month <= dow_month + 10;
- dow_year <= dow_year1
- + (dow_year100 << 2)
- + (dow_year100 << 5)
- + (dow_year100 << 6) - 1;
- if(dow_year1)
- dow_year1 <= dow_year1 - 1;
- else begin
- dow_year1 <= 99;
- dow_year100 <= dow_year100 - 1;
- end
- end else begin
- dow_month <= dow_month - 2;
- dow_year <= dow_year1 + (dow_year100 << 2) + (dow_year100 << 5) + (dow_year100 << 6);
- end
- end
- STATE_DOW2: begin
- dow_tmp <= (83 * dow_month);
- end
- STATE_DOW3: begin
- dow_tmp <= (dow_tmp >> 5)
- + dow_day
- + dow_year
- + (dow_year >> 2)
- - (dow_year100)
- + (dow_year100 >> 2);
- end
- STATE_DOW4: begin
- dow_tmp <= dow_tmp - 7;
- end
- STATE_DOW5: begin
- rtc_data_r[59:56] <= {1'b0, dow_tmp[2:0]};
- end
- STATE_LATCH: begin
- rtc_data_out_r <= rtc_data_r;
- end
- endcase
- end
- end
- endmodule
|