Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top...
[debian/gnuradio] / usrp2 / fpga / control_lib / ss_rcvr.v
1
2
3 // Source-synchronous receiver
4 // Assumes both clocks are at the same rate
5 // Relative clock phase is
6 //    unknown
7 //    variable
8 //    bounded
9 // The output will come several cycles later than the input
10
11 // This should synthesize efficiently in Xilinx distributed ram cells,
12 //   which is why we use a buffer depth of 16
13
14 // FIXME Async reset on rxclk side?
15
16 module ss_rcvr
17   #(parameter WIDTH=16)
18     (input rxclk,
19      input sysclk,
20      input rst,
21      
22      input [WIDTH-1:0] data_in,
23      output [WIDTH-1:0] data_out,
24      output reg clock_present);
25    
26    wire [3:0] rd_addr, wr_addr;
27
28    // Distributed RAM
29    reg [WIDTH-1:0] buffer [0:15];
30    always @(posedge rxclk)
31      buffer[wr_addr] <= data_in;
32    
33    assign          data_out = buffer[rd_addr];
34    
35    // Write address generation
36    reg [3:0]       wr_counter;
37    always @(posedge rxclk or posedge rst)
38      if (rst)
39        wr_counter <= 0;
40      else
41        wr_counter <= wr_counter + 1;
42    
43    assign          wr_addr = {wr_counter[3], ^wr_counter[3:2], ^wr_counter[2:1], ^wr_counter[1:0]};
44    
45    // Read Address generation
46    wire [3:0]      wr_ctr_sys, diff, abs_diff;
47    reg [3:0]       wr_addr_sys_d1, wr_addr_sys_d2;
48    reg [3:0]       rd_counter;
49    
50    assign          rd_addr = {rd_counter[3], ^rd_counter[3:2], ^rd_counter[2:1], ^rd_counter[1:0]};
51    
52    always @(posedge sysclk)
53      wr_addr_sys_d1 <= wr_addr;
54    
55    always @(posedge sysclk)
56      wr_addr_sys_d2 <= wr_addr_sys_d1;
57    
58    assign          wr_ctr_sys = {wr_addr_sys_d2[3],^wr_addr_sys_d2[3:2],^wr_addr_sys_d2[3:1],^wr_addr_sys_d2[3:0]};
59    
60    assign          diff = wr_ctr_sys - rd_counter;
61    assign          abs_diff = diff[3] ? (~diff+1) : diff;
62    
63    always @(posedge sysclk)
64      if(rst)
65        begin
66           clock_present <= 0;
67           rd_counter <= 0;
68        end
69      else 
70        if(~clock_present)
71          if(abs_diff > 5)
72            clock_present <= 1;
73          else
74            ;
75        else
76          if(abs_diff<3)
77            clock_present <= 0;
78          else
79            rd_counter <= rd_counter + 1;
80
81 endmodule // ss_rcvr