fpga开发-存储器及其应用

ops/2024/11/17 17:28:15/

目录

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.ppmy.cn/ops/134479.html

相关文章

【深圳大学】数据结构A+攻略(计软版)

1. 考试 1.1 形式 分为平时&#xff0c;笔试&#xff0c;机试三部分。其中&#xff1a; 平时占30%&#xff0c;包含平时OJ测验和课堂练习&#xff0c;注意这个可能会因老师的不同和课题组的新策略而改变。笔试占60%&#xff0c;是分值占比的主要部分。机试占10%。 1.2 题型…

MAC上的Office三件套报53错误解决方案(随笔记)

目录 现象原因解决方式1. 可视化2. 命令行 参考链接 现象 最近Mac Mini M4非常热门&#xff0c;我也种草买了一台丐中丐版本来体验一下。 在安装Office三件套后&#xff0c;遇到了一个53的错误&#xff1a; Run-time error 53:File not found: Library/Application Support/A…

idea的mapper.xml文件里写sql语句出现Tag name expected错误提示

原因如下&#xff1a; xml文件的某些特殊字符是自动转义的, xml解析器会忽视CDATA中的内容 解决方法&#xff1a; 使用下面的表达式表示对应符号。 小于(<)&#xff1a;<大于(>)&#xff1a;>和号(&)&#xff1a;&amp;单引号()&#xff1a;&apos;双引…

结合计算机知识学习英语四级词汇 P1(A1 ~ A5)(每次重点积累 5 个词汇)

引入 结合计算机知识学习英语四级词汇有 3 大利 减少单纯学习英语的枯燥&#xff0c;避免知识孤岛&#xff0c;将英语知识与专业领域知识联系交叉 许多计算机文档、教程、API 文档、最新研究论文都是用英语编写的&#xff0c;扎实的英语词汇积累能让我们减小学习新技术的阻力…

Wireshark中的length栏位

注&#xff1a;Ethernet II的最小data length为46&#xff0c;如果小于&#xff0c;会补全到46. 1.指定网卡抓取的&#xff0c;链路为ethernet。 IPv4 Ethernet II 长度为 14 bytes - L1ipv4 header中的length包括header和payload的总长度 - L2wireshark中length表示抓取的pac…

如何在 Ubuntu 上安装 Emby 媒体服务器

Emby 是一个开源的媒体服务器解决方案&#xff0c;它能让你整理、流媒体播放和分享你的个人媒体收藏&#xff0c;包括电影、音乐、电视节目和照片。Emby 帮你集中多媒体内容&#xff0c;让你无论在家还是在外都能轻松访问。它还支持转码&#xff0c;让你能够播放各种格式的内容…

河道无人机雷达测流监测系统由哪几部分组成?

在现代水利管理中&#xff0c;河道无人机雷达监测系统正逐渐成为一种重要的工具&#xff0c;为河道的安全和管理提供了强大的技术支持。那么&#xff0c;这个先进的监测系统究竟由哪几部分组成呢&#xff1f; 河道无人机雷达监测系统工作原理 雷达传感器通过发射电磁波或激光束…

对称加密算法DES的实现

一、实验目的 1、了解对称密码体制基本原理 2、掌握编程语言实现对称加密、解密 二、实验原理 DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位&#xff0c;产生最大 64 位的分组大小。这是一个迭代的分组密码&#xff0c;使用称为 Feistel 的技术&#xff0c;其中将加密…