patternMinor
Divide a clock signal by 8
Viewed 0 times
dividesignalclock
Problem
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:
The Simulation output (EDAPlayground) is as I expect it to be:
Now I want to know if that code is suitable for real applications or if there are some things I need to reconsider.
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 7) begin
// Reset the counter
counter <= 0;
// Toggle the prescaled clock output
prescaledCLK <= ~prescaledCLK;
end else begin
// Increment counter
counter <= counter + 1;
end
end
endmoduleThe Simulation output (EDAPlayground) is as I expect it to be:
Now I want to know if that code is suitable for real applications or if there are some things I need to reconsider.
Solution
I would recommend a using modern Verilog header:
adding bit size to your constants is best practice.
The use of initial is only valid in FPGA synthesis, for ASIC you should use a active low async reset.
Versus for ASIC:
You can reuse the counter bits (as mentioned in another answer) for your slower clocks
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.
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;
endVersus for ASIC:
always @ (posedge CLK or negedge rst_n) begin
if(~rst_n) begin
counter <= 'd0;
end
else begin
counter <= counter + 1'd1;
end
endYou 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.
Code Snippets
module prescaleMainCLK(
input CLK,
output reg prescaledCLK
);reg [3:0] counter;
initial begin
// Initialise both variables
counter <= 'b0;
end
always @ (posedge CLK) begin
counter <= counter + 1'd1;
endalways @ (posedge CLK or negedge rst_n) begin
if(~rst_n) begin
counter <= 'd0;
end
else begin
counter <= counter + 1'd1;
end
endwire clk_div2 = counter[0];
wire clk_div4 = counter[1];
wire clk_div8 = counter[2];
wire clk_div16 = counter[3];Context
StackExchange Code Review Q#121134, answer score: 6
Revisions (0)
No revisions yet.