0%

一、实验设计目标

(1)设计实现一个可容纳四组选手参赛的抢答器系统,每组设一个抢答按钮。答题开始后,由主持人按下“开始”键后进入抢答环节,当某个小组抢答成功时,抢答器系统发出半秒的低频音,显示该组别序号并点亮该组“选手指示灯”直至系统复位。此时进入答题计时环节,若超过30秒仍未答出,抢答器系统发出1秒的高频音示警,同时点亮“超时灯”1秒。由裁判员按下“复位”键,开始新一轮答题。

(2)通过此实验学习Anlogic_FPGA开发板上的蜂鸣器的发声原理。

二、实验设计思路

本实验设计实现一个抢答器系统,它由第一信号鉴别、锁存模块,答题计时模块,蜂鸣器发声模块和数码管显示模块组成,图7.1是该系统的示意图。

img

7.1 抢答器系统示意图

第一信号鉴别、锁存模块的关键在于准确判断出第一抢答者并将其锁存。设置

一个主持人“开始”按钮Start,四个抢答按钮K1、K2、K3、K4,主持人开始后,抢答信号才能被有效识别,在某个小组抢答成功后,其他组的抢答信号无效。本模块输出LED_Out[3:0]、Player_Number[3:0]、Buzzer_Answer和Timer_Start信号。LED_Out用于控制“选手指示灯”;Player_Number存储抢答成功的小组序号;Buzzer_Answer作为“抢答成功鸣笛标志位”,送到蜂鸣器发声模块,控制蜂鸣器的发声频率及时间;Timer_Start作为答题计时模块的“启动标志位”,当某个小组抢答成功后,Timer_Start变为1,启动答题计时器。

答题计时模块的关键在于倒计时的启动,利用Timer_Start信号控制倒计时的开启。在实验六中设计实现了一个加法计数器,类似的,本模块只需实现一个“30-29-…-01-00”的减法计数器即可。本模块输出TimerH[3:0]、TimerL[3:0]、Buzzer_TimeOver和LED_OverTime信号。TimerH和TimerL分别存储倒计时的十位和个位;Buzzer_TimeOver作为“答题超时鸣笛标志位”,送到蜂鸣器发声模块;LED_OverTime用于控制答题“超时灯”。

蜂鸣器发声模块用于控制蜂鸣器的发声频率、何时发声及发声时长。通过标志位Buzzer_Answer和Buzzer_TimeOver控制送到蜂鸣器上的电压值及电压变化频率。Buzzer_Out即为最终送给蜂鸣器的信号。

数码管显示模块用于显示倒计时的时间和抢答成功的组别序号,驱动原理与实验六相同。

三、功能模块图与输入输出引脚说明

该工程包含顶层模块responder与底层模块Sel_module、Timer_module、Buzzer_module和Digitron_NumDisplay_module。底层模块依次对应于图7.1中从左至右四个功能模块。整个工程的模块功能图参考图7.1即可。下面介绍一下顶层模块各主要引脚的功能:

(1)CLK:50MHz的基准时钟信号输入。在Sel_module模块中将其分频后产生标准秒脉冲CLK1。

(2)RSTn:系统复位输入信号。低电平有效,由裁判员控制,复位后系统回到初始状态,“选手指示灯、超时灯”熄灭,蜂鸣器不响,数码管显示“030”。

(3)Start:抢答开始输入信号。由主持人控制,当Start为1时,各个小组的抢答信号有效。

(4)Key_In:抢答输入信号,Key_In[3:0]连接到矩阵键盘的列信号Key_Col[3:0]上,给Key_Row[3:0]恒定输出4’b0111,当KEY[3:0]中有按键被按下,Key_Col[3:0]对应位输出低电平,表示存在抢答操作。

(5)LED_Out:“选手指示灯”输出信号,输出到LED灯,共有四位。LED_Out [3:0]分别连接第四组~第一组选手的指示灯,例如若第四组选手抢答成功,LED_Out [3:0]的值为“1000”。

(6)Buzzer_Out:输出到蜂鸣器。

(7)LED_OverTime_Out:答题“超时灯”输出信号。LED_OverTime_Out信号与抢答器电路的LED_OverTime相连,控制超时灯。

(8)Digitron_Out:七段数码管的显示输出,共有八位。

(9)DigitronCS_Out:数码管的片选信号,共有四位。

四、程序设计

(1)7.3是截取自底层模块Sel_module的部分代码:

img

7.2 Sel_module核心代码

30-42:Timer_Start是“计时器启动标志位”,当第一信号鉴别、锁存模块锁存了第一抢答信号后,令Timer_Start变为1,启动答题计时器电路。当Timer_Start变为1后,30-42行代码将Buzzer_Answer(“抢答成功鸣笛标志位”)置为1,保持半秒后,再置为0。这里用到了一个很简单的计数器Count,用于控制半秒的时间。

43-49:判断是否已经锁存以及第一组别是否有抢答操作,Block是锁存信号,高电平表示电路已锁存。若第一组抢答,且在此之前未有其他组抢答成功(Block为0),45-48行依次为点亮第一组“选手指示灯”,锁存电路,开启答题计时器,将第一组别序号送给数码管。

(2)图7.3是截取自底层模块Buzzer_module的部分代码,请结合第一篇的1.3节中关于蜂鸣器模块的介绍内容进行理解:

img

7.3 Buzzer_module核心代码

​ 17-25:通过“鸣笛标志位”控制送到蜂鸣器上的电压和电压变化频率。例如,当某个小组抢答成功时,“抢答成功鸣笛标志位” Buzzer_Answer将被置为1且经过半秒后变回0,这半秒内将常量_Answer的值(’d95419)赋给Pulse_x,半秒后Pulse_x的值变为’d20000。

29-37:这是一个小型计数器。若Pulse_x的值为“_Answer”或“_TimeOver”,则控制W_buzzer的值以一定频率在“0”和“1”之间翻转,这样便形成了一定频

率的脉冲信号。W_buzzer的值即为将送给蜂鸣器的值,该脉冲信号的频率即控制蜂鸣器发声的频率。

(3) 图7.4是数码管显示模块

1625847432(1)

13-30:分频程序,用于产生频率为250KHz的扫描信号,并在每个扫描周期对cnt在0-2循环计数。

1625847476(1)

32-44:片选信号DigitronCS_Out的扫描程序。W_DigitronCS_Out[3:0]信号的值将在程序的最后赋给DigitronCS_Out[3:0]信号,当它的某一位为0时,对应的数码管选中,反之则不选中。在本实验中使用数码管DIG1、DIG0显示显示倒计时数字,DIG2显示抢答号,因而DigitronCS_Out[3:0]的值根据cnt计数结果在“1110,1101,1011”之间变换,变换频率为250KHz。

1625847658(1)

46-76:根据SingleNum信号的值选择输送到数码管的常量,控制字码段的点亮情况。例如当SingleNum的值为4’b1000时,输送到数码管的常量为“_8”, 即Digitron_Out[7:0]的值为8’b0111_1111,字码段A、B、C、D、E、F、G全部点亮,DP(小数点)熄灭,数码管显示数字“8”。

五、FPGA管脚配置

Anlogic FPGA的IO 分配使用如下:DIG2(DigitronCS_Out[2])显示抢答成功组别的序号,使用DIG1(DigitronCS_Out[1])和DIG0(DigitronCS_Out[0])显示倒计时的十位和个位;复位输入信号RSTn和抢答开始信号Start分别与开发板上的SW0和SW1相连;Buzzer_Out信号输出到蜂鸣器引脚;

观察矩阵按键的原理图,Key_In[3:0]代表物理按键KEY3 - KEY0,他们分别与矩阵按键的Key_Col[3:0]相连,因此当我们给Key_Row[3:0]输出恒定的4’b0111时,按下KEY0,Key_Col[0]就会出现低电平;

img

LED_Out[3:0]分别输出到LED3~LED0,LED_OverTime_Out输出到LED7,LED7点亮表明答题超过30秒。

set_pin_assignment { Buzzer_Out } { LOCATION = H11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { CLK } { LOCATION = R7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[0] } { LOCATION = C9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[1] } { LOCATION = B6; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[2] } { LOCATION = A5; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[3] } { LOCATION = A3; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[0] } { LOCATION = A4; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[1] } { LOCATION = A6; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[2] } { LOCATION = B8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[3] } { LOCATION = E8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[4] } { LOCATION = A7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[5] } { LOCATION = B5; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[6] } { LOCATION = A8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[7] } { LOCATION = C8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_In[0] } { LOCATION = E11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_In[1] } { LOCATION = D11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_In[2] } { LOCATION = C11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_In[3] } { LOCATION = F10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_OverTime_Out } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { RSTn } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Start } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[0] } { LOCATION = D9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[1] } { LOCATION = F9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[2] } { LOCATION = C10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[3] } { LOCATION = E10; IOSTANDARD = LVCMOS33; }

抢答器系统IO Constraint

六、实验结果

当SWO和SW1均拨至“UP”时,系统进入抢答环节。若假设第二组选手抢答成功,此时蜂鸣器鸣低频音并持续半秒钟,灯LED1点亮,数码管DIG2将显示“2”,DIG1和DIG0将显示倒计时数字;若答题超过30秒,灯LED4将点亮1秒,蜂鸣器鸣高频音并持续1秒钟,DIG1和DIG0显示“00”并保持直到系统复位。因篇幅受限,其他情况请自行验证。

七、思考与拓展

(1)新建一个工程,自行设计程序或查询相关资料,实现以下功能:①计分功能,每组开始预置5分,由主持人计分,答对一次加1分,答错一次减1分;②抢答未开始前若有人抢答则报警并点亮相应选手指示灯。

(2)本实验初次使用蜂鸣器显示实验结果,请仔细理解蜂鸣器的工作方法,并新建工程,实现按键控制蜂鸣器发“Do、Re、Mi、Fa、Sol、La、Si”音阶的功能。实际上本实验中的低频音和高频音即为“Do、Si”,频率的计算方法参考实验5.3中的公式(5.3)。各个音阶的参考频率依次为262、294、330、349、392、440和494Hz。

一、实验设计目标

(1)在FPGA中设计实现24进制加法计数器。

(3)通过此实验学习Anlogic_FPGA开发板上的数码管的使用方法。

二、实验设计思路

本实验设计实现一个24进制的加法计数器,它由晶体振荡器、分频器、计数器和数码管显示器组成,图6.1是该加法计数器的示意图。

img

6.1 24进制加法计数器示意图

晶体振荡器产生稳定的50MHz的脉冲信号CLK,经过分频器后输出标准秒脉冲CLK1,作为计数器的计数时钟。计数器按照“00-01-02…22-23-00-01”的规律计数,每增加1秒,计数器加1,信号Result[7:4]代表计数器输出结果的十位,

Result[3:0]代表个位,RSTn为复位输入信号。将计数器的结果Result输出给数码管显示。

三、功能模块图与输入输出引脚说明

该工程包含顶层模块counter24与底层模块Accumulator_module、Digitron_NumDisplay_module。其中,Accumulator_module实现分频器和计数器的功能,Digitron_NumDisplay_module实现数码管显示器的功能。图6.2是整个工程的模块功能图。下面介绍一下顶层模块各引脚的功能:

img

6.2 加法计数器模块功能图

(1)CLK:50MHz的时钟信号输入。将其分频后产生标准秒脉冲CLK1。

(2)RSTn:复位输入信号。低电平有效,复位后计数器输出Result变为00。

(3)DigitronCS_Out[3:0],Digitron_Out[7:0]:数码管的输出,共有四位片选和八位段选总线。

四、程序设计

(1)图6.3是截取自底层模块Accumulator_module的部分代码:

​ 16-24:CLK1是CLK通过分频代码产生的标准秒脉冲,周期为1s。

28-29:RSTn为0时,系统复位,计数器输出Result[7:0] 变为“00”。

​ 31-42:这是一个24进制计数器,个位(Result[3:0])满10后向十位进位,

整体按照“23”翻“00”规律计数。

img

6.3 Accumulator_module核心代码

(2)图6.4是截取自底层模块Digitron_NumDisplay的部分代码:

1625845227(1)

11-40:分频和数码管位选程序,使用Count产生250KHz的扫描频率,每个扫描周期改变数码管位选W_DigitronCS_Out,这里数码管显示在低两位切换。

1625845580(1)

45-48:参数型常量定义。定义了“_0_1_2…_9”这九个输送到数码管的常量的值。

52-55:当数码管位选变化时,将该位上需要显示的值赋给SinleNum;

57-68:根据SingleNum的值,选择要显示的数字对应的LED段码赋给W_Digitron_Out;

五、FPGA管脚配置

下面是本例中Anlogic FPGA的引脚分配。

set_pin_assignment { CLK } { LOCATION = R7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[0] } { LOCATION = C9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[1] } { LOCATION = B6; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[2] } { LOCATION = A5; IOSTANDARD = LVCMOS33; }

set_pin_assignment { DigitronCS_Out[3] } { LOCATION = A3; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[0] } { LOCATION = A4; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[1] } { LOCATION = A6; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[2] } { LOCATION = B8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[3] } { LOCATION = E8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[4] } { LOCATION = A7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[5] } { LOCATION = B5; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[6] } { LOCATION = A8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Digitron_Out[7] } { LOCATION = C8; IOSTANDARD = LVCMOS33; }

set_pin_assignment { RSTn } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

六、实验结果

当SW0拨至“UP”时的实验现象,数码管从00到23循环计数。当SW0拨至“DOWN”时,将显示“00”。

七、思考与拓展

(1)本实验初次使用数码管验证实验输出,认真阅读代码,理解数码管的驱动原理,这将在后面的实验中频繁出现。

一、实验设计目标

(1)设计实现一个4输入的带置位和清零端的正边沿触发的JK触发器。

(2)通过此实验学习利用编程得到任意频率的时钟信号的基本方法。

二、实验设计思路

类似于实验5.2节,本节实验设计实现一个带置位和清零端的正边沿触发的JK触发器。包含时钟信号CLK1,置位端Setn,清零端Clrn,四组数据输入信号J3J0、K3K0和四组数据输出信号Q3~Q0。当Setn和 Clrn都为高电平时,输出Q在时钟信号CLK1的上升沿处随输入J、K的值变化,在J、K端均为1时,每遇到一个时钟的上升沿,输出端的状态翻转一次。

表5.2是第i组输入输出信号的真值表,img表示该组输出的当前值,img表示该组输出上一刻的状态,从真值表可以写出img的逻辑表达式:

img img (5.2)

5.2 带置位与清零端的JK触发器真值表

置位 清零 输入 输出
img img img img img img img
0 X X X X 1 0
1 0 X X X 0 1
1 1 img 0 0 img(保持) img(保持)
1 1 img 0 1 0 1
1 1 img 1 0 1 0
1 1 img 1 1 img(翻转) img(翻转)

三、功能模块图与输入输出引脚说明

JK触发器工程包含顶层模块triggerJK1和底层模块trigger_module,图5.8是整个工程的模块功能图。下面介绍一下顶层模块各引脚的功能:

img

图5.8 JK触发器模块功能图

(1)CLK:50MHz的系统基准时钟输入。为了能观察到JK触发器的翻转效果,必须降低时钟信号CLK1的频率,将CLK适当分频可得到频率为12.5HZ的时钟信号CLK1,用CLK1的上升沿作为JK触发器的触发信号。

(2)Setn:置位输入信号,连接至Key_Col[0]。当Key_Row[3]输出低电平,KEY0按下时,Setn由高电平变为低电平,JK触发器输出Q恒为1。

(3)Clrn:清零输入信号,连接至Key_Col[1],当Key_Row[3]输出低电平,KEY1按下时,Clrn由高电平变为低电平。当Setn为高电平,且Clrn为低电平时输出Q恒为0。且Setn信号的优先级高于Clrn信号。

(4)SW_In:拨动开关输入,共有八位总线。SW_In[7:4]分别连接“JK触发器”的输入J3J0,SW_In[3:0]分别连接“JK触发器”的输入K3K0,用于模拟输入信号。

(5)LED_Out:输出到LED灯,共有八位总线。LED_Out[7:4]分别连接“JK触发器”的输出Q3~Q0;LED_Out[3:0]分别连接“JK触发器”的输出Q_n0(对应于表5.2中的img),通过LED灯的亮灭情况来观察触发器的输出效果。

四、程序设计

​ 图5.9是截取自底层模块trigger_module的部分代码:

img

5.9 JK触发器实验核心代码

13-26:一个分频程序的基本写法,用于产生频率为12.5Hz的时钟信号CLK1。13-15定义了该分频程序需用到的内部信号及参数,需要注意的是常量的书写格式;19行代码中的“-1’b1”用于保证所得到的时钟信号CLK1的频率的准确性,非常重要;时钟信号CLK1的频率计算公式为

img (5.3)

img

28-38:实现带异步置位和清零端的JK触发器的逻辑表达式,见公式(5.2)。Setn信号的优先级高于Clrn信号。

五、FPGA管脚配置

以下是Anlogic FPGA的IO Constraint,CLK信号、Setn信号、Clrn信号、SW_In[7:0]输入信号和LED_Out[7:0]的引脚连接信息如下表。

set_pin_assignment { CLK } { LOCATION = R7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Clrn } { LOCATION = D11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[0] } { LOCATION = D9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[1] } { LOCATION = F9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[2] } { LOCATION = C10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[3] } { LOCATION = E10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[7] } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Setn } { LOCATION = E11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[0] } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[1] } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[2] } { LOCATION = B10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[3] } { LOCATION = A11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[4] } { LOCATION = A12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[5] } { LOCATION = B12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[6] } { LOCATION = A13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[7] } { LOCATION = A14; IOSTANDARD = LVCMOS33; }

六、实验结果

本实验设计实现包含4组输入输出信号的JK触发器,在验证实验时仅需挑选其中一组进行观察。如挑选第四组输入输出信号,SW7和SW3分别连接J3、K3输入信号,LED7和LED3分别连接Q3、Q_n3输出信号。当SW7和SW3均拨至“DOWN”时,输出处于“保持”状态,LED7和LED3的状态不改变;当SW7和SW3分别拨至“DOWN、UP”时,输出Q为0,LED7灭,LED3亮;当SW7和SW3分别拨至“UP、DOWN”时,输出Q为1,LED7亮,LED3灭;当SW7和SW3均拨至“UP”时,输出处于“翻转”状态,每遇到一个时钟信号CLK1的上升沿,LED7和LED3的状态翻转一次。因篇幅受限,其他情况请自行验证。

七、思考与拓展

(1)在观察现象时,发现实验结果不太理想,LED灯的状态变换情况存在一定的延时,请问这是什么原因造成的?

(2)为解决(1)中的延时问题,令trigger_module.v文件中的参数Timex =

21’d200_000,当SW7和SW3均拨至“UP”时,LED7和LED3快速闪烁。

(3)参考实验5.1中D触发器实验思路,使用结构描述的方式实现带置位和清零端的JK触发器功能。

*一、实验设计目标*

(1)在FPGA中使用门级结构描述D触发器。

(3)通过此实验学习门级结构建模的基本方法。

*二、实验设计思路*

一个逻辑电路是由许多逻辑门和开关组成的,因此用基本逻辑门的模型来描述逻辑电路结构是最直观的。本实验设计使用结构描述语句实现D触发器功能,采用带

异步置位和清零端的正边沿触发方式,输入信号包含时钟信号CLK、置位端Setn、清零端Clrn和一个数据输入D,输出信号包含数据输出Q和~Q。当Setn为低电平时输出Q恒为1;当Setn为高电平且Clrn为低电平时输出恒为0;当Setn和 Clrn都为高电平时,输出Q在时钟信号CLK的上升沿处被赋予输入D的值。

图5.1是带异步置位和清零端的正边沿触发的D触发器的电路结构图,该逻辑电路的行为分析如下:

img

5.1 带异步置位和清零端的正边沿触发的D触发器

当Setn和Clrn都为1时,可不考虑Setn和Clrn引脚,此时与非门1和与非门2构成一个SR锁存器。当S和R(即图5.1中的反馈信号f4和f5)都为1时,该锁存器处于存储状态。假设,时钟信号CLK为0,D为1,则信号f4和f5都为1,SR锁存器进入存储状态。同时,信号f6将变为0,f3将为1。假设CLK变为1,这将使f4变为0,输出Q被置为1。如果现在输入D变为0,时钟信号CLK仍为1,则f6将变为1,只要时钟信号CLK保持为1,f3也将保持为1。则f4仍为0,输出Q保持为1不变。而当时钟信号变为0时,f4和f5都将变为1,SR锁存器再次处于存储状态,输出Q保持为不变。也就是说输出Q只在时钟信号CLK的上升沿被置为输入D的值。其他情况也可类似讨论。

当置位信号Setn(清零信号Clrn)为0时,输出Q立即变为1(0),而不用等到下一个时钟上升沿的到来,此即为异步置位和清零的特点。并且对于输出Q来说,Setn的优先级高于Clrn。

*三、功能模块图与输入输出引脚说明*

该工程包含顶层模块triggerD1与底层模块trigger_module,图5.2是整个工程的模块功能图。本实验仅验证了输出Q而未验证输出~Q,下面介绍一下顶层模块各引脚的功能:

img

5.3 D触发器模块功能图

(1)CLK:50MHz的时钟信号输入。用CLK的上升沿作为D触发器的触发信号。

(2)Setn:置位输入信号,与SW1相连。当Setn为低电平时输出Q恒为1。

(3)Clrn:清零输入信号,与SW0相连。当Setn为高电平且Clrn为低电平时输出Q恒为0。对输出Q来说,Setn信号的优先级高于Clrn信号。

(4)SW_In:拨动开关输入,与SW2相连。SW_In直接连接“D触发器”的输入“D”,用于模拟输入信号。

(5)LED_Out:输出到LED0。LED_Out直接连接“D触发器”的输出“Q”,通过LED灯的亮灭情况来显示触发器的输出Q。

*四、程序设计*

​ 图5.3是截取自底层模块trigger_module的部分代码:

img

5.3 D触发器实验核心代码

5-9:输入输出信号声明。

​ 11-21:使用门级结构描述D触发器的电路结构图(图5.1)。门声明语句的格式为:

<门的类型>[<驱动能力><延时>]<门实例1>[,<门实例2>,…,<门实例n>];

​ 门的类型是门声明语句必须的;驱动能力和延时是可选项;门实例1是在本模块中所引用的第一个这种类型的门,而门实例n是引用的第n个这种类型的门,且在结束时使用逗号,最后才用分号。

​ 在本例中,代码第11行使用了一个名为U1的与非门,对应图5.1中的与非

门1,输入为Setn、f4和f2,输出为f1。输出与输入无延时。

*五、FPGA管脚配置*

以下是Anlogic FPGA的IO Constraint,CLK时钟输入信号与Anlogic_FPGA开发板上的50MHz的晶振时钟相连;置位输入信号Setn与开发板上的SW1相连;清零输入信号Clrn与开发板上的SW0相连;LED_Out输出信号与LED0相连;SW_In输入信号与开发板上的SW2相连。

set_pin_assignment { CLK } { LOCATION = R7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Clrn } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Setn } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In } { LOCATION = B10; IOSTANDARD = LVCMOS33; }

*六、实验结果*

当开关SW1拨向下(Setn = 0)时,LED0点亮;当开关SW1拨向上(Setn = 1),SW0拨向下(Clrn = 0)时, LED0熄灭;当开关SW1,SW0均拨向上(Setn = 1,Clrn = 1)时,在每个时钟的上升沿,LED0输出SW2的状态。因篇幅有限,置位与清零功能请自行验证。

*七、思考与拓展*

(1)本实验仅验证了输出Q而未验证输出Q。对于输出Q来说,Setn信号的优先级高于Clrn信号,那么对于输出Q又是怎样的呢?请适当修改程序同时观察输出Q和~Q,并结合图5.1解释实验现象。

*八、实验小结*

Verilog既可以是一种行为描述的语言也可以是一种结构描述的语言。Verilog模型可以是实际电路的不同级别的抽象,这些抽象的级别包括:系统级、算法级、RTL(Register Transfer Level)级、门级和开关级。前三种都属于行为描述,后两种属于结构描述,RTL级是描述数据在寄存器之前流动和如何处理、控制这些数据流动的模型,门级是描述逻辑门及逻辑门之间的连接的模型。本实验使用门级结构描述D触发器,通过此实验可以学习门级结构建模的基本方法,在下一节实验中将使用行为描述语句实现8D触发器功能。

一、实验设计目标

(1)在FPGA中使用行为描述语句实现8D触发器功能。

(3)结合实验5.1与实验5.1,对比理解行为描述语句和结构描述语句的不同及各自的优点。

二、实验设计思路

输出在时钟信号某个特定时刻随输入改变的器件称为触发器。本实验设计实现一个带异步置位与清零端的正边沿触发的8D触发器,除包含8个数据输入端D7D0、和8个数据输出端Q7Q0外,其他功能均与实验5.1相同,此处就不再赘述。

表5.1是第i组输入输出信号的真值表,从真值表可以写出img的逻辑表达式:

img img (5.1)

5.1 8D触发器真值表

置位 清零 输入 输出
img img img img img
0 X X X 1
1 0 X X 0
1 1 img 0 0
1 1 img 1 1

三、功能模块图与输入输出引脚说明

该工程包含顶层模块triggerD2与底层模块trigger_module,图5.5是整个工程的模块功能图。

img

5.5 8D触发器模块功能图

下面介绍一下顶层模块各引脚的功能:

(1)CLK信号、Setn信号和Clrn信号的功能均与实验5.1中D触发器相同,但在本例中,如下图,Setn信号连接到Key_Col[0],Clrn信号连接到Key_Col[1]。这里我们将矩阵键盘的行信号(Key_Row[3:0])输出恒定的4’b0111,即Key_Row[3]始终为低,这样Key0按下时,Key_Col[0](FPGA的E11脚)由高变低,Key1按下时,Key_Col[1](FPGA的D11脚)由高变低。

img

(2)SW_In:拨动开关输入,共有八位。SW_In[7:0]分别连接“8D触发器”的数据输入“D7~D0”,用于模拟输入信号。

(5)LED_Out:输出到LED灯,共有八位。LED_Out[7:0]分别连接“8D触发器”的输出“Q7~Q0”,通过8个LED灯的亮灭情况来显示触发器的输出结果。

四、程序设计

​ 图5.6是截取自底层模块trigger_module的部分代码:

img

5.6 8D触发器实验核心代码

5-9:输入输出信号声明。

​ 11-21:使用行为描述语句实现带异步置位和清零端的8D触发器的逻辑表达式,见公式(5.1)。Setn信号的优先级高于Clrn信号。

五、FPGA管脚配置

以下 是Anlogic FPGA的IO Constraint,CLK信号、Setn信号和Clrn信号的配置方式均与实验5.1中相应信号的配置方式相同; LED_Out[7:0]输出信号分别与开发板上的LED7LED0相连;SW_In[7:0]输入信号分别与SW7SW0相连。

set_pin_assignment { CLK } { LOCATION = R7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Clrn } { LOCATION = D11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[0] } { LOCATION = D9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[1] } { LOCATION = F9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[2] } { LOCATION = C10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Key_Row[3] } { LOCATION = E10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[7] } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Setn } { LOCATION = E11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[0] } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[1] } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[2] } { LOCATION = B10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[3] } { LOCATION = A11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[4] } { LOCATION = A12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[5] } { LOCATION = B12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[6] } { LOCATION = A13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[7] } { LOCATION = A14; IOSTANDARD = LVCMOS33; }

六、实验结果

当按键开关KEY0按下时,LED7~LED0均点亮;当按键开关KEY0不按下,KEY1

按下时,LED7LED0均熄灭;当按键开关KEY0,KEY1均不按下时,在每个时钟的上升沿,LED7LED0分别输出SW7~SW0的状态。因篇幅有限,置位与清零功能请自行验证。

七、思考与拓展

图5.8是使用if语句直接描述D触发器功能的实验代码,它不同于实验5.1

节从触发器的门级结构出发,也不同于实验5.3节从触发器的真值表出发,实际上在设计更为复杂的FPGA系统时,往往结合这几种方式,择优处理。请参考图5.8示代码自行建立工程实现8D触发器功能。

img

5.8 if语句实现8D触发器参考代码

八、实验小结

(1)在本实验中,我们使用了非阻塞语句运算符“<=”代替阻塞语句运算符“=”。当使用阻塞运算符“=”时,赋值语句立即就把当前值赋给变量;但是,当使用非阻塞运算符“<=”时,赋值语句要等到always块结束时后,才完成对变量的赋值操作。

(2)行为描述语句可描述顺序执行或并行执行的程序结构,本节实验使用行为描述语言实现8D触发器功能,相较于实验5.1,程序更加直观、简洁,请结合实验5.1理解它们各自的特点和优势。

一、实验设计目标

(1)使用case语句设计实现自定义数据位宽的4选1数据选择器。

(2)通过此实验初步掌握case语句的使用方法。

(3)通过此实验初步掌握参数(parameter)型常数的定义方法和使用方法。

二、实验设计思路

数据选择器又称多路转换器或称多路开关,其功能是根据地址码的不同,从多个输入数据流中选择一个送往公共的输出端。根据数据输入端的个数的不同,可分为16选1、8选1、4选1等数据选择器。

本实验设计使用case语句实现4选1数据选择器功能,包含4个数据输入端D3D0,2个地址输入端A1A0,一个输入使能控制端CSn和一个数据输出端Y。当CSn为低电平时允许数据选择器工作;每组输入信号(D3~D0)的数据位宽是可自定义的,因按键开关个数限制,在验证实验时将其位宽定为1位。表4.1给出了对应的真值表。

4.1 41数据选择器真值表

地址 使能 输入 输出1
img img img img img img img img
X X 1 0
0 0 0 img
0 1 0 img
1 0 0 img
1 1 0 img

三、功能模块图与输入输出引脚说明

数据选择器工程包含顶层模块mux41与底层模块mux41_module,图4.1是整个工程的模块功能图。下面介绍一下各主要引脚的功能:

img

4.1 数据选择器模块功能图

​ (1)Width:数据位宽,在程序中定义,不属于输入输出信号。实验时,将width定为1,即每组输入信号和输出端信号的位宽都为1位。

(2)CSn:输入使能控制信号,低电平有效,连接在SW_In[2]。当CSn=0时,允许数据选择器工作;当CSn=1时,禁止数据选择器工作。

(3)SW_In[1:0]:拨动开关输入,共有两位。SW_In[1:0]分别连接“数据选择器”的地址输入信号A1~A0,用于地址选择。

(4)Data_In[3:0]:“数据选择器”的数据输入信号D[3:0],连接到拨动开关SW_In[7:4]。

(5)LED_Out:输出到LED灯,共有八位。LED_Out0连接“数据选择器”的数据输出端Y,通过LED灯的亮灭情况来显示结果。LED_Out[7:1]输出恒定低电平。

四、程序设计

​ 图4.2是截取自底层模块mux41_module的部分代码:

img

4.2 数据选择器实验核心代码

5-8:输入输出信号声明。

​ 12:敏感事件程序清单中的*号将自动包含always块中的语句或条件表达式中的所有信号,也可直接写always @ ( A or CSn )。

​ 15-20:使用case语句实现数据选择,选择方式请参考真值表4.4。

​ 21:当使能控制信号CSn=1时,数据选择器不工作,输出恒为0。

五、FPGA管脚配置

​ 以下是Anlogic FPGA的IO Constraint,输入控制使能信号CSn与Anlogic_FPGA开发板上SW2相连;SW_In[1:0] 分别与开发板上的SW1SW0相连;Data_In0 Data_In3分别与开发板上的SW4~SW7相连;LED_Out[0]与开发板上的LED0相连。

set_pin_assignment { CSn } { LOCATION = B10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Data_In0 } { LOCATION = A12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Data_In1 } { LOCATION = B12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Data_In2 } { LOCATION = A13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Data_In3 } { LOCATION = A14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[7] } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[0] } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[1] } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

4.3 数据选择器IO Constraint

六、实验结果

当拨动开关SW2拨至“DOWN”,且SW1~SW0均拨至“UP”,选中输入SW7,此时LED0输出SW7的状态,当拨下SW7时,LED0灭,反之则亮。具体实验现象请参照真值表4.1自行验证。

七、实验小结

(1)if语句必须包含在一个always块中,always块中的语句按它们出现的顺序执行。

(2)用parameter来定义一个标识符代表一个常量,称为符号常量,即标识符形式的常量,采用符号常量可提高程序的可读性和可维护性。

一、实验设计目标

(1)使用for循环语句设计实现8-3优先编码器。

(2)通过此实验初步掌握for语句的使用方法。

二、实验设计思路

编码器就是译码器的反向器件,有2n个输入和n个输出。编码器常用来告知计算机当前请求中断的外部设备是哪个,当有多个外部中断请求时,计算机将响应优先级高的那个中断。本实验设计实现一个8-3优先编码器,假定输入信号中不会出现高阻态或不定值,如果编码器的多个输入同时为高电平,它将选择优先级高的那个输入。表3.2给出了对应的真值表。

3.2 8-3 优先编码器真值表

img img img img img img img img img img img
0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 X 0 0 1
0 0 0 0 0 1 X X 0 1 0
0 0 0 0 1 X X X 0 1 1
0 0 0 1 X X X X 1 0 0
0 0 1 X X X X X 1 0 1
0 1 X X X X X X 1 1 0
1 X X X X X X X 1 1 1

三、功能模块图与输入输出引脚说明

编码器工程包含顶层模块pencode83和底层模块pencode_module,图3.4是整个工程的模块功能图。下面介绍一下顶层模块各引脚的功能:

img

3.4 编码器模块功能图

(1)CLK:50MHz的系统基准时钟输入。用CLK的上升沿作为always模块的触发信号。

(2)SW_In:拨动开关输入,共有八位。SW_In[7:0]分别连接“编码器”的输入信号x7~x0,用于模拟二进制输入。

(3)LED_Out:输出到LED灯。LED_Out[2:0]分别连接“编码器”的输出信号y2~y0,通过LED灯的点亮或熄灭来表示编码器的二进制输出。LED_Out3连接Valid,输出有效标志位,用于表明编码器的输出是否有效。只要输入的8个元素中有一个为1,输出Valid的值就为1,否则为0。LED_Out[7:4]一直输出低电平,熄灭LED7-LED4。

四、程序设计

​ 图3.5是截取自底层模块pencode_module的部分代码:

5-8:输入输出信号声明,always块的输出信号均必须定义为reg型。

​ 14-15:在always块中,将y和Valid的值初始化为“0”,这样它们就总是被赋予一定值的,否则,可能会生成一个锁存器。

​ 16-21:使用for循环实现优先编码器功能。因为for循环是从0到7的,判

断x[i]是否等于1,这将把最终i的值赋给y,因此,x[7]具有最高优先级。

img

3.5 编码器实验核心代码

​ 20:当x[7:0]!=8’b0,Valid=1’b1,此时的编码输出才是在有输入时的有效输出。如果输出y[2:0]为“000”且Valid的值为1,那么就意味着x[7:0]的输入为“0000_0001”;如果输出y[2:0]为“000”且Valid的值为0,那么就意味着x[7:0]的输入为“0000_0000”,即没有有效输入。

五、FPGA管脚配置

以下是Anlogic FPGA的IO Constraint,CLK时钟输入信号与Anlogic_FPGA开发板上的50MHz的晶振时钟相连;SW_In[7:0]输入信号分别与开发板上的SW7SW0相连;LED_Out[2:0]输出信号分别与LED2LED0相连;Valid输出信号与LED3相连。

set_pin_assignment { CLK } { LOCATION = R7; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[7] } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[0] } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[1] } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[2] } { LOCATION = B10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[3] } { LOCATION = A11; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[4] } { LOCATION = A12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[5] } { LOCATION = B12; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[6] } { LOCATION = A13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[7] } { LOCATION = A14; IOSTANDARD = LVCMOS33; }

六、实验结果

当SW7SW0均拨至DOWN时,LED2LED0全灭,且此时LED3灯灭,表明无有效输入;当SW7SW1均拨至DOWN,SW0拨至UP时,LED2LED0全灭,且此时LED3灯亮,表明存在有效输入SW_In[7:0]=8’b00000001。

当SW6,SW2,SW0均拨至UP时,因为SW6具有最高优先级,编码器输出LED_Out[2:0]=3’b110,即LED2、LED1亮,LED0灭,且此时LED3亮。

七、思考与拓展

(1)使用逻辑方程能更简单的实现不带优先编码功能的8-3编码器,请自行建立工程,实现其功能。

(2)请解释图3.9中第十行代码的含义;如果将i定义为reg型,预编译能通过吗?程序功能能实现吗?

八、实验小结

在定义信号类型时,一般有reg型与wire型。reg型即寄存器型信号,always模块的输出信号均必须定义为reg型;wire可以想象为电路内部连线,若不说明信号类型,则默认为wire型。

一、实验设计目标

在FPGA中使用行为描述语句实现3-8译码器。

二、实验设计思路

译码器电路有n个输入和2n个输出,每个输出都对应着一个可能的二进制输入。本实验设计实现一个3-8译码器,表3.1给出了该译码器的真值表。从真值表可以写出img的逻辑表达式:

img

img

img

img

img

img

img

img (3.1)

3.1 3-8译码器真值表

img img img img img img img img img img img
0 0 0 0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 1 0 0
0 1 1 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 0 0 0
1 0 1 0 0 1 0 0 0 0 0
1 1 0 0 1 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0

三、功能模块图与输入输出引脚说明

译码器工程包含顶层模块decode38与底层模块decode_module,图3.1是整个工程的模块功能图。下面介绍一下顶层模块各引脚的功能:

img

3.1 译码器模块功能图

(1)SW_In:拨动开关输入,共有三位。SW_In[2:0]分别连接“3-8译码器”的输入“a2、a1、a0”。

(2)LED_Out:输出到LED灯,共有八位。LED_Out[7:0]分别连接“3-8译码器”的输出“y7~y0”,通过8个LED灯的亮灭情况来判断二进制输入。

四、程序设计

​ 图3.2是截取自底层模块decode_module的部分代码:

5-6:输入输出信号声明。

​ 8-15:使用连续赋值语句assign实现y7~y0的逻辑表达式,见公式(3.1)。

img

3.2 逻辑门实验核心代码

五、FPGA管脚配置

以下是Anlogic FPGA的IO Constraint,SW_In[2:0]输入信号分别与开发板上的SW2SW0相连;LED_Out[7:0]输出信号分别与开发板上的LED7LED0相连。

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[7] } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[0] } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[1] } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { Sw_In[2] } { LOCATION = B10; IOSTANDARD = LVCMOS33; }

译码器实验IO Constraint

六、实验结果

当输入信号“a2、a1、a0”分别为“1、0、0”时,根据表3.1,输出信号中y4为“1”,其余全为“0”。即LED4亮,其余全灭。因篇幅有限,其他情况请自行验证。

七、思考与拓展

自行建立工程,使用case语句实现3—8译码器。

一、实验设计目标

(1)利用门电路设计实现全加器功能。

(2)通过此实验初步掌握连续赋值语句——assign语句的使用方法。

二、实验设计思路

在电路中,算术运算中的加减乘除运算,往往是分解转化为加法运算,因此,加法器是运算电路的核心。在做二进制的加法时,必须考虑低位向高位的进位。本实验设计实现一个全加器,输入信号包含两加数imgimg,以及进位输入img,输出信号包含结果位img以及进位输出img。其中,进位输入img为低一位加法运算产生的进位,进位输出img将作为高一位加法运算的进位输入。表2.1给出了对应的真值表。从真值表可以写出imgimg的逻辑表达式:

img (2.1)

img (2.2)

化简为:

img (2.3)

img (2.4)

2.1 全加器真值表

img img img img img
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1

三、功能模块图与输入输出引脚说明

全加器工程包含顶层模块adder与底层模块Adder_module,图2.6是整个工程的模块功能图。下面介绍一下顶层模块各引脚的功能:

1625721370(1)

img

2.6 全加器顶层原理图和模块功能图

(1)SW_In:拨动开关输入,共有三位。SW_In[2]、SW_In[1]和SW_In[0]分别连接“全加器”的输入信号c_in、a和b,用于模拟输入信号。

(2)LED_Out:输出到LED灯,共有两位。LED_Out[1]和LED_Out[0]分别连接“全加器”的输出信号c_out和s,通过LED灯的点亮或熄灭来表示全加器的运算结果。

四、程序设计

​ 图2.7是截取自底层模块Adder_module的部分代码:

6-10:信号输入输出端口及类型声明。

​ 12-13:这是本次实验的重要程序,用于实现全加器功能,见公式(2.3)和公式(2.4)。

img

2.7 全加器实验核心代码

五、FPGA管脚配置

下面是Anlogic FPGA的IO Constraint,SW_In[2:0]输入信号分别与MINI_FPGA开发板上的SW2、SW1和SW0相连;LED_Out[1:0]输出信号分别与开发板上的LED1~LED0相连。

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[7] } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { SW_In[0] } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { SW_In[1] } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { SW_In[2] } { LOCATION = B10; IOSTANDARD = LVCMOS33; }

六、实验结果

当SW2、SW1和SW0全部拨至“UP”位置时,此时imgimgimg均为1,全加器运算结果为imgimg,即LED1和LED0均点亮。其他情况请自行验证。

a2957cf38952b6696a5331015176e4d

七、思考与拓展

用四个全加器级联可以构成一个四位的加法器,只需将低位全加器的进位输出连接到高位全加器的进位输入即可,请编写程序在FPGA中实现四位加法器。

一、实验设计目标

在FPGA中实现基本逻辑门并验证其功能。

二、实验设计思路

本实验涉及到的基本逻辑门有“与门”、“与非门”、“或门”、“或非门”、“异或门”和“同或门”,功能简单,实验时使用2个拨动开关模拟逻辑门的输入信号,通过LED灯的点亮或熄灭来验证逻辑门的功能。

三、功能模块图与输入输出引脚说明

逻辑门工程包含顶层模块gate与底层模块Gate_module,图2.1是整个工程的模块功能图。下面介绍一下各主要引脚的功能:

​ (1)SW_In:拨动开关输入,共有两位总线。SW_In[1]和SW_In[0]分别连接“两输入逻辑门”的输入信号。

(2)LED_Out:输出到LED灯,共有六位总线。LED_Out[5:0]分别连接“同或门”、“异或门”、“或非门”、“或门”、“与非门”和“与门”的输出,通过LED灯的点亮或熄灭来表示逻辑门输出的“高”和“低”电平。

img

2.2 逻辑门模块功能图

四、程序设计

​ 图2.2是截取自底层模块Gate_module的部分代码:

img

2.2 逻辑门实验核心代码

6-7:输入输出信号声明。

​ 11-16:这是本次实验的重要程序,11-16行依次实现“与门”、“与非门”、“或门”、“或非门”、“异或门”和“同或门”功能。

五、FPGA管脚配置

下面是Anlogic_FPGA开发板的IO Constraint,SW_In[1:0]输入信号分别与Anlogic_FPGA开发板上的SW1和SW0相连;LED_Out[5:0]输出信号分别与开发板上的LED5~LED0相连。

set_pin_assignment { SW_In[0] } { LOCATION = A10; IOSTANDARD = LVCMOS33; }

set_pin_assignment { SW_In[1] } { LOCATION = A9; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[0] } { LOCATION = B14; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[1] } { LOCATION = B15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[2] } { LOCATION = B16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[3] } { LOCATION = C15; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[4] } { LOCATION = C16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[5] } { LOCATION = E13; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[6] } { LOCATION = E16; IOSTANDARD = LVCMOS33; }

set_pin_assignment { LED_Out[7] } { LOCATION = F16; IOSTANDARD = LVCMOS33; }

逻辑门实验IO Constraint

六、实验结果

当逻辑门两输入分别为“1”和“0”时,“与门”、“与非门”、“或门”、“或非门”、“异或门”和“同或门”输出分别为“0、1、1、0、1、0”,即Gate_Out[0]- Gate_Out[5] 分别为“0、1、1、0、1、0”,则LED0~LED5分别为“灭、亮、亮、灭、亮、灭”。因篇幅有限,其他情况请自行验证。