⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 risc8_asm.pl

📁 这是一篇关于8位RISC CPU设计的文章
💻 PL
📖 第 1 页 / 共 2 页
字号:
       } 
     elsif($word[$start] eq "dcb") {                       # dcb
       if($word[$start+1] =~ /^\"/) {
         @stringg = split "\"", $line_org;
         @bytes = unpack ("C*", $stringg[1]);
         for($i=0; $i <= $#bytes; $i = $i+1) {
           printf TMP_F ("byte=%x\n", $bytes[$i]);
           #printf ("%x\n", $bytes[$i]); 
           $address = $address + 1;
           } 
         }
       else { 
         for($i=$start+1; $i <= $#word; $i = $i+1) {
           ($status, $off) = extract_byte($word[$i]);
           printf  TMP_F ("byte=%x\n", $off);
           $address = $address + 1;
           } 
         } 
       }
     elsif($word[$start] eq "dmem") {                      # dmem
       check_argument_count($#word, 1);
       if($word[$start+1] !~ /\(/) { 
         $count = $word[$start+1]; $fill = "00";}
       else { 
         @filler = split /\(/, $word[$start+1];
         $count = $filler[0];  $fill = $filler[1]; 
         $fill =~ s/\)//g;
         }
       ($status, $fill) = extract_byte($fill);
       ($status, $off) = extract_word($count);
       if($status != 0) { printf ("invalid dmem count\n");}
       else {  
         for($i=0; $i < $off;  $i = $i + 1) {
           printf  TMP_F ("byte=%x\n", $fill);
           $address = $address + 1;
           } 
         } 
       }
     }

   #---------------------------------------------
   # Type 11: pmov - Pseudo MOV instruction
   #---------------------------------------------
   elsif($opcode_type{$word[$start]} == 11) {
     check_argument_count($#word, ($start+2));
     if($word[$start+1] !~ /^(a0|a1|a2|a3)$/) {                # pmov An 16-bit
       printf("Error: Invalid pmove argument \"%s\" at line %d: %s\n",
                              $word[$start+2], $line_no, $line_o);
       $error = $error + 1;
       }
     else {
       $opcode = $opcode_value{"ldi"} . $reg_map{$word[$start+1]}. "0";
       printf TMP_F ("pmov=%s", $opcode);
       $opcode = $opcode_value{"ldi"} . $reg_map{$word[$start+1]}. "1";
       printf TMP_F ("#6#%s", $opcode);
       ($status, $off) = extract_word($word[$start+2]);
       if($status == 0) { printf  TMP_F ("#7#%x\n", $off);}
       elsif($status == 2) {
         printf  TMP_F ("#8#%s#9#%d#a#%d\n", $off,$line_no, ($address + 2));}
       $address = $address + 4;
       }
     }
   }


 #----------------------------------------------------------
 # Second pass to Resolve the forward references
 # Create the memory file - 16 bytes per line
 #----------------------------------------------------------
 $error2 = 0;
 $byte_count = 0;

 if($error == 0) {
   close TMP_F;
   open (TMP_F, "$tmp_file") or die ("Can't open $tmp_file: $!\n");
   while ($line = <TMP_F>)
     {
     chop $line; 
     if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
     if($line =~ /@(.+)/) { 
       printf MEM_F ("\n@%s\n", $1); $byte_count = 0;}
     elsif($line =~ /opcode=(\d{4})(\d{4})$/) { 
       printf MEM_F (" %s%s", $bin2_hex{$1}, $bin2_hex{$2});  $byte_count++; }
     elsif($line =~ /byte=(.{1})$/) { 
       printf MEM_F (" 0%s", $1); $byte_count++;}
     elsif($line =~ /byte=(.{2})$/) { 
       printf MEM_F (" %s", $1); $byte_count++;}

     elsif($line =~ /word=(.+)$/) { 
       @digits = split "", $1; 
       if($#digits == 0 )   { $low = "0" . $digits[0]; $high = "00";}
       elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";}
       elsif($#digits == 2) { $low = $digits[1] . $digits[2] ;
                              $high = "0" . $digits[0];}
       else                 { $low = $digits[2] . $digits[3] ;
                              $high = $digits[0] . $digits[1];}

       printf MEM_F (" %s", $low); $byte_count++;
       if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
       printf MEM_F (" %s", $high); $byte_count++;
       }
     elsif($line =~ /pmov=(\d{4})(\d{4})#6#(\d{4})(\d{4})#7#(.+)$/) {
       @digits = split "", $5; 
       if($#digits == 0 )   { $low = "0" . $digits[0]; $high = "00";}
       elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";}
       elsif($#digits == 2) { $low = $digits[1] . $digits[2] ; 
                              $high = "0" . $digits[0];}
       else                 { $low = $digits[2] . $digits[3] ; 
                              $high = $digits[0] . $digits[1];}
       printf MEM_F (" %s%s", $bin2_hex{$1}, $bin2_hex{$2});  $byte_count++; 
       if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
       printf MEM_F (" %s", $low); $byte_count++;
       if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
       printf MEM_F (" %s%s", $bin2_hex{$3}, $bin2_hex{$4});  $byte_count++; 
       if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
       printf MEM_F (" %s", $high); $byte_count++;
       }
     elsif($line =~ /pmov=(\d{4})(\d{4})#6#(\d{4})(\d{4})#8#(.+)#9#(.+)#a#(.+)$/) {
       if($valid_label{$5} == 1) {
         $off1 = $addr_label{$5};
         $offset = "";
         $offset = sprintf "%lx", $off1;
         @digits = split "", $offset;
         if($#digits == 0 )   { $low = "0" . $digits[0]; $high = "00";}
         elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";}
         elsif($#digits == 2) { $low = $digits[1] . $digits[2] ;
                                $high = "0" . $digits[0];}
         else                 { $low = $digits[2] . $digits[3] ;
                                $high = $digits[0] . $digits[1];}
         printf MEM_F (" %s%s", $bin2_hex{$1}, $bin2_hex{$2});  $byte_count++; 
         if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
         printf MEM_F (" %s", $low); $byte_count++;
         if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
         printf MEM_F (" %s%s", $bin2_hex{$3}, $bin2_hex{$4});  $byte_count++; 
         if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
         printf MEM_F (" %s", $high); $byte_count++;
         }
       else {
         $error2 = $error2 + 1;
         printf("Error: Label not found \"%s\" at line %d\n", $5, $6);
         next;
         }
       }
 
     elsif($line =~ /b_label=(.+)#4#(.+)#5#(.+)$/) { 
       if($valid_label{$1} == 1) { 
         #printf("LAB=%d, %d\n", $addr_label{$1}, $3);
         $off1 = ($addr_label{$1}-$3); 
         $offset = "";
         $offset = sprintf "%lx", $off1;
         if($off1 > 255) {
           $error2 = $error2 + 1;
           printf("Error: relative jump bigger than 8bits \"%s\" on line %d\n",
                                                                  $1, $2);
           }
         else {
           #printf MEM_F ("lab = %d, %s\n", $off1, $offset);
           if($off1 <= 15) { printf MEM_F (" 0%s", $offset); }
           else            { printf MEM_F (" %s", $offset); }
           $byte_count++;
           }
         }
       else {
         $error2 = $error2 + 1;
         printf("Error: Label not found \"%s\" at line %d\n", $1, $2);
         next;
         } 
       } 
     elsif($line =~ /w_label=(.+)#4#(.+)#5#(.+)$/) { 
       if($valid_label{$1} == 1) { 
         $off1 = $addr_label{$1}; 
         $offset = "";
         $offset = sprintf "%lx", $off1;
         @digits = split "", $offset;
         if($#digits == 0 )   { $low = "0" . $digits[0]; $high = "00";}
         elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";}
         elsif($#digits == 2) { $low = $digits[1] . $digits[2] ;
                                $high = "0" . $digits[0];}
         else                 { $low = $digits[2] . $digits[3] ;
                                $high = $digits[0] . $digits[1];}
         printf MEM_F (" %s", $low); $byte_count++;
         if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;}
         printf MEM_F (" %s", $high); $byte_count++;
         }
       else {
         $error2 = $error2 + 1;
         printf("Error: Label not found \"%s\" at line %d\n", $1, $2);
         next;
         }
       } 
     } 
     printf MEM_F ("\n");
   }

 close ASM_F;
 close MEM_F;
 close TMP_F;
 #close LST_F;

 # generate the hex file
 open (MEM_F, "$mem_file") or die ("Can't open $mem_file: $!\n");
 for($i=0 ; $i <= 65535; $i = $i+1) { $hex_data[$i] = $mem_init_value;}
 $address = 0;
 while ($line = <MEM_F>)
   {
   #chop $line;
   @words = split " ", $line;
   if($words[0] =~ /^@(.+)$/) {$addr = "0x" . $1; $address = oct $addr;}  
   elsif($#words == -1) {next;}
   else{
     for($i=0 ; $i <= $#words; $i = $i+1) { 
       $hex_data[$address] = $words[$i]; $address = $address + 1;}
     }
   }
 $count = 0;
 for($i=0 ; $i <= 65535; $i = $i+1) { 
   if($count == 32) { printf HEX_F ("\n"); $count = 0; }
   printf HEX_F ("%s", $hex_data[$i]); 
   $count = $count + 1; 
   }
   printf HEX_F ("\n");
 
 close MEM_F;
 close HEX_F;
 system ("rm $tmp_file");

 $t_errors = $error+$error2;
 printf("\nTotal Errors = %d\n", $t_errors);
 if($t_errors != 0) {
   #system("rm $hex_file");
   system("rm $mem_file");
   } 

 #----------------------------------------------------------
 # End of main Program and start of procedure declarations
 #----------------------------------------------------------

 #-------------------------------------------------------------
 # Checks for valid number of arguments in an instruction  
 #-------------------------------------------------------------
 sub check_argument_count {
   my ($tmp1, $tmp2) = @_;
   if($tmp1 != $tmp2) {
     printf("Error: Invalid number of arguments at line %d: %s\n", $line_no, 
                                                                    $line_o);
     $error = $error + 1;
     }
   }
 
 #-------------------------------------------------------------
 # Checks for valid data register usage in an instruction  
 #-------------------------------------------------------------
 sub check_data_register {
   my ($tmp) = @_;
   if($tmp !~ /^(r0|r1|r2|r3|r4|r5|r6|r7)$/) {
     printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, 
                                                                      $line_o);
     $error = $error + 1;
     }
   }

 #-------------------------------------------------------------
 # Checks for valid address register usage in an instruction  
 #-------------------------------------------------------------
 sub check_address_register {
   my ($tmp) = @_;
   if($tmp !~ /^(a0|a1|a2|a3)$/) {
     printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, 
                                                                      $line_o);
     $error = $error + 1;
     }
   }

 #-------------------------------------------------------------
 # Checks for valid conditions in a jump instruction  
 #-------------------------------------------------------------
 sub check_condition {
   my ($tmp) = @_;
   if($tmp !~ /^(eq|ne|gt|lt|cs|cc|ns|al)$/) {
     printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, 
                                                                      $line_o);
     $error = $error + 1;
     }
   }

 #-------------------------------------------------------------
 # Checks for valid register arguments in a mov instruction  
 #-------------------------------------------------------------
 sub check_mov_registers {
   my ($tmp) = @_;
   if($tmp !~ /^(sp|a0|a1|a2|a3|r0|r1|r2|r3|r4|r5|r6|r7)$/) {
     printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, 
                                                                      $line_o);
     $error = $error + 1;
     }
   }


 #-------------------------------------------------------------
 # Extracts the 8-bit immediate data  
 #-------------------------------------------------------------
 sub extract_byte {
   my ($tmp) = @_;
   if($tmp =~ /^(0x.+)$/) {$tmp = oct $1; 
     if($tmp <= 255) {return (0,$tmp);}
     else {   
       printf("Error: Overflow, 8-bit value expected \"%s\" at line %d: %s\n",
                                                      $tmp, $line_no, $line_o);
       $error = $error + 1;
       return (1,$tmp);
       }
     }
   elsif ($tmp =~ /^(\d+)$/) { $tmp = $1;
     if($tmp <= 255) {return (0, $tmp);}
     else {   
       printf("Error: Overflow, 8-bit value expected \"%s\" at line %d: %s\n",
                                                      $tmp, $line_no, $line_o);
       $error = $error + 1;
       return (1,$tmp);
       }
     }
   elsif ($valid_label{$tmp}) { 
   #elsif ($valid_label{$tmp} == 1) { 
     $tmp1 = $address + 1 - $addr_label{$tmp};
     $tmp = 0xff - $tmp1 + 1;
     #printf("addr=%x label=%x %x\n", $address,  $tmp1, $tmp);
     if($tmp1 <= 255) {return (0, $tmp);}
     else {   
       printf("Error: Overflow, 8-bit value expected \"%s\" at line %d: %s\n",
                                                      $tmp, $line_no, $line_o);
       $error = $error + 1;
       return (1,$tmp);
       }
     }
   else {
     return (2,$tmp);
     }
   }

 #-------------------------------------------------------------
 # Extracts the 16-bit immediate data  
 #-------------------------------------------------------------
 sub extract_word {
   my ($tmp) = @_; 
   if($tmp =~ /^(0x.+)$/) {$tmp = oct $1;  
     if($tmp <= 0xffff) {return (0, $tmp);}
     else {
       printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n",
                                                      $tmp, $line_no, $line_o);
       $error = $error + 1;
       return (1,$tmp);
       }
     }
   elsif ($tmp =~ /^(\d+)$/) {$tmp = $1;
     if($tmp <= 0xffff) {return (0, $tmp);}
     else {
       printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n",
                                                      $tmp, $line_no, $line_o);
       $error = $error + 1;
       return (1,$tmp);
       }
     }
   elsif ($valid_label{$tmp}) { $tmp = $addr_label{$tmp};
   #elsif ($valid_label{$tmp} == 1) { $tmp = $addr_label{$tmp};
     return (0, $tmp);
     }
   else {
     return (2,$tmp);
     }
   }

 #-------------------------------------------------------------
 # Extracts the address for the "org" directive  
 #-------------------------------------------------------------
 sub extract_addr {
   my ($tmp) = @_;
   if($tmp =~ /^(0x.+)$/) {$tmp = oct $1;
     if($tmp <= 0xffff) {return $tmp;}
     else {
       printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n",
                                                      $tmp, $line_no, $line_o);
       $error = $error + 1;
       }
     }
   elsif ($tmp =~ /^(\d+)$/) { $tmp = $1;
     if($tmp <= 0xffff) {return $tmp;}
     else {
       printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n",
                                                      $tmp, $line_no, $line_o);
       $error = $error + 1;
       }
     }
   else {
     printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no,
                                                                      $line_o);
     $error = $error + 1;
     }
   }


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -