- 可编程逻辑器件PLD
- 复杂可编程逻辑器件CPLD
- 现场可编程门阵列FPGA
7.1 只读存储器(ROM)
7.1.1 ROM的结构
- ROM存储器 = 存储阵列 + 地址译码器 + 输出控制电路
- 存储阵列,由许多存储单元(1bit)组成。每次读出一组数据,组=字。一个字的位数称为字长。
- 地址译码器,将地址代码转换成 相应字单元的控制信号。从存储矩阵中选出指定的存储单元。将数据送到输出控制电路。
- 输出控制电路,三态缓冲器。与系统数据总线连接。(驱动数据总线 或者 保持高阻状态)
- 下图中,地址 A 1 A 0 = 01 A_1A_0=01 A1A0=01,地址译码器给出 Y 3 Y 2 Y 1 Y 0 = 1101 Y_3Y_2Y_1Y_0=1101 Y3Y2Y1Y0=1101
- 字线, Y 1 Y_1 Y1是低电平。 Y 1 Y_1 Y1字线与位线交接处有 二极管的,二极管都会被导通。
- 位线,在二极管导通后,会被拉低成0。位线的状态会被传给输出控制电路。
- 最终输出 D 3 D 2 D 1 D 0 = 1101 D_3D_2D_1D_0=1101 D3D2D1D0=1101
- 可以发现,读出的数值,取决于字线和位线之间是否有二极管连接。
- 存储器的容量(密度)= 字线数 * 位线数。(字数*字长)
7.1.2 二维译码
- 译码电路,随着输入地址宽度的增加,译码电路的复杂度呈指数级增加。
- 二维译码= 行译码+列译码
- 地址为8位宽度时,一维译码电路的输出端 需要有 2 8 = 256 2^8=256 28=256个输出口。译码电路内部变的非常复杂。
- 地址为8位宽度时,二维译码电路,行译码变成4位( 2 4 = 16 2^4=16 24=16个译码器输出口),列译码变成4位( 2 4 = 16 2^4=16 24=16个数据选择器输入口)
7.1.3 可编程ROM
-
只读存储器ROM(Read-Only Memory)
- 固定ROM(掩膜ROM)。出厂前已经写入存储阵列。
- 可编程ROM(PROM) (Programmable ROM)
- 一次可编程ROM(PROM)。金属熔丝二极管,一次性编程。
- 光可擦除可编程存储器(EPROM)(Erasable PROM)。SIMOS管。透明石英盖板,紫外线或X射线照射擦除。不装透明石英盖板,不可擦除,OTP EPROM。
- 电可擦除可编程存储器(EEPROM)(Electrical Erasable PROM)。Flotox Mos。
- 闪烁存储器(FLASH Memory)。快闪叠栅MOS。
7.1.4 集成电路MOS
- AT27C010,128Kx8,OTP EPROM。
- C E ‾ \overline{CE} CE片选信号
- O E ‾ \overline{OE} OE输出使能信号
- P G M ‾ \overline{PGM} PGM编程信号
7.2 随机存取存储器(RAM)
- 随机存取存储器RAM (Random Access Memory)
- 静态随机存取存储器SRAM (Static RAM)(触发器存储,两个稳态)
- 同步静态随机存取存储器SSRAM
- 动态随机存取存储器DRAM (Dynamic RAM)(电容存储,需要定时刷新,否则会逐渐消散)
- 静态随机存取存储器SRAM (Static RAM)(触发器存储,两个稳态)
7.2.1 静态随机存取存储器
普通 SRAM(异步)
- 普通(异步)SRAM = 存储阵列+地址译码+输入输出控制电路
- 存储阵列的存储单元是 锁存器。只要不断电,SRAM可以永久保存数据。
- 大多数SRAM的读周期和写周期是相同的。10纳秒左右。
FIFO SRAM
- FIFO SRAM。数据输入/输出分开,无地址输入端(改成:读地址指针计数器+写地址指针计数器)。
- 输出信号:空,半满,满
- FIFO SRAM 常用作 “数据缓冲器”。适合长时间连续高速数据采集。
同步静态随机存取存储器 SSRAM
- SSRAM:基于SRAM的高速RAM。
-
需要时钟脉冲输入,在节拍控制下完成读写。
-
地址寄存器。寄存地址线上的地址。
-
输入寄存器。寄存数据线上的数据。
-
读写控制逻辑电路。
-
丛发(burst 快速连续发生)控制逻辑电路。减少外部总线的占用时间,提高效率。
- 丛发控制计数器是2位的计数器。叠加在输入的地址之上。地址最低2位 b i t [ 1 : 0 ] bit[1:0] bit[1:0]从00变化到11,超过11后,会回到00。
- 输入一个地址,可自动连线读取/写入以此向后4个地址的数据。不需要外部输入这些连续的地址。
-
速度快于SRAM。
-
应用:超高速缓冲存储器Cache。
-
SDR
- 单倍速率(Single Data Rate)SDR SRAM
- 就是前文的 SSRAM。只在时钟上升沿 传输数据,共用读写数据总线(读写不能同时)。
DDR
- 双倍速率(Double Data Rate)DDR SRAM
- 在SSRAM的基础上,在时钟上升沿和下降沿 都进行数据传输。依然共用读写数据总线(读写不能同时)。
- 后续升级改善,有DDR Ⅱ。
QDR
- 四倍速率(Quad Data Rate)QDR SRAM
- 在SSRAM的基础上,在时钟上升沿和下降沿 都进行数据传输。提供读数据总线和写数据总线(读写同时)。
- 后续升级改善,有QDR Ⅱ。
- 重要指标,容量,时钟工作频率。
7.2.3 动态随机存取存储器
DRAM的基本结构
- SRAM的存储单元,由锁存器(或者触发器)构成。一个锁存器的结构就很复杂,需要多个MOS管。占用较大的体积。SRAM的集成度很难提高。
- DRAM的存储单元,由一个MOS管和一个电容器构成。体积小。
- 电容存储电荷,高电平1,低电平0。
- 电容器存在漏电流,需要定期补充电荷。称为“刷新”或者再生。
- DRAM的集成度很高,容量大。需要的地址线也多。
- DRAM大都采用行地址、列地址分时送入的方法。
- 1M字大小的空间( 2 20 = 1048576 字 2^{20}=1048576字 220=1048576字),需要20根地址线。当采用分时传入行列地址时,只需要10根地址线。
- 行地址选通信号 R A S ‾ \overline{RAS} RAS
- 列地址选通信号 C A S ‾ \overline{CAS} CAS
DRAM的操作
- DRAM的操作较为复杂:
-
读写操作
- (1) R A S ‾ \overline{RAS} RAS拉低,送入行地址,再拉高。
- (2) C A S ‾ \overline{CAS} CAS拉低,送入列地址,再拉高。
- (3) W E ‾ \overline{WE} WE拉低,使能读写。
- (4)
O
E
‾
\overline{OE}
OE拉低,读操作时,输出使能。
-
页模式操作
- 同一行的所有列构成的存储单元。
- 选定行地址之后,不用再改变行地址。
R
A
S
‾
\overline{RAS}
RAS始终拉低。
-
R A S ‾ \overline{RAS} RAS只刷新操作
- 刷新地址由外部地址计数器提供
- 只刷新 行地址 指定的行的所有存储单元。
- 列地址的 C A S ‾ \overline{CAS} CAS保持高电平
- 不进行读写操作。
- 每行刷新间隔15.6us。刷新操作小于100ns。
-
同步动态随机存取存储器 SDRAM
SDR
- 同步DRAM(SDRAM)
DDR
- 双倍数据速率DRAM (DDR SDRAM),目前电脑使用的内存条即使用的这个技术。
QDR
- 四倍数据传输速率DRAM (QDR SDRAM)
7.2.4 存储容量的扩展
字长(位线数)的扩展
- 地址线宽度不变
- 每个地址对应的数据位宽,扩大
字数(字线数)的扩展
- 地址线宽度变大,(增加地址译码器)
- 每个地址对应的数据位宽不变
7.3 复杂可编程逻辑器件(CPLD)
- 简单PLD:PAL、GAL等
- 复杂PLD:CPLD
- 早期使用EPROM编程技术
- 后来使用EEPROM和FLASH编程技术,支持“在系统可编程(ISP)”
- 在系统可编程ISP : 未编程的ISP器件,可以直接焊接在电路中,可通过计算机的数据传输端口和专用的编程电缆对ISP器件进行多次编程。
- 编程电路和升压电路已经集成在ISP器件内部。
7.3.1 CPLD的结构
-
更多的 输入信号
-
更多的 乘积单元
-
更多的 宏单元
-
CPLD中的逻辑块:相当于一个GAL器件(参考6.7小节)。与或阵列+OLMC
-
CPLD的结构如下:
7.3.2 CPLD的编程简介
- CPLD的内部可编程单元,用于CPLD的各种逻辑功能的实现
- CPLD的内部可编程单元,大都采用EEPROM或者FLASH编程技术
- 绝大多数CPLD支持ISP。
- Altera公司的CPLD
- MAX7000S(5V)
- MAX7000A(3.3V)
- MAX7000B(2.5V)
- Xilinx公司的CPLD
- XC9500
- Lattice公司的CPLD
- 不同公司的ISP接口不完全相同,但都支持JTAG标准编程。
7.4 现场可编程门阵列
- CPLD使用“与或”阵列实现逻辑函数
- FPGA使用查找表LUT实现逻辑函数。
- FPGA中的LUT和触发器的数量非常多,能够实现更大规模,更复杂的逻辑电路
7.4.1 FPGA的查找表LUT和数据选择器MUX
- FPGA中:
- 组合逻辑基本电路是LUT和数据选择器。
- 时序逻辑基本电路是触发器
- (1)LUT(查找表LookUpTable)本质是一个SRAM。
- 普通(异步)SRAM = 存储阵列+地址译码+输入输出控制电路
- 可以理解为,根据地址An…A0,在SRAM中读出数据Dm…D0
- 大多LUT是 : 4输入变量,1输出结果
-
(2)数据选择器(参考4.4.3)
-
(3)扩展LUT逻辑函数的输入变量个数,通过数据选择器MUX实现LUT的级联。
- 数据选择器级联,LUT输出接在MUX上,因而LUT也实现了级联。
- 数据选择器级联,LUT输出接在MUX上,因而LUT也实现了级联。
-
HDL语言描述一个逻辑电路,FPGA开发软件算出所有可能结果(真值表),写入LUT(SRAM)
- LUT因而具有逻辑功能 F = f ( A , B , C , D ) F=f(A,B,C,D) F=f(A,B,C,D)。
-
FPGA上电之后,从外部PROM中读入编程数据,写入各种可编程单元中(包括查找表LUT)。
7.4.2 FPGA的结构
可配置逻辑块CLB
- 可配置逻辑块CLB,内部由多个微片Slice 组成
- 一个微片Slice 由两个逻辑单元LC 组成
- 一个逻辑单元LC(logic cell),由查找表LUT,进位及控制逻辑,D触发器构成。
输入输出模块IOB
- 一个IOB对应一个封装引脚
- IOB可以配置为引脚输入,输出,双向。
- VCCO是输出VCC电压
- VREF是输入参考电压
- 输出信号O,可经过数据选择器,再到输出缓冲器。也可以直接到输出缓冲器
- 输入信号I,来自输出缓冲器
- 多个IOB组成一个Bank,一般有8个bank
可编程布线资源
-
局部布线资源:进出CLB的连线资源
- CLB到通用布线矩阵GRM
- CLB到自己,输出到输入,高速反馈连接
- CLB到相邻CLB,直接快速连接,避免了通过GRM产生的延时。
-
通用布线资源:通用布线矩阵GRM+与之连线
- 是FPGA主要的内部资源
- GRM是 行线资源 与 列线资源 互联 的 开关矩阵
-
I/O布线资源:CLB与IO块外围之间,附加的布线资源,“万能环” VersaRing
- 实现引脚的交换和锁定
- 使引脚的位置变动和内部逻辑无关
-
专用布线资源
- 横向片内三态总线
- 纵向进位链
-
全局布线资源
- 分配时钟信号
- 其他贯穿整个器件的高扇出信号
- 分为主次两级
- 主全局布线资源,与高扇出时钟信号输入引脚,构成4个专用全局时钟网络,驱动CLB,IOB,RAM的时钟引脚。
- 次全局布线资源,24根干线,12根穿越芯片顶部,12根穿越芯片底部,不受时钟引脚限制,使用灵活
7.4.3 FPGA编程简介
配置数据
- 配置数据(编程数据):FPGA的存储单元中的数据(用于配置CLB,IOB,布线资源)。
- 不同规模的FPGA,配置数据量不同。
- 配置数据由FPGA开发软件生成。
装载配置数据的引脚
- 专用引脚
引脚 | 描述 |
---|---|
M0,M1,M2 | 输入,用于指定配置模式 |
CCLK | 输入或者输出,配置时钟。(1)从配置模式时,为输入。(2)主配置模式时,为输出。(3)配置完成后为输入,处于"无关x"状态 |
PROGRAM | 输入,低电平时,开始配置过程 |
DONE | 双向,由低到高表示配置装载完成。(1)输入低电平,可以推迟启动工作。(2)输出为开漏。 |
V C C I N T V_{CCINT} VCCINT | 输入,内部核心逻辑电源引脚 |
V C O O V_{COO} VCOO | 输入,IO输出驱动电源引脚 |
- 非专用引脚
引脚 | 描述 |
---|---|
INIT | 双向(开漏),(1)低电平时,表示配置存储单元 正在清零。(2)结束后,可作为用户IO。 |
BUSY/DOUT | 输出,(1)从并模式下,busy控制装载速率。(2)串行模式下,多个器件链式配置,DOUT作为向下一级传递数据流的出口。(3)结束后,可作为用户IO。 |
D0/DIN,D1,D2,D3,D4,D5,D6,D7 | 输入或者输出,(1)从并模式下,配置数据输入。(2)串行模式下,DIN为输入。(3)结束后,可作为用户IO。 |
WRITE | 输入,(1)从并模式下,写使能,低电平有效。(2)结束后,可作为用户IO。 |
CS | 输入,(1)从并模式下,片选信号,低电平有效。(2)结束后,可作为用户IO。 |
-
M 2 M 1 = 00 M_2M_1=00 M2M1=00, 配置模式是“主 串”,CCLK输出,数据宽1位,DOUT串行输出, M 0 = 1 M_0=1 M0=1时,相关引脚上拉
-
M 2 M 1 = 11 M_2M_1=11 M2M1=11, 配置模式是“从 串”,CCLK输入,数据宽1位,DOUT串行输出, M 0 = 0 M_0=0 M0=0时,相关引脚上拉
-
M 2 M 1 = 01 M_2M_1=01 M2M1=01, 配置模式是“从 并”,CCLK输入,数据宽8位,DOUT不输出, M 0 = 0 M_0=0 M0=0时,相关引脚上拉
-
主串模式电路,PROGRAM 由外部控制,DONE起始低电平用于存储芯片的片选信号,FPGA的CCLK输出道存储芯片的CLK。
7.5 EDA技术和可编程器件的例题
例1 定时器
- 设计一个定时器,定时时间为24s,递减计时,每隔1s定时器减1。
- 2个外部控制开关,复位,暂停
复位nRst | 暂停nPAUSE | 功能 |
---|---|---|
0 | x | 定时器复位,置初值24 |
1 | 1 | 定时器开始计时 |
1 | 0 | 定时器暂停计时 |
- 定时器减到0后,定时器保持不变,同时发出警报信号。
- 输入时钟脉冲的频率为1Hz,输出为8421BCD码。
设计
- HDL描述分为3个部分:
- 第一部分,定义输入信号(复位nRST,暂停nPAUSE,时钟CP),定义输出(定时器的十位,定时器的个位),报警Alarm。
- 第二部分,连续复制语句assign(定时器减到0时,报警Alarm=1)。
- 第三部分,时序逻辑电路,过程块always(计数器计数,处理操作,十位和个位按照8421BCD码方式递减计数)。
- 打篮球的规则,进攻方只能进攻24秒,这和本定时器的功能设计是一致的。本模块的命令是篮球24秒。
module basketball24(TimerH,TimerL,Alarm,nRST,nPAUSE,CP);
input nRST,nPAUSE,CP;
wire nRST,nPAUSE,CP;
output [3:0] TimerH,TimerL;
reg [3:0] TimerH,TimerL;
output Alarm;
//输出报警信号
assign Alarm = ({TimerH,TimerL}==8'h00)&(nRST == 1'b1);
//计数处理
always @(posedge CP or negedge nRST or negedge nPAUSE)//异步复位,异步暂停
begin
if(~nRST)
{TimerH,TimerL} <= 8'h24;//复位初值24
else if(~nPAUSE)
{TimerH,TimerL} <= {TimerH,TimerL};//暂停
else if({TimerH,TimerL} == 8'h00)//定时时间到,保持0不变
{TimerH,TimerL} <= {TimerH,TimerL};
else if(TimerL==4'h0)
begin
TimerH <= TimerH - 1'b1;
TimerL <= 4'h9;
end
else
begin
TimerH <= TimerH;
TimerL <= TimerL -1b'1;
end
end
endmodule
例2 时分秒电子钟
- 按照24小时制计时
- 输出时分秒的8421BCD码
- 计时输入脉冲频率为1Hz
- 具有分钟,小时的校正功能,校正输入脉冲频率为1Hz
- 采用分层设计。
设计
- 顶层模块(top_clock.v)
- 分钟计数分为 十位 和 个位。
- 分钟计数分为 十位 和 个位。
module top_clock(Hour,Minute,Second,CP,nCR,EN,Adj_Min,Adj_Hour);
input CP,nCR,EN,Adj_Min,Adj_Hour;
output [7:0] Hour,Minute,Second;
wire [7:0] Hour,Minute,Second;
supply1 Vdd;
wire MinL_EN,MinH_EN,HOur_EN;//定义中间变量
//60秒计数器
counter10 U1(Second[3:0],nCR,EN,CP);
counter6 U2(Second[7:4],nCR,(Second[3:0] == 4'h9),CP);
//Adj_Min = 1时,校准分钟,立即使能分钟的个位计数,下一个时钟,分钟个位加一。
//Adj_Min = 0时,当秒数为59时,使能分钟的个位计数,下一个时钟(60s),分钟个位加一。
assign MinL_EN = Adj_Min? Vdd : (Second==8'h59);
//Adj_Min = 1 且分钟的个位数为9时,立即使能分钟的十位计数,下一个时钟,分钟十位加一。
//或者,分钟的个位计数到了9,秒数计到了59,使能分钟的十位计数,下一个时钟,分钟十位加一。
assign MinH_EN = (Adj_Min && (Minute[3:0] == 4'h9)) || (Minute[3:0] == 4'h9) && (Second == 8'h59);
//60分钟计数器
counter10 U3(Minute[3:0],nCR,MinL_EN,CP); //分计数器个数
counter6 U4(Minute[7:4],nCR,MinH_EN,CP); //分计数器十位
//Adj_hour = 1时,校准小时,立即使能小时的个位计数,下一个时钟,小时个位加一。
//Adj_hour = 0时,当分钟数为59,秒数为59时,使能小时的个位计数,下一个时钟(60min),小时个位加一。
assign Hour_EN = Adj_Hour ? Vdd : (Minute == 8'h59) && (Second == 8'h59);
//24小时计数器
counter24 U5(Hour[7:4],Hour[3:0],nCR,Hour_EN,CP);//小时计数器 十位 个位
endmodule
- counter10.v BCD 0-9
module counter10(Q,nCR,EN,CP);
input CP,nCR,EN;
output [3:0] Q;
reg [3:0] Q;
always @ (posedge CP or negedge nCR)
begin
if(~CR) Q <= 4'b0000; //异步清零
else if(~EN) Q <= Q; //暂停计数
else if(Q == 4'b1001) Q <= 4'b0000;
else Q <= Q + 1'b1; //计数+1
end
endmodule
- counter6.v BCD 0-5
module counter6(Q,nCR,EN,CP);
input CP,nCR,EN;
output [3:0] Q;
reg [3:0] Q;
always @ (posedge CP or negedge nCR)
begin
if(~CR) Q <= 4'b0000; //异步清零
else if(~EN) Q <= Q; //暂停计数
else if(Q == 4'b0101) Q <= 4'b0000;
else Q <= Q + 1'b1; //计数+1
end
endmodule
- counter24.v BCD 0-23
module counter23(CntH,CntL,nCR,EN,CP);
input CP,nCR,EN;
output [3:0] CntH,CntL;
reg [3:0] CntH,CntL;
reg CO;
always @ (posedge CP or negedge nCR)
begin
if(~nCR) {CntH,CntL} <= 8'h00;
else if(~EN) {CntH,CntL} <= {CntH,CntL};
else if((CntH>2) || (CntL>9) ||( (CntH == 2) && (CntL >=3)) {CntH,CntL} <= 8'h00;
else if((CntH == 2) && (CntL < 3)) begin CntH <= CntH; CntL <= CntL + 1'b1; end
else if(CntL == 9) begin CntH <= CntH+1'b1; CntL <= 4'b0000; end
else begin CntH <= CntH; CntL <= CntL + 1'b1; end
end
endmodule