添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
用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;
  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);
                  len = 0;
              //CHECK
              //ch  = $fgetc(fid);
              //ch  = $fgetc(fid);
        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);  
  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;
  endfunction
endmodule