Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

evaluation of erros in clock divider in verilog

Status
Not open for further replies.

theHermes

Newbie level 6
Joined
Mar 13, 2011
Messages
13
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,434
I need to design a clock divider as part of my verilog program for SPI but unfortunately I have a few errors and I am not able to correct the errors.
the code is as follows:

module clockdivider(mclk,rst,sclk);
input mclk;
input rst;
output sclk;
reg [7:0]divide;
integer i;
always@(negedge mclk)
begin
if (rst==1)
begin
sclk=0;
i=0;
end
else
begin
assign sclk =mclk/(divide+1)*2
i=i+1;
end
end
endmodule

please evaluate the errors-
thanks.
 

maybe you could start with mentioning the errors in your message
 

1.) not many people use "assign" within an always block. I guess not technically an error.
2.) a 1b wire divided by anything doesn't really make sense.
3.) "i" is incremented but never used.
4.) divide is used but never assigned.
 

Clock dividers made easy...

1. Divide by 2 = D-FF with output fedback to input inverted. (Q inverted and fed back to D, or Qbar fed back to D).
2. For all other clock dividers.. use counters.. count upto the value and then change state of output signal from 0 to 1.. then again count .. change state from 1 to 0.


##. You cannot use assign statement inside an always block.. assign statements are concurrent statements.. not procdeural..
##. sclk =mclk/(divide+1)*2 is functionally wrong...use counter logic here..
 

I need to design a clock divider as part of my verilog program for SPI but unfortunately I have a few errors and I am not able to correct the errors.
the code is as follows:

See permute's comments...

Also, you can use the CODE tags to make it a bit easier to read.

Made a few (style) changes as a suggestion how you could do things...

Note the difference in use of <= instead of = inside the always block, as permute already mentioned. Also note the port list. This way you don't have to write things twice.


Code:
`default_nettype none
module clockdivider (
    input  wire mclk,
    input  wire rst,
    output wire sclk
    );

reg [7:0] divide;

assign sclk = divide[7]; // Use the MSB of the divider counter as output divided clock.

always @(negedge mclk or posedge rst) begin // IMO, better practice for an fpga target is posedge mclk. Also, don't forget to include the reset in sensitivity list
    if (rst==1) begin
        divide <= 0;
    end else begin
        divide <= divide + 1'd1; // note the use of 1'd1 instead of 1. This is to prevent useles truncation warnings during synthesis
     end
 end
endmodule // clockdivider
`default_nettype wire
 

actually, as I had found out previously, there is actually a use for using blocking assigns for the divided clock. basically, if you have a register clocked by mclk that connects to sclk for tx, and a register clocked by sclk connected to a register clocked by mclk for rx, the sims can have issues. with nonblocking, it does:
mclk event. evaluate all registers clocked by mclk. update all registers.
sclk has changed.
sclk event. evaluate all registers clocked by sclk. update all.

notice the tx path register in the mclk domain was updated at the same time as sclk, causing the sclk domain's tx register to be updated with that value!

with blocking, the order goes:
mclk event, evaluate all logic affected by mclk. sclk is updated add sclk's events to the list of logic to evaluate. now, update both mclk and sclk's registers.

but the above is just sim -- the actual HW works as you would expect two registers in series to work.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top