├── .gitignore ├── README.md ├── PhaseDetector.v ├── FFD.v ├── NDivider.v ├── FFJK.v ├── TestBenchNDivider.v ├── TestBenchDLF.v ├── TestBenchIDC.v ├── TestBench.v ├── DPLL.v ├── DLF.v └── IDCounter.v /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | *.* 3 | !.gitignore 4 | !*.v 5 | !*.md 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DPLL-FPGA 2 | The Digital Phase-locked Loop implemented on Spartan-6 FPGA. 3 | -------------------------------------------------------------------------------- /PhaseDetector.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 100ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01:08:06 05/06/2018 7 | // Design Name: 8 | // Module Name: PhaseDetector 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module PhaseDetector( 22 | input inputSigA, 23 | input inputSigB, 24 | output errSig 25 | ); 26 | 27 | assign errSig = inputSigA ^ inputSigB; 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /FFD.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 02:20:39 05/06/2018 7 | // Design Name: 8 | // Module Name: FFD 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module FFD( 22 | input clk, 23 | input reset, 24 | input sigIn, 25 | output reg sigOut, 26 | output sigOut_n 27 | ); 28 | 29 | always @(posedge clk or negedge reset) begin 30 | if(!reset) 31 | sigOut = 0; 32 | else begin 33 | sigOut <= sigIn; 34 | end 35 | end 36 | assign sigOut_n = ~sigOut; 37 | 38 | endmodule 39 | -------------------------------------------------------------------------------- /NDivider.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 100ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 02:51:00 05/06/2018 7 | // Design Name: 8 | // Module Name: Divider 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: Divide the clk 2 * (N + 1) times. The duty cycle of the output is 50%. 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module NDivider( 22 | input clk, 23 | input reset, 24 | input [7:0] N, 25 | output reg out 26 | ); 27 | 28 | reg [7:0]cnt; 29 | always @(posedge clk or negedge reset) begin 30 | if(!reset) 31 | begin 32 | cnt <= N; 33 | out <= 0; 34 | end 35 | else begin 36 | if(cnt != 8'd0) 37 | cnt <= cnt - 1; 38 | else 39 | begin 40 | out <= ~out; 41 | cnt <= N; 42 | end 43 | end 44 | end 45 | 46 | endmodule 47 | -------------------------------------------------------------------------------- /FFJK.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 02:30:36 05/06/2018 7 | // Design Name: 8 | // Module Name: FFJK 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module FFJK( 22 | input clk, 23 | input reset, 24 | input j, 25 | input k, 26 | output reg out, 27 | output reg out_n 28 | ); 29 | 30 | always @(posedge clk or negedge reset) begin 31 | if(!reset) begin 32 | out <= 0; 33 | end 34 | else begin 35 | case({j, k}) 36 | 2'b00: begin out <= out; out_n <= out_n; end 37 | 2'b01: begin out <= 1'b0; out_n <= 1'b1; end 38 | 2'b10: begin out <= 1'b1; out_n <= 1'b0; end 39 | 2'b11: begin out <= ~out; out_n <= ~out_n; end 40 | endcase 41 | end 42 | end 43 | 44 | endmodule 45 | -------------------------------------------------------------------------------- /TestBenchNDivider.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // Company: 5 | // Engineer: 6 | // 7 | // Create Date: 14:10:22 05/06/2018 8 | // Design Name: NDivider 9 | // Module Name: /home/iair-p05/Projects/DPLL-FPGA/TestBenchNDivider.v 10 | // Project Name: DPLL-FPGA 11 | // Target Device: 12 | // Tool versions: 13 | // Description: 14 | // 15 | // Verilog Test Fixture created by ISE for module: NDivider 16 | // 17 | // Dependencies: 18 | // 19 | // Revision: 20 | // Revision 0.01 - File Created 21 | // Additional Comments: 22 | // 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | module TestBenchNDivider; 26 | 27 | // Inputs 28 | reg clk; 29 | reg reset; 30 | reg [7:0] N; 31 | 32 | // Outputs 33 | wire out; 34 | 35 | // Instantiate the Unit Under Test (UUT) 36 | NDivider uut ( 37 | .clk(clk), 38 | .reset(reset), 39 | .N(N), 40 | .out(out) 41 | ); 42 | 43 | initial begin 44 | // Initialize Inputs 45 | clk = 0; 46 | reset = 0; 47 | N = 8'd4; 48 | 49 | // Wait 100 ns for global reset to finish 50 | #100; 51 | reset = 1; 52 | #100 53 | reset = 0; 54 | N = 8'd0; 55 | #5 56 | reset = 1; 57 | 58 | // Add stimulus here 59 | 60 | end 61 | always #1 clk = ~clk; 62 | 63 | endmodule 64 | 65 | -------------------------------------------------------------------------------- /TestBenchDLF.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // Company: 5 | // Engineer: 6 | // 7 | // Create Date: 15:16:00 05/06/2018 8 | // Design Name: DLF 9 | // Module Name: /home/iair-p05/Projects/DPLL-FPGA/TestBenchDLF.v 10 | // Project Name: DPLL-FPGA 11 | // Target Device: 12 | // Tool versions: 13 | // Description: 14 | // 15 | // Verilog Test Fixture created by ISE for module: DLF 16 | // 17 | // Dependencies: 18 | // 19 | // Revision: 20 | // Revision 0.01 - File Created 21 | // Additional Comments: 22 | // 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | module TestBenchDLF; 26 | 27 | // Inputs 28 | reg clk; 29 | reg reset; 30 | reg dirSig; 31 | reg enable; 32 | reg [3:0] kMode; 33 | 34 | // Outputs 35 | wire carry; 36 | wire borrow; 37 | wire [19:0] count; 38 | 39 | // Instantiate the Unit Under Test (UUT) 40 | DLF uut ( 41 | .clk(clk), 42 | .reset(reset), 43 | .dirSig(dirSig), 44 | .enable(enable), 45 | .kMode(kMode), 46 | .carry(carry), 47 | .borrow(borrow), 48 | .count(count) 49 | ); 50 | 51 | initial begin 52 | // Initialize Inputs 53 | clk = 0; 54 | reset = 0; 55 | dirSig = 0; 56 | enable = 0; 57 | kMode = 4'b0001; 58 | 59 | // Wait 100 ns for global reset to finish 60 | #100; 61 | 62 | // Add stimulus here 63 | 64 | enable = 1; 65 | reset = 1; 66 | #100 67 | kMode = 4'b0010; 68 | #100 69 | dirSig = 1; 70 | 71 | 72 | end 73 | 74 | always #1 clk = ~clk; 75 | 76 | 77 | endmodule 78 | 79 | -------------------------------------------------------------------------------- /TestBenchIDC.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01:12:28 07/06/2018 7 | // Design Name: 8 | // Module Name: TestBenchIDC 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module TestBenchIDC; 22 | 23 | // Inputs 24 | reg clock; 25 | reg reset; 26 | reg inc; 27 | reg dec; 28 | 29 | // Outputs 30 | wire DCOout; 31 | wire incDelayed; 32 | wire decDelayed; 33 | wire incIgn; 34 | wire decIgn; 35 | IDCounter DCO( 36 | .clk(clock), 37 | .reset(reset), 38 | .incIn(inc), 39 | .decIn(dec), 40 | .inc(incDelayed), 41 | .dec(decDelayed), 42 | .incIgnore(incIgn), 43 | .decIgnore(decIgn), 44 | .IDout(DCOout) 45 | ); 46 | 47 | initial begin 48 | // Initialize Inputs 49 | clock = 0; 50 | reset = 0; 51 | inc = 0; 52 | dec = 0; 53 | 54 | #100; 55 | 56 | reset = 1; 57 | #200 inc = 1; 58 | #20 inc = 0; 59 | #10 inc = 1; 60 | #10 inc = 0; 61 | #10 inc = 1; 62 | #10 inc = 0; 63 | #10 inc = 1; 64 | #10 inc = 0; 65 | end 66 | always #10 clock = ~clock; 67 | 68 | 69 | 70 | 71 | endmodule 72 | -------------------------------------------------------------------------------- /TestBench.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 100ps 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // Company: 5 | // Engineer: 6 | // 7 | // Create Date: 00:42:57 05/06/2018 8 | // Design Name: DPLL 9 | // Module Name: /home/thunderbird/Projects/DPLL-FPGA/TestBench.v 10 | // Project Name: DPLL-FPGA 11 | // Target Device: 12 | // Tool versions: 13 | // Description: 14 | // 15 | // Verilog Test Fixture created by ISE for module: DPLL 16 | // 17 | // Dependencies: 18 | // 19 | // Revision: 20 | // Revision 0.01 - File Created 21 | // Additional Comments: 22 | // 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | module TestBench; 26 | 27 | // Inputs 28 | reg baseClockInput; 29 | reg oscInput; 30 | reg reset; 31 | 32 | // Outputs 33 | wire dpllOutput; 34 | wire xorOutput; 35 | wire dlfCarry; 36 | wire dlfBorrow; 37 | wire DCOout; 38 | wire [19:0]counter; 39 | 40 | // Instantiate the Unit Under Test (UUT) 41 | DPLL uut ( 42 | .baseClockInput(baseClockInput), 43 | .oscInput(oscInput), 44 | .reset(reset), 45 | .dpllOutput(dpllOutput), 46 | .dpdOut(xorOutput), 47 | .dlfCarry(dlfCarry), 48 | .dlfBorrow(dlfBorrow), 49 | .inc(inc), 50 | .dec(dec), 51 | .DCOout(DCOout), 52 | .HDivClk(HDivClk), 53 | .counter(counter) 54 | ); 55 | 56 | initial begin 57 | // Initialize Inputs 58 | baseClockInput = 0; 59 | oscInput = 0; 60 | reset = 0; 61 | 62 | // Wait 100 ns for global reset to finish 63 | #100; 64 | 65 | // Add stimulus here 66 | 67 | reset = 1; 68 | 69 | 70 | end 71 | always #50 oscInput =~ oscInput; 72 | always #103200 baseClockInput =~ baseClockInput; 73 | 74 | endmodule 75 | 76 | -------------------------------------------------------------------------------- /DPLL.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 100ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 23:05:55 05/05/2018 7 | // Design Name: 8 | // Module Name: DPLL 9 | // Project Name: DPLL-FPGA 10 | // Target Devices: XC6SLX9-2FTG256 11 | // Tool versions: 12 | // Description: The digital phase-locked loop. 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module DPLL( 22 | input baseClockInput, 23 | input oscInput, 24 | input reset, 25 | output dpllOutput, 26 | // Signal for debug 27 | output dpdOut, 28 | output dlfCarry, 29 | output dlfBorrow, 30 | output inc, 31 | output dec, 32 | output DCOout, 33 | output HDivClk, 34 | output [19:0]counter 35 | ); 36 | 37 | reg [3:0] kMode = 4'b0011; 38 | reg [7:0] multN = 8'd128; 39 | reg [7:0] H = 8'd1; 40 | wire idclock; 41 | 42 | PhaseDetector DPD( 43 | .inputSigA(baseClockInput), 44 | .inputSigB(dpllOutput), 45 | .errSig(dpdOut) 46 | ); 47 | 48 | DLF KCounter( 49 | .clk(oscInput), 50 | .reset(reset), 51 | .dirSig(dpdOut), 52 | .enable(1), 53 | .kMode(kMode), 54 | .carry(dlfCarry), 55 | .borrow(dlfBorrow), 56 | .count(counter) 57 | ); 58 | 59 | NDivider oscDIV( 60 | .clk(oscInput), 61 | .reset(reset), 62 | .N(H), 63 | .out(HDivClk) 64 | ); 65 | 66 | IDCounter DCO( 67 | .clk(HDivClk), 68 | .reset(reset), 69 | .incIn(dlfCarry), 70 | .decIn(dlfBorrow), 71 | .IDout(DCOout), 72 | .inc(inc), 73 | .dec(dec) 74 | ); 75 | 76 | NDivider DIV( 77 | .clk(DCOout), 78 | .reset(reset), 79 | .N(multN), 80 | .out(dpllOutput) 81 | ); 82 | 83 | // For debug 84 | 85 | 86 | 87 | endmodule 88 | -------------------------------------------------------------------------------- /DLF.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 100ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01:14:57 05/06/2018 7 | // Design Name: 8 | // Module Name: DLF 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module DLF( 22 | input clk, 23 | input reset, 24 | input dirSig, 25 | input enable, 26 | input [3:0] kMode, 27 | output carry, 28 | output borrow, 29 | // For debug 30 | output reg [19:0] count 31 | ); 32 | 33 | //reg [19:0]count; 34 | reg [19:0]kTop; 35 | 36 | always @(kMode) begin 37 | case(kMode) 38 | 4'b0001:kTop<=7; 39 | 4'b0010:kTop<=15; 40 | 4'b0011:kTop<=31; 41 | 4'b0100:kTop<=63; 42 | 4'b0101:kTop<=127; 43 | 4'b0110:kTop<=255; 44 | 4'b0111:kTop<=511; 45 | 4'b1000:kTop<=1023; 46 | 4'b1001:kTop<=2047; 47 | 4'b1010:kTop<=4095; 48 | 4'b1011:kTop<=8191; 49 | 4'b1100:kTop<=16383; 50 | 4'd1101:kTop<=32767; 51 | 4'd1110:kTop<=65535; 52 | 4'd1111:kTop<=131072; 53 | default:kTop<=7; 54 | endcase 55 | end 56 | always @(posedge clk, negedge reset) begin 57 | if(!reset) 58 | count <= 0; 59 | else if(enable) begin 60 | if(!dirSig) begin 61 | if(count == kTop) 62 | count <= 0; 63 | else 64 | count <= count + 1; 65 | end 66 | else begin 67 | if(count == 0) 68 | count <= kTop; 69 | else 70 | count <= count - 1; 71 | end 72 | end 73 | end 74 | assign carry = reset & enable & (!dirSig) & (count == kTop); 75 | assign borrow = reset & enable & dirSig & (count == 0); 76 | endmodule 77 | -------------------------------------------------------------------------------- /IDCounter.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 100ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01:44:23 05/06/2018 7 | // Design Name: 8 | // Module Name: IDCounter 9 | // Project Name: 10 | // Target Devices: 11 | // Tool versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module IDCounter( 22 | input clk, 23 | input reset, 24 | input incIn, 25 | input decIn, 26 | output IDout, 27 | // Debug Sig 28 | output reg inc, 29 | output reg dec, 30 | output reg incIgnore, 31 | output reg decIgnore 32 | ); 33 | 34 | wire Q1, Qn1, Q2, Qn2, Q3, Qn3; 35 | wire Q4, Qn4, Q5, Qn5, Q6, Qn6; 36 | wire Q7, Qn7, Q8, Qn8, Q9, Qn9; 37 | wire D7, D8; 38 | 39 | // reg inc; 40 | // reg dec; 41 | always @(negedge reset) 42 | begin 43 | inc <= 0; 44 | dec <= 0; 45 | incIgnore <= 0; 46 | decIgnore <= 0; 47 | end 48 | 49 | always @(posedge incIn or posedge clk) 50 | begin 51 | if(incIn & !incIgnore) 52 | inc <= incIn; 53 | if(clk) 54 | if(inc) 55 | incIgnore <= 1; 56 | else 57 | incIgnore <= 0; 58 | end 59 | 60 | always @(posedge Q2) 61 | begin 62 | inc <= 0; 63 | end 64 | /* 65 | always @(negedge clk) 66 | begin 67 | if(Q2) 68 | inc <= 0; 69 | end 70 | */ 71 | 72 | always @(posedge decIn or posedge clk) 73 | begin 74 | if(decIn & !decIgnore) 75 | dec <= decIn; 76 | if(clk) 77 | if(dec) 78 | decIgnore <= 1; 79 | else 80 | decIgnore <= 0; 81 | end 82 | 83 | always @(negedge clk) 84 | begin 85 | if(decIgnore) 86 | dec <= 0; 87 | end 88 | 89 | FFD FFD1(clk, reset, dec, Q1, Qn1); 90 | FFD FFD3(clk, reset, Q1, Q3, Qn3); 91 | FFD FFD5(clk, reset, Q3, Q5, Qn5); 92 | 93 | FFD FFD2(clk, reset, inc, Q2, Qn2); 94 | FFD FFD4(clk, reset, Q2, Q4, Qn4); 95 | FFD FFD6(clk, reset, Q4, Q6, Qn6); 96 | assign D7=((Q9 & Qn1 & Q3)|(Q9 & Q5 & Qn3)); 97 | assign D8=((Qn9 & Qn2 & Q4)|(Qn9 & Q6 & Qn4)); 98 | //assign D7 = ((Qn1 & Q3 & Qn9) | (Qn3 & Q5 & Qn9)); 99 | //assign D8 = ((Qn2 & Q4 & Q9) | (Qn4 & Q6 & Q9)); 100 | FFD FFD7(clk, reset, D7, Q7, Qn7 ); 101 | FFD FFD8(clk, reset, D8, Q8, Qn8 ); 102 | FFJK FFJK1(clk, reset, Qn7, Qn8, Q9, Qn9); 103 | assign IDout = (!clk) & Q9; 104 | 105 | endmodule 106 | --------------------------------------------------------------------------------