小猫种鱼

你从远方来,我到远方去,遥远的路程经过这里,天空一无所有,为何给我安慰

导航

hex转mif文件 verilog

Posted on 2017-08-26 17:35  遥远的路  阅读(1861)  评论(1编辑  收藏  举报
用FPGA来跑ARM 核的时候,刚开始将Keil编译产生的hex文件拿来仿真和下到板子上的时候,发现程序运行不正确。细细观察仿真波形发现,在Altera的ROM IP中直接调用Keil产生的hex文件,出来数据是不正确的。比较Quartus产生的HEX文件和标准的Hex文件,发现两者之间的格式不是完全一样。于是干脆直接将Keil产生的Hex文件转换成mif文件。
代码是用verilog写的,已调试通过,ARM核也运行正常。由于没有判断Extended LinearAddress Record,该程序只能转换小于64Kbyte的hex文件。
hex转mif代码如下。
 
//-----------------------------------------------------------------
//    Author:    wuzhangquan
//    Blog:      http://www.cnblogs.com/xinlukk/
//    Email:     wuzhangquan@foxmail.com
//-----------------------------------------------------------------

//: 10 0000 00 F0FF0F20 B9010000 B1010000 AD010000 B8

`timescale  1ns/1ns
module  hex2mif;

parameter MEM_DEPTH = 16*1024;

integer fid;
integer i;
integer tf;

reg   [7:0] ch;
reg   [7:0]   len;
reg   [15:0]  ext_addr;
reg   [15:0]  addr;
reg   [7:0]   dtype;
reg   [7:0]   data;

reg   [7:0]   mem[0:MEM_DEPTH-1];

initial begin

  ch  = 0;
  ext_addr  = 0;
  addr  = 0;
  dtype = 0;
  data  = 0;

  for(i=0;i<MEM_DEPTH;i++)
    mem[i] = 0;

  fid=$fopen("rom.hex","rb");
 
  if(fid==0)  begin
          $display("Cann't find rom.hex!!");
          $finish;
  end

  ch  = $fgetc(fid);
  while(ch!=8'hff)
    begin
        //$write("%c",ch);

        if(ch==":")   
          begin
              ch  = $fgetc(fid);
              len[7:4] = asc2hex(ch);
              ch  = $fgetc(fid);
              len[3:0] = asc2hex(ch);
              //Get Addr
              ch  = $fgetc(fid);
              addr[15:12] = asc2hex(ch);
              ch  = $fgetc(fid);
              addr[11:8] = asc2hex(ch);
              ch  = $fgetc(fid);
              addr[7:4] = asc2hex(ch);
              ch  = $fgetc(fid);
              addr[3:0] = asc2hex(ch);
              //get Data type
              ch  = $fgetc(fid);
              dtype[7:4] = asc2hex(ch);
              ch  = $fgetc(fid);
              dtype[3:0] = asc2hex(ch);
              //DATA
              if(dtype==8'h00)  begin //Data
                  for(i=0;i<len;i++)  begin
                      ch  = $fgetc(fid);
                      data[7:4] = asc2hex(ch);
                      ch  = $fgetc(fid);
                      data[3:0] = asc2hex(ch);
                      mem[ext_addr + addr] = data;
                      addr = addr + 1;
                      $fwrite(tf,"%h",data);
                  end
                  len = 0;
              end

              //CHECK
              //ch  = $fgetc(fid);
              //ch  = $fgetc(fid);

          end

        ch  = $fgetc(fid);
    end //while end

    $fclose(fid);
    fid = $fopen("rom.mif","w");


    $fdisplay(fid,"WIDTH=32;");
    $fdisplay(fid,"DEPTH=4096;");
    $fdisplay(fid,"ADDRESS_RADIX=HEX;");
    $fdisplay(fid,"DATA_RADIX=HEX;");

    $fdisplay(fid,"CONTENT BEGIN");

    for(i=0;i<(MEM_DEPTH/4);i=i+1)
          $fdisplay(fid,"%h : %h%h%h%h;",i,mem[i*4+3],mem[i*4+2],mem[i*4+1],mem[i*4]);

    $fdisplay(fid,"END;");

    $fclose(fid);  

//    fid = $fopen("rom.txt","w");
//    
//    for(i=0;i<(MEM_DEPTH/4);i=i+1)
//          $fdisplay(fid,"%h%h%h%h",mem[i*4+3],mem[i*4+2],mem[i*4+1],mem[i*4]);
//
//    $fclose(fid);  


end

  function  [3:0] asc2hex;
    input   [7:0] din;
    begin
        if(din<="9")  asc2hex = din - "0";
        else if( (din>="A") && (din<="F"))  asc2hex = din - "A" + 4'ha;
        else if( (din>="a") && (din<="f"))  asc2hex = din - "a" + 4'ha;
        else  asc2hex = 0;
    end
  endfunction

endmodule