`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 11:51:06 06/08/2020 // Design Name: // Module Name: test_784TR_top // Project Name: // Target Devices: // Tool versions: // Description: // ??????9?byte? ?1-8?????????????????8???????????????????3?byte???5?don't care?? // ?9byte??4bit??spi??4bit?????? // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// /*************?????????*******************/ module adf4351_2( input i_sysclk , input i_arstn , output o_cfgover , output o_ADF4351_SCK , output o_ADF4351_DATA , output o_ADF4351_LE , output o_ADF4351_CE , output o_ADF4351_mutel , input i_ADF4351_locked ); localparam DATA_WIDTH = 32; localparam DATA_LENTH = 6; localparam SYS_CLOCK = 10; localparam LOCK_PIRED = SYS_CLOCK * 100000; localparam rst_time = 16'h7fff;//16'h7fff reg[7:0] cnt_word = 8'd0; reg[5:0] cnt_bits = 6'd0; reg [DATA_WIDTH-1:0] cfgdata = 0; wire [DATA_WIDTH-1:0] regdata; reg cfgover = 1'b0 ; reg pll_locked = 1'b0 ; reg load_en = 1'b0 ; reg [31:0] cnt_lock = 32'b0; (* KEEP = "TRUE" *)reg[3:0] cfgstate = 4'b0000; wire spiIdle; reg spi_sdi = 1'b0,spi_csb = 1'b1 ; assign o_cfgover = cfgover ; assign o_ADF4351_LE = load_en ; assign o_ADF4351_mutel= 1'b1 ; assign o_ADF4351_SCK = o_ADF4351_CE ? 1'b0 : i_sysclk ; assign o_ADF4351_CE = spi_csb ; assign o_ADF4351_DATA = spi_sdi ; reg [DATA_WIDTH-1:0] CFGREG0 ; assign regdata = CFGREG0 ; reg cfg_start ; reg [15:0] counter0 ; always@ (posedge i_sysclk) if(~i_arstn) CFGREG0 <= 32'b0; else begin //RFout = Fpfd*(INT + (Frac/Mod)) Fpfd = Refin*[(1+D)/(R*(1+T))] case (cnt_word) 8'h00: CFGREG0 <= {32'h580005}; //reg 5 8'h01: CFGREG0 <= {32'h85003C}; //reg 4 8'h02: CFGREG0 <= {32'h4B3}; //reg 3 8'h03: CFGREG0 <= {32'h28F42}; //reg 2 {5'b0,T,R,D,12'h,reg2} R = 1 D = 1 T = 1 8'h04: CFGREG0 <= {32'h8008011}; //reg 1 {3'd0,phase adjust,prescaler,phase value,Frac,reg1}mod = 25 8'h05: CFGREG0 <= {32'hC80000}; //reg 0 {1'b0,int,frac,reg0} int = 52 frac= 8 default : CFGREG0 <= 32'b0; endcase end always@(negedge i_sysclk)begin if(~i_arstn)begin cfgdata <= 0; cnt_word <= 8'd0; cnt_bits <= 6'd0; cfgover <= 1'b0; cfgstate <= 4'd0; spi_csb <= 1'b1; load_en <= 1'b1; spi_sdi <= 1'b0; end else begin case(cfgstate) 4'd0:begin if(cfg_start)begin cfgstate <= 4'd1; end else begin spi_csb <= 1'b1; load_en <= 1'b0; spi_sdi <= 1'b0; cfgover <= 1'b0; cfgstate <= 4'd0; end end 4'd1:begin cfgdata <= regdata; cnt_lock <= 32'd0; cnt_bits <= 6'd0; cfgstate <= cfgstate + 1'b1; end 4'd2:begin spi_csb <= 1'b0; load_en <= 1'b0; spi_sdi <= cfgdata[DATA_WIDTH-1]; cfgdata <= cfgdata << 1'b1; cnt_bits <= cnt_bits + 1'b1; if(cnt_bits == DATA_WIDTH-1)begin cfgstate <= cfgstate + 1'b1; cnt_word <= cnt_word + 1'b1; end end 4'd3:begin spi_csb <= 1'b1; load_en <= 1'b1; spi_sdi <= 1'b0; if(cnt_word == DATA_LENTH) cfgstate <= cfgstate + 1'b1; else cfgstate <= 4'd0; end 4'd4:begin cfgstate <= 4'd5; spi_csb <= 1'b1; load_en <= 1'b0; spi_sdi <= 1'b0; end 4'd5:begin//ftw cfg if(cnt_lock > LOCK_PIRED) begin pll_locked <= i_ADF4351_locked; cnt_lock <= cnt_lock; if( (pll_locked == 1'b0) && (cnt_lock > LOCK_PIRED)) begin cfgstate <= 4'd1; cnt_word <= 8'd0; end else begin cfgstate <= 4'd5; spi_csb <= 1'b1; spi_sdi <= 1'b0; cfgover <= 1'b1; end end else begin cnt_lock <= cnt_lock + 1'b1; end end default:cfgstate <= 4'd0; endcase end end always@(negedge i_sysclk)begin if(~i_arstn)begin counter0 <= 16'd0; cfg_start <= 1'b0; end else begin if(counter0 == rst_time)begin//16'h7fff counter0 <= counter0; cfg_start <= 1'b1; end else begin counter0 <= counter0 + 1'b1; cfg_start <= 1'b0; end end end endmodule