Hi guys, I'm starting using verilog.
I need Numerically Controlled Oscillator as clock generator but code I've found on the web is too complicated for me, so I'm designing my NCO step by step.
I am using overflow bit as flag, to be cleared after 1 clock cycle.
Here my working (until now) code:
module NCO_4bit
#(
parameter WACCUM = 24 // accumulator register width [bits]
/*
output frequency [MHz] = (step [counts] * Fosc [MHz])/(2^WACCUM)
example:
always #5 ck = ~ck; clock period = 10ns, clock frequency = 100 [MHz]
WACCUM = 8 [bits]
step = 3 [value]
output frequency fout = 1.1764705882 [MHz]
*/
)
(
input [WACCUM-1:0] step, // phase value
output reg [WACCUM:0] accu, // accumulator
output fout, // output frequency
input n_res, // clear command (active low)
input ck // system clock (on rising edge)
);
wire [WACCUM:0] mask;
assign mask = { {1'b0}, {(WACCUM){1'b1}} }; // creating mask, WACCUM+1 bits wide, only MSB 0, remaining bits set to 1
// check for reset, check at falling edge of n_res or every rising edge of ck
always @(posedge ck or negedge n_res)
begin
if (!n_res)
accu <= 0; // clear accu register
else
begin
// check if accu MSB is set, if so clear it so fout high only for 1 clock cycle
//$display("\ninit accu= %b, flag= %b", accu, accu[WACCUM]);
if (accu[WACCUM])
begin
//accu[WACCUM] <= 1'b0;
accu <= (accu+step)&mask;
end
else
begin
accu <= accu+step;
end
$display("current accu value= %b, flag= %b", accu, accu[WACCUM]);
end
end
assign fout={accu[WACCUM]};
endmodule
It looks working, I just add "step" value to "accu" and using MSB of accu register to detect rollover of the counter.
I want rollover flag (fout) high for 1 clock cycle, then I clear it.
First code I wrote:
if (!n_res)
accu <= 0; // clear accu register
else
begin
// check if accu MSB is set, if so clear it so fout high only for 1 clock cycle
//$display("\ninit accu= %b, flag= %b", accu, accu[WACCUM]);
if (accu[WACCUM])
begin
accu[WACCUM] <= 1'b0;
end
accu <= accu+step;
end
When detecting MSB set I try to clear it, but no effect.
I also tested accu <= 5 as test.
I can enter inside if (accu[WACCUM]) but it looks
accu <= accu+step;
would override all previous instructions.
Am I missing something?
Thanks.