Initializing counters in Verilog

A

Adam

Guest
I have a verilog design and testbench I made using Webpack 4.2 and am
simulating it using Modelsim5.5e. It has a stack pointer(SP) in it that I
need to initialize to a value for simulation. How do I do this in Verilog?
My target device is an xc2s100 but I'm wondering if there is a general way
to do it. The code I'm working on is below(an Am2909 sequencer). This is
my first design(other than simple registers/muxes) so any feedback
appreciated.

Thanks,

Adam

module Am2909(S,FE_N,PUP,RE_N,OR,ZERO_N,OE_N,Cn,R,D,CP,Y,Cn4);
input [1:0] S;
input FE_N;
input PUP;
input RE_N;
input [3:0] OR;
input ZERO_N;
input OE_N;
input Cn;
input [3:0] R;
input [3:0] D;
input CP;
output [3:0] Y;
output Cn4;

integer i; //Loop control

reg [3:0] AR;
reg [3:0] uPC; //Internal registers
reg [3:0] MUXOUT, Iout, Y;//Non registered signals
reg Cn4; //Incrementer Carryout

reg [1:0] SP; //Stack pointer
reg [3:0] stacks [3:0]; //Stack registers

wire [3:0] STK; //Stack data output

assign STK = stacks[SP]; //Assign stack output

always@(negedge CP) begin
if(FE_N == 0 && PUP == 1) begin
stacks[SP] = uPC; //Push uPC into stacks[SP] on negative edge
end
else stacks[SP]=stacks[SP];
end

always@(posedge CP) begin
if(RE_N==0) AR = R;
else AR = AR;
uPC = Iout;

if(FE_N==0) begin //If file enable is true do push/pop
if(PUP==1) begin
SP = SP + 1;
end
else SP = SP - 1; //Pop stack pointer
end
end

always@(MUXOUT or Cn) begin
if(Cn==1) begin
if(MUXOUT=='hF) begin
Iout = 'h0;
Cn4 = 1;
end
else begin
Iout = MUXOUT + 1;
Cn4 = 0;
end
end
else begin
Iout = MUXOUT;
Cn4 = 0;
end
end

//Data source select
always@(S or ZERO_N or OR or uPC or AR or STK or D) begin
if(ZERO_N==0) MUXOUT = 'h0;
else begin
case (S)
'b00:MUXOUT = uPC;
'b01:MUXOUT = AR;
'b10:MUXOUT = STK;
'b11:MUXOUT = D;
endcase
for(i=0;i<4;i=i+1) begin
if(OR==1) MUXOUT = 1;
end
end
end
//Output enable
always@(MUXOUT or OE_N) begin
if(OE_N==1) Y = 'bZZZZ;
else Y = MUXOUT;
end
endmodule
 
"Adam" <1@1.com> wrote in message news:<t062b.5446$7G2.2258@twister.nyroc.rr.com>...
I have a verilog design and testbench I made using Webpack 4.2 and am
simulating it using Modelsim5.5e. It has a stack pointer(SP) in it that I
need to initialize to a value for simulation.
You need to initialize any pointer for both simulation
*and* synthesis for the proper working of the logic.

How do I do this in Verilog?
My target device is an xc2s100 but I'm wondering if there is a general way
to do it. The code I'm working on is below(an Am2909 sequencer). This is
my first design(other than simple registers/muxes) so any feedback
appreciated.

Thanks,

Adam

[...]
always@(posedge CP) begin
if(RE_N==0) AR = R;
else AR = AR;
uPC = Iout;

if (!RE_N) // assuming RE_N is your active low reset
SP = 4'b0; // and your pointer is 4-bit wide.
else

if(FE_N==0) begin //If file enable is true do push/pop
if(PUP==1) begin
SP = SP + 1;
end
else SP = SP - 1; //Pop stack pointer
end
end

[...]

HTH.
- Swapnajit.
--
=-=-= 100% pure Verilog PLI - go, get it ! =-=-=
Principles of Verilog PLI -By- Swapnajit Mittra
Kluwer Academic Publishers. ISBN: 0-7923-8477-6
http://www.angelfire.com/ca/verilog/
 
You could use an asynchronous reset. The code below requires an actual
reset signal (used or unused)but it will guarantee that the registers
primitives used will guarantee the selected power-up state. In your
simulation, you then need to assert the reset at the start of your
simulation to initialize the values.

always @ (posedge CP or negedge nReset)
if( ~nReset ) begin
AR <= 3'h0;
SP <= 2'h3;
end
else begin
if(RE_N==0) AR = R;
else AR = AR;
uPC = Iout;
if(FE_N==0) begin //If file enable is true do push/pop
if(PUP==1) SP = SP + 1;
else SP = SP - 1; //Pop stack pointer
end
end
 
I forgot to finish the edits and make a comment in the code segment in the
previous post.
A word of warning: blocking assignments (=) tend to bite the designer in
synchronous code where the non-blocking operator (<=) is preferred. Be
careful!

A good design rule is to use (and count on the behavior of) non-blocking
operators for synchronous code and blocking operators for asynchronous
blocks. Most synthesizers don't like to see a mixture of the two forms in
one block so stick to the rule above and your code will look like most
professional Verilog code.
 
"Adam" <1@1.com> wrote in message
news:Zp83b.19258$lk1.770@twister.nyroc.rr.com...
Thanks for the advice. So if the chips themselves don't have resets, to
implement them with HDL's I will have to add that capability.
That's the easiest way to get simulation and synthesis match.

Icarus verilog may support initial blocks for synthesis as well - this was
something that was developed because of the power-up states allowed in the
Xilinx parts according to what I was told on this newsgroup. I've also
begged Synplicity to include support for initial blocks to pass INITs down
to the Xilinx tools.

Without Icarus (or other vendors' support), the INIT attributes can be
applied bit-by-bit for the counter bits in the Xilinx user constraints file
or through a synthesizer set of constraints that get passed to Xilinx
through the edif or an .ncf file. An initial block is still required in
your simulation code. It's up to the user to verify the INITs and the
initial block values all correspond.

This messy detail is why I suggested the async mechanism. It'll give you
what you want without INITs or initial values for the counter bits; it's all
in the code.

- John_H
 

Welcome to EDABoard.com

Sponsor

Back
Top