当前位置: 首页 > news >正文

fpga开发-存储器及其应用

目录

ROM

RAM

FIFO


  以结构化方式存储大量二值信息的半导体器件。存储器单元数×每个单元的存储位数

  掩膜ROM    PROM    EPROM    *E2PROM    *快闪存储器     *静态RAM(SRAM)    *动态RAM(DRAM),存储器分为ROM和RAM两种基本类型。ROM分为单口ROM和双口ROM两种类型。RAM分为单口RAM、双口RAM和伪双端口RAM三种类型。除ROM和RAM之外,在数字系统设计中还经常应用一类特殊的存储器,称为FIFO,具有先进先出的特性,用于串行数据的缓存和跨时钟域数据的传输。

ROM

    ROM本质上为组合逻辑电路。小容量的ROM可以直接应用case语句定义存储数据。描述二进制显示译码的16×7位ROM的Verilog代码参考如下

module rom_16x7b(bincode,oHex7); input [3:0] bincode;output reg [6:0] oHex7;// 存储数据描述always @( bincode )case ( bincode )     // gfedcba, 高电平有效4'b0000 : oHex7 = 7'b0111111;  // 显示 04'b0001 : oHex7 = 7'b0000110;  // 显示 1             4'b0010 : oHex7 = 7'b1011011;  // 显示 24'b0011 : oHex7 = 7'b1001111;  // 显示 34'b0100 : oHex7 = 7'b1100110;  // 显示 44'b0101 : oHex7 = 7'b1101101;  // 显示 54'b0110 : oHex7 = 7'b1111101;  // 显示 64'b0111 : oHex7 = 7'b0000111;  // 显示 74'b1000 : oHex7 = 7'b1111111;  // 显示 84'b1001 : oHex7 = 7'b1101111;  // 显示 94'b1010 : oHex7 = 7'b1110111;  // 显示 A4'b1011 : oHex7 = 7'b1111100;  // 显示 b4'b1100 : oHex7 = 7'b0111001;  // 显示 c4'b1101 : oHex7 = 7'b0011110;  // 显示 d4'b1110 : oHex7 = 7'b1111001;  // 显示 E4'b1111 : oHex7 = 7'b1110001;  // 显示 Fdefault : oHex7 = 7'b0000000;  // 不显示endcase
endmodule

设计数码序列控制电路,能够在单个数码管上依次循环显示自然数序列(0~9)、奇数序列(1、3、5、7、9)、音乐序列(0~7)和偶数序列(0、2、4、6、8)。

 分析:自然序列有10个数码,奇数序列和偶数序列分别有5个数码,音乐顺序有8个数码,因此一个完整的显示循环共有28个数码。因此,先描述28×4位的ROM,并应用case语句定义28个单元的数据为序列BCD码,再设计一个28进制计数器,将计数器的状态作为ROM的地址,驱动ROM输出BCD码序列,最后再应用显示译码器将BCD码译为七段码输出,驱动数码管显示相应的数字。

设计过程: 描述数码序列控制电路的Verilog代码参考如下:

 module SEG_controller(iclk,rst_n,oseg7);input iclk,rst_n;output reg [6:0] oseg7;// 内部寄存器变量定义reg [4:0] cnt_q;reg [3:0] disp_bcd;           // 时序逻辑过程,描述28进制计数器always @( posedge iclk or negedge rst_n ) if ( !rst_n ) cnt_q <= 5'd0;     else if ( cnt_q == 5'd27 )cnt_q <= 5'd0;elsecnt_q <= cnt_q + 1'b1;// 组合逻辑过程,定义显示序列BCD码always @( cnt_q )                   case( cnt_q )5'd0  :  disp_bcd = 4'd0;5'd1  :  disp_bcd = 4'd1;5'd2  :  disp_bcd = 4'd2;5'd3  :  disp_bcd = 4'd3;5'd4  :  disp_bcd = 4'd4;5'd5  :  disp_bcd = 4'd5;5'd6  :  disp_bcd = 4'd6;5'd7  :  disp_bcd = 4'd7;5'd8  :  disp_bcd = 4'd8;5'd9  :  disp_bcd = 4'd9;5'd10 : disp_bcd = 4'd1;5'd11 : disp_bcd = 4'd3;5'd12 : disp_bcd = 4'd5;5'd13 : disp_bcd = 4'd7;5'd14 : disp_bcd = 4'd9;5'd15 : disp_bcd = 4'd0;5'd16 : disp_bcd = 4'd1;5'd17 : disp_bcd = 4'd2;5'd18 : disp_bcd = 4'd3;       5'd19 : disp_bcd = 4'd4;5'd20 : disp_bcd = 4'd5;5'd21 : disp_bcd = 4'd6;5'd22 : disp_bcd = 4'd7;5'd23 : disp_bcd = 4'd0;5'd24 : disp_bcd = 4'd2;5'd25 : disp_bcd = 4'd4;5'd26 : disp_bcd = 4'd6;5'd27 : disp_bcd = 4'd8;default : disp_bcd = 4'd0;endcasealways @ (posedge iclk)   // 显示译码输出            case ( disp_bcd )              4'd0 :  oseg7 <= 7'b1000000;                     4'd1 :  oseg7 <= 7'b1111001;4'd2 :  oseg7 <= 7'b0100100;4'd3 :  oseg7 <= 7'b0110000;4'd4 :  oseg7 <= 7'b0011001;4'd5 :  oseg7 <= 7'b0010010;4'd6 :  oseg7 <= 7'b0000010;4'd7 :  oseg7 <= 7'b1111000;4'd8 :  oseg7 <= 7'b0000000;4'd9 :  oseg7 <= 7'b0010000;default :  oseg7 <= 7'b1111111;endcase  
endmodule

    一般地,通用ROM可以用寄存器数组描述,然后将定义存储数据的存储器初始化数据文件(.mif或者.hex)加载到寄存器数组中实现。

   设计音乐播放控制模块,将文件swanlake_scene_notes.mif加载到《天鹅湖》场景音乐ROM中,然后按音符的时长控制播放。

module swanlake_controller( clk2p8Hz,rst_n,tone_fpdat );input clk2p8Hz;input rst_n;output reg [11:0] tone_fpdat;reg [15:0] swanlake_scene_rom [0:83] /* synthesis ram_init_file ="swanlake_scene_notes.mif"  */; reg [3:0] beat_cnt;   // 节拍计数reg [6:0] tone_addr;  // 音调地址always @( posedge clk2p8Hz or negedge rst_n ) if ( !rst_n ) begintone_addr = 7'd0;beat_cnt = swanlake_scene_rom[0][15:12];tone_fpdat = swanlake_scene_rom[0][11:0];   endelse beginbeat_cnt = beat_cnt - 1'b1; if ( beat_cnt == 0 )if ( tone_addr == 7'd83 )   tone_addr = 7'd0;else begin  tone_addr = tone_addr + 1'b1;beat_cnt = swanlake_scene_rom[tone_addr][15:12];tone_fpdat = swanlake_scene_rom[tone_addr][11:0];  endend
endmodule

上升沿检测电路的工作原理是:        应用三级(或两级)移位寄存器,在440kHz时钟脉冲的作用下,对2.8Hz时钟信号进行采样并依次右移存入移位寄存器中。当移位寄存器中的存储数据为“x10”时,则输出时钟上升沿检测标志脉冲。

描述上升沿检测模块的Verilog代码参考如下: 
module rising_edge_det (clock, clkin, detout );input clock;        // 440kHzinput clkin;        // 2.8Hzoutput wire detout;    // 检测输出reg [0:2] dat_reg;   // 移位寄存器定义// 右移存入过程,以消除亚稳态always @ ( posedge clock ) dat_reg <= { clkin,dat_reg[0:1] };// 上升沿检测逻辑assign detout = dat_reg[1] & ~dat_reg[2] ;
endmodule

RAM

  在基于FPGA的数字系统设计中,构建小容量RAM有两种方法:一是应用RAM IP核,基于片上存储资源构建;二是应用Verilog HDL描述,基于FPGA内部逻辑资源构建。构建片内RAM的原则是,构建较大的存储器应用片上存储资源,构建较小的存储器可以使用代码直接描述。

   单口(Single-Port)RAM具有一组地址线、一组输入数据线和一组数据输出线。由于读/写时共用时钟和地址线, 所以单口RAM的读操作和写操作不能同时进行。

1024×8位单口RAM功能描述。

module RAM_1port #( parameter ADDR_WIDTH=10,DATA_WIDTH=8 )( clock,data,wren,address,q );localparam RAM_DEPTH = 1 << ADDR_WIDTH;input clock;input [DATA_WIDTH-1:0] data; input wren;input [ADDR_WIDTH-1:0] address;output wire [DATA_WIDTH-1:0] q;// 定义存储器reg [DATA_WIDTH-1:0] mem [RAM_DEPTH-1:0];always @ ( posedge clock )    // 存储过程if ( wren )     mem[address] <= data;assign q = mem[address];    // 直接输出型endmodule

   双口(Dual-Port)RAM具有两组地址线、两组输入数据线和两组输出数据线,分为单时钟和双时钟两种类型, 由于双口RAM具有两组独立的读写端口,因此读写可以同时进行。双口RAM在异构系统中应用广泛,可以通过双口RAM实现跨时钟域数据的传输。  但是,如果双口RAM的两个端口同时对同一个存储单元进行读写操作,就会引发冲突。

  伪双口(Simple Dual-Port)RAM与双口RAM的区别在于一个端口只读,另一个端口只写,而双口RAM的两组端口都可以进行读写。  1024×8位伪双口RAM的电路框图如图所示,其中inclock和outclock分别为写时钟和读时钟,data为写数据输入端,wraddress为写地址端,wren为写使能信号,rdaddress为读地址端,rden为读使能信号,q为读数据输出端。

FIFO

    FIFO为先进先出(first-in first-out)的缓存器,通常由双口RAM附加读写逻辑电路构成。与双口RAM不同的是,FIFO没有外部地址线,只能按顺序写入和读出,而双口RAM可以根据地址对指定的存储单元进行读写。   描述FIFO有宽度(width)和深度(depth)两个主要参数,其中宽度表示每个存储单元能够存储二进制数据的位数,而深度表示存储单元的个数。

 根据FIFO读写时钟的差异,将FIFO分为同步FIFO和异步FIFO两种类型。

   同步FIFO的读操作和写操作基于同一时钟,使用读/写指针(即地址)指定数据的读写单元。写指针wp(write pointer)总是指向下一个要写入数据的单元。读指针rp(read pointer)总是指向下一个要读出数据的单元。

  由于同步FIFO的读/写时钟相同,所以可以通过统计数据存储个数来产生空标志(empty)和满标志(full)。FIFO初始化时数据存储个数设置为0,写入一个数据后存储个数加1,读出一个数后后存储个数减1。当数据存储个数为0时,产生empty标志;当数据存储个数等于FIFO的深度时,产生full标志。

1024×8位同步FIFO功能描述。

`timescale 1ns/1psmodule sync_FIFO #( FIFO_WIDTH=8 )(input FIFO_clk,                      // FIFO时钟input FIFO_rst_n,                   // 复位信号,低电平有效input FIFO_rdreq,                   // 读请求信号 input FIFO_wrreq,                   // 写请求信号input [FIFO_WIDTH-1:0] wdata,  // 需要写入的数据output reg [FIFO_WIDTH-1:0] rdata,  // 读出的数据output wire full,                           // FIFO满标志output wire empty                          // FIFO空标志);// FIFO存储深度定义parameter FIFO_ADDR=10;localparam FIFO_DEPTH = 1 << FIFO_ADDR;// 内部线网和变量定义wire rden,wren;                         // 允许读信号和允许写信号
reg [FIFO_ADDR-1:0] rp,wp;      // 读指针和写指针
reg [FIFO_ADDR:0]   used_cnt;   // 存储数据个数统计
// 描述FIFO存储实体
reg [FIFO_WIDTH-1:0] FIFO_mem [FIFO_DEPTH-1:0]; 
// 读写允许逻辑定义
assign rden =  FIFO_rdreq && !empty ;
assign wren =  FIFO_wrreq && !full ;
// 状态标志逻辑,高电平有效
assign empty = ( used_cnt == 0 );
assign full  = ( used_cnt == FIFO_DEPTH );
always @( posedge FIFO_clk )  // 读过程if ( rden ) rdata <= FIFO_mem[rp];
always @( posedge FIFO_clk )  // 写过程if ( wren ) FIFO_mem[wp] <= wdata;
// 读指针处理过程
always @ ( posedge FIFO_clk or negedge FIFO_rst_n)if ( !FIFO_rst_n ) rp <= 0;else if( rden )  rp <= rp + 1;
// 写指针处理过程
always @ ( posedge FIFO_clk or negedge FIFO_rst_n)if ( !FIFO_rst_n ) wp <= 0;else if( wren )  wp <= wp + 1;
// 数据存储个数统计
always @( posedge FIFO_clk or  negedge FIFO_rst_n )if ( !FIFO_rst_n )used_cnt <= 0;else case ({rden,wren})2'b01: if ( used_cnt !=    FIFO_DEPTH ) used_cnt <= used_cnt + 1'b1;2'b10: if ( used_cnt !=    0 ) used_cnt <= used_cnt - 1'b1;default: used_cnt <= used_cnt;endcase
endmodule


http://www.mrgr.cn/news/74730.html

相关文章:

  • 雷池waf安装并部署防护站点
  • SQL50题
  • Redis增删改查、复杂查询案例分析
  • Scala中的case class
  • 明源地产ERP系统 WFWebService 反序列化漏洞复现
  • C#画图板代码
  • 图像识别
  • AI开发-三方库-PyTorch-Matplotlib
  • TLP2361光耦器:为高速、高可靠性数字接口提供解决方案
  • STM32F407简单驱动步进电机(标准库)
  • 3.5MachineLearing1Chapter
  • 威联通Docker Compose搭建NAS媒体库资源工具NAS Tools
  • 基于51单片机的高压锅控制系统proteus仿真
  • 污水处理领域的可视化大屏,3D流程图绝对有很大用武之地。
  • PHP“well”运动健身APP 87702-计算机毕业设计项目选题推荐(附源码)
  • DAY112代码审计PHP开发框架POP链利用Yii反序列化POP利用链
  • NocoBase 本周更新汇总:提升工作流易用性
  • C/C++精品项目之图床共享云存储(3):网络缓冲区类和main
  • 「媒体邀约」科技类企业如何利用媒体专访提升品牌知名度
  • Vuex vs Pinia:新一代Vue状态管理方案对比
  • IDEA2024:右下角显示内存
  • 苹果APNs消息推送
  • HO-PEG-MACA中PEG的修饰使其提高了稳定性,有助于其在各种溶剂中保持稳定的性能。
  • ESP32-S3模组上跑通esp32-camera(16)
  • 基于51单片机的高压蒸汽灭菌自动控制器proteus仿真
  • 远程踏勘系统(源码+文档+部署+讲解)