Sequential microprocessor code to vhdl - easy conversion tips?

Discussion in 'VHDL' started by Oliver Mattos, Feb 2, 2011.

  1. 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...
     
    Oliver Mattos, Feb 2, 2011
    #1
    1. Advertising

  2. 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
     
    Mike Treseler, Feb 3, 2011
    #2
    1. Advertising

  3. Oliver Mattos

    Gabor Sz Guest

    On Feb 3, 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.
    >
    >              -- 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
     
    Gabor Sz, Feb 4, 2011
    #3
  4. On 2/4/2011 7:34 AM, Gabor Sz wrote:
    > On Feb 3, 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.
    >>
    >> -- 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
     
    Mike Treseler, Feb 6, 2011
    #4
  5. Oliver Mattos

    Al Guest

    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 <>
    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: <>
     
    Al, Feb 11, 2011
    #5
  6. Oliver Mattos

    Al Guest

    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.
     
    Al, Feb 11, 2011
    #6
  7. Oliver Mattos

    Kellyng91

    Joined:
    Apr 5, 2011
    Messages:
    1
    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.

    Hi, is there any other method of write this coding instead of count + 1?
     
    Kellyng91, Apr 5, 2011
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. abhishek jain

    VHDL code for a microprocessor

    abhishek jain, Jan 31, 2004, in forum: VHDL
    Replies:
    5
    Views:
    12,111
    Jonathan Bromley
    Feb 4, 2004
  2. Vladutzz
    Replies:
    0
    Views:
    1,197
    Vladutzz
    Aug 3, 2009
  3. Oliver Mattos
    Replies:
    8
    Views:
    1,133
    rickman
    Feb 12, 2011
  4. Oliver Mattos
    Replies:
    0
    Views:
    783
    Oliver Mattos
    Feb 3, 2011
  5. Oliver Mattos
    Replies:
    1
    Views:
    791
Loading...

Share This Page