Help with a simple problem?

T

Tobias Weingartner

Guest
Hello all,

I've been messing around with some verilog code, trying to implement
a digital controlled oscilator (overglorified counter). I thought
that I had the basics of verilog down, but it seems that I have some
to learn yet. :)

Anyways, below is some verilog code (I hope) that I wrote, but it does
not seem to want to do what I want it to do. Funny how that goes. It
should respect a reset (and seems to) pulse, as well as a "load" pulse
to load a value, and then start counting up to that value wrapping to
zero when you hit that value. Each time you hit the loaded value, the
output "q" should change, giving you sort of a DCO 50% waveform. For
some reason, div stays "x", and never loads...

Thougths? Pointers to the problem? All suggestions welcome. :)


module dco(clk,reset,load,data,q);
parameter DBW = 1;
input clk; // System clock
input reset; // Reset
input load; // Load data value
input [DBW-1:0] data; // Data (count) value
output q; // Output waveform

reg [DBW-1:0] count;
reg [DBW-1:0] div;
reg q;

always @(posedge clk)
if(reset) begin
count <= 0;
q <= 0;
end
else if(load) begin
div <= data;
end
else begin
if(count == div) begin
count <= 0;
q <= ~q;
end
else begin
count <= count + 1;
end
end
endmodule

module test;

parameter WIDTH = 14;

reg reset;
reg clk;
reg dco_load;
reg [WIDTH-1:0] dco_data;
wire dco_out;

dco #(WIDTH) dco0(clk,reset,dco_load,dco_data,dco_out);

// Start our clock
initial begin
#0 clk = 0;
forever #5 clk = ~clk;
end

// Send reset pulse, run simulation...
initial begin
reset = 1'bx;
#25 reset = 0;
#25 reset = 1;
#50 dco_load = 0; // Load a value into the DCO
#50 dco_data = 13;
#55 dco_load = 1;
#65 dco_load = 0;
#1000 $finish(2);
end

// Results display code
initial
begin
#0 $write ("\n");
#0 $display ("Results display");
end

always begin @(clk)
begin
$timeformat(-9, 0, "ns", 5);
$display ("%T", $time,,"%b",clk,,
"%b",reset,,
"%b",dco_load,,
"%d",dco_data,,
"%b",dco_out,,
"%d",dco0.div,,
"%d",dco0.count,,
"%b",dco0.q,,
);
end
end

endmodule



Oh, I'm using cver, nothing fancy...

--
[100~Plax]sb16i0A2172656B63616820636420726568746F6E61207473754A[dZ1!=b]salax
 
On Mon, 24 Jan 2005 20:22:11 +0000 (UTC), weingart@cs.ualberta.ca
(Tobias Weingartner) wrote:

always @(posedge clk)
if(reset) begin
count <= 0;
q <= 0;
....
initial begin
reset = 1'bx;
#25 reset = 0;
#25 reset = 1;
Your reset is active high and you leave it high in your testbench so
load never gets a chance to be loaded.
 
In article <kvtav0lcssnthapq76p4jbflqb5vujl4df@4ax.com>, mk wrote:
On Mon, 24 Jan 2005 20:22:11 +0000 (UTC), weingart@cs.ualberta.ca
(Tobias Weingartner) wrote:

always @(posedge clk)
if(reset) begin
count <= 0;
q <= 0;
...
initial begin
reset = 1'bx;
#25 reset = 0;
#25 reset = 1;

Your reset is active high and you leave it high in your testbench so
load never gets a chance to be loaded.
Thank you. I found this about 15 minutes ago. Learned another usefull
debugging method by finding this. Thank you for looking at this. It's
my first try at verilog coding. :)


--
[100~Plax]sb16i0A2172656B63616820636420726568746F6E61207473754A[dZ1!=b]salax
 
Tobias Weingartner wrote:
Hello all,

I've been messing around with some verilog code, trying to implement
a digital controlled oscilator (overglorified counter). I thought
that I had the basics of verilog down, but it seems that I have some
to learn yet. :)

Anyways, below is some verilog code (I hope) that I wrote, but it does
not seem to want to do what I want it to do. Funny how that goes. It
should respect a reset (and seems to) pulse, as well as a "load" pulse
to load a value, and then start counting up to that value wrapping to
zero when you hit that value. Each time you hit the loaded value, the
output "q" should change, giving you sort of a DCO 50% waveform. For
some reason, div stays "x", and never loads...

Thougths? Pointers to the problem? All suggestions welcome. :)


module dco(clk,reset,load,data,q);
parameter DBW = 1;
input clk; // System clock
input reset; // Reset
input load; // Load data value
input [DBW-1:0] data; // Data (count) value
output q; // Output waveform

reg [DBW-1:0] count;
reg [DBW-1:0] div;
reg q;

always @(posedge clk)
if(reset) begin
count <= 0;
q <= 0;
end
else if(load) begin
div <= data;
end
else begin
if(count == div) begin
count <= 0;
q <= ~q;
end
else begin
count <= count + 1;
end
end
endmodule
A few other thoughts about your circuit, just for interest:

- Your reset is synchronous - which is probably what you wanted, but async
reset is common enough to warrent a mention.

- In the cycle in which you load data, your counter will not be incremented.
To get round this, rather than writing complex if statements, I would
separate count and q, and div into two separate always blocks. This will
also make your code a bit more readable, since the two blocks will show the
different functions: counting circuit, and value loading circuit.

- Synthesis of this circuit may not give the same result as simulation.
Your "div" register is not reset, and therefore will be X on startup. The
term "count == div" will not match this value, and therefore your counter
will increment, wrapping at maximum value. In a synthesised circuit, the
"div" register will hold a value upon reset, and therefore the counter will
increment and loop at that particular value. In other words, simulation
will show that, before a load event, the counter will _always_ wrap at its
maximum value. In a synthesised circuit, before a load event, the counter
will wrap at an arbitary value. The reason for this disparity is that the
"if(count == div)" statement squashes X values; "div" will reset to X, but
this will not be visible in the value of "count". For a more accurate
representation, use a case statement something like this:

case (count == div)
1'b1 : begin
count <= 0;
q <= ~q;
end
1'b0 : begin
count <= count+1;
end
default : begin
count <= {DBW{1'bx}};
end
endcase


--
John Penton - posting as an individual unless otherwise indicated.
 
On Fri, 28 Jan 2005 11:35:25 -0000, "John Penton"
<John.Penton@arm.com> wrote:

- Synthesis of this circuit may not give the same result as simulation.
Your "div" register is not reset, and therefore will be X on startup. The
term "count == div" will not match this value, and therefore your counter
will increment, wrapping at maximum value. In a synthesised circuit, the
"div" register will hold a value upon reset, and therefore the counter will
increment and loop at that particular value. In other words, simulation
will show that, before a load event, the counter will _always_ wrap at its
maximum value. In a synthesised circuit, before a load event, the counter
will wrap at an arbitary value. The reason for this disparity is that the
"if(count == div)" statement squashes X values; "div" will reset to X, but
this will not be visible in the value of "count".
You seem to be saying that for a synthesized circuit, div will get a
non-X but artibrary set of ones and zeros. I don't think this is
right. The initial value of a DFF cell which one gets after synthesis
is also X so I don't think there would be any difference between rtl
and gate-level simulations in this regard. In silicon it's a different
question of course.
 
mk wrote:
On Fri, 28 Jan 2005 11:35:25 -0000, "John Penton"
John.Penton@arm.com> wrote:

- Synthesis of this circuit may not give the same result as
simulation. Your "div" register is not reset, and therefore will be
X on startup. The term "count == div" will not match this value,
and therefore your counter will increment, wrapping at maximum
value. In a synthesised circuit, the "div" register will hold a
value upon reset, and therefore the counter will increment and loop
at that particular value. In other words, simulation will show
that, before a load event, the counter will _always_ wrap at its
maximum value. In a synthesised circuit, before a load event, the
counter will wrap at an arbitary value. The reason for this
disparity is that the "if(count == div)" statement squashes X
values; "div" will reset to X, but this will not be visible in the
value of "count".

You seem to be saying that for a synthesized circuit, div will get a
non-X but artibrary set of ones and zeros. I don't think this is
right. The initial value of a DFF cell which one gets after synthesis
is also X so I don't think there would be any difference between rtl
and gate-level simulations in this regard. In silicon it's a different
question of course.
Yes. When I said "synthesised circuit" I did mean "synthesised and
fabricated circuit" - ie. on silicon.

John

--
John Penton - posting as an individual unless otherwise indicated.
 

Welcome to EDABoard.com

Sponsor

Back
Top