Generating customs waveforms - execution order?

J

JeffC

Guest
I have created some Verilog code which appears to work in the hardware.
The idea is to generate two custom waveforms which repeat/are periodic.
The code is below.
The problem is, I wish to insert a one off waveform sequence at startup
immediately before the periodic sequence begins. That is to say, I want
to produce a digital waveform which occurs only once at startup after
which the continuous periodic waveform begins to run. I was thinking of
using a loop in the initial block (see 2nd chunk of code), but from what
I can tell, the initial block executes in parallel with the always block
or so I have read in which case this will not work. Perhaps I am asking
how to control the execution order?

[screen grab http://img155.imageshack.us/img155/9850/verilograbqn7.jpg]

module waveforms(clock, linesout);

input clock;
output [1:0] linesout; //FPGA lines out
reg [1:0] lines;
reg [4:0] clkdiv; //Clock divider
reg [31:0] wf; //Waveform 1
reg [31:0] wfb; //Waveform 2
reg [31:0] index; //Index to waveform vectors

assign linesout = lines;

initial begin
wf = 32'b00001111111111111111111111111111; //Initialize
waveform vectors
wfb = 32'b00001110000011111111111111111111;
end

always @(posedge clock)
begin
clkdiv <= clkdiv - 1;
if (clkdiv == 0) begin
index <= index + 1;
lines[0] <= wf[index]; //Assign indexed waveform
element to lines
lines[1] <= wfb[index];
end
end
endmodule

Using the initial block to create a one off digital sequence at startup-
will not work correctly?

initial begin

wf = 32'b00001111111111111111111111111111;
wfb = 32'b00001110000011111111111111111111;
wfini = 32'b11111111111001111001111100011111;
wfbini = 32'b11111111111001111000000000011111;

for (i = 0; i < 32; i = i +1) begin
lines[0] <= wfini;
lines[1] <= wfbini;
end

end
 
There is no "initial" in hardware, there is however the concept of
reset. Initial will not by synthesized into any gates of your FPGA,
and is essentially ignored.

To fix the logic :

- Create a reset_n signal. and change your block code to look
something like this :

always @(posedge clk or negedge reset_n)
if (!reset_n) // This code is assuming an active-low reset
begin
.. set your initial values here ..
end
else
begin
.. the rest of your original code ..
end

These are good habits to get into when doing any digital design.
Anything that you need to have a "known" state, needs to be
resettable.

- Double flop your reset signal, coming from the pin. Nearly all proto
boards will have a hardwired reset for you

wire reset_pin ;
reg reset_1, reset_n ;
always @(posedge clk)
{ reset_n, reset_1 } <= { reset_1, reset_pin } ;

- Try using your vendors build int PLL / DLL to do clock division. In
this case, you aren't doing anything bad, but generally it is best to
use a build in clock divider. They can just take a clock pin and
create a divide by 16 clock easily for you. and you can call your
clk : clk_div32 on the input to help you keep track of such things
( if you need ).

Hope that helps.

-Art
 
One more tiny thing, I noticed late :

you have :

....
reg [31:0] wfb ;
reg [31:0] index ;

....
lines[1] <= wfb[index] ;
....


There are only 32 indexes into wfb, so you only need a [4:0] reg, to
index every bit. It probably makes most sense to change index to a
[4:0] reg. Otherwise another technique would be to use
"wfb[index[4:0]]", which selects just 5 bits of the total count.

-Art
 
Art Stamness wrote:
One more tiny thing, I noticed late :

you have :

...
reg [31:0] wfb ;
reg [31:0] index ;

...
lines[1] <= wfb[index] ;
...


There are only 32 indexes into wfb, so you only need a [4:0] reg, to
index every bit. It probably makes most sense to change index to a
[4:0] reg. Otherwise another technique would be to use
"wfb[index[4:0]]", which selects just 5 bits of the total count.

-Art

Hi Art, yes I noticed that too...I think I must have carried it over
from something else. Thanks for your help - it should be enough to get
me going.
 

Welcome to EDABoard.com

Sponsor

Back
Top