Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
770 Views

output doesn't toggle when simulating with other entities in Modelsim

Hi, I'm working on a vhdl testbench to simulate the behaviour of an I2C bus. I started with an original code (written in verilog) that works, made some changes to it an simulate it's behaviour as a stand-alone module using the .do file:

 

Code:

# I2C HPS

add wave -noupdate -label hps_sclk /I2C_to_GPIO/hps_sclk

add wave -noupdate -label hps_sda /I2C_to_GPIO/hps_sda_i

add wave -noupdate -label hps_sda_o_e /I2C_to_GPIO/hps_sda_o_e

# parallel store

add wave -noupdate -label gpio_input_reg /I2C_to_GPIO/gpio_input_reg

add wave -noupdate -label exph_input_reg /I2C_to_GPIO/exph_input_reg

add wave -noupdate -label expl_input_reg /I2C_to_GPIO/expl_input_reg

# inputs

add wave -noupdate -label gpio_input /I2C_to_GPIO/gpio_input

add wave -noupdate -label exp_input /I2C_to_GPIO/exp_input

# read/write byte count

add wave -noupdate -label hps_data_count_rd /I2C_to_GPIO/hps_data_count

# parallel store

add wave -noupdate -label gpio_output_pre /I2C_to_GPIO/gpio_output_pre

add wave -noupdate -label exph_output_pre /I2C_to_GPIO/exph_output_pre

add wave -noupdate -label expl_output_pre /I2C_to_GPIO/expl_output_pre

# outputs

add wave -noupdate -label gpio_output /I2C_to_GPIO/gpio_output

add wave -noupdate -label exp_output /I2C_to_GPIO/exp_output

add wave -noupdate -label dc_pwren /I2C_to_GPIO/dc_pwren

# i2c hps flags

add wave -noupdate -label hps_read_oper /I2C_to_GPIO/hps_read_oper

add wave -noupdate -label hps_data_or_address /I2C_to_GPIO/hps_data_or_address

add wave -noupdate -label hps_done /I2C_to_GPIO/hps_done

add wave -noupdate -label ack_flag /I2C_to_GPIO/ack_flag

add wave -noupdate -label hps_count /I2C_to_GPIO/hps_count

add wave -noupdate -label hps_sda_is_ack /I2C_to_GPIO/hps_sda_is_ack

 

# clock

force -freeze sim:/I2C_to_GPIO/hps_sclk 1 25, 0 {75 ns} -r 100

 

force -drive sim:/I2C_to_GPIO/gpio_input 00100010 0

force -drive sim:/I2C_to_GPIO/exp_input 0110101100 0

 

#######################################################################

# write

#######################################################################

# start pulse high

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 25

run 50

# start 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 150

# 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 100

# 0 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 200

# 1 1 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 300

# write and wait ack

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0 -cancel 100

run 200

# 0 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 200

# 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 100

# 0 0 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 300

# 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 100

# 0 and wait ack

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0 -cancel 100

run 200

# 1 1 1 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 400

# 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 100

# 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 100

# 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 100

# 1 and wait ack

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0 -cancel 100

run 200

# 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 100

# 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 100

# 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 100

# 0

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0

run 100

# 1 1

force -drive sim:/I2C_to_GPIO/hps_sda_i 1 0

run 200

# 0 0 and wait ack

force -drive sim:/I2C_to_GPIO/hps_sda_i 0 0 -cancel 200

run 2000

When using the module - do file combination, it seemed to be working properly, so I moved ahead and added an I2C master entity to the bus, added a stimulus entity and a test-bench for connecting the units:

 

Code:

-- I omitted definition and architecture.. --

begin

 

slave: I2C_to_GPIO port map (

hps_sda_i => sda,

hps_sda_o_e => sda_o_e,

hps_sclk => scl,

gpio_input => gpio_input,

gpio_output => gpio_output,

write_pulse => write_pulse,

exp_input => exp_input,

exp_output => exp_output,

dc_pwren => dc_pwren,

state => gpio_state ;) // had to add this output bc sda_o_e wouldn't toggle

master: i2c_master port map (

clk => clock,

reset_n => reset_n,

ena => ena,

addr => addr,

rw => rw,

data_wr => data_wr, -- data to write to slave

busy => busy,

data_rd => data_rd, -- data read from slave

ack_error => ack_error,

sda_i => sda,

scl => scl,

mem_present => mem_present);

 

 

stimulus_tb: stimulus port map (

clock => clock,

reset_n => reset_n,

ena => ena,

addr => addr,

rw => rw,

data_wr => data_wr,

scl => scl,

sda => sda,

sda_o_e => sda_o_e,

mem_present => mem_present,

start_reg => start,

cmd => cmd,

rst_n => reset);

end;

The problem when using the former, is that the output hps_sda_o_e from I2C_to_GPIO entity wasn't toggling, even when I run using break points to the lines were it should, I even disconnected it from stimulus' 'sda_o_e' to make sure that there was nothing driving it, toggle the logic of the output, but still no toggling.. Finally, I added the 'state' output and made state change to a unique value every time sda_o_e was supposed to toggle. Since state did change, I set hps_sda_o_e to be the msb from state and this did the trick, I include the proccess in I2C_to_GPIO.v were hps_sda_o_e is driven:

 

see attached for code and definition

 

I want to know if this behavior is due to something that I'm missing and what could I do to prevent it. Thanks in advance!

 

0 Kudos
12 Replies
Highlighted
Valued Contributor III
3 Views

I dont really understand, from your description, what the problem is. If something isnt toggling then the usualy debug is to trace the signal back until you find the source of the problem. 

 

As a side note - You would probably be better off driving the design from the testbench rather than force from a .do file. Are you sure the paths here are correct? have they changed at all between original verilog and vhdl top level? Force is really only for overriding a value already set in a test.
0 Kudos
Highlighted
Valued Contributor III
3 Views

 

--- Quote Start ---  

I dont really understand, from your description, what the problem is. If something isnt toggling then the usualy debug is to trace the signal back until you find the source of the problem. 

 

--- Quote End ---  

 

 

Hi, sorry I didn't make myself clear the first time I posted (by the way, I don't see the content of my post, just the title), the problem is that just a single output from a stand alone working module stops toggling when added to a test bench, and the fix is to assign that output to another signal at the same time that is supposed to toggle.  

 

 

 

--- Quote Start ---  

As a side note - You would probably be better off driving the design from the testbench rather than force from a .do file. Are you sure the paths here are correct? have they changed at all between original verilog and vhdl top level? Force is really only for overriding a value already set in a test. 

--- Quote End ---  

 

The paths are correct and everything is working, I'm using a test bench, the do file was using for testing the module as a stand alone unit.
0 Kudos
Highlighted
Valued Contributor III
3 Views

 

--- Quote Start ---  

Hi, sorry I didn't make myself clear the first time I posted (by the way, I don't see the content of my post, just the title), the problem is that just a single output from a stand alone working module stops toggling when added to a test bench, and the fix is to assign that output to another signal at the same time that is supposed to  

--- Quote End ---  

 

 

Sorry, it was moderated - I cleared it (I could see the text, hence my reply) 

 

Again, not sure what you mean by " assign that output to another signal at the same time that is supposed to toggle". You should just assign it to a signal and then monitor the signal on a wave window. 

It might be easier if you posted the actual code and then specify exactly what isnt happening that you expect. That way, we can see the same problems ourselves.
0 Kudos
Highlighted
Valued Contributor III
3 Views

Hi, here is the code that works fine by it self: 

 

if (condition_1) begin signal <= '1'; end if (condition_2) begin signal <= '0'; end assign output <= signal;  

 

The conditions are met both when simulating as a stand alone unit and embedded, the problem is, when embedded on a test bench, even though the conditions are met, the output doesn't toggle, this fix made it work: 

 

if (condition_1) begin signal <= '1'; other_signal <= '1'; end if (condition_2) begin signal <= '0'; other_signal <= '0'; end assign output <= other_signal;
0 Kudos
Highlighted
Valued Contributor III
3 Views

Again that doesnt really explain anything. Can you post the whole code?

0 Kudos
Highlighted
Valued Contributor III
3 Views

Here it is, I commented the two portions of the code where I'm seeing the issue: 

 

 

state <= 8'h07; // signal sda_o_e <= 1'b0; // other_signal  

 

and 

 

sda_o_e <= 1'b1; // signal state <= 8'h81; // other_signal  

 

assign at the bottom: 

 

assign hps_sda_o_e = state; // change from assign hps_sda_o_e = sda_o_e;
0 Kudos
Highlighted
Valued Contributor III
3 Views

and the testbench?

0 Kudos
Highlighted
Valued Contributor III
3 Views

here's the test bench

0 Kudos
Highlighted
Valued Contributor III
3 Views

and you forgot load.txt

0 Kudos
Highlighted
Valued Contributor III
3 Views

sorry.. here it is

0 Kudos
Highlighted
Valued Contributor III
3 Views

Its actually a Verilog syntax problem. 

 

The end of your "sending your read data" always block, you have this code: 

 

end else state <= 8'h07; // signal sda_o_e <= 1'b0; // other_signal end  

 

Note there is no begin..end around the assignments. That means that only the state asignment is in the else, and the sda_o_e <= 1'b0; is in the original start-stop if block. This will mean this assignment to 0 always overrides whatever else was assigned. 

 

its a bit of a gotcha in verilog that you're allowed to code without begin..end, but you must remember that only 1 line of code gets included.  

Putting begin..end around it fixed the problem.
0 Kudos
Highlighted
Valued Contributor III
3 Views

Hi, after simulating with the begin.. end it worked as you said. Thank you!

0 Kudos