rtc.v 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 23:32:12 01/08/2011
  7. // Design Name:
  8. // Module Name: rtc_srtc
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module rtc (
  22. input clkin,
  23. input pgm_we,
  24. input [55:0] rtc_data_in,
  25. input we1,
  26. input [59:0] rtc_data_in1,
  27. output [59:0] rtc_data
  28. );
  29. reg [59:0] rtc_data_r;
  30. reg [59:0] rtc_data_out_r;
  31. reg [1:0] pgm_we_sreg;
  32. always @(posedge clkin) pgm_we_sreg <= {pgm_we_sreg[0], pgm_we};
  33. wire pgm_we_rising = (pgm_we_sreg[1:0] == 2'b01);
  34. reg [2:0] we1_sreg;
  35. always @(posedge clkin) we1_sreg <= {we1_sreg[1:0], we1};
  36. wire we1_rising = (we1_sreg[2:1] == 2'b01);
  37. reg [31:0] tick_cnt;
  38. always @(posedge clkin) begin
  39. tick_cnt <= tick_cnt + 1;
  40. if((tick_cnt == 22000000) || pgm_we_rising) tick_cnt <= 0;
  41. end
  42. assign rtc_data = rtc_data_out_r;
  43. reg [21:0] rtc_state;
  44. reg carry;
  45. reg [3:0] dom1[11:0];
  46. reg [3:0] dom10[11:0];
  47. reg [3:0] month;
  48. reg [1:0] year;
  49. reg [4:0] dow_day;
  50. reg [3:0] dow_month;
  51. reg [13:0] dow_year;
  52. reg [6:0] dow_year1;
  53. reg [6:0] dow_year100;
  54. reg [15:0] dow_tmp;
  55. parameter [21:0]
  56. STATE_SEC1 = 22'b0000000000000000000001,
  57. STATE_SEC10 = 22'b0000000000000000000010,
  58. STATE_MIN1 = 22'b0000000000000000000100,
  59. STATE_MIN10 = 22'b0000000000000000001000,
  60. STATE_HOUR1 = 22'b0000000000000000010000,
  61. STATE_HOUR10 = 22'b0000000000000000100000,
  62. STATE_DAY1 = 22'b0000000000000001000000,
  63. STATE_DAY10 = 22'b0000000000000010000000,
  64. STATE_MON1 = 22'b0000000000000100000000,
  65. STATE_MON10 = 22'b0000000000001000000000,
  66. STATE_YEAR1 = 22'b0000000000010000000000,
  67. STATE_YEAR10 = 22'b0000000000100000000000,
  68. STATE_YEAR100 = 22'b0000000001000000000000,
  69. STATE_YEAR1000 = 22'b0000000010000000000000,
  70. STATE_DOW0 = 22'b0000000100000000000000,
  71. STATE_DOW1 = 22'b0000001000000000000000,
  72. STATE_DOW2 = 22'b0000010000000000000000,
  73. STATE_DOW3 = 22'b0000100000000000000000,
  74. STATE_DOW4 = 22'b0001000000000000000000,
  75. STATE_DOW5 = 22'b0010000000000000000000,
  76. STATE_LATCH = 22'b0100000000000000000000,
  77. STATE_IDLE = 22'b1000000000000000000000;
  78. initial begin
  79. rtc_state = STATE_IDLE;
  80. dom1[0] = 1; dom10[0] = 3;
  81. dom1[1] = 8; dom10[1] = 2;
  82. dom1[2] = 1; dom10[2] = 3;
  83. dom1[3] = 0; dom10[3] = 3;
  84. dom1[4] = 1; dom10[4] = 3;
  85. dom1[5] = 0; dom10[5] = 3;
  86. dom1[6] = 1; dom10[6] = 3;
  87. dom1[7] = 1; dom10[7] = 3;
  88. dom1[8] = 0; dom10[8] = 3;
  89. dom1[9] = 1; dom10[9] = 3;
  90. dom1[10] = 0; dom10[10] = 3;
  91. dom1[11] = 1; dom10[11] = 3;
  92. month = 0;
  93. rtc_data_r = 60'h220110301000000;
  94. tick_cnt = 0;
  95. end
  96. wire is_leapyear_feb = (month == 1) && (year[1:0] == 2'b00);
  97. always @(posedge clkin) begin
  98. if(!tick_cnt) begin
  99. rtc_state <= STATE_SEC1;
  100. end else begin
  101. case (rtc_state)
  102. STATE_SEC1:
  103. rtc_state <= STATE_SEC10;
  104. STATE_SEC10:
  105. rtc_state <= STATE_MIN1;
  106. STATE_MIN1:
  107. rtc_state <= STATE_MIN10;
  108. STATE_MIN10:
  109. rtc_state <= STATE_HOUR1;
  110. STATE_HOUR1:
  111. rtc_state <= STATE_HOUR10;
  112. STATE_HOUR10:
  113. rtc_state <= STATE_DAY1;
  114. STATE_DAY1:
  115. rtc_state <= STATE_DAY10;
  116. STATE_DAY10:
  117. rtc_state <= STATE_MON1;
  118. STATE_MON1:
  119. rtc_state <= STATE_MON10;
  120. STATE_MON10:
  121. rtc_state <= STATE_YEAR1;
  122. STATE_YEAR1:
  123. rtc_state <= STATE_YEAR10;
  124. STATE_YEAR10:
  125. rtc_state <= STATE_YEAR100;
  126. STATE_YEAR100:
  127. rtc_state <= STATE_YEAR1000;
  128. STATE_YEAR1000:
  129. rtc_state <= STATE_DOW0;
  130. STATE_DOW0:
  131. rtc_state <= STATE_DOW1;
  132. STATE_DOW1:
  133. rtc_state <= STATE_DOW2;
  134. STATE_DOW2:
  135. rtc_state <= STATE_DOW3;
  136. STATE_DOW3:
  137. rtc_state <= STATE_DOW4;
  138. STATE_DOW4:
  139. if(dow_tmp > 13)
  140. rtc_state <= STATE_DOW4;
  141. else
  142. rtc_state <= STATE_DOW5;
  143. STATE_DOW5:
  144. rtc_state <= STATE_LATCH;
  145. STATE_LATCH:
  146. rtc_state <= STATE_IDLE;
  147. default:
  148. rtc_state <= STATE_IDLE;
  149. endcase
  150. end
  151. end
  152. always @(posedge clkin) begin
  153. if(pgm_we_rising) begin
  154. rtc_data_r[55:0] <= rtc_data_in;
  155. end else if (we1_rising) begin
  156. rtc_data_r <= rtc_data_in1;
  157. end else begin
  158. case(rtc_state)
  159. STATE_SEC1: begin
  160. if(rtc_data_r[3:0] == 9) begin
  161. rtc_data_r[3:0] <= 0;
  162. carry <= 1;
  163. end else begin
  164. rtc_data_r[3:0] <= rtc_data_r[3:0] + 1;
  165. carry <= 0;
  166. end
  167. end
  168. STATE_SEC10: begin
  169. if(carry) begin
  170. if(rtc_data_r[7:4] == 5) begin
  171. rtc_data_r[7:4] <= 0;
  172. carry <= 1;
  173. end else begin
  174. rtc_data_r[7:4] <= rtc_data_r[7:4] + 1;
  175. carry <= 0;
  176. end
  177. end
  178. end
  179. STATE_MIN1: begin
  180. if(carry) begin
  181. if(rtc_data_r[11:8] == 9) begin
  182. rtc_data_r[11:8] <= 0;
  183. carry <= 1;
  184. end else begin
  185. rtc_data_r[11:8] <= rtc_data_r[11:8] + 1;
  186. carry <= 0;
  187. end
  188. end
  189. end
  190. STATE_MIN10: begin
  191. if(carry) begin
  192. if(rtc_data_r[15:12] == 5) begin
  193. rtc_data_r[15:12] <= 0;
  194. carry <= 1;
  195. end else begin
  196. rtc_data_r[15:12] <= rtc_data_r[15:12] + 1;
  197. carry <= 0;
  198. end
  199. end
  200. end
  201. STATE_HOUR1: begin
  202. if(carry) begin
  203. if(rtc_data_r[23:20] == 2 && rtc_data_r[19:16] == 3) begin
  204. rtc_data_r[19:16] <= 0;
  205. carry <= 1;
  206. end else if (rtc_data_r[19:16] == 9) begin
  207. rtc_data_r[19:16] <= 0;
  208. carry <= 1;
  209. end else begin
  210. rtc_data_r[19:16] <= rtc_data_r[19:16] + 1;
  211. carry <= 0;
  212. end
  213. end
  214. end
  215. STATE_HOUR10: begin
  216. if(carry) begin
  217. if(rtc_data_r[23:20] == 2) begin
  218. rtc_data_r[23:20] <= 0;
  219. carry <= 1;
  220. end else begin
  221. rtc_data_r[23:20] <= rtc_data_r[23:20] + 1;
  222. carry <= 0;
  223. end
  224. end
  225. end
  226. STATE_DAY1: begin
  227. if(carry) begin
  228. if(rtc_data_r[31:28] == dom10[month]
  229. && rtc_data_r[27:24] == dom1[month] + is_leapyear_feb) begin
  230. rtc_data_r[27:24] <= 0;
  231. carry <= 1;
  232. end else if (rtc_data_r[27:24] == 9) begin
  233. rtc_data_r[27:24] <= 0;
  234. carry <= 1;
  235. end else begin
  236. rtc_data_r[27:24] <= rtc_data_r[27:24] + 1;
  237. carry <= 0;
  238. end
  239. end
  240. end
  241. STATE_DAY10: begin
  242. if(carry) begin
  243. if(rtc_data_r[31:28] == dom10[month]) begin
  244. rtc_data_r[31:28] <= 0;
  245. rtc_data_r[27:24] <= 1;
  246. carry <= 1;
  247. end else begin
  248. rtc_data_r[31:28] <= rtc_data_r[31:28] + 1;
  249. carry <= 0;
  250. end
  251. end
  252. end
  253. STATE_MON1: begin
  254. if(carry) begin
  255. if(rtc_data_r[39:36] == 1 && rtc_data_r[35:32] == 2) begin
  256. rtc_data_r[35:32] <= 1;
  257. carry <= 1;
  258. end else if (rtc_data_r[35:32] == 9) begin
  259. rtc_data_r[35:32] <= 0;
  260. carry <= 1;
  261. end else begin
  262. rtc_data_r[35:32] <= rtc_data_r[35:32] + 1;
  263. carry <= 0;
  264. end
  265. end
  266. end
  267. STATE_MON10: begin
  268. if(carry) begin
  269. if(rtc_data_r[39:36] == 1) begin
  270. rtc_data_r[39:36] <= 0;
  271. carry <= 1;
  272. end else begin
  273. rtc_data_r[39:36] <= rtc_data_r[39:36] + 1;
  274. carry <= 0;
  275. end
  276. end
  277. end
  278. STATE_YEAR1: begin
  279. month <= rtc_data_r[35:32] + (rtc_data_r[36] ? 10 : 0) - 1;
  280. if(carry) begin
  281. if(rtc_data_r[43:40] == 9) begin
  282. rtc_data_r[43:40] <= 0;
  283. carry <= 1;
  284. end else begin
  285. rtc_data_r[43:40] <= rtc_data_r[43:40] + 1;
  286. carry <= 0;
  287. end
  288. end
  289. end
  290. STATE_YEAR10: begin
  291. if(carry) begin
  292. if(rtc_data_r[47:44] == 9) begin
  293. rtc_data_r[47:44] <= 0;
  294. carry <= 1;
  295. end else begin
  296. rtc_data_r[47:44] <= rtc_data_r[47:44] + 1;
  297. carry <= 0;
  298. end
  299. end
  300. end
  301. STATE_YEAR100: begin
  302. if(carry) begin
  303. if(rtc_data_r[51:48] == 9) begin
  304. rtc_data_r[51:48] <= 0;
  305. carry <= 1;
  306. end else begin
  307. rtc_data_r[51:48] <= rtc_data_r[51:48] + 1;
  308. carry <= 0;
  309. end
  310. end
  311. end
  312. STATE_YEAR1000: begin
  313. if(carry) begin
  314. if(rtc_data_r[55:52] == 9) begin
  315. rtc_data_r[55:52] <= 0;
  316. carry <= 1;
  317. end else begin
  318. rtc_data_r[55:52] <= rtc_data_r[55:52] + 1;
  319. carry <= 0;
  320. end
  321. end
  322. end
  323. STATE_DOW0: begin
  324. dow_year1 <= rtc_data_r[43:40]
  325. +(rtc_data_r[47:44] << 1) + (rtc_data_r[47:44] << 3);
  326. dow_year100 <= rtc_data_r[51:48]
  327. +(rtc_data_r[55:52] << 1) + (rtc_data_r[55:52] << 3);
  328. dow_month <= month + 1;
  329. dow_day <= rtc_data_r[27:24]
  330. + (rtc_data_r[31:28] << 1)
  331. + (rtc_data_r[31:28] << 3);
  332. end
  333. STATE_DOW1: begin
  334. year <= dow_year1[1:0];
  335. if(dow_month <= 2) begin
  336. dow_month <= dow_month + 10;
  337. dow_year <= dow_year1
  338. + (dow_year100 << 2)
  339. + (dow_year100 << 5)
  340. + (dow_year100 << 6) - 1;
  341. if(dow_year1)
  342. dow_year1 <= dow_year1 - 1;
  343. else begin
  344. dow_year1 <= 99;
  345. dow_year100 <= dow_year100 - 1;
  346. end
  347. end else begin
  348. dow_month <= dow_month - 2;
  349. dow_year <= dow_year1 + (dow_year100 << 2) + (dow_year100 << 5) + (dow_year100 << 6);
  350. end
  351. end
  352. STATE_DOW2: begin
  353. dow_tmp <= (83 * dow_month);
  354. end
  355. STATE_DOW3: begin
  356. dow_tmp <= (dow_tmp >> 5)
  357. + dow_day
  358. + dow_year
  359. + (dow_year >> 2)
  360. - (dow_year100)
  361. + (dow_year100 >> 2);
  362. end
  363. STATE_DOW4: begin
  364. dow_tmp <= dow_tmp - 7;
  365. end
  366. STATE_DOW5: begin
  367. rtc_data_r[59:56] <= {1'b0, dow_tmp[2:0]};
  368. end
  369. STATE_LATCH: begin
  370. rtc_data_out_r <= rtc_data_r;
  371. end
  372. endcase
  373. end
  374. end
  375. endmodule