用VHDL语言编写可逆向计数的计数器,要求如下:

用VHDL语言编写可逆向计数的计数器,要求如下:,第1张

已经仿真过,请放心使用!

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_unsignedall;

entity Ctl_CNT is

port (

clk: in STD_LOGIC;

back: in STD_LOGIC;

clr: in STD_LOGIC;

rst: in STD_LOGIC;

dis_h: out STD_LOGIC_VECTOR (6 downto 0);

dis_l: out STD_LOGIC_VECTOR (6 downto 0)

);

end Ctl_CNT;

architecture Ctl_CNT_arch of Ctl_CNT is

signal qh:std_logic_vector(3 downto 0);

signal ql: std_logic_vector(3 downto 0);

begin

p1: process(back,rst,clr,clk)

begin

if clr'event and clr='1' then

qh<="0000";

ql<="0000";

elsif

rst'event and rst='1' then

qh<="0110";

ql<="0110";

elsif

clk'event and clk='1'then

if back'event and back='1' then

if ql="0000" then

if qh="0000"

then ql<="1001" ;qh<="1001";

else

qh<=qh-'1';

end if;

else

ql<=ql-'1' ;

end if ;

else

if ql="1001" then

if qh="1001"

then ql<="0000" ;qh<="0000";

else

qh<=qh+'1';

end if;

else

ql<=ql+'1';

end if ;

end if;

end if;

end process p1;

p2:process(qh,ql)

begin

case qh is

when"0000"=> dis_h<="0111111";

when"0001"=> dis_h<="0000110";

when"0010"=> dis_h<="1011011";

when"0011"=> dis_h<="1001111";

when"0100"=> dis_h<="1100110";

when"0101"=> dis_h<="1101101";

when"0110"=> dis_h<="1111101";

when"0111"=> dis_h<="0000111";

when"1000"=>dis_h<="1111111";

when"1001"=> dis_h<="1101111";

when others=>dis_h<="0000000";

end case;

case ql is

when"0000"=> dis_l<="0111111";

when"0001"=> dis_l<="0000110";

when"0010"=> dis_l<="1011011";

when"0011"=> dis_l<="1001111";

when"0100"=> dis_l<="1100110";

when"0101"=> dis_l<="1101101";

when"0110"=> dis_l<="1111101";

when"0111"=>dis_l<="0000111";

when"1000"=> dis_l<="1111111";

when"1001"=> dis_l<="1101111";

when others=> dis_l<="0000000";

end case;

end process p2;

end Ctl_CNT_arch;

直接在实体定义的时候把g设置成inout就可以了,然后当第三种情况直接g<=g;

library IEEE;

use IEEESTD_LOGIC_1164ALL;

use ieeestd_logic_arithall;

use IEEESTD_LOGIC_UNSIGNEDALL;

entity aaa is

Port (clk : in std_logic;

         x :in std_logic_vector(3 downto 0);

         g :inout std_logic

       );

end aaa;

architecture Behavioral of aaa is

begin

process(clk)

variable a : integer range 0 to 20:=10;

variable b : integer range 0 to 20:=5;

variable c : integer range 0 to 20:=0;

begin

if(clk' event and clk='1') then

c:=conv_integer(x);

if(x>a) then

g<='0';

elsif (x<b) then

g<='1';

else

g<=g;

end if;

end if;

end process;

end Behavioral;

这个是我仿真的截图,满足你的要求

写好后存盘

一 将设计项目设置成工程文件(PROJECT)

为了对输入的设计项目进行各项处理,必须将设计文件,设置成Project。如果设计项目由多个设计文件组成,则应该将它们的主文件,即顶层文件设置成Project。如果要对其中某一底层文件进行单独编译、仿真和测试,也必须首先将其设置成Projcet。即需要对哪个设计项目进行编译、仿真等 *** 作时,就设定哪个项目为工程。

将设计项目(如h_addergdf)设定为工程文件,有两个途径:

1、执行菜单File  Project  Set Project to Current File,即将当前设计文件设置成Project。选择此项后可以看到菜单上面的标题栏显示出所设文件的路径。(前一部分是目前编译器所指向的工程文件名称)。这点特别重要,此后的设计应该特别关注此路径的指向是否正确!如果已经指向待编译的文件,就不必再次设置为工程。

2、如果设计文件未打开,执行菜单File  Project  Name,然后在跳出的Project Name窗中找到文件夹及文件名,此时即选定此文件为本次设计的工程文件了。

步骤4:选择目标器件并编译

在对文件编译前必须选定最后实现本设计项目的目标器件,执行菜单AssignDevice,d出Device窗口。此窗口的Device Family是器件序列栏,应该首先在此拦中选定目标器件对应的序列名,如EPM7128S对应的是MAX7000S系列、EPF10K10对应的是FLEX10K、EP1K30对应的是ACEXlK系列等。为了选择EPF10K10LC84-4器件,应将此栏下方标有Show only Fastest Speed Grades的勾消去,以便显示出所有速度级别的器件。完成器件选择后,按OK键。

启动编译器。首先选择左上角菜单的MAX+plusII选项,在其下拉菜单中选择编译器项Compiler,此编译器的功能包括网表文件提取、设计文件排错、逻辑综合、逻辑分配、适配(结构综合)、时序仿真文件提取和编程下载文件装配等。如图5所示。

点击Start,开始编译!如果发现有错,一般情况下,会告诉用户错误的位置和情况,双击编译信息(Messages -Compiler)窗错误信息条,会直接跳到错误位置,排除错误后再次编译。

说明:错误位置是用元件左下部的浅色数字显示的,该数字是用户在Enter Symbol的时候自动顺序编号的。

图5 编译窗口

图5编译窗各功能项目块含义如下:

• Compiler Netlist Extractor :编译器网表文件提取器,该功能块将输入的原理图文件或HDL文本文件转化成网表文件并检查其中可能的错误。该模块还负责连接顶层设计中的多层次设计文件;此外还包含一个内置的,用于接受外部标准网表文件的阅读器。

• Database Builder :基本编译文件建立器,该功能块将含有任何层次的设计网表文件转化成一个单一层次的网表文件,以便进行逻辑综合。

• Logic Synthesizer :逻辑综合器,对设计项目进行逻辑化简、逻辑优化和检查逻辑错误。综合后输出的网表文件表达了设计项目中底层逻辑元件最基本的连接方式和逻辑关系。逻辑综合器的工作方式和优化方案可以通过一些选项来实现。

• Partitioner :逻辑分割器,如果选定的目标器件逻辑资源过小,而设计项目较大,该分割器则自动将设计项目进行分割,使得它们能够实现在多个选定的器件中。

• Fitter :适配器,适配器也称结构综合器或布线布局器。它将逻辑综合所得的网表文件,即底层逻辑元件的基本连接关系,在选定的目标器件中具体实现。对于布线布局的策略和优化方式也可以通过设置一些选项来改变和实现。

• Timing SNF Extractor :时序仿真网表文件提取器,该功能块从适配器输出的文件中提取时序仿真网表文件,留待对设计项目进行仿真测试用。对于大的设计项目一般先进行功能仿真,方法是在Compiler窗口下选择Processing项中的Functional SNF Extractor功能仿真网表文件提取器选项。

• Assembler :装配器,该功能块将适配器输出的文件,根据不同的目标器件,不同的配置ROM产生多种格式的编程/配置文件,如用于CPLD或配置ROM用的POF编程文件(编程目标文件);用于对FPGA直接配置的SOF文件(SRAM目标文件);可用于单片机对FPGA配置的Hex文件,以及其它TTFs、Jam、JBC和JEDEC文件等。

步骤5:时序仿真

接下来应该测试设计项目的正确性,即逻辑仿真,简单的说仿真就是人为模拟输入信号,观察输出信号的变化,判断是否合乎预计的设计要求。具体步骤如下:

1、建立波形文件。按照以上“步骤2”,为此设计建立一个波形测试文件。选择File项及其New,再选择图1下侧New窗中的Waveform Editer项,打开波形编辑窗。如图6所示。

图6 波形编辑窗口

2、输入信号节点。执行菜单Node → Enter Nodes from SNF。在d出的窗口(图7)中首先点击List键,这时左窗口将列出该项设计所有信号节点。由于设计者有时只需要观察其中部分信号的波形,因此要利用中间的“=>”键将需要观察的信号选到右栏中,然后点击OK键即可。波形编辑窗口变成图8所示。

图7 列出并选择需要观察的信号节点

3、设置波形参量。图8所示的波形编辑窗中已经调入了半加器的所有节点信号,在为编辑窗的半加器输入信号a和b设定必要的测试电平之前,首先设定相关的仿真参数。如图8所示, 在Options选项中消去网格对齐Snap to Grid的选择(消去勾),以便能够任意设置输入电平位置,或设置输入时钟信号的周期。这点切记

图8 调入所有节点后的图形编辑窗口

4、设定仿真时间宽度。执行菜单File→End Time选项,在End time选择窗中选择适当的仿真时间域,如可选3s(3微秒),以便有足够长的观察时间,但是不要设定时间太长,否则,仿真工作量大,占用的机时太长。软件默认仿真时间为1s。

5、设定输入信号。现在可以为输入信号a和b设定测试电平了。如图9标出的那样,利用必要的功能键为a和b加上适当的电平,以便仿真后能测试so和co输出信号。如果需要对输入信号a在某段时间间隔内赋值,在该信号的该段时间起点拖动鼠标,移动到该段时间终点,使之变成黑色,然后点击左侧工具箱中的相应赋值按键。如果对信号从头至尾(End Time)赋值,只需用鼠标在左部的Name区点击相应的位置,该信号会全部变黑,表示全选。

图9 设定输入信号的测试电平

赋值取反:就是对“黑色”时间段的信号取反码,如:0→1、1→0、B9→46

6、波形文件存盘。执行菜单File →Save,按OK键即可。由于存盘窗中的波形文件名是默认的(这里是h_adderscf),所以直接存盘即可。

7、运行仿真器。执行菜单MAX+plusII →Simulator选项,点击跳出的仿真器窗口(图10)中的Start键。图11是仿真运算完成后的时序波形。如果没有变化,看看是否因为显示比例太大,点击图9的放大按钮或显示全部按钮。

图10 仿真器窗口

图11 半加器仿真波形

上图的Value栏的数值,代表竖线处(830ns)各个信号的电平。

8、观察分析波形。很明显,图11显示的半加器的时序波形是正确的。还可以进一步了解信号的延时情况。图11的竖线是测试参考线,它上方(与Ref数据框处相同)标出的830ns是此线所在的位置;鼠标箭头(该线右侧‘+’处)所在处时间显示在Time数据框里,为930ns;二者的时间差显示在窗口上方的Interval小窗中。由图可见输入与输出波形间有一个小的延时量10ns。

有时,为了观察方便需要将某些信号作为一组来观测。步骤:

①. 鼠标在Name区选择co使之全部变黑,按住ALT键,向下拖动鼠标,复制一个co,或者全黑后,右键→Copy,在其它空白区域再右键→Paste;然后再复制一个so;或者菜单Node → Enter Nodes from SNF,再加上一个co和so。建议co在so的上面,且二者相邻。

②. 将鼠标移动到Name的co上(不要在带红线的“信号性质说明”上),按下鼠标左键并向下拖动鼠标至so,松开后鼠标左键,可选中信号co、so

③. 在选中区域(黑色)上,点击鼠标右键,在浮动菜单上选择Enter Group或直接执行菜单Node → Enter Group,出现如图12所示的设置组对话框

图12 设置组对话框

④. 选择合适进制后,选择OK,可得到如图13所示的波形图。

图13 组显示结果(10进制)

说明:在以后的仿真时,对于多位的数据,双击Value区,也可以改变数据的显示格式,可以直观显示。步骤①不一定是必须的。但是Group的高位是所选数据的最上面的那个,低位是所选数据的最下面的那个。输入数据也可以编组,有时在信号赋值时比较方便。

9、为了精确测量半加器输入与输出波形间的延时量,可打开时序分析器,方法是选择左上角的MAX+plusII项及其中的Timing Analyzer选项,点击跳出的分析器窗口(图14)中的Start键,延时信息即刻显示在图表中。其中左排的列表是输入信号,上排列出输出信号,中间是对应的延时量,这个延时量是精确针对EPF10K10LC84-4器件的。

图14 延时分析结果

10、包装元件入库。重新回到半加器设计文件h_addergdf,执行菜单File → Create Default Symbol项,此时即将当前文件变成了一个包装好的单一元件h_addersym,并被放置在工程路径指定的目录(e:\MYNAME\shiyan_1)中,以备后用。

时钟信号 clk触发 ,count=0,sum=0

每个clk event 变量 count=count+1,如果count小于等于100,则

sum=count+sum; 有段日子没用了,我说下思想吧

(1)先做一个消抖,存到文件debouncevhd

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_arithall;

use IEEEstd_logic_unsignedall;

entity debounce is

generic (

CLK_FREQ_MHz : integer := 20; --in MHz

BUTTON_PRESS_STATUS : std_logic := '0'

);

port (

reset_n : in std_logic;

clk : in std_logic;

btnIn : in std_logic;

btnPressed : out std_logic

);

end debounce;

architecture debounce_arch of debounce is

constant MAX_MS_CNT : integer := CLK_FREQ_MHz 1000 - 1;

signal msCnt : integer range 0 to MAX_MS_CNT;

signal msClk : std_logic; --做一个毫秒脉冲,每1毫秒对按钮采样一次

signal btnIn_q : std_logic_vector(9 downto 0); --记住最后10次采样

signal btn : std_logic;

signal btn_q : std_logic;

begin

--产生毫秒脉冲

process(reset_n, clk)

begin

if reset_n = '0' then

msCnt <= 0;

msClk <= '0';

elsif rising_edge(clk) then

if msCnt >= MAX_MS_CNT then

msCnt <= 0;

msClk <= '1';

else

msCnt <= msCnt + 1;

msClk <= '0';

end if;

end if;

end process;

--记住最后10次采样

process(reset_n, clk)

begin

if reset_n = '0' then

btnIn_q <= (others => not BUTTON_PRESS_STATUS);

elsif rising_edge(clk) then

if msClk = '1' then

btnIn_q <= btnIn_q(btnIn_q'left-1 downto 0) & btnIn;

else

btnIn_q <= btnIn_q;

end if;

end if;

end process;

process(reset_n, clk)

variable all_samples_are_pressed : std_logic_vector(btnIn_q'left downto 0) := (others => BUTTON_PRESS_STATUS);

begin

if reset_n = '0' then

btn <= '0';

btn_q <= '0';

elsif rising_edge(clk) then

if btnIn_q = all_samples_are_pressed then

btn <= '1'; --最后10次采样都是按下状态,就确认按钮按下(10ms消抖)

elsif btnIn_q = not all_samples_are_pressed then

btn <= '0'; --最后10次采样都是抬起状态,就确认按钮抬起(10ms消抖)

else

btn <= btn; --否则保持不变

end if;

btn_q <= btn;

end if;

end process;

btnPressed <= '1' when btn = '1' and btn_q = '0' else '0'; --按钮按下上升沿检测

end debounce_arch;

(2)做一个加法器,存到文件addervhd

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_arithall;

use IEEEstd_logic_unsignedall;

entity adder is

port (

reset_n : in std_logic;

clk : in std_logic;

adderEn : in std_logic;

data : out std_logic_vector(3 downto 0);

dataValid : out std_logic

);

end adder;

architecture adder_arch of adder is

signal cnt : std_logic_vector(3 downto 0);

begin

process(reset_n, clk)

begin

if reset_n = '0' then

cnt <= x"0";

dataValid <= '0';

elsif rising_edge(clk) then

if adderEn = '1' then --将被替换成,按钮按下时,计数+1

if cnt >= x"9" then

cnt <= x"0";

else

cnt <= cnt + 1;

end if;

dataValid <= '1';

else

cnt <= cnt;

dataValid <= '0';

end if;

end if;

end process;

data <= cnt;

end adder_arch;

(3)做7段数码管显示,存到文件SevenSegmentvhd

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_arithall;

use IEEEstd_logic_unsignedall;

entity SevenSegment is

generic (

LED_ON : std_logic := '0'

);

port (

reset_n : in std_logic;

clk : in std_logic;

data : in std_logic_vector(3 downto 0);

dataValid : in std_logic;

ledOut : out std_logic_vector(6 downto 0)

);

end SevenSegment;

architecture SevenSegment_arch of SevenSegment is

constant LED_OFF : std_logic := not LED_ON;

signal led : std_logic_vector(6 downto 0);

begin

-- --a--

-- |f |b

-- --g--

-- |e |c

-- --d--

process(reset_n, clk)

begin

if reset_n = '0' then

led <= LED_ON & LED_ON & LED_ON & LED_ON & LED_ON & LED_ON &LED_OFF; --display 0

elsif rising_edge(clk) then

if dataValid = '1' then

case data is --a b c d e f g

when x"0" =>

led <= LED_ON & LED_ON & LED_ON & LED_ON & LED_ON & LED_ON & LED_OFF; --display 0

when x"1" =>

led <= LED_OFF & LED_ON & LED_ON & LED_OFF & LED_OFF & LED_OFF & LED_OFF; --display 1

when x"2" =>

led <= LED_ON & LED_ON & LED_OFF & LED_ON & LED_ON & LED_OFF & LED_ON ; --display 2

when x"3" =>

led <= LED_ON & LED_ON & LED_ON & LED_ON & LED_OFF & LED_OFF & LED_ON ; --display 3

when x"4" =>

led <= LED_OFF & LED_ON & LED_ON & LED_OFF & LED_OFF & LED_ON & LED_ON ; --display 4

when x"5" =>

led <= LED_ON & LED_OFF & LED_ON & LED_ON & LED_OFF & LED_ON & LED_ON ; --display 5

when x"6" =>

led <= LED_ON & LED_OFF & LED_ON & LED_ON & LED_ON & LED_ON & LED_ON ; --display 6

when x"7" =>

led <= LED_ON & LED_ON & LED_ON & LED_OFF & LED_OFF & LED_OFF & LED_OFF; --display 7

when x"8" =>

led <= LED_ON & LED_ON & LED_ON & LED_ON & LED_ON & LED_ON & LED_ON ; --display 8

when x"9" =>

led <= LED_ON & LED_ON & LED_ON & LED_ON & LED_OFF & LED_ON & LED_ON ; --display 9

when others =>

led <= (others => LED_OFF);

end case;

else

led <= led;

end if;

end if;

end process;

ledOut <= led;

end SevenSegment_arch;

(4)最后,综合到一起,存到文件topvhd

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_arithall;

use IEEEstd_logic_unsignedall;

entity top is

generic (

CLK_FREQ_MHz : integer := 20; --可以修改成你的系统时钟频率,以MHz为单位

BUTTON_PRESS_STATUS : std_logic := '0'; --指定按钮按下时,是逻辑0还是1

LED_ON : std_logic := '0' --指定数码管点亮需要输出0还是1

);

port (

reset_n : in std_logic;

clk : in std_logic;

btnIn : in std_logic;

ledOut : out std_logic_vector(6 downto 0)

);

end top;

architecture top_arch of top is

component debounce

generic (

CLK_FREQ_MHz : integer := 20; --in MHz

BUTTON_PRESS_STATUS : std_logic := '0'

);

port (

reset_n : in std_logic;

clk : in std_logic;

btnIn : in std_logic;

btnPressed : out std_logic

);

end component;

component adder

port (

reset_n : in std_logic;

clk : in std_logic;

adderEn : in std_logic;

data : out std_logic_vector(3 downto 0);

dataValid : out std_logic

);

end component;

component SevenSegment

generic (

LED_ON : std_logic := '0'

);

port (

reset_n : in std_logic;

clk : in std_logic;

data : in std_logic_vector(3 downto 0);

dataValid : in std_logic;

ledOut : out std_logic_vector(6 downto 0)

);

end component;

signal btnPressed : std_logic;

signal data : std_logic_vector(3 downto 0);

signal dataValid : std_logic;

begin

debounce_inst : debounce

generic map (

CLK_FREQ_MHz => CLK_FREQ_MHz, --in MHz

BUTTON_PRESS_STATUS => BUTTON_PRESS_STATUS

)

port map(

reset_n => reset_n,

clk => clk,

btnIn => btnIn,

btnPressed => btnPressed

);

addr_inst : adder

port map (

reset_n => reset_n,

clk => clk,

adderEn => btnPressed,

data => data,

dataValid => dataValid

);

SevenSegment_inst : SevenSegment

generic map (

LED_ON => LED_ON

)

port map (

reset_n => reset_n,

clk => clk,

data => data,

dataValid => dataValid,

ledOut => ledOut

);

end top_arch;

(5)你只要修改topvhd里generic的定义,设定时钟频率、按钮按下状态和数码管点亮状态即可

--======================================

-- 3 input OR-gate

--======================================

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_unsignedall;

entity or3input is

port (

input1 : in std_logic ;

input2 : in std_logic ;

input3 : in std_logic ;

out_OR : out std_logic

);

end or3input ;

architecture RTL of or3input is

begin

out_OR <= input1 or input2 or input1 ;

end RTL ;

--======================================

-- DFF

--======================================

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_unsignedall;

entity dff is

port (

clock : in std_logic ;

reset : in std_logic ;

din : in std_logic ;

dout : out std_logic

);

end dff ;

architecture RTL of dff is

begin

process (clock,reset) begin

if (reset = '1') then

dout <= '0';

elsif (clock'event and clock = '1') then

dout <= din ;

end if;

end process;

end RTL ;

--======================================

-- Serial Gen

--======================================

library IEEE;

use IEEEstd_logic_1164all;

use IEEEstd_logic_unsignedall;

entity dff is

port (

clock : in std_logic ;

reset : in std_logic ;

dout : out std_logic

);

end dff ;

architecture RTL of dff is

signal shft_reg : std_logic_vector (15 downto 0) ;

begin

process (clock,reset) begin

if (reset = '1') then

shft_reg <= "0110110111001011" ;

elsif (clock'event and clock = '1') then

shft_reg <= shft_reg(14 downto 0)& shft_reg(15) ;

end if;

end process;

dout <= shft_reg(15) ;

end RTL ;

以上就是关于用VHDL语言编写可逆向计数的计数器,要求如下:全部的内容,包括:用VHDL语言编写可逆向计数的计数器,要求如下:、VHDL编程时,如何编写保持前一状态的程序。高手进 加分 程序示例如下:、请问写好一个VHDL程序后,怎么样一步步到仿真等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9709760.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存