6
\$\begingroup\$

I'm a fresh verilog / HDL programmer and I'm writing this post to get some feedback from more experienced verilog / HDL programmers.

My very first task was to divide a clock by eight.

I know there are some better methods to do this, but as I'm new to HDL this is my first, naive, attempt:

module prescaleMainCLK(CLK, prescaledCLK);
    input CLK;
    output reg prescaledCLK;

    // ''Define'' a 4bit counter, max value: 15
    reg [3:0] counter;

    initial begin
        // Initialise both variables
        prescaledCLK <= 0;
        counter      <= 0;
    end

    always @ (posedge CLK) begin

        // Did the counter reach its end?
        if (counter > 7) begin

            // Reset the counter
            counter <= 0;

            // Toggle the prescaled clock output
            prescaledCLK <= ~prescaledCLK;

        end else begin

            // Increment counter
            counter <= counter + 1;

        end

    end

endmodule

The Simulation output (EDAPlayground) is as I expect it to be:

enter image description here

Now I want to know if that code is suitable for real applications or if there are some things I need to reconsider.

\$\endgroup\$
5
\$\begingroup\$

I would recommend a using modern Verilog header:

module prescaleMainCLK(
    input      CLK,
    output reg prescaledCLK
);

adding bit size to your constants is best practice. 'b0 for all zeros with auto sizing. 0 is an integer likely only 32 bits long which can get you in trouble if you start applying to regs bigger than than 32 bits.

The use of initial is only valid in FPGA synthesis, for ASIC you should use a active low async reset.

reg [3:0] counter;

initial begin
    // Initialise both variables
    counter      <= 'b0;
end

always @ (posedge CLK) begin
  counter <= counter + 1'd1;
end

Versus for ASIC:

always @ (posedge CLK or negedge rst_n) begin
  if(~rst_n) begin
    counter <= 'd0;
  end
  else begin
    counter <= counter + 1'd1;
  end
end

You can reuse the counter bits (as mentioned in another answer) for your slower clocks

wire clk_div2  = counter[0];
wire clk_div4  = counter[1];
wire clk_div8  = counter[2];
wire clk_div16 = counter[3];

At faster frequencies this often becomes tricky to balance clocks correctly. A standard industry practice would be to use enables (derived from this counter) for a clock gate. The clock gate allows a pulse from the faster clock through, you loose the 50 50 duty cycle of the clock but balancing the clock tress becomes much easier.

\$\endgroup\$
  • 1
    \$\begingroup\$ Well done for posting to the correct site! Would love to see more Verilog being submitted for review, I think this place is pretty under-utilised. \$\endgroup\$ – Munkymorgy Feb 26 '16 at 10:04
  • 1
    \$\begingroup\$ Regarding using the more modern verilog header, why do you recommend me using the more modern one? I think the ''old'' one looks more clean. What are the advantages? \$\endgroup\$ – d3L Feb 27 '16 at 23:57
  • 2
    \$\begingroup\$ The new style does not force you to replicate port names multiple times. having to write the same thing multiple times costs time for code maintenance and is source of compilation errors. \$\endgroup\$ – Munkymorgy Feb 28 '16 at 10:41
2
\$\begingroup\$

I'm no Verilog expert. However, it's clear that if you just keep adding 1 to a 4-bit counter and letting it wrap around, then prescaledCLK would just be the most significant bit of counter. You should be able to eliminate the conditional, I think.

\$\endgroup\$
  • \$\begingroup\$ Thats what I had in mind too \$\endgroup\$ – d3L Feb 26 '16 at 7:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.