// Divide by 4080 using only 2 Xilinx Virtex slices // (4 LUT, 3 of which are used as SRL16E) // Copyright (C) 2002 Larry Doolittle // Simulation tested with Icarus Verilog `timescale 1ns / 1ns module div4080(clk, in_ce, out_ce); input clk, in_ce; output out_ce; wire clk, in_ce, out_ce; // 17-long shift register, filled with zeros except for a single 1 wire q1; reg d1; initial d1=1; SRL16E #(.INIT(0)) s1(.Q(q1), .A0(1), .A1(1), .A2(1), .A3(1), .CE(in_ce), .CLK(clk), .D(d1)); always @(posedge clk) if (in_ce) d1 <= q1; // 16-long shift register, filled with zeros except for a single 1 wire q2; reg d2; initial d2=1; SRL16E #(.INIT(0)) s2(.Q(q2), .A0(0), .A1(1), .A2(1), .A3(1), .CE(in_ce), .CLK(clk), .D(d2)); always @(posedge clk) if (in_ce) d2 <= q2; // 15-long shift register, filled with zeros except for a single 1 wire q3; reg d3; initial d3=1; SRL16E #(.INIT(0)) s3(.Q(q3), .A0(1), .A1(0), .A2(1), .A3(1), .CE(in_ce), .CLK(clk), .D(d3)); always @(posedge clk) if (in_ce) d3 <= q3; // Every 15*16*17=4080 cycles a 1 will pop out of all three shift registers at once. // Including the clock-enable (needed for cascades), we stick to four inputs to // this AND gate to stay within a single 4-LUT. assign out_ce = in_ce & d1 & d2 & d3; endmodule // Example use of div4080: heartbeat LED driver based on 40-ish MHz input clock, // uses less than 5 Xilinx Virtex slices. // Entirely synchronous, fits within the base clock domain. // Don't bother trying to simulate it. Only a masochist would want to // follow 32 million clock cycles. module heartbeat(clk, led); input clk; output led; reg led; initial led=0; div4080 s1(clk, 1, stage1); div4080 s2(clk, stage1, stage2); always @(posedge clk) if (stage2) led <= ~led; endmodule // Test routine to follow a few cycles of div4080 module main(); integer cc; reg clk; initial begin $dumpfile("test.vcd"); $dumpvars(1,main); for (cc = 0; cc < 45000; cc = cc + 1) begin clk=0; #20; clk=1; #20; end end wire result; div4080 mut(clk, 1, result); wire led; heartbeat x(clk, led); endmodule