mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-11-02 21:13:14 +00:00
133 lines
4.3 KiB
Verilog
133 lines
4.3 KiB
Verilog
//
|
|
// Copyright 2011 Ettus Research LLC
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
|
|
|
|
// AD9510 Register Map (from datasheet Rev. A)
|
|
|
|
/* INSTRUCTION word format (16 bits)
|
|
* 15 Read = 1, Write = 0
|
|
* 14:13 W1/W0, Number of bytes 00 - 1, 01 - 2, 10 - 3, 11 - stream
|
|
* 12:0 Address
|
|
*/
|
|
|
|
/* ADDR Contents Value (hex)
|
|
* 00 Serial Config Port 10 (def) -- MSB first, SDI/SDO separate
|
|
* 04 A Counter
|
|
* 05-06 B Counter
|
|
* 07-0A PLL Control
|
|
* 0B-0C R Divider
|
|
* 0D PLL Control
|
|
* 34-3A Fine Delay
|
|
* 3C-3F LVPECL Outs
|
|
* 40-43 LVDS/CMOS Outs
|
|
* 45 Clock select, power down
|
|
* 48-57 Dividers
|
|
* 58 Func and Sync
|
|
* 5A Update regs
|
|
*/
|
|
|
|
|
|
module clock_control
|
|
(input reset,
|
|
input aux_clk, // 25MHz, for before fpga clock is active
|
|
input clk_fpga, // real 100 MHz FPGA clock
|
|
output [1:0] clk_en, // controls source of reference clock
|
|
output [1:0] clk_sel, // controls source of reference clock
|
|
input clk_func, // FIXME needs to be some kind of out SYNC or reset to 9510
|
|
input clk_status, // Monitor PLL or SYNC status
|
|
|
|
output sen, // Enable for the AD9510
|
|
output sclk, // FIXME these need to be shared
|
|
input sdi,
|
|
output sdo
|
|
);
|
|
|
|
wire read = 1'b0; // Always write for now
|
|
wire [1:0] w = 2'b00; // Always send 1 byte at a time
|
|
|
|
assign clk_sel = 2'b00; // Both outputs from External Ref (SMA)
|
|
assign clk_en = 2'b11; // Both outputs enabled
|
|
|
|
reg [20:0] addr_data;
|
|
|
|
reg [5:0] entry;
|
|
reg start;
|
|
reg [7:0] counter;
|
|
reg [23:0] command;
|
|
|
|
always @*
|
|
case(entry)
|
|
6'd00 : addr_data = {13'h00,8'h10}; // Serial setup
|
|
6'd01 : addr_data = {13'h45,8'h00}; // CLK2 drives distribution, everything on
|
|
6'd02 : addr_data = {13'h3D,8'h80}; // Turn on output 1, normal levels
|
|
6'd03 : addr_data = {13'h4B,8'h80}; // Bypass divider 1 (div by 1)
|
|
6'd04 : addr_data = {13'h08,8'h47}; // POS PFD, Dig LK Det, Charge Pump normal
|
|
6'd05 : addr_data = {13'h09,8'h70}; // Max Charge Pump current
|
|
6'd06 : addr_data = {13'h0A,8'h04}; // Normal operation, Prescalar Div by 2, PLL On
|
|
6'd07 : addr_data = {13'h0B,8'h00}; // RDIV MSB (6 bits)
|
|
6'd08 : addr_data = {13'h0C,8'h01}; // RDIV LSB (8 bits), Div by 1
|
|
6'd09 : addr_data = {13'h0D,8'h00}; // Everything normal, Dig Lock Det
|
|
6'd10 : addr_data = {13'h07,8'h00}; // Disable LOR detect - LOR causes failure...
|
|
6'd11 : addr_data = {13'h04,8'h00}; // A Counter = Don't Care
|
|
6'd12 : addr_data = {13'h05,8'h00}; // B Counter MSB = 0
|
|
6'd13 : addr_data = {13'h06,8'h05}; // B Counter LSB = 5
|
|
default : addr_data = {13'h5A,8'h01}; // Register Update
|
|
endcase // case(entry)
|
|
|
|
wire [5:0] lastentry = 6'd15;
|
|
wire done = (counter == 8'd49);
|
|
|
|
always @(posedge aux_clk)
|
|
if(reset)
|
|
begin
|
|
entry <= #1 6'd0;
|
|
start <= #1 1'b1;
|
|
end
|
|
else if(start)
|
|
start <= #1 1'b0;
|
|
else if(done && (entry<lastentry))
|
|
begin
|
|
entry <= #1 entry + 6'd1;
|
|
start <= #1 1'b1;
|
|
end
|
|
|
|
always @(posedge aux_clk)
|
|
if(reset)
|
|
begin
|
|
counter <= #1 7'd0;
|
|
command <= #1 20'd0;
|
|
end
|
|
else if(start)
|
|
begin
|
|
counter <= #1 7'd1;
|
|
command <= #1 {read,w,addr_data};
|
|
end
|
|
else if( |counter && ~done )
|
|
begin
|
|
counter <= #1 counter + 7'd1;
|
|
if(~counter[0])
|
|
command <= {command[22:0],1'b0};
|
|
end
|
|
|
|
|
|
assign sen = (done | counter == 8'd0); // CSB is high when we're not doing anything
|
|
assign sclk = ~counter[0];
|
|
assign sdo = command[23];
|
|
|
|
endmodule // clock_control
|