State machine incrementing

  • Thread starter zooplibob@gmail.com
  • Start date
Z

zooplibob@gmail.com

Guest
I have the following code in my state machine for an I2C controller.
Basically when I get to state data_out4, I want to increment the
variable "datacount" by 1. However I stay in that state for many clock
cycles and it increments many times. How can I code it so that it
increments the variable only once when I'm in that state? Thanks

elsif state = data_out1 then
sda_sig <= 'Z';
scl_sig <= '0';
elsif state = data_out2 then
if data_out(7-datacount) = '0' then
sda_sig <= '0';
else
sda_sig <= 'Z';
end if;
scl_sig <= '0';
elsif state = data_out3 then
if data_out(7-datacount) = '0' then
sda_sig <= '0';
else
sda_sig <= 'Z';
end if;
scl_sig <= '1';
elsif state = data_out4 then
if data_out(7-datacount) = '0' then
sda_sig <= '0';
else
sda_sig <= 'Z';
end if;
scl_sig <= '0';
datacount:=datacount+1;
 
Its interesting that it simulates correctly in the Xilinx simulator,
but when running on the CPLD, it increments as fast as possible.
I think this is more of a synthesis problem, because I could just
expand those lines instead of using the variable "datacount" hardcode
it from 0 to 7 and just copy and paste the whole thing 7 times, but it
seems like I should be able to write it like this and have it
synthesize properly
 
<zooplibob@gmail.com> wrote in message
news:cfda7a27-6949-48a8-9fad-a29bd6704a61@p20g2000yqi.googlegroups.com...
I have the following code in my state machine for an I2C controller.
Basically when I get to state data_out4, I want to increment the
variable "datacount" by 1. However I stay in that state for many clock
cycles and it increments many times. How can I code it so that it
increments the variable only once when I'm in that state? Thanks
1. Use a synchronous process
process(Clock)
begin
if rising_edge(Clock) then
... -- Put your code here
end if;
end process;

2. Synchronize all inputs the the clock before using
3. Simulate
4. Perform static timing analysis

Kevin Jennings
 
zooplibob@gmail.com wrote:
I have the following code in my state machine for an I2C controller.
Basically when I get to state data_out4, I want to increment the
variable "datacount" by 1. However I stay in that state for many clock
cycles and it increments many times. How can I code it so that it
increments the variable only once when I'm in that state? Thanks

elsif state = data_out1 then
sda_sig <= 'Z';
scl_sig <= '0';
elsif state = data_out2 then
if data_out(7-datacount) = '0' then
sda_sig <= '0';
else
sda_sig <= 'Z';
end if;
scl_sig <= '0';
elsif state = data_out3 then
if data_out(7-datacount) = '0' then
sda_sig <= '0';
else
sda_sig <= 'Z';
end if;
scl_sig <= '1';
elsif state = data_out4 then
if data_out(7-datacount) = '0' then
sda_sig <= '0';
else
sda_sig <= 'Z';
end if;
scl_sig <= '0';
datacount:=datacount+1;
One possibility would be to create another state, so that it is only in
the data_out4 state for one cycle and then waits the additional cycles
in a new state.

Another possibility would be to increment "datacount" at the same point
that you set the state to data_out4, assuming that only happens once.
(Since you didn't include the code that changes state it's hard to tell.)

Chris
 
On Mar 13, 7:06 pm, "zoopli...@gmail.com" <zoopli...@gmail.com> wrote:
I have the following code in my state machine for an I2C controller.
Basically when I get to state data_out4, I want to increment the
variable "datacount" by 1. However I stay in that state for many clock
cycles and it increments many times.  How can I code it so that it
increments the variable only once when I'm in that state? Thanks

       elsif state = data_out1 then
                                sda_sig <= 'Z';
                                scl_sig <= '0';
       elsif state = data_out2 then
                                if data_out(7-datacount) = '0' then
                                        sda_sig <= '0';
                                else
                                        sda_sig <= 'Z';
                                end if;
                                scl_sig <= '0';
       elsif state = data_out3 then
                                if data_out(7-datacount) = '0' then
                                        sda_sig <= '0';
                                else
                                        sda_sig <= 'Z';
                                end if;
                                scl_sig <= '1';
       elsif state = data_out4 then
                                if data_out(7-datacount) = '0' then
                                        sda_sig <= '0';
                                else
                                        sda_sig <= 'Z';
                                end if;
                                scl_sig <= '0';
                                datacount:=datacount+1;
To figure this out, it's just as important to reveal the process
(sensitivity, and master clock condition) wrapping your sequential
logic above as the logic itself. There could be all kinds of other
race conditions going on as a result of the code structure. I'm also
assuming you've checked for noise, risetime, & levels on the holy
trinity of bringing up a real board: physical clock signals, reset
signals, and power/ground.

- Kenn
 

Welcome to EDABoard.com

Sponsor

Back
Top