SRAM
Verilog设计一个sram,供仿真使用,实际工程中,FPGA直接例化工具自带的IP Core,ASIC由后端做专门的memory。 csen_n为低,wren_n为高写数据 csen_n为低,wren_n为高读数据 csen_n为高,memory不工作 。
reg [DATA_WIDTH-1:0] register[2**ADDR_WIDTH-1:0];
always @(posedge clk)begin
if(!wren_n && !csen_n)
register[addr] <= data_i;
end
always @(posedge clk)begin
if(wren_n && !csen_n)
data_o <= register[addr];
end
双口RAM
双口ram是单一时钟,支持一个读地址和一个写地址。本设计是同步读数ram,异步读数ram去掉时钟即可。
reg [DATA_WIDTH-1:0] register[2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addrb_r;
always @(posedge clk)begin
if(!wrena_n && !csen_n)
register[addra] <= data_a;
end
always @(posedge clk)begin
if(!rdenb_n && !csen_n)
data_b <= register[addrb];//read old data
//addrb_r <= addrb//read new data
end
//assign data_b = register[addrb_r];//read new data
真双口RAM
真双口ram是两个时钟,支持两套独立完整的读写。
reg [DATA_WIDTH-1:0] register[2**ADDR_WIDTH-1:0];
always @(posedge clka)begin
if(!wrena_n && !csen_n)begin
register[addra] <= dina;
douta <= dina;
end
else if(!csen_n)
douta <= register[addra];
end
always @(posedge clkb)begin
if(!wrenb_n && !csen_n)begin
register[addrb] <= dinb;
doutb <= dinb;
end
else if (!csen_n)begin
doutb <= register[addrb];
end
end
Register File
在我的认知中Register File的写法其实和上述大同小异,在FPGA中写成Register File,工具貌似会综合成BRAM资源,在ASIC设计中RAM Memory需要专门去做存储块。本文大致了解RAM的原理,只可供仿真使用。
使用Reg File在存储为小规模使用时有优势,面积小速度快,当存储的规模大于256个单元时,提倡使用sram的标准单元库。
SRAM和DRAM
SRAM:Static Random-Access Memory,静态随机存取存储器,只要供电数据就会保持,但断电数据就会消失,也被称为Volatile Memory
DRAM:Dynamic Random Access Memory,动态随机存储器,主要原理是利用电容存储电荷的多少来代表一个bit是0还是1,由于晶体管的漏电电流现象,电容会放电,所以要周期性的给电容充电,叫刷新。SRAM不需要刷新也会保持数据丢失,但是两者断电后数据都会消失,称为Volatile Memory
SDRAM和DDR
SDRAM:Synchronous Dynamic Random Access Memory,同步动态随机存储器,同步写入和读出数据的DRAM。
DDR:Double Data Synchronous Dynamic Random Access Memory,双倍速率同步动态随机存储器,就是DDR SDRAM双倍速率传输的SDRAM,在时钟的上升沿和下降沿都可以进行数据传输。我们电脑的内存条都是DDR芯片。
留一个练习
设计一个双口RAM,要求可读可写,可以同时读写,两种处理方式
- 将输入输出参数化,可重复调用
- 读取原来存储的值,然后立即写入新值
- 不能读取原来的值,而是直接获得正在写入的值
将设计电路参数化可重复使用,构建自己的代码库,搭建起你的数字积木,本设计博主放在了GitHub上,关注 硅农 可以在订阅号后台回复 “ip_lib”得到GitHub路径进行交流。