- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Again that doesnt really explain anything. Can you post the whole code?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
and the testbench?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
and you forgot load.txt
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, after simulating with the begin.. end it worked as you said. Thank you!
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page