ROM:只读,只有读接口(读地址、读数据)
RAM:可读可写,有读接口(读地址、读数据)和写接口(写使能、写数据、写地址),默认任何时刻都能读,没有读使能,大小和位宽查手册,需要持续供电才能将数据保存在其中(易失性存储器),断电数据丢失
DRAM:动态随机存取存储器,数据存储在电容器中,通过保持电荷实现数据存储(比如电容器充电和放电分别为1和0),价格低,消耗功率高,最常用作计算机的主存储器,需要不断刷新(由于电容器内部用于分隔导电板的电介质不是完美的绝缘体,电容器易放电导致电荷泄漏),以同步或异步模式运行,存储容量为1GB-16GB
SRAM:静态随机存取存储器,数据存储在晶体管中,通过改变晶体管的导通状态进而改变电平高低,需要恒定的功率流,速度快,用于高速缓存,存储容量为1MB-16MB
SDRAM:同步动态随机存储器(与CPU频率同步、存储阵列需要不断刷新来保证数据不丢失、自由指定地址进行数据读写),通过电容充放电实现数据存储,内部分为多个bank,通过流水线操作提高速度(一个bank处于预充电状态,正在经历访问延迟时,另一个bank可进行读取),存储容量大、速度快、价格低,控制逻辑复杂、对时序要求高
DDR:双倍速率同步动态随机存储器,命令和操作只在时钟的上升沿发生,数据传输在时钟上升沿和下降沿发生,每个时钟周期发送两倍数据
FIFO和RAM的差别:FIFO是先入先出,没有读写地址,只能按顺序读写数据,RAM可以读写任意地址,FIFO常用于数据传输通道中,用于缓存数据,避免数据丢失,RAM常用于存储指令或者中间的数据
IP核配置图

| 信号名称 | 信号功能 |
| dina | 端口a的写数据信号 |
| addr | 端口a的读写地址信号 |
| wea | 端口a的写使能信号,高电平为写,低电平为读 |
| ena | 端口a的使能信号,高电平为使能端口a,低电平端口a被禁止,取消此信号后端口a一直有效(可选信号) |
| rsta | 端口a的复位信号(可选信号) |
| regcea | 端口a输出寄存器使能信号,高电平douta保持最后一次输出(可选信号) |
| clka | 端口a的时钟信号 |
| douta | 端口a数据输出 |
新建工程:打开vivado-Quick Start-Create Project-Next-输入工程名和位置(注意工程名和位置中都不能出现中文和空格)-勾选Create project subdirectory(为工程在指定存储路径下建立独立的文件夹)-勾选RTL Project-勾选Do not specifysources at this time(此时不定义源文件)-选择FPGA开发板(我用的是xc7k325tfbg676-3)-Next-Finish
创建RAM IP核:Flow Navigator-IP Catalog-Search:block memory-Block Memory Generator
配置IP核:component name(器件名称,默认即可,不用修改)-basic-interface type(接口类型,默认native)-memory type选择single port ram-write enable中取消勾选字节写使能byte write enable-algorithm options-algorithm选最小面积minimum area-ok

port A options-memory size-write width写数据位宽选择8-write depth写深度选择32-operating mode选no change-enable port type选use ena pin-port A optional output registers都不勾选-port A output reset options勾选RSTA pin-output reset value为0-ok

创建模块ram_rw.v:
project manager-add sources-add or create design sources-next-create file-输入文件名ram_rw.v-ok-finish
module ram_rw(
input clk,
input rst_n,//端口复位,为0时复位
input [7:0] r_data,//读数据
output reg [7:0] w_data,//写数据
output ram_we,//写使能
output reg [4:0] ram_addr,//读写地址
output ram_en//端口使能
);
(* DONT_TOUCH = "TRUE" *) reg [5:0] wr_cnt;//读写计数,因为没有规定输入输出,所以加上前缀括号
assign ram_en = rst_n;//端口使能
assign ram_we = (wr_cnt<=6'd31 && ram_en==1)? 1'b1 : 1'b0;//写使能:读写计数器在0-31为写,32-63为读,6'd31为6位四进制数,数值为31
//读写计数信号设计
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
wr_cnt <= 0;//复位时读写计数为0
else if(wr_cnt==6'd63)
wr_cnt <= 0;//读写计数为63,赋值为0,准备重新计数
else
wr_cnt <= wr_cnt + 1;//其他情况,每次计数加1
end
//读写地址信号设计
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
ram_addr <= 0;//复位时读写地址为0
else if(ram_addr==5'd31)
ram_addr <= 0;//读写地址为31,赋值为0,重新开始计数
else
ram_addr <= ram_addr + 1;//其他情况,每次地址加1
end
//写数据信号设计
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
w_data <= 0;//复位时写数据为0
else if(wr_cnt <= 6'd31)
w_data <= w_data + 1;//读写计数在0-31为写
else
w_data <= 0;//其他情况,写数据为0
end
//读数据信号设计
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
r_data <= 0;//复位时读数据为0
else if(wr_cnt >= 6'd32 && wr_cnt <= 6'd63)
r_data <= r_data + 1;//读写计数在32-63为读
else
r_data <= 0;//其他情况,读数据为0
end
endmodule
本部分的功能:对一个数据位宽为8、深度为32的单端口RAM 进行读写操作设计,注意一个always设计一个信号,对于每个信号的设计,要覆盖到其所有情况
例化IP核blk_mem_gen_0及ram_rw 模块:
sources-IP sources-找到.veo文件,查看例化ram IP核的模板
blk_mem_gen_0 your_instance_name (
.clka(clka), // input wire clka
.rsta(rsta), // input wire rsta
.ena(ena), // input wire ena
.wea(wea), // input wire [0 : 0] wea
.addra(addra), // input wire [4 : 0] addra
.dina(dina), // input wire [7 : 0] dina
.douta(douta), // output wire [7 : 0] douta
.rsta_busy(rsta_busy) // output wire rsta_busy
);
创建顶层模块ipram:
module ipram(
input sys_clk,
input sys_rst
);
wire [7:0] r_data;
wire [7:0] w_data;
wire ram_en;
wire ram_we;
wire [4:0] ram_addr;
ram_rw ram_rw_inst(
.clk (sys_clk),//例化本质上就是调用的过程,顶层模块ipram调用读写模块ram_rw,括号内为顶层模块的信号名
.rst_n (sys_rst),
.r_data (r_data),
.w_data (w_data),
.ram_we (ram_we),
.ram_addr(ram_addr),
.ram_en (ram_en) );
blk_mem_gen_0 blk_mem_gen_1 (//顶层模块ipram调用ram IP核blk_mem_gen_0
.clka (sys_clk), // input wire clka
.rsta (sys_rst), // input wire rsta
.ena (ram_en), // input wire ena
.wea (ram_we), // input wire [0 : 0] wea
.addra (ram_addr), // input wire [4 : 0] addra
.dina (w_data), // input wire [7 : 0] dina
.douta (r_data) // output wire [7 : 0] douta
//.rsta_busy(rsta_busy) // output wire rsta_busy顶层模块没有用到此信号
);
endmodule
仿真程序:
module tb_ram_ip(
);
(* DONT_TOUCH = "TRUE" *) reg sys_clk;//输入信号
(* DONT_TOUCH = "TRUE" *) reg sys_rst;
ipram ipram_inst(
.sys_clk(sys_clk),//仿真模块tb_ram_ip调用顶层模块ipram
.sys_rst(sys_rst)
);
initial begin
sys_clk = 0;
sys_rst = 0;
#10//等待复位完成
sys_rst = 1;
#256
$stop;
end
always #5 sys_clk = ~sys_clk;//10ns一个周期,产生100MHz时钟源
endmodule
参考文献:
【Vivado】ram ip核的使用_想学fpga的小猪同学的博客-CSDN博客_vivado移位寄存器FIFO RAM的差异与共同点_IC小鸽的博客-CSDN博客_fifo和ram的区别
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po