x393  1.0
FPGAcodeforElphelNC393camera
rtc393.v
Go to the documentation of this file.
1 
41 `timescale 1ns/1ps
42 
43 module rtc393 #(
44  parameter RTC_ADDR = 'h704, //..'h707
45  parameter RTC_STATUS_REG_ADDR = 'h31, // address where status can be read out (currently just sequence # and alternating bit)
46  parameter RTC_SEC_USEC_ADDR = 'h32, //'h33 address where seconds of the snapshot can be read (microseconds - next address)
47 
48  parameter RTC_MASK = 'h7fc,
49  parameter RTC_MHZ = 25, // RTC input clock in MHz (should be interger number)
50  parameter RTC_BITC_PREDIV = 5, // number of bits to generate 2 MHz pulses counting refclk
51  parameter RTC_SET_USEC = 0, // 20-bit number of microseconds
52  parameter RTC_SET_SEC = 1, // 32-bit full number of seconds (and actually update timer)
53  parameter RTC_SET_CORR = 2, // write correction 16-bit signed
54  parameter RTC_SET_STATUS = 3 // set status mode, and take a time snapshot (wait response and read time)
55 
56 ) (
57 // input rst,
58  input mclk,
59  input mrst, // @ posedge mclk - sync reset
60 
61  input refclk, // not a global clock, reference frequency < mclk/2
62  // programming interface
63  input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
64  input cmd_stb, // strobe (with first byte) for the command a/d
65 
66  output [7:0] status_ad, // status address/data - up to 5 bytes: A - {seq,status[1:0]} - status[2:9] - status[10:17] - status[18:25]
67  output status_rq, // input request to send status downstream
68  input status_start, // Acknowledge of the first status packet byte (address)
69 
70  output [31:0] live_sec,
71  output [19:0] live_usec);
72 // output reg snap); // take a snapshot (externally)
73 
74  wire [31:0] cmd_data;
75  wire [1:0] cmd_a;
76  wire cmd_we;
77 
78  wire set_usec_w;
79  wire set_sec_w;
80  wire set_corr_w;
82 
83  reg [19:0] wusec;
84  reg [31:0] wsec;
85  reg [15:0] corr;
86 
87  reg [RTC_BITC_PREDIV-1:0] pre_cntr = 0;
88  reg [3:0] halfusec = 0; // 1-hot running pulse with 0.5 usec period
89  reg [2:0] refclk_mclk;
91  reg enable_rtc=0;
93  reg set_cntr; // valid for the full 0.5 usec
94  reg [23:0] acc;
95  wire [24:0] next_acc;
96  reg [1:0] inc_usec;
97  reg [1:0] inc_sec;
98 
99  reg [19:0] usec;
100  reg [31:0] sec;
101 
102  reg [19:0] usec_plus1;
103  reg [31:0] sec_plus1;
104 
105  reg [31:0] pio_sec; // seconds snapshot to be read as PIO
106  reg [19:0] pio_usec; // micro seconds snapshot to be read as PIO
107  reg pio_alt_snap; // FF to invert after each PIO snapshot (used to generate status)
108 
109 
110  assign set_usec_w = cmd_we && (cmd_a == RTC_SET_USEC);
111  assign set_sec_w = cmd_we && (cmd_a == RTC_SET_SEC);
112  assign set_corr_w = cmd_we && (cmd_a == RTC_SET_CORR);
113  assign set_status_w = cmd_we && (cmd_a == RTC_SET_STATUS);
114  assign next_acc[24:0]= {1'b0,acc[23:0]} + {1'b0,~corr [15], {7{corr [15]}}, corr[15:0]};
115 
116  assign live_sec = sec;
117  assign live_usec = usec;
118 
119  always @ (posedge mclk) begin
120  if (mrst) pio_alt_snap <= 0;
121  else if (set_status_w) pio_alt_snap <= ~pio_alt_snap;
122  end
123 
124  always @ (posedge mclk) begin
125  if (set_status_w) pio_sec <= live_sec;
127  end
128 
129  always @ (posedge mclk) begin
130  if (set_usec_w) wusec <= cmd_data[19:0];
131  if (set_sec_w) wsec <= cmd_data[31:0];
132  if (set_corr_w) corr <= cmd_data[15:0];
133  end
134 
135  always @ (posedge mclk) begin
136  if (mrst) enable_rtc <= 0;
137  else if (set_sec_w) enable_rtc <= 1;
138  end
139 
140  always @ (posedge mclk) begin
141 
142  if (!enable_rtc || halfusec[0]) pre_cntr <= RTC_MHZ-2;
143  else if (refclk2x_mclk) pre_cntr <= pre_cntr - 1;
144 
145  if (!enable_rtc) halfusec <= 0;
146  else halfusec <= {halfusec[2:0], (|pre_cntr || !refclk2x_mclk)?1'b0:1'b1};
147 
148  if (set_usec_w) pend_set_cntr <= 1'b0; // just to get rid of undefined
149  if (set_sec_w) pend_set_cntr <= 1'b1;
150  else if (halfusec[3])pend_set_cntr <= 1'b0;
151 
152 
153  refclk_mclk <= {refclk_mclk[1:0], refclk};
155 
156  if (halfusec[1]) acc[23:0] <= set_cntr?24'h0:next_acc[23:0];
157 
158  if (!enable_rtc) set_cntr <= 1'b0;
159  else if (halfusec[3]) set_cntr <= pend_set_cntr;
160 
161 
162  inc_usec <= {inc_usec[0],halfusec[1] & next_acc[24]};
163  inc_sec <= {inc_sec[0], halfusec[1] & next_acc[24] & ((usec[19:0]==20'hf423f)?1'b1:1'b0)};
164 
165  sec_plus1 <= sec + 1;
166  usec_plus1 <= usec + 1;
167 
168  if (set_cntr) usec[19:0] <= wusec[19:0];
169  else if (inc_sec[1]) usec[19:0] <= 20'h0;
170  else if (inc_usec[1]) usec[19:0] <= usec_plus1[19:0];
171 
172  if (set_cntr) sec[31:0] <= wsec[31:0];
173  else if (inc_sec[1]) sec[31:0] <= sec_plus1[31:0];
174 
175  end
176 
178  .ADDR (RTC_ADDR),
179  .ADDR_MASK (RTC_MASK),
180  .NUM_CYCLES (6),
181  .ADDR_WIDTH (2),
182  .DATA_WIDTH (32)
183  ) cmd_deser_32bit_i (
184  .rst (1'b0), //rst), // input
185  .clk (mclk), // input
186  .srst (mrst), // input
187  .ad (cmd_ad), // input[7:0]
188  .stb (cmd_stb), // input
189  .addr (cmd_a), // output[3:0]
190  .data (cmd_data), // output[31:0]
191  .we (cmd_we) // output
192  );
193 
195  .STATUS_REG_ADDR (RTC_STATUS_REG_ADDR),
196  .PAYLOAD_BITS (1),
197  .REGISTER_STATUS (0),
198  .EXTRA_WORDS (2),
199  .EXTRA_REG_ADDR (RTC_SEC_USEC_ADDR)
200  ) status_generate_i (
201  .rst (1'b0), // rst), // input
202  .clk (mclk), // input
203  .srst (mrst), // input
204  .we (set_status_w), // input
205  .wd (cmd_data[7:0]), // input[7:0]
206  .status ({12'b0,pio_usec,pio_sec,pio_alt_snap}), // input[14:0]
207  .ad (status_ad), // output[7:0]
208  .rq (status_rq), // output
209  .start (status_start) // input
210  );
211 
212 
213 
214 endmodule
215 
status_generate_i status_generate
Definition: rtc393.v:194
9556RTC_ADDR'h704
Definition: rtc393.v:44
9565RTC_SET_STATUS3
Definition: rtc393.v:54
Definition: rtc393.v:43
9583wusecreg[19:0]
Definition: rtc393.v:83
9597usecreg[19:0]
Definition: rtc393.v:99
9590enable_rtcreg
Definition: rtc393.v:91
9600sec_plus1reg[31:0]
Definition: rtc393.v:103
9584wsecreg[31:0]
Definition: rtc393.v:84
9562RTC_SET_USEC0
Definition: rtc393.v:51
9558RTC_SEC_USEC_ADDR'h32
Definition: rtc393.v:46
9602pio_usecreg[19:0]
Definition: rtc393.v:106
9594next_accwire[24:0]
Definition: rtc393.v:95
[7:0] 9569cmd_ad
Definition: rtc393.v:63
9595inc_usecreg[1:0]
Definition: rtc393.v:96
9598secreg[31:0]
Definition: rtc393.v:100
9589refclk2x_mclkreg
Definition: rtc393.v:90
9599usec_plus1reg[19:0]
Definition: rtc393.v:102
[7:0] 9571status_ad
Definition: rtc393.v:66
9579set_usec_wwire
Definition: rtc393.v:78
9592set_cntrreg
Definition: rtc393.v:93
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
Definition: cmd_deser.v:60
9580set_sec_wwire
Definition: rtc393.v:79
[19:0] 9575live_usec
Definition: rtc393.v:71
9596inc_secreg[1:0]
Definition: rtc393.v:97
9563RTC_SET_SEC1
Definition: rtc393.v:52
9577cmd_awire[1:0]
Definition: rtc393.v:75
9582set_status_wwire
Definition: rtc393.v:81
9586pre_cntrreg[RTC_BITC_PREDIV-1:0]
Definition: rtc393.v:87
9566mclk
Definition: rtc393.v:58
[31:0] 9574live_sec
Definition: rtc393.v:70
9573status_start
Definition: rtc393.v:68
[DATA_WIDTH-1:0] 9934data
Definition: cmd_deser.v:59
9559RTC_MASK'h7fc
Definition: rtc393.v:48
9561RTC_BITC_PREDIV5
Definition: rtc393.v:50
9585corrreg[15:0]
Definition: rtc393.v:85
9591pend_set_cntrreg
Definition: rtc393.v:92
9576cmd_datawire[31:0]
Definition: rtc393.v:74
9593accreg[23:0]
Definition: rtc393.v:94
[7:0] 9931ad
Definition: cmd_deser.v:56
[ADDR_WIDTH-1:0] 9933addr
Definition: cmd_deser.v:58
9601pio_secreg[31:0]
Definition: rtc393.v:105
9588refclk_mclkreg[2:0]
Definition: rtc393.v:89
9603pio_alt_snapreg
Definition: rtc393.v:107
9560RTC_MHZ25
Definition: rtc393.v:49
9587halfusecreg[3:0]
Definition: rtc393.v:88
9564RTC_SET_CORR2
Definition: rtc393.v:53
9572status_rq
Definition: rtc393.v:67
9567mrst
Definition: rtc393.v:59
cmd_deser_32bit_i cmd_deser
Definition: rtc393.v:177
9568refclk
Definition: rtc393.v:61
9578cmd_wewire
Definition: rtc393.v:76
[ALL_BITS-1:0] 10777status
9581set_corr_wwire
Definition: rtc393.v:80
9570cmd_stb
Definition: rtc393.v:64
9557RTC_STATUS_REG_ADDR'h31
Definition: rtc393.v:45