Sequential microprocessor code to vhdl - easy conversion tip

O

Oliver Mattos

Guest
Hi,

I have a bit of microprocessor code that looks like this (it's basically bit banging a synchronous serial protocol, with certain timing requirements):

SetPin(A1, HIGH);
delay(100ms)
SetPin(A1, LOW);
delay(10ms)
SetPin(A1, HIGH);
delay(100ms)
for (i=0; i<10; i++) {
SetPin(A1, LOW);
SetPin(A2, (data>>=1)&1 );
delay(10ms)
SetPin(A1, HIGH);
delay(12ms)
}
.... etc.


Basically, it's a sequence of actions happening at variable time intervals.

How would you convert this neatly to VHDL? (I have a clock source of known frequency) I've thought of various methods involving state machines and counters, but they always end up horribly complex.

One method I thought of:

WAIT UNTIL rising_edge(clk);
time <= time+1;
IF time < 0 THEN A1 <= '1'; END IF;
IF time < 100 THEN A1 <= '0'; END IF;
IF time < 210 THEN A1 <= '1'; END IF;
IF time < 310 THEN A1 <= '0'; END IF;
IF time < 310 THEN A2 <= data(0); END IF;
IF time < 410 THEN A1 <= '1'; END IF;
IF time < 510 THEN A1 <= '0'; END IF;
IF time < 510 THEN A2 <= data(1); END IF;
IF time < 610 THEN A1 <= '1'; END IF;
IF time < 710 THEN A1 <= '0'; END IF;
IF time < 710 THEN A2 <= data(2); END IF;
etc....

I'm guessing the above logic will lead to a large slow design and messy code...

Is there a nice and easy way to do this?

Oliver


PS. yes I realize there are bugs in both bits of code, but it gets the example across...
 
On 2/2/2011 2:04 PM, Oliver Mattos wrote:
I have a bit of microprocessor code that looks like this (it's basically bit banging a synchronous serial protocol, with certain timing requirements):
SetPin(A1, HIGH);
delay(100ms)
SetPin(A1, LOW);
delay(10ms)
SetPin(A1, HIGH);
delay(100ms)
for (i=0; i<10; i++) {
SetPin(A1, LOW);
SetPin(A2, (data>>=1)&1 );
delay(10ms)
SetPin(A1, HIGH);
delay(12ms)
}

Basically, it's a sequence of actions happening at variable time intervals.
How would you convert this neatly to VHDL? (I have a clock source of known frequency) I've thought of various methods involving state machines and counters, but they always end up horribly complex.

I would write a single clocked process using the
'clock source of known frequency' to do
the following at every rising edge:

1. count gets count + 1
2. if rollover count gets zero
3. case count is special, toggle appropriate output.

-- Mike Treseler
 
On Feb 3, 5:04 pm, Mike Treseler <mtrese...@gmail.com> wrote:
On 2/2/2011 2:04 PM, Oliver Mattos wrote:



I have a bit of microprocessor code that looks like this  (it's basically bit banging a synchronous serial protocol, with certain timing requirements):
SetPin(A1, HIGH);
delay(100ms)
SetPin(A1, LOW);
delay(10ms)
SetPin(A1, HIGH);
delay(100ms)
for (i=0; i<10; i++) {
   SetPin(A1, LOW);
   SetPin(A2, (data>>=1)&1 );
   delay(10ms)
   SetPin(A1, HIGH);
   delay(12ms)
}
Basically, it's a sequence of actions happening at variable time intervals.
How would you convert this neatly to VHDL? (I have a clock source of known frequency)  I've thought of various methods involving state machines and counters, but they always end up horribly complex.

I would write a single clocked process using the
'clock source of known frequency' to do
the following at every rising edge:

1. count gets count + 1
2. if rollover count gets zero
3. case count is special, toggle appropriate output.

             -- Mike Treseler
I've seen an interesting use of "subroutines" in a state machine
for just this sort of process. The FSM would have a state called
"spin" or something like that. From another state, you'd
set a signal "time_to_spin" with the number of clock cycles
to sit in the "spin" state, and another signal "return_state"
with the state to fall into when the spin time expires. Then
the "spin" state looks something like:

when SPIN =>
time_to_spin <= time_to_spin - 1;
if time_to_spin = (others => '0') then
state <= return_state;
end if;

-- Gabor
 
On 2/4/2011 7:34 AM, Gabor Sz wrote:
On Feb 3, 5:04 pm, Mike Treseler<mtrese...@gmail.com> wrote:
On 2/2/2011 2:04 PM, Oliver Mattos wrote:



I have a bit of microprocessor code that looks like this (it's basically bit banging a synchronous serial protocol, with certain timing requirements):
SetPin(A1, HIGH);
delay(100ms)
SetPin(A1, LOW);
delay(10ms)
SetPin(A1, HIGH);
delay(100ms)
for (i=0; i<10; i++) {
SetPin(A1, LOW);
SetPin(A2, (data>>=1)&1 );
delay(10ms)
SetPin(A1, HIGH);
delay(12ms)
}
Basically, it's a sequence of actions happening at variable time intervals.
How would you convert this neatly to VHDL? (I have a clock source of known frequency) I've thought of various methods involving state machines and counters, but they always end up horribly complex.

I would write a single clocked process using the
'clock source of known frequency' to do
the following at every rising edge:

1. count gets count + 1
2. if rollover count gets zero
3. case count is special, toggle appropriate output.

-- Mike Treseler

I've seen an interesting use of "subroutines" in a state machine
for just this sort of process. The FSM would have a state called
"spin" or something like that. From another state, you'd
set a signal "time_to_spin" with the number of clock cycles
to sit in the "spin" state, and another signal "return_state"
with the state to fall into when the spin time expires. Then
the "spin" state looks something like:

when SPIN =
time_to_spin<= time_to_spin - 1;
if time_to_spin = (others => '0') then
state<= return_state;
end if;

-- Gabor
Yes. Nice example.
It's ok to have more than one 'state' register.
Sometimes structure and syntax gets it the way of logic.
And vice versa.

-- Mike Treseler
 
On 2/3/2011 5:04 PM, Mike Treseler wrote:
On 2/2/2011 2:04 PM, Oliver Mattos wrote:
I have a bit of microprocessor code that looks like this (it's
basically bit banging a synchronous serial protocol, with certain
timing requirements): SetPin(A1, HIGH); delay(100ms) SetPin(A1,
LOW); delay(10ms) SetPin(A1, HIGH); delay(100ms) for (i=0; i<10;
i++) { SetPin(A1, LOW); SetPin(A2, (data>>=1)&1 ); delay(10ms)
SetPin(A1, HIGH); delay(12ms) }

Basically, it's a sequence of actions happening at variable time
intervals. How would you convert this neatly to VHDL? (I have a
clock source of known frequency) I've thought of various methods
involving state machines and counters, but they always end up
horribly complex.


I would write a single clocked process using the 'clock source of
known frequency' to do the following at every rising edge:

1. count gets count + 1 2. if rollover count gets zero 3. case count
is special, toggle appropriate output.
I think this approach is very straight forward and easy to implement,
even though I believe it carries no information on the structure of the
data itself and maybe very hard to modify or extend.

I replied to the "same" post (with a different subject) arguing that an
fsm with 4 states may do the job.
Here is the reference:


From: Alessandro Basili <alessandro.basili@cern.ch>
Newsgroups: comp.lang.vhdl
Subject: Re: Conversion of sequential time-sensitive algorithm to VHDL
Date: Fri, 11 Feb 2011 12:03:17 -0500
Lines: 53
Message-ID: <8rl8enFkroU1@mid.individual.net>
 
On 2/3/2011 5:04 PM, Mike Treseler wrote:
On 2/2/2011 2:04 PM, Oliver Mattos wrote:
I have a bit of microprocessor code that looks like this (it's
basically bit banging a synchronous serial protocol, with certain
timing requirements):
SetPin(A1, HIGH);
delay(100ms)
SetPin(A1, LOW);
delay(10ms)
SetPin(A1, HIGH);
delay(100ms)
for (i=0; i<10; i++) {
SetPin(A1, LOW);
SetPin(A2, (data>>=1)&1 );
delay(10ms)
SetPin(A1, HIGH);
delay(12ms)
}

Basically, it's a sequence of actions happening at variable time
intervals.
How would you convert this neatly to VHDL? (I have a clock source of
known frequency) I've thought of various methods involving state
machines and counters, but they always end up horribly complex.


I would write a single clocked process using the
'clock source of known frequency' to do
the following at every rising edge:

1. count gets count + 1
2. if rollover count gets zero
3. case count is special, toggle appropriate output.
I think this approach is very straight forward and easy to implement,
even though I believe it carries no information on the structure of the
data itself and maybe very hard to modify or extend.

I replied to the "same" post (with a different subject) arguing that an
fsm with 4 states may do the job.
Here is repeated:

Looking at the structure of his sequence I don't believe the OP needs
more than an FSM and a counter and it looks to me it will need only 4
states:

idle (wait for the conditions to start the sequence)
set1 (used to set 100ms signal)
wait (used to wait 10ms)
set2 (used to set 12ms signals)

The FSM will need some additional logic to distinguish the two phases:

init_done
loop_done

and arcs may follow this logic:

idle -> set1 (start/reset/begin... as you like)
set1 -> wait when timer = 100ms
wait -> set1 when (timer = 10ms) and init_done = 0;
wait -> set2 when (timer = 10ms) and init_done = 1;
wait -> idle when (timer = 10ms) and loop_done = 1;
set2 -> wait when timer = 12ms

In case one day you will find that instead of a loop of 10 you will need
a loop of 200 you will simply need to change the logic for loop_done,
without the need to add 190 states to the FSM, same applies for the init
part.

Al

p.s.: didn't know how to reference to my other post, that is why I
copied it here.
 

Welcome to EDABoard.com

Sponsor

Back
Top