	/*** Assembly Language Compiler ***/

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include "var.h"  //All Variables are defined here
void file_input(void);
void file_print(void);
void opcodes(void);

	/*** Main Program ***/

int main(void)
{
file_input();  //Opeaning Input & Output Files

if(fp==NULL)  // If error in Opeaning Exit from Program
    { printf("\nError opeaning the outputfile");
         goto exit_program;
    }
if(fp1==NULL) 
    { printf("\nError opeaning the inputfile");
         goto exit_program;
    }

file_print();   //writing to Output File 

while(fscanf(fp1,"%s",&opcode)>0)  //Reading Opcode till end
{
   fscanf(fp1,"%d",&mem_add);  //Reading memory Address
   fscanf(fp1,"%d",&operand);  //Reading Operand 
   count++;
   input:
   cin=0;
	/*** Opcode1 will be copied Binary Value of Opcode ***/
	     if(strcmp(opcode,"sto")==0)
	     	strcpy(opcode1,sto);
	else if(strcmp(opcode,"add")==0)
		strcpy(opcode1,add);
	else if(strcmp(opcode,"sub")==0)
		{
		strcpy(opcode1,sub);
		cin=1;
		}
	else if(strcmp(opcode,"and")==0)
		strcpy(opcode1,and);
	else if(strcmp(opcode,"or")==0)
		strcpy(opcode1,or);
	else if(strcmp(opcode,"xor")==0)
		strcpy(opcode1,xor);
	else if(strcmp(opcode,"not")==0)
		strcpy(opcode1,not);
	else if(strcmp(opcode,"STO")==0)
		strcpy(opcode1,sto);
	else if(strcmp(opcode,"ADD")==0)
		strcpy(opcode1,add);
	else if(strcmp(opcode,"SUB")==0)
		{
		strcpy(opcode1,sub);
		cin=1;
		}
	else if(strcmp(opcode,"AND")==0)
		strcpy(opcode1,and);
	else if(strcmp(opcode,"OR")==0)
		strcpy(opcode1,or);
	else if(strcmp(opcode,"XOR")==0)
		strcpy(opcode1,xor);
	else if(strcmp(opcode,"NOT")==0)
		strcpy(opcode1,not);
	else
  		{ 
printf("\n INCORRECT OPCODE SPECIFICATION IN LINE  %d.\n",count);
printf("\t( %s  %d  %d )\n",opcode,mem_add,operand);
printf("\tCHANGE OPCODE ? [Y/N]....");
fflush(stdin);
scanf("%s",&change);
	if(change=='y'|change=='Y')
	{
		opcodes();
	printf("ENTER THE OPCODE....");
	scanf("%s",&opcode);
	goto input;
	}
	else
	break;
		}

addr:
if(mem_add>15)
		{
printf("\nINCORRECT MEMORY ADDRESS SPECIFICATION IN LINE  %d.\n",count);
printf("\t( %s  %d  %d )\n",opcode,mem_add,operand);
printf("\tCHANGE MEMORY ADDRESS ? [Y/N]...");
	scanf("%s",&change);
	if(change=='y'|change=='Y')
	{
printf("ENTER THE MEMORY ADDRESS....\n");
printf("THE ADDRESS SHOULD BE LESS THAN 16...");
	scanf("%d",&mem_add);
	goto addr;
	}
	else
	break;
		}

oper:
if(operand>15)
		{
printf("\nINCORRECT OPERAND2 SPECIFICATION IN LINE %d.\n",count);
printf("\t( %s  %d  %d )\n",opcode,mem_add,operand);
printf("\tCHANGE OPERAND ? [Y/N]...");
	scanf("%s",&change);
	if(change=='y'|change=='Y')
	{
printf("ENTER THE OPERAND....\n");
printf("THE OPERAND SHOULD BE LESS THAN 16...");
	scanf("%d",&operand);
	goto oper;
	}
	else
	break;
		}

dec_bin(mem_add,&bin1);
dec_bin(operand,&bin2);

fprintf(fp,"#30 reset=1;opcode=3'b%s;op1=4'b%s;op2=4'b%s;cin=1'b%d;\n",opcode1,bin1,bin2,cin);

}
fprintf(fp,"#30 $finish;\n");
fprintf(fp,"end\n");
fprintf(fp,"endmodule\n");
fclose(fp1);
fclose(fp);
printf("\n\n\t%d OPCODES WRITTEN TO FILE NAMED \"%s\" SUCESSFULLY....OK!...\n",count,fname);
exit_program:
printf("\n");
}


void file_print(void)
{

fprintf(fp,"module stimulus;\n");
fprintf(fp,"reg [3:0] op1,op2;\n");
fprintf(fp,"wire [3:0] dout;\n");
fprintf(fp,"reg [2:0] opcode;\n");
fprintf(fp,"reg clk,cin,reset;\n");
fprintf(fp,"processor pro(.opcode(opcode),.op1(op1),.op2(op2),.clk(clk),.cin(cin),.reset(reset),.dout(dout));\n");
fprintf(fp,"\ninitial\n");
fprintf(fp,"begin\n");
fprintf(fp,"clk=0;\n");
fprintf(fp,"forever #2 clk=~clk;\n");
fprintf(fp,"end\n\n");
fprintf(fp,"initial\n");
fprintf(fp,"begin\n");
fprintf(fp,"$dumpfile(\"file.vcd\");\n");
fprintf(fp,"$dumpvars(0,stimulus);\n");
//fprintf(fp,"clk=0;\n");
fprintf(fp,"$monitor($time,\"  opcode=\%b,  op1=\%b,  op2=\%b,  cin=\%b,  reset=\%b,  dataout=\%b\",opcode,op1,op2,cin,reset,dout);\n"); 
fprintf(fp,"cin=1'b0;\n");
fprintf(fp,"reset=0;opcode=3'b000;op1=4'b0000;op2=4'b0000;cin=1'b0;\n");
}


void file_input(void)
{
printf("Enter File Name of source file:");
scanf("%s",&fname1);
printf("Enter File Name of Destination:");
scanf("%s",&fname);
fp1=fopen(fname1,"r"); 
fp=fopen(fname,"w");
}

dec_bin(int a,char out[3])
{
switch(a)
{
case 0:  strcpy(out,"0000");  break;
case 1:  strcpy(out,"0001");  break;
case 2:  strcpy(out,"0010");  break;
case 3:  strcpy(out,"0011");  break;
case 4:  strcpy(out,"0100");  break;
case 5:  strcpy(out,"0101");  break;
case 6:  strcpy(out,"0110");  break;
case 7:  strcpy(out,"0111");  break;
case 8:  strcpy(out,"1000");  break;
case 9:  strcpy(out,"1001");  break;
case 10:  strcpy(out,"1010");  break;
case 11:  strcpy(out,"1011");  break;
case 12:  strcpy(out,"1100");  break;
case 13:  strcpy(out,"1101");  break;
case 14:  strcpy(out,"1110");  break;
case 15:  strcpy(out,"1111");  break;
default : strcpy(out,"0000");
}
}

void opcodes(void)
{
printf("\nSELECT  OPCODE\n");
printf("\t sto\n");
printf("\t add\n");
printf("\t sub\n");
printf("\t and\n");
printf("\t or\n");
printf("\t xor\n");
printf("\t not\n");
}

