IF RISING_EDGE(CLK) THEN
IF WREN='1' THEN --如果时钟有上升沿出现,且写使能为高电平,则
MEM(CONV_INTEGER(A))<=DIN;--RAM数据口的数据被写入指定地址的单元 END IF; END IF;
IF(FALLING_EDGE(CLK))THEN --如果时钟有下降沿出现,则 Q<=MEM(CONV_INTEGER(A));--读出存储器中的数据 END IF; END PROCESS; END BHV;
--解2:以图7-18代码形式设计RAM
7-3 修改例7-6,用GENERIC语句定义例7-6中的数据线宽和存储单元的深度的参数,再设计一个顶层文件例化例7-6。此顶层文件能将参数传入底层模块例7-6。顶层文件的参数设数据宽度=16,存储深度msize=1024。
--解1:用GENERIC定义DB和AB修改【例7-6】设计双边沿控制读写RAM的VHDL程序。 LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;--此程序包括含转换函数CONV_INTEGERlA) USE IEEE.STD_LOGIC_UNSIGNED.ALL;--此程序包包含算符重载函数 ENTITY RAM7x8 IS
GENERIC(D_Bus: integer:=8;A_Bus: integer:=7;MEM_Num: integer:=128;init_file: string:=\
PORT( CLK: IN STD_LOGIC;--定义时钟 WREN: IN STD_LOGIC;--定义写允许控制
A: IN STD_LOGIC_VECTOR(A_Bus-1 DOWNTO 0);--定义RAM的7位地址输入端口 DIN: IN STD_LOGIC_VECTOR(D_Bus-1 DOWNTO 0);--定义RAM的8位数据输入端口 Q:OUT STD_LOGIC_VECTOR(D_Bus-1 DOWNTO 0));--定义RAM的8位数据输出端口 END;
ARCHITECTURE bhv OF RAM7x8 IS
TYPE G_ARRAY IS ARRAY(0 TO MEM_Num-1) OF STD_LOGIC_VECTOR(D_Bus-1 DOWNTO 0); SIGNAL MEM: G_ARRAY;--定义信号MEM的数据类型为用户新定义的类型G_ARRAY
attribute ram_init_file: string; --定义字符串属性的标识符ram_init_file。 attribute ram_init_file of MEM: SIGNAL IS init_file; --定义标识符ram_init_file是MEM的属性,
--并将字符串\初始化赋给ram_init_file。
BEGIN
PROCESS(CLK)
BEGIN
IF RISING_EDGE(CLK) THEN
IF WREN='1' THEN --如果时钟有上升沿出现,且写使能为高电平,则 MEM(CONV_INTEGER(A))<=DIN;--RAM数据口的数据被写入指定地址的单元 END IF; END IF;
IF(FALLING_EDGE(CLK))THEN --如果时钟有下降沿出现,则 Q<=MEM(CONV_INTEGER(A));--读出存储器中的数据 END IF; END PROCESS
--解2:用例化调用修改后例7-6生成10位AB和8位DB的RAM LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;--此程序包括含转换函数CONV_INTEGERlA) USE IEEE.STD_LOGIC_UNSIGNED.ALL;--此程序包包含算符重载函数 ENTITY RAM10x8 IS
PORT( CLK: IN STD_LOGIC;--定义时钟 WREN: IN STD_LOGIC;--定义写允许控制
A: IN STD_LOGIC_VECTOR(9 DOWNTO 0);--定义RAM的10位地址输入端口 DIN: IN STD_LOGIC_VECTOR(7 DOWNTO 0);--定义RAM的8位数据输入端口 Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));--定义RAM的8位数据输出端口 END;
ARCHITECTURE bhv OF RAM10x8 IS
COMPONENT RAM7x8 --RAM7x8模块的调用声明
GENERIC(D_Bus: integer;A_Bus: integer;MEM_Num: integer;init_file: string); PORT( CLK: IN STD_LOGIC;--定义时钟 WREN: IN STD_LOGIC;--定义写允许控制
A: IN STD_LOGIC_VECTOR(A_Bus-1 DOWNTO 0);--定义RAM的7位地址输入端口 DIN: IN STD_LOGIC_VECTOR(D_Bus-1 DOWNTO 0);--定义RAM的8位数据输入端口 Q:OUT STD_LOGIC_VECTOR(D_Bus-1 DOWNTO 0));--定义RAM的8位数据输出端口 END COMPONENT; BEGIN
u1: RAM7x8 GENERIC MAP(D_Bus=>8,A_Bus=>10,MEM_Num=>1024,init_file=>\ PORT MAP(CLK,WREN,A,DIN,Q); END BHV;
7-4 建立一个原理图顶层设计工程,调用LPM_RAM,结构参数与习题7-3相同,初始化文件是hex格式的正弦波数据文件。给出设计的仿真波形。
解:7-4 顶层设计用原理图调用LPM_RAM(结构参数与习题7-3相同)
7-5(略)参考Quartus II的Help(Contents),详细说明LPM元件altcam、altsyncram、 LPM_fifo、LPM_shiftreg的使用方法,以及其中各参量的含义和设置方法。
8 习 题
8-1(5-1)什么是固有延时?什么是惯性延时?P225~226 答:固有延时(Inertial Delay)也称为惯性延时,固有延时的主要物理机制是分布电容效应。
8-2(5-4)说明信号和变量的功能特点,以及应用上的异同点。P208~P210
答:变量:变量是一个局部量,只能在进程和子程序中使用。变量不能将信息带出对它做出定义的当前结构。变量的赋值是一种理想化的数据传输,是立即发生的,不存在任何延时行为。变量的主要作用是在进程中作为临时的数据存储单元。
信号:信号是描述硬件系统的基本数据对象,其性质类似于连接线;可作为设计实体中并行语句模块间的信息交流通道。信号不但可以容纳当前值,也可以保持历史值;与触发器的记忆功能有很好的对应关系。
8-3 从不完整的条件语句产生时序模块的原理看,例8-7和从表面上看都包含不完整条件语句,试说明,为什么它们的综合结果都是组合电路。 P214~P216 答:根据变量具有顺序立即赋值传送特性,例8-7中的不完整条件语句对变量赋值前对变量进行初始值设置;每次敏感信号触发,对变量的赋值,总能产生结果,无保持状态——即输出是输入的函数;因此,只能产生组合逻辑电路;不可能产生时序逻辑电路。 --【例8-7】预设计4选1多路器(通过变量测选择条件,将产生正确结果。) LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; ENTITY mux4 IS
PORT(i0,i1,i2,i3,a,b: IN STD_LOGIC; q: OUT STD_LOGIC); END mux4;
ARCHITECTURE body_mux4 OF mux4 IS BEGIN
process(i0,i1,i2,i3,a,b)
variable muxval: integer range 7 DOWNTO 0; begin
muxval:=0;
if (a= '1') then muxval := muxval+1; end if; if (b= '1') then muxval := muxval+2; end if; case muxval is when 0=> q<=i0; when 1=> q<=i1; when 2=> q<=i2; when 3=> q<=i3;
when others=>q<='X'; --null; end case; end process; END body_mux4;
8-4 设计一个求补码的程序,输入数据是一个有符号的8位二进制数。
--解:8-4 设计一个求补码的程序,输入数据是一个有符号的8位二进制数。 LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY org_patch IS
PORT( org_data : IN STD_LOGIC_VECTOR(7 DOWNTO 0);--原码输入 patch_data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));--补码输出 END org_patch;
ARCHITECTURE BHV OF org_patch IS BEGIN
PROCESS(org_data) BEGIN
IF(org_data(7)='0') THEN
patch_data<=org_data; --org_data>=0,补码=原码。 else
patch_data<=org_data(7)&(not org_data(6 DOWNTO 0))+1;--org_data<0,补码=|原码|取反+1。 END IF; END PROCESS; END BHV;
8-5 设计一个比较电路,当输入的8421BCD码大于5时输出1,否则输出0。 --解:8-5 设计一个比较电路,当输入的8421BCD码大于5时输出1,否则输出0。 LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY g_5_cmp IS
PORT( d_in : IN STD_LOGIC_VECTOR(3 DOWNTO 0); --输入数据
cmp_out : OUT STD_LOGIC); --比较输出(1:输入数据>5) END g_5_cmp;
ARCHITECTURE BHV OF g_5_cmp IS BEGIN
PROCESS(d_in) BEGIN
IF(d_in>\
cmp_out<='1'; --输入数据大于5,比较输出1。 else
cmp_out<='0'; --输入数据小于等于5,比较输出0。 END IF; END PROCESS; END BHV;
8-6 用原理图或VHDL输入方式分别设计一个周期性产生二进制序列01001011001的序列发生器,用移位寄存器或用同步时序电路实现,并用时序仿真器验证其功能。(可预置数11位序列发生器)
解(1):用原理图设计产生01001011001序列