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!