4 (input wb_clk_i, input rst_i,
5 input cyc_i, input stb_i, input [2:0] adr_i,
6 input we_i, input [31:0] dat_i, output [31:0] dat_o, output ack_o,
7 input sys_clk_i, output [31:0] master_time_o,
8 input pps_posedge, input pps_negedge,
9 input exp_pps_in, output exp_pps_out,
14 wire [31:0] master_time_rcvd;
15 reg [31:0] master_time;
16 reg [31:0] delta_time;
19 wire sync_rcvd, pps_ext;
20 reg [31:0] tick_time, tick_time_wb;
22 reg tick_int_enable, tick_source, external_sync;
23 reg [31:0] tick_interval;
28 // Generate master time
29 always @(posedge sys_clk_i)
32 else if(external_sync & sync_rcvd)
33 master_time <= master_time_rcvd + delta_time;
34 else if(pps_ext & (sync_on_next_pps|sync_every_pps))
37 master_time <= master_time + 1;
38 assign master_time_o = master_time;
40 time_sender time_sender
41 (.clk(sys_clk_i),.rst(rst_i),
42 .master_time(master_time),
43 .send_sync(internal_tick),
44 .exp_pps_out(exp_pps_out) );
46 time_receiver time_receiver
47 (.clk(sys_clk_i),.rst(rst_i),
48 .master_time(master_time_rcvd),
49 .sync_rcvd(sync_rcvd),
50 .exp_pps_in(exp_pps_in) );
53 wire wb_write = cyc_i & stb_i & we_i;
54 wire wb_read = cyc_i & stb_i & ~we_i;
55 wire wb_acc = cyc_i & stb_i;
57 always @(posedge wb_clk_i)
63 tick_interval <= 100000-1; // default to 1K times per second
72 tick_source <= dat_i[0];
73 tick_int_enable <= dat_i[1];
74 external_sync <= dat_i[2];
76 sync_every_pps <= dat_i[4];
79 tick_interval <= dat_i;
84 // Do nothing here, this is to arm the sync_on_next
85 endcase // case(adr_i[2:0])
87 always @(posedge sys_clk_i)
89 sync_on_next_pps <= 0;
91 sync_on_next_pps <= 0;
92 else if(wb_write & (adr_i[2:0] == 3))
93 sync_on_next_pps <= 1;
95 always @(posedge sys_clk_i)
97 tick_time <= master_time;
99 always @(posedge wb_clk_i)
100 tick_time_wb <= tick_time;
102 assign dat_o = tick_time_wb;
104 always @(posedge sys_clk_i)
105 internal_tick <= (tick_source == 0) ? tick_free_run : pps_ext;
108 always @(posedge sys_clk_i)
111 else if(tick_free_run)
114 counter <= counter + 1;
115 assign tick_free_run = (counter >= tick_interval);
117 // Properly Latch and edge detect External PPS input
118 reg pps_in_d1, pps_in_d2;
119 always @(posedge sys_clk_i)
121 pps_in_d1 <= pps_edge ? pps_posedge : pps_negedge;
122 pps_in_d2 <= pps_in_d1;
124 assign pps_ext = pps_in_d1 & ~pps_in_d2;
126 always @(posedge sys_clk_i)
129 // Need to register this?
130 reg internal_tick_d1;
131 always @(posedge sys_clk_i) internal_tick_d1 <= internal_tick;
133 always @(posedge wb_clk_i)
137 else if(tick_int_enable & (internal_tick | internal_tick_d1))
142 always @(posedge sys_clk_i)
146 epoch_o <= (master_time_o[27:0] == 0);
147 endmodule // time_sync