Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. -- converts binary files to quartus MIF files
  2.  
  3. import System.Environment
  4. import System.IO
  5. import Data.List
  6. import Data.Word
  7. import qualified Data.ByteString as B
  8. import qualified Numeric as N
  9.  
  10. data MyWordType = MyByte | MyWord | MyLong deriving (Show)
  11.  
  12.  
  13.  
  14. main = do
  15.        args <- getArgs
  16.        let (wordtype, infile, outfile) = parseArgs args
  17.  
  18.        indata <- B.readFile infile
  19.        let outdata = buildMif indata wordtype
  20.  
  21.        writeFile outfile outdata
  22.  
  23.  
  24.  
  25.  
  26. -- parse arguments and return full info
  27. parseArgs :: [String] -> (MyWordType, String, String)
  28. parseArgs []        = error "empty args! must be bin2mif [-b|-w|-l|--byte|--word|--long] infile [outfile]"
  29. parseArgs (x:[])    = (MyByte, x, x++".mif")
  30. parseArgs (x:y:[])  = (parseHelp x, y, y++".mif")
  31. parseArgs (x:y:z:_) = (parseHelp x, y, z)
  32.  
  33. -- parse helper
  34. parseHelp :: String -> MyWordType
  35. parseHelp "-b"      = MyByte
  36. parseHelp "--byte"  = MyByte
  37. parseHelp "-w"      = MyWord
  38. parseHelp "--word"  = MyWord
  39. parseHelp "-l"      = MyLong
  40. parseHelp "--long"  = MyLong
  41. parseHelp _         = error "only -b, -w, -l, --byte, --word, --long!"
  42.  
  43.  
  44. -- MIF builder
  45. buildMif :: B.ByteString -> MyWordType -> String
  46.  
  47. buildMif _ MyWord      =  error "words not supported yet!"
  48. buildMif _ MyLong      =  error "longs not supported yet!"
  49. buildMif bytes _       =  (bmifHeader bytes)++(bmifBody bytes)++(bmifEnd)
  50.  
  51. -- header for bytewise mifs
  52. bmifHeader :: B.ByteString -> String
  53. bmifHeader b  = "--built by bin2mif.hs\n\n"++
  54.                 "WIDTH=8;\n"++
  55.                 "DEPTH="++(show $ B.length b)++";\n\n"++
  56.                 "ADDRESS_RADIX=HEX;\nDATA_RADIX=HEX;\n\n"++
  57.                 "CONTENT BEGIN\n"
  58.  
  59. -- end for bytewise mifs
  60. bmifEnd :: String
  61. bmifEnd = "END;\n"
  62.  
  63. -- body for bytewise mifs
  64. bmifBody :: B.ByteString -> String
  65. bmifBody b  = bmifEmit.reverse $ foldl bmifMkAddrLen [] $ B.group b
  66.  
  67. bmifMkAddrLen :: [(Int,Int,Word8)] -> B.ByteString -> [(Int,Int,Word8)]
  68. bmifMkAddrLen []                       b =  [(0,(B.length b),(B.head b))]
  69. bmifMkAddrLen x@((oldaddr,oldlen,_):_) b =  let len = B.length b
  70.                                             in [(oldaddr+oldlen,len,(B.head b))]++x
  71.  
  72. bmifEmit :: [(Int,Int,Word8)] -> String
  73. bmifEmit []   = ""
  74. bmifEmit ((addr,len,byte):xs) = (bmifMkLine addr len byte)++(bmifEmit xs)
  75.  
  76. bmifMkLine :: Int -> Int -> Word8 -> String
  77. bmifMkLine addr len byte | len==1     = "\t"++(N.showHex addr "")++" : "++(N.showHex (fromIntegral byte) "")++";\n"
  78.                          | otherwise  = "\t["++
  79.                                         (N.showHex addr "")++".."++
  80.                                         (N.showHex (addr+len-1) "")++"] : "++
  81.                                         (N.showHex (fromIntegral byte) "")++";\n"
  82.  
  83.  
  84.                          
  85.