Attention

This documentation is a work in progress. Expect to see errors and unfinished things.

phasex Source File

 1`timescale 1ns / 1ns
 2
 3// DMTD-inspired investigation into clock phasing
 4// No on-chip analysis, but that could be added later once we see the captured patterns
 5module phasex #(
 6     parameter aw=10
 7) (
 8     input uclk1,  // unknown clock 1
 9     input uclk2,  // unknown clock 2
10     input sclk,   // sampling clock
11     input rclk,   // readout clock (data transfer, local bus)
12     // all of the following are in rclk domain
13     input trig,
14     output ready,
15     input [aw-1:0] addr,
16     output [15:0] dout
17);
18
19// Move software-created trigger to sclk domain
20wire trig2;
21flag_xdomain trigx(.clk1(rclk), .flagin_clk1(trig),
22     .clk2(sclk), .flagout_clk2(trig2));
23
24// Dividers for snapshot operation
25reg div1=0, div2=0;
26always @(posedge uclk1) div1 <= ~div1;
27always @(posedge uclk2) div2 <= ~div2;
28
29// Control logic in sclk domain
30// aw bits row address, 3 bits to control stuffing of 8 bit-pairs into one 16-bit word
31reg [aw+2:0] count=0;
32reg run=0;
33always @(posedge sclk) begin
34     if (trig2) run <= 1;
35     if (run) count <= count+1;
36     if (&count) run <= 0;
37end
38wire wen = run & (&count[2:0]);
39wire [aw-1:0] waddr = count[aw+2:3];
40
41// Safely cross clock domains
42wire [1:0] snap;
43reg_tech_cdc #(.POST_STAGES(0)) snap1(.I(div1), .C(sclk), .O(snap[0]));
44reg_tech_cdc #(.POST_STAGES(0)) snap2(.I(div2), .C(sclk), .O(snap[1]));
45
46// Data flow logic, also in sclk domain
47reg [15:0] shiftr=0;
48always @(posedge sclk) begin
49     if (run) shiftr <= {shiftr[13:0], snap};
50end
51
52// Store the result
53dpram #(.aw(aw), .dw(16)) phmem(.clka(sclk), .clkb(rclk),
54     .addra(waddr), .dina(shiftr), .wena(wen),
55     .addrb(addr), .doutb(dout));
56
57// Single status bit, OK to capture in rclk domain
58reg ready_r=0;
59reg invalid=0;
60always @(posedge rclk) begin
61     ready_r <= ~run;  // safely crosses clock domain
62     if (trig) invalid <= 1;
63     if (~ready_r) invalid <= 0;
64end
65assign ready = ready_r & ~invalid;
66
67endmodule