《 E D A 技 术》 课 程 教 学 讲授:伍宗富 湖南文理学院电气与信息工程学院 2017年3月2日星期四
第 九 讲 存储器与状态机设计 教学目的:使学生掌握存储器与状态机的设计方法。 第 九 讲 存储器与状态机设计 教学目的:使学生掌握存储器与状态机的设计方法。 教学重点:存储器与状态机逻辑电路设计(SRAM与A/D转换控制) 教学难点: A/D转换控制。 教学方法:讲授法、计算机辅助法。 课时计划:2学时 使用教材:EDA技术及应用.谭会生等.西安:西安电子科技大学出版社 主要参考文献: [1] 徐光辉等.CPLD/FPGA的开发和应用[M].北京:电子工业出版社 [2] 侯伯亨等.VHDL硬件描述语言与数字逻辑电路设计[M].西安:西安电子科技大学出版社 [3] http://www.altera.com [4] 周立功等.SOPC嵌入式系统基础教程[M].北京:北京航空航天大学出版社
课题:存储器与状态机设计 一、ROM的VHDL设计 二、SRAM的VHDL设计 三、FIFO的VHDL设计 四、状态机的VHDL设计 五 、课堂小结 六、作业
一、ROM的VHDL设计 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY ROM4 IS PORT(EN:IN STD_LOGIC; ADDR:IN STD_LOGIC_VECTOR(7 DOWNTO 0); DOUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); END ENTITY ROM4; ARCHITECTURE ART OF ROM4 IS BEGIN PROCESS(EN,ADDR) IF EN='1' THEN CASE ADDR IS WHEN "00000000"=>DOUT<= "00000001"; WHEN "00000001"=>DOUT<= "00000010"; WHEN "00000010"=>DOUT<= "00000100"; WHEN "00000011"=>DOUT<= "00001000"; WHEN OTHERS=>DOUT<= "00000000"; END CASE; END IF; END PROCESS; END ARCHITECTURE ART;
二、SRAM的VHDL设计 --8x8位双口RAM LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY SRAM IS GENERIC(WIDTH:INTEGER:=8; DEPTH:INTEGER:=8; ADDER:INTEGER:=3); PORT(DATAIN:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); DATAOUT:OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); CLOCK:IN STD_LOGIC; WE,RE:IN STD_LOGIC; WADD:IN STD_LOGIC_VECTOR(ADDER-1 DOWNTO 0); RADD:IN STD_LOGIC_VECTOR(ADDER-1 DOWNTO 0)); END ENTITY SRAM; ARCHITECTURE ART OF SRAM IS TYPE MEM IS ARRAY(0 TO DEPTH-1) OF STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); SIGNAL RAMTMP:MEM; BEGIN
二、SRAM的VHDL设计 --写进程 PROCESS(CLOCK) BEGIN IF (CLOCK'EVENT AND CLOCK='1') THEN IF(WE='1')THEN RAMTMP(CONV_INTEGER(WADD))<=DATAIN; END IF; END PROCESS; --读进程 IF(CLOCK'EVENT AND CLOCK='1')THEN IF (RE='1') THEN DATAOUT<=RAMTMP(CONV_INTEGER(RADD)); END ARCHITECTURE ART;
三、FIFO的VHDL设计 -- REG_FIFO .VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY REG_FIFO IS GENERIC(WIDTH:INTEGER:=8; DEPTH:INTEGER:=8; ADDR:INTEGER:=3); PORT(DATAIN:IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); DATAOUT:OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); ACLR:IN STD_LOGIC; CLOCK:IN STD_LOGIC; WE:IN STD_LOGIC; RE:IN STD_LOGIC; FF:OUT STD_LOGIC;--满标志 EF:OUT STD_LOGIC);--空标志 END ENTITY REG_FIFO;
三、FIFO的VHDL设计 ARCHITECTURE ART OF REG_FIFO IS TYPE MEM IS ARRAY(DEPTH-1 DOWNTO 0) OF STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0); SIGNAL RAMTMP:MEM; SIGNAL WADD:STD_LOGIC_VECTOR(ADDR-1 DOWNTO 0); SIGNAL RADD:STD_LOGIC_VECTOR(ADDR-1 DOWNTO 0); --SIGNAL WORDS:STD_LOGIC_VECTOR(ADDR-1 DOWNTO 0); SIGNAL W,W1,R,R1:INTEGER RANGE 0 TO 8; BEGIN
三、FIFO的VHDL设计 --写指针修改进程 WRITE_POINTER:PROCESS(ACLR,CLOCK) IS BEGIN IF (ACLR='0') THEN WADD<=(OTHERS=>'0'); ELSIF (CLOCK'EVENT AND CLOCK='1') THEN IF (WE='1') THEN --IF (WADD=WORDS) THEN IF (WADD=7) THEN ELSE WADD<=WADD+'1'; END IF; W<=CONV_INTEGER(WADD); W1<=W-1; END PROCESS WRITE_POINTER; --写操作进程 WRITE_RAM:PROCESS(CLOCK) IS IF (CLOCK'EVENT AND CLOCK='1') THEN RAMTMP(CONV_INTEGER(WADD))<=DATAIN; END PROCESS WRITE_RAM;
三、FIFO的VHDL设计 --读指针修改 READ_POINIER:PROCESS(ACLR,CLOCK) IS BEGIN IF (ACLR='0') THEN RADD<=(OTHERS=>'0'); ELSIF (CLOCK'EVENT AND CLOCK='1') THEN IF (RE='1') THEN --IF (RADD=WORDS) THEN IF (RADD=7) THEN ELSE RADD<=RADD+'1'; END IF; R<=CONV_INTEGER(RADD); R1<=R-1; END PROCESS READ_POINIER; --读操作进程 READ_RAM:PROCESS(CLOCK) IF (CLOCK'EVENT AND CLOCK='1') THEN DATAOUT<=RAMTMP(CONV_INTEGER(RADD)); END PROCESS READ_RAM;
三、FIFO的VHDL设计 --产生满标志进程 FFLAG:PROCESS(ACLR,CLOCK) BEGIN IF (ACLR='0') THEN FF<='0'; ELSIF (CLOCK'EVENT AND CLOCK='1') THEN IF (WE='1' AND RE='0') THEN --IF ((WADD=RADD-1) OR ((WADD=DEPTH-1) AND (RADD=0))) THEN IF(W=R1)OR((WADD=CONV_STD_LOGIC_VECTOR(DEPTH-1,3)) AND (RADD="000")) THEN FF<='1'; END IF; ELSE END PROCESS FFLAG;
三、FIFO的VHDL设计 --产生空标志进程 EFLAG:PROCESS(ACLR,CLOCK) BEGIN IF (ACLR='0') THEN EF<='0'; ELSIF (CLOCK'EVENT AND CLOCK='1') THEN IF (RE='1' AND WE='0') THEN --IF ((WADD=RADD+1) OR ((RADD=DEPTH-1)AND(WADD=0))) THEN IF(R=W1)OR((RADD=CONV_STD_LOGIC_VECTOR(DEPTH-1,3)) AND (WADD="000")) THEN EF<='1'; END IF; ELSE END PROCESS EFLAG; END ARCHITECTURE ART;
三、FIFO的VHDL设计 仿真结果: 满标志 空标志
四、状态机的VHDL设计 典型的状态机:摩尔(MOORE)状态机和米立(MEALY)状态机。 摩尔状态机:输出只是当前状态值的函数,并且仅在时钟 边沿到来时才发生变化。 米立状态机:输出则是当前状态值、当前输出值和当前输 入值的函数。 注:对于这两类状态机,控制定序都取决于当前状态和输入信号。大多数实用的状态机都是同步的时序电路,由时钟信号触发状态的转换。时钟信号同所有的的边沿触发的状态寄存器和输出寄存器相连,这使得状态的改变发生在时钟的上升沿。 此外,还利用组合逻辑的传播延迟实现状态机存储功能的异步状态机,这样的状态机难于设计并且容易发生故障,所以一般用同步时序状态机。
四、状态机的VHDL设计 【例】 基于状态机的ADC0809与SRAM6264的通信控制器的设计。下图是该控制器ADTOSRAM与ADC0809及SRAM6264接口示意图。 ① ② ③ ④⑤ ⑥ ⑦ ⑧ ⑨ ①ⅹ
四、状态机的VHDL设计 【例】 基于状态机的ADC0809与SRAM6264的通信控制器的设计。 --VHDL源程序ADTOSRAM.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY ADTOSRAM IS PORT( --ADC0809接口信号 DIN:IN STD_LOGIC_VECTOR(7 DOWNTO 0); --0809转换数据输入口 CLK,EOC:IN STD_LOGIC; --CLK:状态机工作时钟;EOC:转换结束状态信号 RST:IN STD_LOGIC; --系统复位信号 ALE:OUT STD_LOGIC; --0809采样通道选择地址锁存信号 START:OUT STD_LOGIC; --0809采样启动信号,上升沿有效 OE:OUT STD_LOGIC;--转换数据输出使能,接0809的ENABLE(PIN 9) ADDA:OUT STD_LOGIC; --0809采样通道地址最低位 --SRAM 6264接口信号 CS:OUT STD_LOGIC; --6264片选控制信号,低电平有效 RD,WR:OUT STD_LOGIC;--6264读/写控制信号,低电平有效 RAM_DIN:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--6264数据写入端口 ADDRESS:OUT STD_LOGIC_VECTOR(12 DOWNTO 0));--地址输出端口 END ENTITY ADTOSRAM;
四、状态机的VHDL设计 【例】 基于状态机的ADC0809与SRAM6264的通信控制器的设计。 --VHDL源程序ADTOSRAM.VHD ARCHITECTURE ART OF ADTOSRAM IS TYPE AD_STATES IS(ST0,ST1,ST2,ST3,ST4,ST5,ST6,ST7);--A/D转换状态定义 TYPE WRIT_STATES IS (START_WRITE,WRITE1,WRITE2,WRITE3,WRITE_END); --SRAM数据写入控制状态定义 SIGNAL RAM_CURRENT_STATE,RAM_NEXT_STATE:WRIT_STATES; SIGNAL ADC_CURRENT_STATE,ADC_NEXT_STATE:AD_STATES; SIGNAL ADC_END:STD_LOGIC; --0809数据转换结束并锁存标志位,高电平有效 SIGNAL LOCK:STD_LOGIC; --转换后数据输出锁存信号 SIGNAL ENABLE:STD_LOGIC; --A/D转换允许信号,高电平有效 SIGNAL ADDRES_PLUS:STD_LOGIC;--SRAM地址加1时钟信号 SIGNAL ADC_DATA:STD_LOGIC_VECTOR(7 DOWNTO 0);--转换数据读入锁存器 SIGNAL ADDRES_CNT:STD_LOGIC_VECTOR(12 DOWNTO 0);--SRAM地址锁存器 BEGIN ADDA<='1';--ADDA=1,ADDB=0,ADDC=0选A/D采样通道为IN-1 RD<='1';
四、状态机的VHDL设计 【例】 基于状态机的ADC0809与SRAM6264的通信控制器的设计。 --VHDL源程序ADTOSRAM.VHD --ADC0809采样控制状态机 ADC:PROCESS(ADC_CURRENT_STATE,EOC,ENABLE) --A/D转换状态机组合电路进程 BEGIN IF (RST='1') THEN ADC_NEXT_STATE<=ST0;--状态机复位 ELSE CASE ADC_CURRENT_STATE IS WHEN ST0=>ALE<='0';START<='0';OE<='0';LOCK<='0';ADC_END<='0';--A/D转换初始化 IF (ENABLE='1') THEN ADC_NEXT_STATE<=ST1;--允许转换,转下一状态 ELSE ADC_NEXT_STATE<=ST0;--禁止转换,仍停留在本状态 END IF; WHEN ST1=>ALE<='1';START<='0';OE<='0';LOCK<='0';ADC_END<='0'; ADC_NEXT_STATE<=ST2; --通道选择地址锁存,并转下一状态 WHEN ST2=>ALE<='1';START<='1';OE<='0';LOCK<='0';ADC_END<='0'; ADC_NEXT_STATE<=ST3; --启动A/D转换信号START WHEN ST3=>ALE<='1';START<='1';OE<='0';LOCK<='0';ADC_END<='0';--延迟一个脉冲周期 IF (EOC='0') THEN ADC_NEXT_STATE<=ST4; ELSE ADC_NEXT_STATE<=ST3; --转换未结束,继续等待 WHEN ST4=>ALE<='0';START<='0';OE<='0';LOCK<='0';ADC_END<='0'; IF(EOC='0')THEN ADC_NEXT_STATE<=ST5;--转换结束,转下一状态 ELSE ADC_NEXT_STATE<=ST4; --转换未结束,继续等待 WHEN ST5=>ALE<='0';START<='0';OE<='1';LOCK<='1';ADC_END<='1'; ADC_NEXT_STATE<=ST6; --开启数据输出使能信号OE WHEN ST6=>ALE<='0';START<='0';OE<='1';LOCK<='1';ADC_END<='1'; ADC_NEXT_STATE<=ST7; --开启数据锁存信号 WHEN ST7=>ALE<='0';START<='0';OE<='1';LOCK<='1';ADC_END<='1'; ADC_NEXT_STATE<=ST0;--为6264数据定入发出A/D转换周期结束信号 WHEN OTHERS=>ADC_NEXT_STATE<=ST0;--所有闲置状态导入初始态 END CASE; END PROCESS ADC;
四、状态机的VHDL设计 【例】 基于状态机的ADC0809与SRAM6264的通信控制器的设计。 --VHDL源程序ADTOSRAM.VHD AD_STATE:PROCESS(CLK) --A/D转换状态机时序电路进程 BEGIN IF(CLK'EVENT AND CLK='1')THEN ADC_CURRENT_STATE<=ADC_NEXT_STATE;--在时钟上升沿,转至下一状态 END IF; END PROCESS AD_STATE;--由信号CURRENT_STATE将当前状态值带出此进程 DATA_LOCK:PROCESS(LOCK) BEGIN--此进程中,在LOCK的上升沿,将转换好的数据锁入锁存器ADC_DATA中 IF (LOCK='1'AND LOCK'EVENT) THEN ADC_DATA<=DIN; END PROCESS DATA_LOCK; --SRAM数据写入控制状态机 WRIT_STATE:PROCESS(CLK,RST)--SRAM写入控制状态机时序电路进程 IF RST='1' THEN RAM_CURRENT_STATE<=START_WRITE;--系统复位 ELSIF(CLK'EVENT AND CLK='1') THEN RAM_CURRENT_STATE<=RAM_NEXT_STATE;--在时钟上升沿,转下一状态 END PROCESS WRIT_STATE;
四、状态机的VHDL设计 【例】 基于状态机的ADC0809与SRAM6264的通信控制器的设计。 --VHDL源程序ADTOSRAM.VHD RAM_WRITE:PROCESS(RAM_CURRENT_STATE,ADC_END) --SRAM控制时序电路进程 BEGIN CASE RAM_CURRENT_STATE IS WHEN START_WRITE=>CS<='1';WR<='1';ADDRES_PLUS<='0'; IF (ADDRES_CNT="1111111111111") THEN --数据写入初始化 ENABLE<='0'; --SRAM地址计数器已满,禁止A/D转换 RAM_NEXT_STATE<=START_WRITE; ELSE ENABLE<='1'; --SRAM地址计数器未满,允许A/D转换 END IF; WHEN WRITE1=>CS<='1';WR<='1';ADDRES_PLUS<='0';ENABLE<='1';--判断A/D转换周期是否结束 IF (ADC_END='1')THEN RAM_NEXT_STATE<=WRITE2; --已结束 ELSE RAM_NEXT_STATE<=WRITE1;--A/D转换周期未结束,等待 WHEN WRITE2=>CS<='0';WR<='1'; --打开SRAM片选信号 ENABLE<='0';--禁止A/D转换 ADDRES_PLUS<='0';ADDRESS<=ADDRES_CNT; --输出13位地址 RAM_DIN<=ADC_DATA; --8位已转换好的数据输向SRAM数据口 RAM_NEXT_STATE<=WRITE3; --进入下一状态 WHEN WRITE3=>CS<='0';WR<='0'; --打开写允许信号 ENABLE<='0'; --仍然禁止A/D转换 ADDRES_PLUS<='1'; --产生地址加1时钟上升沿,使地址计数器加1 RAM_NEXT_STATE<=WRITE_END; --进入结束状态 WHEN WRITE_END=>CS<='1';WR<='1'; ENABLE<='1'; --打开A/D转换允许开关 ADDRES_PLUS<='0'; --地址加1时钟脉冲结束 RAM_NEXT_STATE<=START_WRITE; --返回初始状态 WHEN OTHERS=> RAM_NEXT_STATE<=START_WRITE; END CASE; END PROCESS RAM_WRITE; COUNTER:PROCESS(ADDRES_PLUS) --地址计数器加1进程 IF(RST='1')THEN ADDRES_CNT<="0000000000000";--计数器复位 ELSIF(ADDRES_PLUS'EVENT AND ADDRES_PLUS='1')THEN ADDRES_CNT<=ADDRES_CNT+1; END PROCESS COUNTER; END ARCHITECTURE ART;
课堂小结 一、ROM的VHDL设计 二、SRAM的VHDL设计 三、FIFO的VHDL设计 四、状态机的VHDL设计
课外作业: 上机调试