srtc.v 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 13:33:14 02/09/2011
  7. // Design Name:
  8. // Module Name: 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 srtc(
  22. input clkin,
  23. input addr_in,
  24. input [3:0] data_in,
  25. output [7:0] data_out,
  26. input [59:0] rtc_data_in,
  27. output [59:0] rtc_data_out,
  28. input reg_we,
  29. input reg_oe,
  30. input enable,
  31. output rtc_we,
  32. input reset,
  33. /* DEBUG */
  34. output [4:0] srtc_state,
  35. output srtc_reg_we_rising,
  36. output [3:0] srtc_rtc_ptr,
  37. output [5:0] srtc_we_sreg
  38. );
  39. reg [59:0] rtc_data_r;
  40. reg [59:0] rtc_data_out_r;
  41. assign rtc_data_out = rtc_data_out_r;
  42. reg [3:0] rtc_ptr;
  43. reg [7:0] data_out_r;
  44. reg [4:0] mode_r;
  45. reg rtc_we_r;
  46. assign rtc_we = rtc_we_r;
  47. assign data_out = data_out_r;
  48. reg [5:0] reg_oe_sreg;
  49. always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe};
  50. wire reg_oe_falling = (reg_oe_sreg[5:1] == 5'b11110);
  51. wire reg_oe_rising = (reg_oe_sreg[5:1] == 5'b00001);
  52. reg [5:0] reg_we_sreg;
  53. always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we};
  54. wire reg_we_rising = (reg_we_sreg[5:1] == 5'b00001);
  55. reg [1:0] reset_sreg;
  56. always @(posedge clkin) reset_sreg <= {reset_sreg[0], reset};
  57. wire reset_rising = (reset_sreg[1:0] == 2'b01);
  58. reg[2:0] we_countdown_r;
  59. parameter SRTC_IDLE = 5'b00001;
  60. parameter SRTC_READ = 5'b00010;
  61. parameter SRTC_COMMAND = 5'b00100;
  62. parameter SRTC_WRITE = 5'b01000;
  63. parameter SRTC_WRITE2 = 5'b10000;
  64. reg [3:0] data_in_r;
  65. reg [3:0] addr_in_r;
  66. always @(posedge clkin) addr_in_r <= {addr_in_r[2:0], addr_in};
  67. assign srtc_reg_we_rising = reg_we_rising;
  68. assign srtc_state = mode_r;
  69. assign srtc_rtc_ptr = rtc_ptr;
  70. assign srtc_we_sreg = reg_we_sreg;
  71. initial begin
  72. rtc_we_r = 0;
  73. mode_r = SRTC_READ;
  74. rtc_ptr = 4'hf;
  75. data_out_r = 8'h00;
  76. end
  77. //always @(posedge clkin) data_in_r <= data_in;
  78. always @(posedge clkin) begin
  79. if(~reg_we) data_in_r <= data_in;
  80. end
  81. always @(posedge clkin) begin
  82. if(reset_rising) begin
  83. mode_r <= SRTC_READ;
  84. rtc_ptr <= 4'hf;
  85. end else if(reg_we_rising && enable) begin
  86. case (addr_in_r[0])
  87. // 1'b0: // data register is read only
  88. 1'b1: // control register
  89. case (data_in_r)
  90. 4'hd: begin
  91. mode_r <= SRTC_READ;
  92. rtc_ptr <= 4'hf;
  93. end
  94. 4'he: begin
  95. mode_r <= SRTC_COMMAND;
  96. end
  97. default: begin
  98. if(mode_r == SRTC_COMMAND) begin
  99. case (data_in_r)
  100. 4'h0: begin
  101. mode_r <= SRTC_WRITE;
  102. rtc_data_out_r <= rtc_data_in;
  103. rtc_ptr <= 4'h0;
  104. end
  105. 4'h4: begin
  106. mode_r <= SRTC_IDLE;
  107. rtc_ptr <= 4'hf;
  108. end
  109. default:
  110. mode_r <= SRTC_IDLE;
  111. endcase
  112. end else if(mode_r == SRTC_WRITE) begin
  113. rtc_ptr <= rtc_ptr + 1;
  114. case(rtc_ptr)
  115. 0: rtc_data_out_r[3:0] <= data_in_r;
  116. 1: rtc_data_out_r[7:4] <= data_in_r;
  117. 2: rtc_data_out_r[11:8] <= data_in_r;
  118. 3: rtc_data_out_r[15:12] <= data_in_r;
  119. 4: rtc_data_out_r[19:16] <= data_in_r;
  120. 5: rtc_data_out_r[23:20] <= data_in_r;
  121. 6: rtc_data_out_r[27:24] <= data_in_r;
  122. 7: rtc_data_out_r[31:28] <= data_in_r;
  123. 8: begin
  124. rtc_data_out_r[35:32] <= (data_in_r < 10)
  125. ? data_in_r
  126. : data_in_r - 10;
  127. rtc_data_out_r[39:36] <= data_in_r < 10 ? 0 : 1;
  128. end
  129. 9: rtc_data_out_r[43:40] <= data_in_r;
  130. 10: rtc_data_out_r[47:44] <= data_in_r;
  131. 11: begin
  132. rtc_data_out_r[51:48] <= (data_in_r < 10)
  133. ? data_in_r
  134. : data_in_r - 10;
  135. rtc_data_out_r[55:52] <= data_in_r < 10 ? 1 : 2;
  136. end
  137. endcase
  138. mode_r <= SRTC_WRITE2;
  139. we_countdown_r <= 4;
  140. rtc_we_r <= 1;
  141. end
  142. end
  143. endcase
  144. endcase
  145. end else if(reg_oe_falling && enable) begin
  146. case (addr_in_r[0])
  147. 1'b0: // read data register
  148. if(mode_r == SRTC_READ) begin
  149. case(rtc_ptr)
  150. 0: data_out_r <= rtc_data_r[3:0];
  151. 1: data_out_r <= rtc_data_r[7:4];
  152. 2: data_out_r <= rtc_data_r[11:8];
  153. 3: data_out_r <= rtc_data_r[15:12];
  154. 4: data_out_r <= rtc_data_r[19:16];
  155. 5: data_out_r <= rtc_data_r[23:20];
  156. 6: data_out_r <= rtc_data_r[27:24];
  157. 7: data_out_r <= rtc_data_r[31:28];
  158. 8: data_out_r <= rtc_data_r[35:32]
  159. + (rtc_data_r[39:36] << 1)
  160. + (rtc_data_r[39:36] << 3);
  161. 9: data_out_r <= rtc_data_r[43:40];
  162. 10: data_out_r <= rtc_data_r[47:44];
  163. 11: data_out_r <= rtc_data_r[51:48]
  164. + (rtc_data_r[55:52] << 1)
  165. + (rtc_data_r[55:52] << 3) - 10;
  166. 12: data_out_r <= rtc_data_r[59:56];
  167. // 14: mode_r <= SRTC_IDLE;
  168. 15: begin
  169. rtc_data_r <= rtc_data_in;
  170. data_out_r <= 8'h0f;
  171. end
  172. default: data_out_r <= 8'h0f;
  173. endcase
  174. rtc_ptr <= rtc_ptr == 13 ? 15 : rtc_ptr + 1;
  175. end else begin
  176. data_out_r <= 8'h00;
  177. end
  178. // 1'b1: // control register is write only
  179. endcase
  180. end else if(mode_r == SRTC_WRITE2) begin
  181. we_countdown_r <= we_countdown_r - 1;
  182. if (we_countdown_r == 3'b000) begin
  183. mode_r <= SRTC_WRITE;
  184. rtc_we_r <= 0;
  185. end
  186. end
  187. end
  188. endmodule