原创 SystemVerilog实现Fat12文件系统

2008-12-11 19:46 3767 9 6 分类: 工程师职场
最近用systemverilog实了一个简单的fat12文件系统,做为一实验,目的不是实现一个完善的系统,所以只实现了一些基本的东西。下面是系统的框架和一些说明。

限制:任何一级目录不能大于一个扇区,
      Fat不能大于一个扇区,边界情况没有测试
      del删除目录时必须保证赠录为空
      append文件是必须保证文件为空
      镜像为1.44M软盘格式,仅对1号,19号,和33号开始的扇区有写入
      没有做充分的输入合法性检查
      文件日期,属性等没有根据情况进行设置


/*
cd()                      改变当前目录
dir()                     列出当前目录内的目录和文件
pwd()                     显示当前目录
makefile(filename)        创建空文件
makedir(dirname)          创建目录
appand(filename, byte[]) 追加文件内容
del(name)                 删除文件和目录
catfile(filename,out)    显示文件内容,输出保存到仿真目录下out文件内
close()                   保存结果到镜像文件
*/


class fsdriver;
//定义一个软盘镜像
local image disk;
//当前目录对应的簇号,0表示根目录
local shortint CurDir;
//保存Fat对应的扇区数据       
local byte Fat [];
//保存当前目录所在扇区数据
local byte DirBlk [];
//ImageFileName用于保存结果镜像
function new (string ImageFileName );
    disk = new(ImageFileName);
    CurDir = 0;
    disk.read(1, Fat);
    disk.read(19,DirBlk);
endfunction
//文件系统操作命令
extern function void catfile (string infile, string outfile);
extern function void dir ();
extern function void pwd ();
extern function void cd (string dirname);
extern function void del (string filename);
extern function void append (string filename, byte data[]);
extern function void makedir (string dirname);
extern function void makefile (string filename);
extern function void close();
//检查并转换文件名成8.3格式
extern local function string padded_filename (string filename);
//返回当前Fat第一个可能簇号
extern local function shortint find_FirAvClus();


endclass
`include "fsdriver.svh"


class image;


local int fd;
local byte disk[0:1474559];


function new (string imagefilename);
    $readmemh("init.disk",disk);
    fd = $fopen (imagefilename);
endfunction


extern function void display();
extern function void read (int SectorNum, output byte result[0:511]);
extern function void write (int SectorNum, byte WrBlkDat[0:511]);
endclass
`include "image.svh"


下面是函数的算法说明


catfile:
   0、转换文件名
   1、查找文件是否存在,如存在,读出第一簇号,否则ERROR
   2、如果簇号不为0,读取对应扇区的数据
   3、读出下一簇号,如果不是最后一个扇区,转2
dir:
   1、遍历目录扇区,如果不为空,则显示文件名
pwd:
   1、如果CurDir为0,则为根目录,返回
   2、读取DirBlk中".."目录的簇号,并根据簇号读出该扇区
   3、在读出的扇区中查找簇号等于CurDir的记录,并返回文件名
cd:
   0、如果当前是ROOT并且输入为"."或".."则返回
   1、转换文件名
   2、查找目标目录,并返回簇号,更新CurDir
   3、根据CurDir更新DirBlk
del:
   0、转换文件名
   1、查找文件名,找到后把记录第一字节置成E5,并读取簇号
   2、如果簇号不为0,则读取下一扇区簇号,并置Fat中当前簇号为空
   3、如果当前不是最后扇区,转2
append:
   0、转换文件名
   1、查找文件名,写入第一可用簇号,写入文件大小
   2、写入数据,更新fat指向下一可用簇号
   3、如果未写完,继续2,否则更新最后簇号为结束簇号
makedir:
   0、转换文件名
   1、找到第一个空记录,分配一个可用簇号,更新记录
   2、初始化刚分配的扇区为全0
   3,初始化前两条记录为"."和"..",分别指向自己当前目录
makefile:
   0、转换文件名
   1、找到一个空记录,写入文件信息
close:
   0、调用image函数,保存结果到镜像文件
padded_filename:
   0、如果是"."和"..",补空格成8.3格式
   1、如果文件名长度大于12或者为0, ERROR
   2、如果主文件名长度为0,ERROR
   3、如果主文件名大于8个字符,ERROR
   4、如果扩展文件名大于3个字符,ERROR
   输出为8.3格式,不足的自动以空格补齐
find_FirAvClus:
   0、从2开始遍历Fat,找到第一个为空的簇号


下面是仿真的log输出


#    Command: MakeFile (abc123.def)
#    Command: MakeFile (abc1.def)
#    Command: MakeFile (abc12.def)
#    Command: MakeDir (123)
#    Command: DIR
#    ABC123 DEF FILE
#    ABC1    DEF FILE
#    ABC12   DEF FILE
#    123        DIR
#    Command: CD (123)
#    Command: Pwd : Current diretory is : "123        "
#    Command: MakeFile (123aa.def)
#    Command: MakeFile (123bb.def)
#    Command: Append (123aa.def)
#    Command: Append (123bb.def)
#    Command: DIR
#    .          DIR
#    ..         DIR
#    123AA   DEF FILE
#    123BB   DEF FILE
#    Command: MakeDir (456)
#    Command: CD (456)
#    Command: Pwd : Current diretory is : "456        "
#    Command: MakeFile (456aa)
#    Command: MakeFile (456bb)
#    Command: DIR
#    .          DIR
#    ..         DIR
#    456AA      FILE
#    456BB      FILE
#    Command: MakeDir (789)
#    Command: CD (789)
#    Command: Pwd : Current diretory is : "789        "
#    Command: MakeFile (789aa)
#    Command: MakeFile (789bb)
#    Command: DIR
#    .          DIR
#    ..         DIR
#    789AA      FILE
#    789BB      FILE
#    Command: Append (789aa)
#    Command: CD (..)
#    Command: Pwd : Current diretory is : "456        "
#    Command: CD (..)
#    Command: Pwd : Current diretory is : "123        "
#    Command: CD (..)
#    Command: Pwd : Current diretory is ROOT
#    Command: Append (abc123.def)
#    Command: Catfile(abc123.def) to "abc123.out"
#    Command: Del (abc123.def)
#    Command: MakeDir (dddd)
#    Command: DIR
#    DDDD       DIR
#    ABC1    DEF FILE
#    ABC12   DEF FILE
#    123        DIR
#    Command: Del (dddd)
#    Command: DIR
#    ABC1    DEF FILE
#    ABC12   DEF FILE
#    123        DIR

下面是输出的image挂载在到软驱后的效果


/cygdrive/a $ll
total 0
drwxr-xr-x    3 Administ None            0 Apr 18 21:21 123/
-rw-r--r--    1 Administ None            0 Apr 18 21:21 ABC1.DEF
-rw-r--r--    1 Administ None            0 Apr 18 21:21 ABC12.DEF
/cygdrive/a $ll 123
total 3
drwxr-xr-x    3 Administ None            0 Apr 18 21:21 ./
drwxr-xr-x    2 Administ None            0 Jan 1 1980 ../
-rw-r--r--    1 Administ None          515 Apr 18 21:21 123AA.DEF
-rw-r--r--    1 Administ None         1025 Apr 18 21:21 123BB.DEF
drwxr-xr-x    3 Administ None            0 Apr 18 21:21 456/
/cygdrive/a $ll 123/456
total 0
drwxr-xr-x    3 Administ None            0 Apr 18 21:21 ./
drwxr-xr-x    3 Administ None            0 Apr 18 21:21 ../
-rw-r--r--    1 Administ None            0 Apr 18 21:21 456AA
-rw-r--r--    1 Administ None            0 Apr 18 21:21 456BB
drwxr-xr-x    2 Administ None            0 Apr 18 21:21 789/
/cygdrive/a $ll 123/456/789
total 1
drwxr-xr-x    2 Administ None            0 Apr 18 21:21 ./
drwxr-xr-x    3 Administ None            0 Apr 18 21:21 ../
-rw-r--r--    1 Administ None          600 Apr 18 21:21 789AA
-rw-r--r--    1 Administ None            0 Apr 18 21:21 789BB
/cygdrive/a $

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条