FPGA学习之片上ROM

存储器在FPGA设计中可分为两类:一类是FPGA自带的存储单元,这些存储单元可以灵活设置成ROM、SRAM、FIFO及所需要的其他形式,使用方便;但是FPGA自带的存储器与FPGA的等级有关,等级越高,存储器容量越大,价格也就越高。另一类是FPGA的外部存储器,他们的大嘴有点就是存储容量不再是问题,不过他们一般专有一种功能,要么是ROM,要么就是SRAM,再者就是FIFO等,而且操作也比前一类更为复杂。
下面说一个找工作面试官最容易问到的低级问题,那就是:你所使用的微处理器的内部存储器有多大?
Cyclone II 内嵌存储器是由多列M4K存储器块组成,每个M4K块相当于4608RAM位,是这样计算得来的:
M4k+512位校验位= 4*1024+512=4608  M4K指的是4kbits
而开发板使用的EP2C8具有36个M4K RAM块(4K位+512位校验位),所以RAM位总位数是:165888。
下面贴出的是用于存储char型字符的ROM设计:
/*******************************************************
ROM Design
********************************************************/
module char_rom( 
address ,
        data 
        );
input  [5:0]address;    //输入地址
output [7:0]data; //输出数据
reg    [7:0]data; //输出数据时reg类型
 function  [7:0] char_to_integer; //这里使用了function,注意function的使用方法
input  [7:0]indata;
reg    [7:0]result;            //一个字符型需要8bit来装          
begin
case(indata)
  " " : result = 32;  //字符型要使用双引号
  "!" : result = 33;
  "\"" : result = 34;
  "#" : result = 35;
  "$" : result = 36;
  "%" : result = 37;
  "&" : result = 38;
  "'" : result = 39;
  "(" : result = 40;
  ")" : result = 41;
  "*" : result = 42;
  "+" : result = 43;
  "," : result = 44;
  "-" : result = 45;
  "." : result = 46;
  "/" : result = 47;
  "0" : result = 48;
  "1" : result = 49;
  "2" : result = 50;
  "3" : result = 51;
  "4" : result = 52;
  "5" : result = 53;
  "6" : result = 54;
  "7" : result = 55;
  "8" : result = 56;
  "9" : result = 57;
  ":" : result = 58;
  ";" : result = 59;
  "<" : result = 60;
  "=" : result = 61;
  ">" : result = 62;
  "?" : result = 63;
  "@" : result = 64;
  "A" : result = 65;
  "B" : result = 66;
  "C" : result = 67;
  "D" : result = 68;
  "E" : result = 69;
  "F" : result = 70;
  "G" : result = 71;
  "H" : result = 72;
  "I" : result = 73;
  "J" : result = 74;
  "K" : result = 75;
  "L" : result = 76;
  "M" : result = 77;
  "N" : result = 78;
  "O" : result = 79;
  "P" : result = 80;
  "Q" : result = 81;
  "R" : result = 82;
  "S" : result = 83;
  "T" : result = 84;
  "U" : result = 85;
  "V" : result = 86;
  "W" : result = 87;
  "X" : result = 88;
  "Y" : result = 89;
  "Z" : result = 90;
  "[" : result = 91;
//      "\\" : result = 92;
  "]" : result = 93;
  "^" : result = 94;
  "_" : result = 95;
  "`" : result = 96;
  "a" : result = 97;
  "b" : result = 98;
  "c" : result = 99;
  "d" : result = 100;
  "e" : result = 101;
  "f" : result = 102;
  "g" : result = 103;
  "h" : result = 104;
  "i" : result = 105;
  "j" : result = 106;
  "k" : result = 107;
  "l" : result = 108;
  "m" : result = 109;
  "n" : result = 110;
  "o" : result = 111;
  "p" : result = 112;
  "q" : result = 113;
  "r" : result = 114;
  "s" : result = 115;
  "t" : result = 116;
  "u" : result = 117;
  "v" : result = 118;
  "w" : result = 119;
  "x" : result = 120;
  "y" : result = 121;
  "z" : result = 122;
  "{" : result = 123;
  "|" : result = 124;
  "}" : result = 125;
  "~" : result = 126;
  default  :      result = 32;
endcase
char_to_integer = result;
end
endfunction

always @(address)
begin
case (address)  //根据地址调用相应的数据
   6'b000000  :data <= char_to_integer ("W");
   6'b000001  :data <= char_to_integer ("e");
   6'b000010  :data <= char_to_integer ("l");
   6'b000011  :data <= char_to_integer ("e");
   6'b000100  :data <= char_to_integer ("c");
   6'b000101  :data <= char_to_integer ("o");
   6'b000110  :data <= char_to_integer ("m");
   6'b000111  :data <= char_to_integer ("e");
   6'b001000  :data <= char_to_integer (" ");
   6'b001001  :data <= char_to_integer (" ");
   6'b001010  :data <= char_to_integer ("B");
   6'b001011  :data <= char_to_integer ("A");
   6'b001100  :data <= char_to_integer ("I");
   6'b001101  :data <= char_to_integer ("X");
   6'b001110  :data <= char_to_integer ("U");
   6'b001111  :data <= char_to_integer ("N");
   6'b010000  :data <= char_to_integer (" ");
   6'b010001  :data <= char_to_integer (" ");
   6'b010010  :data <= char_to_integer ("B");
   6'b010011  :data <= char_to_integer ("o");
   6'b010100  :data <= char_to_integer ("a");
   6'b010101  :data <= char_to_integer ("r");
   6'b010110  :data <= char_to_integer ("d");
   6'b010111  :data <= char_to_integer ("!");
  default     :data <= char_to_integer (" ");
endcase
 end
endmodule

这里值得一提的是function的使用方法,多个输入,但是只能有一个输出,输出就是函数名本身,所以定义函数的时候应该设定输出的范围,不然会被默认为一位。而定义字符型的时候不用像VHDL那样专门指出是character类型,而是直接使用一个8位的reg即可,而且字符和VHDL的表示也不一样,VHDL里面是使用了单引号表示字符,而verilog无论是字符还是字符串都应该使用双引号。而存储多个字符串的时候也不用使用数组,只要把reg位数设置足够宽就行了,例如 reg [0:31]love = "love"; 4*8 =32bit;
当然如果需要装载比较大的内容的时候,我们还使用这样的方法就显得很麻烦,很多工具书都有介绍使用LMP来完成片上ROM的设计,这种方法很简单,在初始化ROM的时候只要(.mif)文件里面输出需要存储的内容即可。



我相信,只要脚踏实地积累,总会有“玩转”的一天。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值