概述
ROM概述
ROM 是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除,且资料不会因为电源关闭而消失。
单端口ROM接口信号
双端口ROM接口信号
单端口ROM的配置
选择使用的时钟模式,可选择单时钟或双时钟。选择单时钟时用一个时钟控制存储块的所有寄存器,选择双时钟时输入时钟控制地址寄存器,输出时钟控制数据输出寄存器。ROM 模式没有写使能、字节使能和数据输入寄存器。这里我们选择默认选项Single clock(单时钟)。
上图是选择是否输出“q”寄存器。这里我们把输出端口的寄存器去掉(如果不去掉的 话,就会使输出延迟一拍。如果没有特别的需求的话我们是不需要延迟这一拍的).
不勾选时,数据输出会延时地址输入一个时钟周期,勾选时,时钟信号会输入更高的频率,数据输出会延时地址输入两个时钟周期
上图是添加文件路径
提示了我们单独使用第三方仿真工具时需要添加名为 “altera_mf”的库
双端口ROM的配置
As a number of words”是按字数确定,“AS a number of bits”是按比特数确定。
(注意:选择的容量需大于我们需要写入的数据文件的数据量
Single clock(单时钟):使用一个时钟控制。
ROM IP核模块
ROM控制模块
ROM控制模块输入输出信号
module rom_ctrl
#(
parameter CNT_MAX = 24'd9_999_999
)
(
input wire sys_clk ,
input wire sys_rst_n,
input wire key1 , //按键1消抖后有效信号
input wire key2 , //按键2消抖后有效信号
output reg [7:0] addr //输出读ROM地址
);
reg [23:0] cnt_200ms ;
reg key1_en; //特定地址 1 标志信号
reg key2_en; //特定地址 2 标志信号
//0.2s 循环计数
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_200ms <= 24'd0;
else if(cnt_200ms == CNT_MAX || key1_en == 1'b1 || key2_en == 1'b1)
cnt_200ms <= 24'd0;
else
cnt_200ms <= cnt_200ms + 1'b1;
//产生特定地址 1 标志信号
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
key1_en <= 1'b0;
else if(key2 == 1'b1)
key1_en <= 1'b0;
else if(key1 == 1'b1)
key1_en <= ~key1_en;
else
key1_en <= key1_en;
/产生特定地址 2 标志信号
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
key2_en <= 1'b0;
else if(key1 == 1'b1)
key2_en <= 1'b0;
else if(key2 == 1'b1)
key2_en <= ~key2_en;
else
key2_en <= key2_en;
//让地址从 0~255 循环,其中两个按键控制两个特定地址的跳转
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
addr <= 8'd0;
else if(addr == 8'd255 && cnt_200ms == CNT_MAX)
addr <= 8'd0;
else if(key1_en == 1'b1)
addr <= 8'd99;
else if(key2_en == 1'b1)
addr <=8'd199;
else if(cnt_200ms == CNT_MAX)
addr <= addr + 1'b1;
endmodule
顶层模块
module rom
(
input wire sys_clk,
input wire sys_rst_n,
input wire key1 ,
input wire key2 ,
output wire ds,
output wire oe,
output wire shcp,
output wire stcp
);
wire key1_flag; //按键 1 消抖信号
wire key2_flag; //按键 2 消抖信号
wire [7:0] addr;
wire [7:0] data; //读出 ROM 数据
key_filter
#(
.CNT_MAX (20'd999_999)
)
key_filter_inst1
(
.sys_clk (sys_clk),
.sys_rst_n(sys_rst_n),
.key_in (key1),
.key_flag (key1_flag) //key_flag 为 1 时表示消抖后检测到按键被按下
);
key_filter
#(
.CNT_MAX (20'd999_999)
)
key_filter_inst2
(
.sys_clk (sys_clk),
.sys_rst_n(sys_rst_n),
.key_in (key2),
.key_flag (key2_flag) //key_flag 为 1 时表示消抖后检测到按键被按下
);
rom_ctrl
#(
.CNT_MAX (24'd9_999_999)
)
rom_ctrl_inst
(
.sys_clk (sys_clk),
.sys_rst_n(sys_rst_n),
.key1 (key1_flag), //按键 1 消抖后有效信号
.key2 (key2_flag), //按键 2 消抖后有效信号
.addr (addr) //输出读 ROM 地址
);
rom_8x256 rom_8x256_inst
(
.address ( addr ),
.clock ( sys_clk ),
.q ( data )
);
seg_595_dynamic seg_595_dynamic
(
.sys_clk (sys_clk),
.sys_rst_n(sys_rst_n),
.data ({12'b0,data}),
.point (6'b000_000), //小数点显示,高电平有效
.sign (1'b0), //符号位,高电平显示负号
.seg_en (1'b1), //数码管使能信号,高电平有效
.ds (ds ), //串行数据输入
.oe (oe ), //输出使能信号
.shcp (shcp), //移位寄存器的时钟输入
.stcp (stcp) //输出数据存储寄时钟
);
endmodule
RTL视图
ROM IP核仿真
`timescale 1ns/1ns
module tb_rom();
reg sys_clk;
reg sys_rst_n;
reg key1;
reg key2;
wire ds;
wire oe;
wire shcp;
wire stcp;
initial
begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
key1 <= 1'b1;
key2 <= 1'b1;
#20
sys_rst_n <= 1'b1;
#700000 //仿真时是100个时钟周期,一个时钟周期20ns,也就是一个
//数据的显示时间是100*20=2000ns,
//256个数据显示时间是256*2000=512000ns,故延时的时间需要大于此值
//key1
key1 <= 1'b0;
#20
key1 <= 1'b1;
#20
key1 <= 1'b0;
#20
key1 <= 1'b1;
#20
key1 <= 1'b0;
#200 //以上是模拟按键前抖动,以下是模拟按键后抖动
key1 <= 1'b1;
#20
key1 <= 1'b0;
#20
key1 <= 1'b1;
#20
key1 <= 1'b0;
#20
key1 <= 1'b1;
//key2
#20000
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#200 //以上是模拟按键前抖动,以下是模拟按键后抖动
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
//key2
#20000
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#200 //以上是模拟按键前抖动,以下是模拟按键后抖动
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
#20
key2 <= 1'b0;
#20
key2 <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
//defparam rom_inst.key_filter_indt1.CNT_MAX = 9;
rom rom_inst
(
.sys_clk (sys_clk ),
.sys_rst_n(sys_rst_n),
.key1 (key1 ),
.key2 (key2 ),
.ds (ds ),
.oe (oe ),
.shcp (shcp ),
.stcp (stcp )
);
endmodule
接下来仿真验证
最后
以上就是生动酒窝为你收集整理的IP核之ROMROM概述单端口ROM的配置的全部内容,希望文章能够帮你解决IP核之ROMROM概述单端口ROM的配置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复