Home arrow News arrow HThreads News arrow Fibonacci Example
User Login
Main Menu
Latest Downloads
File Icon Hybridthreads Compiler: Generation of Application Specific Hardware Thread Cores from C (441)
File Icon Supporting High Level Language Semantics Within Hardware Resident Threads (821)
File Icon RCC Project: Investigating the Feasibility of FPGA-Based Petascale Computing (714)
File Icon Memory Hierarchy for MCSoPC Multithreaded Systems (874)
File Icon htc_v1_setup (167)
Fibonacci Example PDF Print E-mail
Written by Wesley Peck   
Tuesday, 08 August 2006

Fibonacci Example

The following is an example of the Hthreads system. In this simple example, which calculates the first few numbers in the Fibonacci sequence, software and hardware threads interact seamlessly.

Program Flow

The software portion of the code calculates a Fibonacci number, by creating a child thread to do the work. This thread, performs the work by spawning two additional child threads. These child threads are responcible for calculating either the previous, or second previous Fibonacci number. When a thread is asked to calculate Fibonacci 0 or Fibonacci 1, it creates a Hardware thread to perform this action. The hardware thread (granted this is a very simple exampe) only has to write a 1 in the correct address location. Once the hardware thread exits, the child thread may continue its work.

Source Code

  1. #include <stdio.h>
  2. #include <sleep.h>
  3. #include <stdlib.h>
  4. #include <hthread.h>
  5. #include <config.h>
  6. #include <xparameters.h>
  7. #include <xuartns550_l.h>
  8. #define FIBMAX 7
  9. #define HWTI_BASEADDR (void*)(0x63000000)
  10. hthread_mutex_t hwtiMutex;
  11. struct fibonacci {
  12. Huint fibNum;
  13. Huint fibVal;
  14. };
  15. void* findFibHWTI(void * arg) {
  16. //This is the code software would normally be
  17. //running. Instead this is executed in hardware.
  18. struct fibonacci * fib;
  19. fib = (struct fibonacci *) arg;
  20. fib->fibVal = 1;
  21. return NULL;
  22. }
  1. void* findFibonacci(void * arg) {
  2. hthread_attr_t attrBase;
  3. hthread_t threadBase;
  4. hthread_t threadOne;
  5. hthread_t threadTwo;
  6. struct fibonacci * fib;
  7. struct fibonacci fibOne;
  8. struct fibonacci fibTwo;
  9. fib = (struct fibonacci *) arg;
  10. if (fib->fibNum == 0 || fib->fibNum == 1) {
  11. //Set up the attr for a HW thread
  12. hthread_attr_init( &attrBase );
  13. hthread_attr_sethardware( &attrBase, HWTI_BASEADDR );
  14. //Since there is only one HWTI, perform a mutex lock
  15. //on it, then create the HW thread
  16. hthread_mutex_lock( &hwtiMutex );
  17. hthread_create(&threadBase, &attrBase, NULL, (void*)fib);
  18. //Clean up the attr
  19. hthread_attr_destroy( &attrBase );
  20. //Wait for HW thread to finish ... and unlock mutex
  21. hthread_join(threadBase, NULL);
  22. hthread_mutex_unlock( &hwtiMutex );
  23. } else {
  24. fibOne.fibNum = fib->fibNum - 1;
  25. fibTwo.fibNum = fib->fibNum - 2;
  26. //Create two software thread to calculate the two previous Fibonacci numbers.
  27. hthread_create(&threadOne, NULL, findFibonacci, (void*)&fibOne);
  28. hthread_create(&threadTwo, NULL, findFibonacci, (void*)&fibTwo);
  29. //Wait for the child threads to finish
  30. hthread_join(threadOne, NULL);
  31. hthread_join(threadTwo, NULL);
  32. fib->fibVal = fibOne.fibVal + fibTwo.fibVal;
  33. }
  34. return NULL;
  35. }
  1. int main (int argc, char *argv[]) {
  2. hthread_t thread;
  3. struct fibonacci fib;
  4. Huint fibArray[FIBMAX];
  5. Huint i;
  6. //Initialize the hthreads system
  7. hthread_init();
  8. hthread_mutex_init( &hwtiMutex, NULL );
  9. //Calculate the Fibonacci sequence
  10. for( i=0; i<FIBMAX; i++ ) {
  11. fib.fibNum = i;
  12. fib.fibVal = 0;
  13. printf( "Creating Thread for Fibonacci %d\n", i );
  14. hthread_create(&thread, NULL, findFibonacci, (void*)&fib);
  15. hthread_join(thread, NULL);
  16. fibArray[i] = fib.fibVal;
  17. }
  18. for( i=0; i<FIBMAX; i++ ) {
  19. printf( "Fibonacci %d is %d\n", i, fibArray[i] );
  20. }
  21. return 1 ;
  22. }

VHDL Code

  1. library IEEE;
  2. use IEEE.std_logic_1164.all;
  3. use IEEE.std_logic_arith.all;
  4. use IEEE.std_logic_unsigned.all;
  5. use IEEE.std_logic_misc.all;
  6. library Unisim;
  7. use Unisim.all;
  8. ---------------------------------------------------------------------------
  9. -- Thread Manager Entity section
  10. ---------------------------------------------------------------------------
  11. entity user_logic_hwtul is
  12. port (
  13. clock : in std_logic;
  14. intrfc2thrd_status : in std_logic_vector(0 to 3);
  15. intrfc2thrd_result : in std_logic_vector(0 to 31);
  16. thrd2intrfc_opcode : out std_logic_vector(0 to 7);
  17. thrd2intrfc_argument_one : out std_logic_vector(0 to 31);
  18. thrd2intrfc_argument_two : out std_logic_vector(0 to 31)
  19. );
  20. end entity user_logic_hwtul;
  21. ---------------------------------------------------------------------------
  22. -- Architecture section
  23. ---------------------------------------------------------------------------
  24. architecture IMP of user_logic_hwtul is
  25. ---------------------------------------------------------------------------
  26. -- Signal declarations
  27. ---------------------------------------------------------------------------
  28. type hwtul_state is (
  29. START,
  30. IDLE,
  31. WRITE_MEMORY_1,
  32. WRITE_MEMORY_2,
  33. WRITE_MEMORY_3,
  34. WRITE_MEMORY_4,
  35. EXIT_INIT,
  36. EXIT_WAIT
  37. );
  38. signal current_state, next_state : hwtul_state := START;
  39. signal argument, argument_next : std_logic_vector(0 to 31);
  40. signal threadID, threadID_next : std_logic_vector(0 to 31);
  41. signal argVal, argVal_next : std_logic_vector(0 to 31);
  42. signal opcode, opcode_next : std_logic_vector(0 to 7);
  43. signal argOne, argOne_next : std_logic_vector(0 to 31);
  44. signal argTwo, argTwo_next : std_logic_vector(0 to 31);
  45. -- user_status Constants
  46. constant USER_STATUS_RESET : std_logic_vector(0 to 3) := x"1";
  47. constant USER_STATUS_RUN : std_logic_vector(0 to 3) := x"2";
  48. constant USER_STATUS_ACK : std_logic_vector(0 to 3) := x"4";
  49. constant USER_STATUS_PAUSE : std_logic_vector(0 to 3) := x"8";
  50. -- user_opcode Constants
  51. constant OPCODE_NOOP : std_logic_vector(0 to 7) := x"00";
  52. constant OPCODE_HTHREAD_EXIT : std_logic_vector(0 to 7) := x"01";
  53. constant OPCODE_READ : std_logic_vector(0 to 7) := x"02";
  54. constant OPCODE_WRITE : std_logic_vector(0 to 7) := x"03";
  55. constant OPCODE_HTHREAD_SELF : std_logic_vector(0 to 7) := x"04";
  56. constant OPCODE_HTHREAD_YIELD : std_logic_vector(0 to 7) := x"05";
  57. constant OPCODE_HTHREAD_MUTEX_LOCK : std_logic_vector(0 to 7) := x"06";
  58. constant OPCODE_HTHREAD_MUTEX_UNLOCK : std_logic_vector(0 to 7) := x"07";
  59. constant OPCODE_HTHREAD_INTRASSOC : std_logic_vector(0 to 7) := x"08";
  60. -- misc constants
  61. constant Z32 : std_logic_vector(0 to 31) := (others => '0');
  62. constant H32 : std_logic_vector(0 to 31) := (others => '1');
  63. ---------------------------------------------------------------------------
  64. -- Begin architecture
  65. ---------------------------------------------------------------------------
  66. begin -- architecture IMP
  67. HWTUL_STATE_PROCESS : process (clock, argument_next,
  68. opcode_next, argOne_next,
  69. argTwo_next) is
  70. begin
  71. if (clock'event and (clock = '1')) then
  72. argument <= argument_next;
  73. opcode <= opcode_next;
  74. argOne <= argOne_next;
  75. argTwo <= argTwo_next;
  76. argVal <= argVal_next;
  77. threadID <= threadID_next;
  78. thrd2intrfc_opcode <= opcode_next;
  79. thrd2intrfc_argument_one <= argOne_next;
  80. thrd2intrfc_argument_two <= argTwo_next;
  81. if ( intrfc2thrd_status = USER_STATUS_RESET ) then
  82. current_state <= IDLE;
  83. else
  84. current_state <= next_state;
  85. end if;
  86. end if;
  87. end process HWTUL_STATE_PROCESS;
  88. HWTUL_STATE_MACHINE : process (clock) is
  89. begin
  90. -- Default register assignments
  91. next_state <= current_state;
  92. opcode_next <= opcode;
  93. argOne_next <= argOne;
  94. argTwo_next <= argTwo;
  95. argument_next <= argument;
  96. threadID_next <= threadID;
  97. argVal_next <= argVal;
  98. -- The state machine
  99. case current_state is
  100. when START =>
  101. --Set default values
  102. opcode_next <= OPCODE_NOOP;
  103. argOne_next <= Z32;
  104. argTwo_next <= Z32;
  105. next_state <= IDLE;
  106. when IDLE =>
  107. case intrfc2thrd_status is
  108. when USER_STATUS_RUN =>
  109. argument_next <= intrfc2thrd_result;
  110. next_state <= WRITE_MEMORY_1;
  111. when others =>
  112. next_state <= IDLE;
  113. end case;
  114. ---------------------------------------------------------
  115. -- Write a zero value at argument + 4
  116. ---------------------------------------------------------
  117. when WRITE_MEMORY_1 =>
  118. --Prepare the data to write, and the address to write too
  119. argTwo_next <= x"00000001";
  120. argOne_next <= (argument + 4);
  121. next_state <= WRITE_MEMORY_2;
  122. when WRITE_MEMORY_2 =>
  123. --Tell the HWTI to do the write
  124. opcode_next <= OPCODE_WRITE;
  125. next_state <= WRITE_MEMORY_3;
  126. when WRITE_MEMORY_3 =>
  127. --Wait for the HWTI to ACK the write request
  128. if ( intrfc2thrd_status = USER_STATUS_ACK ) then
  129. opcode_next <= OPCODE_NOOP;
  130. next_state <= WRITE_MEMORY_4;
  131. else
  132. next_state <= WRITE_MEMORY_3;
  133. end if;
  134. when WRITE_MEMORY_4 =>
  135. --Wait for the HWTI to tell us to RUN again
  136. if ( intrfc2thrd_status = USER_STATUS_RUN ) then
  137. next_state <= EXIT_INIT;
  138. else
  139. next_state <= WRITE_MEMORY_4;
  140. end if;
  141. ---------------------------------------------------------
  142. -- Exit
  143. -- Initiate the call to the Thread Manager to indicate
  144. -- this thread is done doing its work.
  145. ---------------------------------------------------------
  146. when EXIT_INIT =>
  147. argOne_next <= argVal;
  148. opcode_next <= OPCODE_HTHREAD_EXIT;
  149. next_state <= EXIT_WAIT_ACK;
  150. when EXIT_WAIT_ACK =>
  151. case intrfc2thrd_status is
  152. when USER_STATUS_ACK =>
  153. opcode_next <= OPCODE_NOOP;
  154. next_state <= EXIT_WAIT;
  155. when others =>
  156. next_state <= EXIT_WAIT_ACK;
  157. end case;
  158. when EXIT_WAIT =>
  159. next_state <= EXIT_WAIT;
  160. when others =>
  161. next_state <= IDLE;
  162. end case;
  163. end process HWTUL_STATE_MACHINE;
  164. end architecture IMP;

Program Output

Fibonacci 0 is 1
Fibonacci 1 is 1
Fibonacci 2 is 2
Fibonacci 3 is 3
Fibonacci 4 is 5
Fibonacci 5 is 8
Fibonacci 6 is 13


Last Updated ( Wednesday, 09 August 2006 )
 
Next >
© 2008 HThreads
Joomla! is Free Software released under the GNU/GPL License.