Verilog code + test bench + logic not clear.

D

dash82

Guest
Hi,

My questions are regarding the code that is posted at the end.

I am a bit confused as to how the flow of the code would proceed.
There is no "always" statement in the code.

First, two instances of cic_interp are instantiated .i.e.
cic_interp_i & cic_interp_q . The signal assignments happen. The most
significant signals i_in and q_in are assigned to signal_in of
cic_interp_i & cic_interp_q.

Question 1:

Do both (cic_interp_i & cic_interp_q) instantiation and assignment
happen at the execution time 0 ?

Or for that matter, all (cic_interp_i , cic_interp_q, phase_acc_tx &
tx_cordic_0) instantiations happen at time 0 ?

I am doubtful of what I am thinking above. Because I can see that
cic_interp_i's output signal bb_i is being assigned as input in
tx_cordic_0. So, if I go by my logic, then wrong assignments would
happen.

Question 2:

Lets assume that some logic is defined for all (cic_interp_i ,
cic_interp_q, phase_acc_tx & tx_cordic_0) modules somewhere else. And
suppose cic_inter_i module logic takes 5 clock cycles to finish its
task and tx_cordic_0 module logic takes 8 clock cycles to finish its
task. So, will tx_cordic_0 wait for 5 clock cycles for cic_interp_i to
finish its task, produce bb_i and then tx_cordic_0 uses this new bb_i
and then takes additional 8 clock cycles to finish its task ?
So, total completion time would be 13 clock cycles ? Am I thinking
right or there is something wrong ?

Thanks !

Shah.

tx_chain.v code (The code is open source and protected by GNU GPL. I
have omitted the license details to save space.)

------------------
module tx_chain
(input clock,
input reset,
input enable,
input wire [7:0] interp_rate,
input sample_strobe,
input interpolator_strobe,
input wire [31:0] freq,
input wire [15:0] i_in,
input wire [15:0] q_in,
output wire [15:0] i_out,
output wire [15:0] q_out
);

wire [15:0] bb_i, bb_q;

cic_interp cic_interp_i
( .clock(clock),.reset(reset),.enable(enable),
.rate(interp_rate),.strobe_in(interpolator_strobe),.strobe_out(sample_strobe),
.signal_in(i_in),.signal_out(bb_i) );

cic_interp cic_interp_q
( .clock(clock),.reset(reset),.enable(enable),
.rate(interp_rate),.strobe_in(interpolator_strobe),.strobe_out(sample_strobe),
.signal_in(q_in),.signal_out(bb_q) );

`define NOCORDIC_TX
`ifdef NOCORDIC_TX
assign i_out = bb_i;
assign q_out = bb_q;
`else
wire [31:0] phase;

phase_acc phase_acc_tx
(.clk(clock),.reset(reset),.enable(enable),
.strobe(sample_strobe),.freq(freq),.phase(phase) );

cordic tx_cordic_0
( .clock(clock),.reset(reset),.enable(sample_strobe),
.xi(bb_i),.yi(bb_q),.zi(phase[31:16]),
.xo(i_out),.yo(q_out),.zo() );
`endif

endmodule // tx_chain


Followup:
---------------

I tried writing a simple test bench and stepping
through my code simulation, but it just would'nt work. I am including
my code
below. I know the test bench is pretty stupid,
but I atleast expected it to enter my code.

I would be grateful if Mike or anyone else in the group could give a
brief indication as to :

Do both (cic_interp_i & cic_interp_q) instantiation and assignment
happen at the execution time 0 ?

Or for that matter, all (cic_interp_i , cic_interp_q, phase_acc_tx &
tx_cordic_0) instantiations happen at time 0 ?

If not, what would be the flow.? Also, i do understand that signal
assignments are happening in tx_chain code.
But I do believe that much more than instantiations are happening at
different intervals of time.

I do understand that the 'always' statement is defined in the base
classes (Thanks Mike !) . And I do understand the flow in those base
classes.
But, somehow I am confused with the flow for this top module.

Any help is greatly appreciated.

Thanks.

module stimulus;
reg clock;
reg reset;
reg enable;
reg sample_strobe;
reg interpolator_strobe;
wire [7:0] interp_rate ;
wire [31:0] freq ;
wire [15:0] i_in ;
wire [15:0] q_in ;
wire [15:0] i_out ;
wire [15:0] q_out ;

tx_chain testing
(clock,reset,enable,interp_rate,sample_strobe,interpolator_strobe,freq,i_in,q_in,i_out,
q_out);

initial
begin
clock = 1'b1;
reset = 1'b0 ;
enable = 1'b1 ;
sample_strobe = 1'b1 ;
interpolator_strobe = 1'b1 ;

end

endmodule
 
On Fri, 30 Nov 2007 13:55:15 -0800 (PST),
dash82 <dhavalrules@gmail.com> wrote:

My questions are regarding the code that is posted at the end.
[which was...]

module tx_chain
(input clock,
input reset,
input enable,
input wire [7:0] interp_rate,
input sample_strobe,
input interpolator_strobe,
input wire [31:0] freq,
input wire [15:0] i_in,
input wire [15:0] q_in,
output wire [15:0] i_out,
output wire [15:0] q_out
);

wire [15:0] bb_i, bb_q;

cic_interp cic_interp_i
( .clock(clock),.reset(reset),.enable(enable),
.rate(interp_rate),.strobe_in(interpolator_strobe),.strobe_out(sample_strobe),
.signal_in(i_in),.signal_out(bb_i) );

cic_interp cic_interp_q
( .clock(clock),.reset(reset),.enable(enable),
.rate(interp_rate),.strobe_in(interpolator_strobe),.strobe_out(sample_strobe),
.signal_in(q_in),.signal_out(bb_q) );

`define NOCORDIC_TX
`ifdef NOCORDIC_TX
assign i_out = bb_i;
assign q_out = bb_q;
`else
// unused kruft
`endif

endmodule // tx_chain

I am a bit confused as to how the flow of the code would proceed.
There is no "always" statement in the code.
There may well be "always" statements in the
cic_interp module, of course.

First, two instances of cic_interp are instantiated .i.e.
cic_interp_i & cic_interp_q .
Like any module instantiation, that happens as part of
elaboration and is all completely done before simulation
actually starts at time 0.

The signal assignments happen.
Which ones? There are signal assignments (properly
speaking "continuous assignments") all over the place.
Most of them are implicit; when you connect a signal
to a module's port using the syntax
.port_name(signal_name)
syntax, then for an INPUT port there is an implicit
continuous assignment from the signal to the innards
of the module; for an OUTPUT port there is an implicit
continuous assign from inside the module to the
connected signal.

The most
significant signals i_in and q_in are assigned to
signal_in of cic_interp_i & cic_interp_q.
You'll have a clearer picture in your head if you
say they are "connected".

Question 1:

Do both (cic_interp_i & cic_interp_q) instantiation and assignment
happen at the execution time 0 ?
No. Instantiation happens *before* time 0. The continuous
assignment does whatever it needs to do in order to make
sure that its target is always updated from the value of its
source; in practice this means...
- the assignment is probably executed once at time 0;
- whenever the source expression changes at any future
time, the assignment is executed again to update the
target appropriately.
It's not quite as simple as that, for a bunch of reasons,
but that's a pretty good start.

Or for that matter, all (cic_interp_i , cic_interp_q, phase_acc_tx &
tx_cordic_0) instantiations happen at time 0 ?
See above; except that you don't have instances
of phase_acc_tx or tx_cordic_0.

I am doubtful of what I am thinking above. Because I can see that
cic_interp_i's output signal bb_i is being assigned as input in
tx_cordic_0. So, if I go by my logic, then wrong assignments would
happen.
But tx_cordic_0 isn't instantiated, because you've
disabled the instantiation using your `ifdef. Instead
the two explicit continuous assignments

assign i_out = bb_i;
assign q_out = bb_q;
continuously drive the cic_interp_i modules' outputs
on to your tx_chain module's output.

Question 2:

Lets assume that some logic is defined for all (cic_interp_i ,
cic_interp_q, phase_acc_tx & tx_cordic_0) modules somewhere else.
One would sincerely hope so :)

suppose cic_inter_i module logic takes 5 clock cycles to finish its
task and tx_cordic_0 module logic takes 8 clock cycles to finish its
task. So, will tx_cordic_0 wait for 5 clock cycles for cic_interp_i to
finish its task, produce bb_i and then tx_cordic_0 uses this new bb_i
and then takes additional 8 clock cycles to finish its task ?
So, total completion time would be 13 clock cycles ? Am I thinking
right
No. You are in some vague way thinking of the module instances
as if they were function calls. They are not; they are statically
instantiated, and they sit there for the life of the simulation,
doing whatever their internal code determines they should do in
response to changes on their inputs. In particular, they will
do what we sophisticated engineers know as "bugger all" if they
don't have activity on their clock inputs.

Followup:
I tried writing a simple test bench and stepping
through my code simulation, but it just would'nt work.
See my response to your post in the earlier thread.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Welcome to EDABoard.com

Sponsor

Back
Top