Huffman coding in Spartan 3E (Microblaze) - Help!!

Status
Not open for further replies.

lefti

Newbie level 3
Newbie level 3
Joined
Mar 20, 2012
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,302
Hello,
I am a rookie in embedded systems and I am trying to implement Huffman encoding using Microblaze in Spartan 3E starter kit. I use the following code in C:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <xuartlite_l.h>
#include <xutil.h>
#include <xparameters.h>

/*STRUCTURES*/
struct tree                  //The structure is used to build the binary tree.
{   int data;                //Variable 'data' is used to represent the frequency of each character
    int trav_val;            //trav_value takes 0 if the node is traversed to the right or takes 1 if it is traversed to the left
    char ckey;               //This is the character assigned to the leaf node
    struct tree *rlink;             //Right child
    struct tree *llink;             //Left child
}**root=NULL,*temp;

struct calc_sum              //The structure is used to store the sum of two min values
{   int sum;                 //Sum is the total value
    int right;               //right is the biggest of the two min values
    int left;                //left is the smallest of the two min values
}*total;

struct string                //The structure is used to assign the frequency of each character
{   char alph;               //alph is the character
    int freq;                //freq is the frequency of the character
}*ori_string,*pre_string;    /*ori_string is the original string(containing freq and char of each character entered by user)
                               and pre_string is the preserved string*/

struct encode                //The structure is used to assign the Huffman's code to different characters
{   char letter;             //This is the character assigned to the leaf node
    int *code;               //It contains the Huffman's code for the character
    int length;              //Contains the length of the Huffman's code
}*enc;


/*FUNCTION DECLARATIIONS*/
void sort(struct string [],int);
void insert(struct calc_sum [],int);
void display(struct tree *);
//void encode(struct encode[],char *);


int next_char,str_len;
static int *trav,m,n,root_check,i,j,k;
char ch,input[50];

int main(void)
{
do
{
int flag,char_freq;
xil_printf ("Enter the string and terminate it with backspace:\n\r");


for(n=0;n<50;n++)
{
input[n]= XUartLite_RecvByte (0x84000000);

if (input[n]==0x8)
	break;
}
input[n]='\0';
str_len=n;
xil_printf("\n\r");
xil_printf("Length of the string:%d",str_len);


for(i=32,next_char=0;i<127;i++)
 {
	flag=0,char_freq=0,j=0;
    while(input[j]!='\0')
      {
    	if(input[j]==i)
         {
           flag=1;
           ori_string[next_char].alph=pre_string[next_char].alph=input[j];
           char_freq++;
         }
         j++;
      }

       if(flag)
        {
          ori_string[next_char].freq=pre_string[next_char].freq=char_freq;
          next_char++;
        }
 }

if(next_char==1)
xil_printf("\nEncoding is not possible. You have entered same set of characters");

else
{
  xil_printf("\n\r");
  xil_printf("Character\tFrequency\n\r");
  for(i=0;i<next_char;i++)
  xil_printf("%c\t\t %d\n\r",pre_string[i].alph,pre_string[i].freq);
  sort(ori_string,next_char);
}
xil_printf("\n\nDo you want to continue?(Y/N)\n");
ch= XUartLite_RecvByte (0x84000000);
} while(ch=='y'||ch=='Y');

}



/*
  Name of Routine     :  Sort
  Type/Classified as  :  Sorting
  Function Call       :  sort() from main
  Parameters Passed   :  ori_string,next_char
  Return Type         :  Void
  Purpose             :  Sorts the frequencies in decreasing order
                         Swap is used for swapping values
                         k stores the no. of sum values
*/



void sort(struct string ori_string[],int next_char)
{   k=next_char-1;
    int swap;
    xil_printf("\n\r");
    xil_printf("Left\tRight\tTotal\n\r");
        while(k>0)
        {   for(i=0;i<k+1;i++)
            for(j=i+1;j<k+1;j++)
            {   if(ori_string[i].freq<ori_string[j].freq)
                {   swap=ori_string[i].freq;
                    ori_string[i].freq=ori_string[j].freq;
                    ori_string[j].freq=swap;
                }
            }
            total[next_char-1-k].left=ori_string[i-1].freq;
            total[next_char-1-k].right=ori_string[i-2].freq;
            total[next_char-1-k].sum=total[next_char-1-k].left+total[next_char-1-k].right;
            ori_string[k-1].freq=total[next_char-1-k].sum;
            xil_printf("%d  \t%d  \t%d\n\r",total[next_char-1-k].left,total[next_char-1-k].right,total[next_char-1-k].sum);
            k--;
        }
        insert(total,next_char);
}



/*
  Name of Routine     :  Insert
  Type/Classified as  :  Insertion
  Function Call       :  insert() from sort()
  Parameters Passed   :  total,next_char;
  Return Type         :  Void
  Purpose             :  Constructs a binary tree using the sum and the frequency values
                         Variables rflag and lflag are used to identify a new root
                         Variables lchange and r change are used to compress two roots into 1
                         tot_roots calcultes the no of roots possible and integer value is assigned to roots using the power function
                         roots for max roots that a tree can contain
                         count gives the no. of roots at any time
                         swap for swapping two characters and k stores the no of sum values
*/

void insert(struct calc_sum total[],int next_char)
{   int roots,count=0,lflag,rflag,rchange=0,lchange=0;
    k=0;
    char swap;
    float tot_roots;
    tot_roots=log(2*next_char-1)/log(2);
    roots=pow(2,(int)(tot_roots-1));
    for(i=0;i<roots;i++)
    root[i]=NULL;
    struct tree *r;
    struct tree *l;
    while(k<(next_char-1))
    {   lflag=rflag=1;
        temp->data=total[k].sum;
        if(k==0)
        {
        	r->data=total[k].right;
            r->trav_val=1;
            r->rlink=NULL;
            r->llink=NULL;
            for(i=next_char-1;i>=0;i--)
            {   if(pre_string[i].freq==total[k].right)
                {   r->ckey=pre_string[i].alph;
                    pre_string[i].freq=0;
                    break;
                }
            }
            temp->rlink=r;

            l->data=total[k].left;
            l->trav_val=0;
            l->rlink=NULL;
            l->llink=NULL;
            for(i=next_char-1;i>=0;i--)
            {   if(pre_string[i].freq==total[k].left)
                {   l->ckey=pre_string[i].alph;
                    pre_string[i].freq=0;
                    break;
                }
            }
            temp->llink=l;
            root[0]=temp;
        }
        else
        {   for(i=0;i<roots;i++)      // check for right
            {   if(total[k].right==root[i]->data)
                {
                    root[i]->trav_val=1;
                    temp->rlink=root[i];
                    rflag=0;
                    rchange=i;
                    root[rchange]=temp;
                }
                if(!rflag)
                break;
            }
            if(i>=roots)
            {
            	r->data=total[k].right;
                r->trav_val=1;
                r->rlink=NULL;
                r->llink=NULL;
                for(i=next_char-1;i>=0;i--)
                {   if(pre_string[i].freq==total[k].right)
                    {       r->ckey=pre_string[i].alph;
                        pre_string[i].freq=0;
                        break;
                    }
                }
                temp->rlink=r;
            }
            for(i=0;i<roots;i++)       //check for left
            {   if(total[k].left==root[i]->data)
                {
                    root[i]->trav_val=0;
                    temp->llink=root[i];
                    lflag=0;
                    lchange=i;
                    root[lchange]=temp;
                }
                if(!lflag)
                break;
            }
            if(i>=roots)
            {
                l->data=total[k].left;
                l->trav_val=0;
                l->rlink=NULL;
                l->llink=NULL;
                for(i=next_char-1;i>=0;i--)
                {   if(pre_string[i].freq==total[k].left)
                    {   l->ckey=pre_string[i].alph;
                        pre_string[i].freq=0;
                        break;
                    }
                }
                temp->llink=l;
            }
            if(rflag&&lflag)
            {   root[++count]=temp;
                if(root[count]->llink->data==root[count]->rlink->data)
                {
                    swap=root[count]->llink->ckey;
                    root[count]->llink->ckey=root[count]->rlink->ckey;
                    root[count]->rlink->ckey=swap;
                }
            }
            if(!rflag&&!lflag)
            root[rchange]=NULL;
        }
        k++;
    }

    xil_printf("HUFFMAN CODES\n");
    m=0,i=0,j=0,k=0;
    display(root[lchange]);
    xil_printf("GET THE ENCODED STRING\n");
    // encode(enc,input);
    for(i=0;i<str_len;i++)
             {  j=0;
                while(j<next_char)
                {   if(enc[j].letter==input[i])
                    for(k=0;k<enc[j].length;k++)
                    xil_printf("%d",enc[j].code[k]);
                    j++;
                }
             }
}

/*
  Name of Routine     :  Display
  Type/Classified as  :  I/O
  Function Call       :  disp() from insert()
  Parameters Passed   :  root[lchange]
  Return Type         :  Void
  Purpose             :  Displays the Huffcode for each character
                         root_check is used to check if the current node is the root
                         trav[] is an array which stores the huffman code for each character
*/
void display(struct tree *disp)
{   if(disp!=NULL)
    {   if(root_check>=1)
        trav[m++]=disp->trav_val;
        root_check++;
        display(disp->llink);
        display(disp->rlink);
        if(disp->llink==NULL&&disp->rlink==NULL)
        {
            xil_printf("%c-",disp->ckey);
            enc[i].letter=disp->ckey;
            enc[i].length=0;
            for(m=0;m<root_check-1;m++)
            {          xil_printf("%d",trav[m]);
                       enc[i].code[j]=trav[m];
                       enc[i].length++;
                       j++;
            }
            i++;
            j=0;
            xil_printf("\n\r");
        }
        m--;
        root_check--;
    }
}

and the hyperterminal out is the following:

Code:
Enter the string and terminate it with backspace:
Iron Maiden
Length of the string:11
Character       Frequency
                 1
I                1
M               1
a                1
d                1
e                1
i                 1
n                2
o                1
r                 1

Left    Right   Total
1       1       2
1       1       2
1       1       2
2       1       2
2       2       4
2       2       4
2       2       4
4       4       8
4       8       12
HUFFMAN CODES
GET THE ENCODED STRING


Do you want to continue?(Y/N)


Characters with their codes and the encoded text are not appeared. Could you help me to do this? Thank you.
 

Status
Not open for further replies.