copied over old one which works with icarus
[debian/gnuradio] / usrp2 / fpga / control_lib / clock_control.v
1
2
3 // AD9510 Register Map (from datasheet Rev. A)
4
5 /* INSTRUCTION word format (16 bits)
6  * 15       Read = 1, Write = 0
7  * 14:13    W1/W0,  Number of bytes 00 - 1, 01 - 2, 10 - 3, 11 - stream
8  * 12:0     Address
9  */
10
11 /* ADDR     Contents             Value (hex)
12  * 00       Serial Config Port   10 (def) -- MSB first, SDI/SDO separate
13  * 04       A Counter
14  * 05-06    B Counter
15  * 07-0A    PLL Control
16  * 0B-0C    R Divider
17  * 0D       PLL Control
18  * 34-3A    Fine Delay
19  * 3C-3F    LVPECL Outs
20  * 40-43    LVDS/CMOS Outs
21  * 45       Clock select, power down
22  * 48-57    Dividers
23  * 58       Func and Sync
24  * 5A       Update regs
25  */
26
27
28 module clock_control
29   (input reset,
30    input aux_clk,            // 25MHz, for before fpga clock is active
31    input clk_fpga,           // real 100 MHz FPGA clock
32    output [1:0] clk_en,      // controls source of reference clock
33    output [1:0] clk_sel,     // controls source of reference clock
34    input clk_func,          // FIXME needs to be some kind of out SYNC or reset to 9510
35    input clk_status,         // Monitor PLL or SYNC status
36    
37    output sen,        // Enable for the AD9510
38    output sclk,       // FIXME these need to be shared
39    input sdi,
40    output sdo
41    );
42    
43    wire   read = 1'b0;    // Always write for now
44    wire [1:0] w = 2'b00;  // Always send 1 byte at a time
45    
46    assign     clk_sel = 2'b00;  // Both outputs from External Ref (SMA)
47    assign     clk_en = 2'b11;   // Both outputs enabled
48    
49    reg [20:0] addr_data;
50
51    reg [5:0]  entry;
52    reg        start;
53    reg [7:0]  counter;
54    reg [23:0] command;
55    
56    always @*
57      case(entry)
58        6'd00 : addr_data = {13'h00,8'h10};   // Serial setup
59        6'd01 : addr_data = {13'h45,8'h00};   // CLK2 drives distribution, everything on
60        6'd02 : addr_data = {13'h3D,8'h80};   // Turn on output 1, normal levels
61        6'd03 : addr_data = {13'h4B,8'h80};   // Bypass divider 1 (div by 1)
62        6'd04 : addr_data = {13'h08,8'h47};   // POS PFD, Dig LK Det, Charge Pump normal 
63        6'd05 : addr_data = {13'h09,8'h70};   // Max Charge Pump current
64        6'd06 : addr_data = {13'h0A,8'h04};   // Normal operation, Prescalar Div by 2, PLL On
65        6'd07 : addr_data = {13'h0B,8'h00};   // RDIV MSB (6 bits)
66        6'd08 : addr_data = {13'h0C,8'h01};   // RDIV LSB (8 bits), Div by 1
67        6'd09 : addr_data = {13'h0D,8'h00};   // Everything normal, Dig Lock Det
68        6'd10 : addr_data = {13'h07,8'h00};      // Disable LOR detect - LOR causes failure...
69        6'd11 : addr_data = {13'h04,8'h00};      // A Counter = Don't Care
70        6'd12 : addr_data = {13'h05,8'h00};      // B Counter MSB = 0
71        6'd13 : addr_data = {13'h06,8'h05};   // B Counter LSB = 5
72        default : addr_data = {13'h5A,8'h01}; // Register Update
73      endcase // case(entry)
74
75    wire [5:0]  lastentry = 6'd15;
76    wire        done = (counter == 8'd49);
77    
78    always @(posedge aux_clk)
79      if(reset)
80        begin
81           entry <= #1 6'd0;
82           start <= #1 1'b1;
83        end
84      else if(start)
85        start <= #1 1'b0;
86      else if(done && (entry<lastentry))
87        begin
88           entry <= #1 entry + 6'd1;
89           start <= #1 1'b1;
90        end
91    
92    always @(posedge aux_clk)
93      if(reset)
94        begin
95           counter <= #1 7'd0;
96           command <= #1 20'd0;
97        end
98      else if(start)
99        begin
100           counter <= #1 7'd1;
101           command <= #1 {read,w,addr_data};
102        end
103      else if( |counter && ~done )
104        begin
105           counter <= #1 counter + 7'd1;
106           if(~counter[0])
107             command <= {command[22:0],1'b0};
108        end
109    
110    
111    assign sen = (done | counter == 8'd0);  // CSB is high when we're not doing anything
112    assign sclk = ~counter[0];
113    assign sdo = command[23];
114    
115 endmodule // clock_control