实验12-移位寄存器的设计及应用
发布时间:2025-06-27 17:54 浏览量:2
零、写在前面
在学习硬件课程的过程中,本人经常会遇到实验方面的问题:模块、仿真代码不会写,仿真、验证结果不符合预期……
本人在学习过程中得到了哔哩哔哩一些up主的帮助,因此也想分享一些知识与技巧,希望能帮到有需要的人~
一、实验目的和要求
掌握支持并行输入的移位寄存器的工作原理
掌握支持并行输入的移位寄存器的设计方法
1. 实验内容
任务一:设计8位并行输入的左移移位寄存器
任务二:设计主板16位LED灯驱动模块
任务三:设计主板8位数码管驱动模块
2. 实验原理
2.1 移位寄存器
每来一个时钟脉冲,寄存器中的数据按顺序向左或向右移动一位
· 必须采用主从触发器或边沿触发器
· 不能采用锁存器
数据移动方式:左移、右移、循环移位 数据输入输出方式
· 串行输入,串行输出
· 串行输入,并行输出
· 并行输入,串行输出
2.2 串行输入左移移位寄存器
使用D触发器构成串行输入的左移移位寄存器
2.3 带并行输入的左移移位寄存器
数据输入方式:串行输入、并行输入
2.4 带并行输入的8位左移移位寄存器
module shift_reg8b( input wire clk,S_L,s_in, input wire [7:0] p_in, output wire [7:0] Q); FD...... OR2...... AND2...... AND2...... INV......endmodule2.5 接口说明:实验板16位LED灯
实验板上,采用2个8位移位寄存器74LV164A构成16位串行左移移位寄存器,寄存器的并行输出控制16个LED灯LED0-LED15
LED_CLK: 16位LED灯模块的时钟,上升沿触发移位
LED_CLR:清零,使所有LED亮,低电平有效
LED_DO:串行移位数据输入, 0使LED亮
LED_EN: LED模块总控开关, 1为使能
用LED_CLK和LED_DO按顺序LED15,LED14,.....,LED1,LED0串行移入16位数据
LED_CLR:提供16个时钟
LED_D0:把需要显示的16位二进制数num[15:0]求反左移输出
串行数据发送完毕后要停止时钟。如何实现?
16位LED灯模块的电路原理
8位串行右移移位寄存器芯片74LS164A,可以实现串-并转换。
采用Verilog语言设计16位LED灯驱动模块,模块里实现16位并行-串行转换模块,将需要现实的16位二进制数num[15:0]求反串行左移输出到实验板上的16位LED灯模块,控制个位LED的亮暗。
串行数据发送完毕后要停止时钟,如何实现?
2.6 引脚约束:实验板16位LED灯
LED_CLK: PACKAGE_PIN = N26, IOSTANDARD = LVCMOS33; LED_CLR: PACKAGE_PIN = N24, IOSTANDARD = LVCMOS33;LED_DO: PACKAGE_PIN = M26, IOSTANDARD = LVCMOS33;LED_EN: PACKAGE_PIN = P18, IOSTANDARD = LVCMOS33;2.7 并行-串行转换器设计关键
将需要显示的16位二进制数num[15:0]从LED_D0引脚左移输出到16位LED灯模块
同时在LED_CLK引脚上提供16个周期的时钟
16位数据移位完成后要停止时钟,避免把之前的数据移出16位LED等模块
采用门控时钟方式给LED_CLK提供时钟:
assign LED_CLK = clk | finish;
finish为转换结束标志,为1表示转换结束
如何产生finish?
计数加比较的方式,硬件实现成本非常高
是否可以在移位的同时产生finish信号?
2.8 8位并行-串行转换器
start启动信号拉高以后,产生一个时钟周期宽度的并行加载信号,加载并行输入D0-D7,然后启动左移串行输出,等D0输出后自动停止移位操作
finish输出为0表示当前正在进行左移,为1表示移位停止
a.没有启动命令时
b.有启动命令时
S_L为一个周期的正脉冲
在S_L端为逻辑1时,移位寄存器并行输入,加载的数据里P0为0,使得Q0为0,finish输出0。
在S_L端为逻辑0时,移位寄存器开始左移,移入的Q0为1,原来的Q0的“0”移到Q1,finish依然输出0。
移位即将完成时,最低位数据移动到Q8,Q7为0,finish依然输出0。
转换完成时,Q7-Q0全部为1,finish输出1,标志转换结束。
2.9 16位LED灯驱动模块
构造16位并行-串行转换器
SW[15]拨动一次,产生脉冲宽度为1个周期的信号S_L
采用门控始终方式给LED_CLK提供时钟
assign LED_CLK = clk | finish
2.10 接口说明:主板7段数码管
实验板上,8个74LS164A的并行输出控制8个7段数码管的段码
2.11 引脚约束:主板七段数码管
SEGCLK : PACKAGE_PIN = M24, IOSTANDARD = LVCMOS33; SEGCLR : PACKAGE_PIN = M20, IOSTANDARD = LVCMOS33; SEGDT : PACKAGE_PIN = L24, IOSTANDARD = LVCMOS33; SEGEN : PACKAGE_PIN = R18, IOSTANDARD = LVCMOS33;SEGCLK:8位七段数码管模块的时钟,上升沿触发移位
SEGCLR:清零,所有段亮,低电平有效
SEGDT:串行移位数据输入,0亮
SEGEN: 8位七段数码管模块总控开关,1为使能
用SEGCLR和SEGDT按顺序SEG7_DP,SEG7_g,SEG7_f,……,SEG0_b,SEG0_a串行移入64位数据
2.12 8位数码管驱动模块
主板上8位数码管显示采用的是静态显示,不是动态扫描方式
实验板上用8个74LV164A构成64位串-并转换模块,并行输出控制8个7段数码管
通过SEGCLR和SEGDT串行接收8个数码管*8段码,共计64位数据,移位先后顺序为SEG7_DP,SEG7_g,SEG7_f,……,SEG0_b,SEG0_a
数码管共阳接法,段码为0时对应段亮
参考16位LED驱动模块,扩展设计8位数码管驱动模块
注意发送完成后停止时钟
1. 任务一:设计8位带并行输入的左移移位寄存器
1.1 新建工程Shift_Register8b,用结构化描述设计
模块Verilog代码如下所示:
module Shift_Register8b( input wire clk, input wire S_L,// "bing hang shu ru ming ling" input wire shift_in,// "chuan hang" input input wire [7:0] par_in,// "bing hang" input output wire [7:0] Q// output // Q7,Q6,......,Q1,Q0,from left to right); // according to principle graph,S_L = 1 means "bing hang",S_L = 0 means "chuan hang" wire [7:0] QF; wire [7:0] D; wire _SL; not n0(_SL,S_L); CreatingDC_0(.shift_in(shift_in),._SL(_SL),.par_in(par_in[0]),.S_L(S_L),.D(D[0])); Triggered_D D_0(.SF(1'b1),.Cp(clk),.D(D[0]),.RF(1'b1),.Q(Q[0]),.QF(QF[0])); CreatingD C_1(.shift_in(Q[0]),._SL(_SL),.par_in(par_in[1]),.S_L(S_L),.D(D[1])); Triggered_D D_1(.SF(1'b1),.RF(1'b1),.D(D[1]),.Cp(clk),.Q(Q[1]),.QF(QF[1])); CreatingD C_2(.shift_in(Q[1]),._SL(_SL),.par_in(par_in[2]),.S_L(S_L),.D(D[2])); Triggered_D D_2(.SF(1'b1),.RF(1'b1),.D(D[2]),.Cp(clk),.Q(Q[2]),.QF(QF[1])); CreatingD C_3(.shift_in(Q[2]),._SL(_SL),.par_in(par_in[3]),.S_L(S_L),.D(D[3])); Triggered_D D_3(.SF(1'b1),.RF(1'b1),.D(D[3]),.Cp(clk),.Q(Q[3]),.QF(QF[3])); CreatingD C_4(.shift_in(Q[3]),._SL(_SL),.par_in(par_in[4]),.S_L(S_L),.D(D[4])); Triggered_D D_4(.SF(1'b1),.RF(1'b1),.D(D[4]),.Cp(clk),.Q(Q[4]),.QF(QF[4])); CreatingD C_5(.shift_in(Q[4]),._SL(_SL),.par_in(par_in[5]),.S_L(S_L),.D(D[5])); Triggered_D D_5(.SF(1'b1),.RF(1'b1),.D(D[5]),.Cp(clk),.Q(Q[5]),.QF(QF[5])); CreatingD C_6(.shift_in(Q[5]),._SL(_SL),.par_in(par_in[6]),.S_L(S_L),.D(D[6])); Triggered_D D_6(.SF(1'b1),.RF(1'b1),.D(D[6]),.Cp(clk),.Q(Q[6]),.QF(QF[6])); CreatingD C_7(.shift_in(Q[6]),._SL(_SL),.par_in(par_in[7]),.S_L(S_L),.D(D[7])); Triggered_D D_7(.SF(1'b1),.RF(1'b1),.D(D[7]),.Cp(clk),.Q(Q[7]),.QF(QF[7]));endmodule1.2 进行波形仿真
仿真代码如下所示:
module Shift_Register8bit_testbench; reg clk; reg S_L; reg shift_in; reg [7:0] par_in; wire [7:0] Q; Shift_Register8b Shift_Register8b_uut( .clk(clk), .S_L(S_L),// "bing hang shu ru ming ling" .shift_in(shift_in),// "chuan hang" input .par_in(par_in),// "bing hang" input .Q(Q) ); initial forever begin clk = 0;#25;clk = 1;#25; end initial begin par_in = 8'b00000000; shift_in = 0; S_L = 0;// means "chuan hang" end initial begin // at 0 ns #90; shift_in = 1; // when at 90 ns,provide signal to be passed // at 90 ns #410; // at 410 ns #15; S_L = ~S_L; shift_in = 0; par_in = 8'b01010101; // at 425 ns endendmodule所得仿真波形如下所示:
(仿真波形略)
(具体模块代码、仿真代码、仿真波形分析详见“四、实验结果分析”部分。)
2. 任务二:设计主板16位LED驱动模块
2.1 采用Digital设计电路并仿真
在Digital中绘制Shift_Register8b、Shift_Register9b模块原理图,如下图所示:
Shift_Register8b原理图:
Shift_Register9b原理图:
通过Digital进行仿真
(Digital仿真结果略)
2.2 设计主板16位LED驱动模块
2.2.1 新建工程LEDP2S,采用行为描述设计
简化实验12任务一的电路,设计4个可设自增的4位寄存器,汇总成总线num[15:0],显示在小实验板的4位七段数码管上
利用1个Shfit_Register8b模块和1个Shift_Register9b模块,设计16位LED驱动模块LED_DRV
自行设计激励代码,对驱动模块进行仿真
Top模块Verilog代码
module Top( input wire clk, input wire [3:0] BTN, input wire [15:0] SW, // SW[15] is used to start shift,SW[3:0] are used to contrl add or sub // SW[7:4] are used to control clear output wire [3:0] AN, output wire [7:0] SEGMENT, output wire BTNX4,// very important,without it the button will not work output wire LED_CLK, output wire LED_CLR, output wire LED_EN, output wire LED_D0 ); wire [3:0] A_Load,B_Load,C_Load,D_Load; wire [15:0] I,Co; wire [3:0] A_IN,B_IN,C_IN,D_IN; wire [3:0] A_OUT,B_OUT,C_OUT,D_OUT; wire [31:0] clk_div; wire [15:0] num; wire [15:0] _num; clkdiv c0(.clk(clk), .rst(1'b0), .clk_div(clk_div));// creating a clokc signal // register A Load_Gen LGA(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(BTN[3]),.Load_out(A_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegA(.clk(clk), .IN(A_IN), .Load(A_Load), .OUT(A_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASA(.A(A_OUT), .B(4'b0001), .Ctrl(SW[3]), .S(I[15:12]),.Co(Co[15:12])); assign A_IN = (SW[7] == 1'b0) ? I[15:12]: 4'b0000;// used as 2-to-1 multiplexer // register B Load_Gen LGB(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(BTN[2]),.Load_out(B_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegB(.clk(clk), .IN(B_IN), .Load(B_Load), .OUT(B_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASB(.A(B_OUT), .B(4'b0001), .Ctrl(SW[2]), .S(I[11:8]),.Co(Co[11:8])); assign B_IN = (SW[6] == 1'b0) ? I[11:8]: 4'b0000;// used as 2-to-1 multiplexer // register C Load_Gen LGC(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(BTN[1]),.Load_out(C_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegC(.clk(clk), .IN(C_IN), .Load(C_Load), .OUT(C_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASC(.A(C_OUT), .B(4'b0001), .Ctrl(SW[1]), .S(I[7:4]),.Co(Co[7:4])); assign C_IN = (SW[5] == 1'b0) ? I[7:4]: 4'b0000;// used as 2-to-1 multiplexer // register D Load_Gen LGD(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(BTN[0]),.Load_out(D_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegD(.clk(clk), .IN(D_IN), .Load(D_Load), .OUT(D_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASD(.A(D_OUT), .B(4'b0001), .Ctrl(SW[0]), .S(I[3:0]),.Co(Co[3:0])); assign D_IN = (SW[4] == 1'b0) ? I[3:0]: 4'b0000;// used as 2-to-1 multiplexer assign num = {A_OUT,B_OUT,C_OUT,D_OUT};// 3,2,1,04'b0100,4'b0011,4'b0010,4'b0001 assign BTNX4 = 1'b0; DispNum d0(.scan(clk_div[18:17]), .HEXS(num), .LES(4'b0), .point(4'b0), .AN(AN), .SEGMENT(SEGMENT));//bingo // simulation 1:0 can slow;running 18:17 can not slow //AN[0]-num[3:0] and so on assign _num = ~num; LED_DRV LD(.clear(SW[14]),.clk(clk),.start(SW[15]),.LED_CLK(LED_CLK),.LED_CLR(LED_CLR),.LED_D0(LED_D0),.LED_EN(LED_EN),.LED(_num)); endmodule其中核心模块LED_DRV代码如下所示:
module LED_DRV( input wire clear, input wire clk, input wire start, input wire [15:0] LED, output wire LED_CLK, output wire LED_CLR, output wire LED_EN, output wire LED_D0 ); wire S_L; wire [16:0] Q;//Q[8] is the ser_out wire finish; wire finish1,finish2; assign LED_CLR = clear; assign LED_EN = 1'b1; Load_Gen LGLED_1(.clk(clk),.clk_1ms(1'b0),.btn_in(start),.Load_out(S_L)); Shift_Register8bit SR8(.clk(clk),.S_L(S_L),.par_in({LED[6:0],1'b0}),.shift_in(1'b1),.Q(Q[7:0])); assign finish1 = Q[0] & Q[1] & Q[2] & Q[3] & Q[4] & Q[5] & Q[6] & Q[7]; Shift_Register9bit SR9(.clk(clk),.S_L(S_L),.par_in({LED[15:0],1'b0}),.shift_in(Q[7]),.Q(Q[16:8])); assign finish2 = Q[8] & Q[9] & Q[10] & Q[11] & Q[12] & Q[13] & Q[14] & Q[15] & Q[16]; assign finish = finish1 & finish2; assign LED_CLK = clk | finish;endmodule 2.2.2 仿真验证
仿真代码如下所示:
module Top_testbench; reg clk; reg [3:0] BTN; reg [15:0] SW; wire [3:0] AN; wire [7:0] SEGMENT; wire BTNX4; wire LED_CLK; wire LED_CLR; wire LED_D0; wire LED_EN; Top Top_uut(.clk(clk),.BTN(BTN),.SW(SW),.AN(AN),.SEGMENT(SEGMENT),.BTNX4(BTNX4),.LED_CLK(LED_CLK),.LED_CLR(LED_CLR),.LED_EN(LED_EN),.LED_D0(LED_D0)); initial begin BTN = 4'b0000; SW = 16'b0000000000000000; end initial forever begin clk = 0; #25; clk = 1; #25; end // 一开始有一个加载的过程,体现为灯一开始全亮,然后逐个熄灭 initial begin #100; BTN = 4'b1111; // at 100 ns #75; BTN = 4'b0000; // at 175 ns #25; BTN = 4'b1110; // at 200 ns #75; BTN = 4'b0000; // at 275 ns #25; BTN = 4'b1100; // at 300 ns #75; BTN = 4'b0000; // at 375 ns #25; BTN = 4'b1000; // at 400 ns #75; BTN = 4'b0000; // at 475 ns #325; SW = 16'b1000000000000000; // at 800 ns end endmodule2.2.3 下载验证
典型图片如下图所示:
clear
(图片略)
(图片略)
4231
(图片略)
引脚约束文件如下:
create_clock -name clk100MHZ -period 10.0 [get_ports clk]set_property PACKAGE_PIN AC18 [get_ports clk]set_property IOSTANDARD LVCMOS18 [get_ports clk]# Buttonset_property PACKAGE_PIN W14 [get_ports BTN[0]]set_property PACKAGE_PIN V14 [get_ports BTN[1]]set_property PACKAGE_PIN V19 [get_ports BTN[2]]set_property PACKAGE_PIN V18 [get_ports BTN[3]]set_property PACKAGE_PIN W16 [get_ports BTNX4]set_property IOSTANDARD LVCMOS18 [get_ports BTN[0]]set_property IOSTANDARD LVCMOS18 [get_ports BTN[1]]set_property IOSTANDARD LVCMOS18 [get_ports BTN[2]]set_property IOSTANDARD LVCMOS18 [get_ports BTN[3]]set_property IOSTANDARD LVCMOS18 [get_ports BTNX4]set_property PACKAGE_PIN AA10 [get_ports {SW[0]}]set_property PACKAGE_PIN AB10 [get_ports {SW[1]}]set_property PACKAGE_PIN AA13 [get_ports {SW[2]}]set_property PACKAGE_PIN AA12 [get_ports {SW[3]}]set_property PACKAGE_PIN Y13 [get_ports {SW[4]}]set_property PACKAGE_PIN Y12 [get_ports {SW[5]}]set_property PACKAGE_PIN AD11 [get_ports {SW[6]}]set_property PACKAGE_PIN AD10 [get_ports {SW[7]}]set_property PACKAGE_PIN AE10 [get_ports {SW[8]}]set_property PACKAGE_PIN AE12 [get_ports {SW[9]}]set_property PACKAGE_PIN AF12 [get_ports {SW[10]}]set_property PACKAGE_PIN AE8 [get_ports {SW[11]}]set_property PACKAGE_PIN AF8 [get_ports {SW[12]}]set_property PACKAGE_PIN AE13 [get_ports {SW[13]}]set_property PACKAGE_PIN AF13 [get_ports {SW[14]}]set_property PACKAGE_PIN AF10 [get_ports {SW[15]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[0]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[1]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[2]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[3]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[4]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[5]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[6]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[7]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[8]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[9]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[10]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[11]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[12]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[13]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[14]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[15]}]# 7-Segment LEDset_property PACKAGE_PIN AB22 [get_ports {SEGMENT[0]}]set_property PACKAGE_PIN AD24 [get_ports {SEGMENT[1]}]set_property PACKAGE_PIN AD23 [get_ports {SEGMENT[2]}]set_property PACKAGE_PIN Y21 [get_ports {SEGMENT[3]}]set_property PACKAGE_PIN W20 [get_ports {SEGMENT[4]}]set_property PACKAGE_PIN AC24 [get_ports {SEGMENT[5]}]set_property PACKAGE_PIN AC23 [get_ports {SEGMENT[6]}]set_property PACKAGE_PIN AA22 [get_ports {SEGMENT[7]}]set_property PACKAGE_PIN AD21 [get_ports {AN[0]}]set_property PACKAGE_PIN AC21 [get_ports {AN[1]}]set_property PACKAGE_PIN AB21 [get_ports {AN[2]}]set_property PACKAGE_PIN AC22 [get_ports {AN[3]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[0]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[1]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[2]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[3]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[4]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[5]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[6]}]set_property IOSTANDARD LVCMOS33 [get_ports {SEGMENT[7]}]set_property IOSTANDARD LVCMOS33 [get_ports {AN[0]}]set_property IOSTANDARD LVCMOS33 [get_ports {AN[1]}]set_property IOSTANDARD LVCMOS33 [get_ports {AN[2]}]set_property IOSTANDARD LVCMOS33 [get_ports {AN[3]}]set_property PACKAGE_PIN N26 [get_ports LED_CLK]set_property PACKAGE_PIN N24 [get_ports LED_CLR]set_property PACKAGE_PIN M26 [get_ports LED_D0]set_property PACKAGE_PIN P18 [get_ports LED_EN]set_property IOSTANDARD LVCMOS33 [get_ports LED_CLK]set_property IOSTANDARD LVCMOS33 [get_ports LED_CLR]set_property IOSTANDARD LVCMOS33 [get_ports LED_D0]set_property IOSTANDARD LVCMOS33 [get_ports LED_EN] (具体模块代码、仿真代码、仿真波形、下载验证结果分析详见“四、实验结果分析”部分。)
3. 任务三:设计主板8位数码管驱动模块
3.1 新建工程SEG_P2S。采用行为描述设计
调用8个MyMC14495模块进行段码译码利用7个shfit_reg8b模块和1个shfit_reg9b模块,设计主板8位数码管驱动模块SEG_DRV
自行设计激励代码,对驱动模块进行仿真
Top模块Verilog代码如下所示:
module Top( input wire clk, input wire [15:0] SW, // SW[15] is used to start shift,SW[8] are used to contrl add or sub // SW[7:0] are used to operater,SW[9] is used to control clear output wire SEG_CLK, output wire SEG_CLR, output wire SEG_D0, output wire SEG_EN ); wire A_Load,B_Load,C_Load,D_Load,E_Load,F_Load,G_Load,H_Load; wire [31:0] I,Co; wire [3:0] A_IN,B_IN,C_IN,D_IN,E_IN,F_IN,G_IN,H_IN; wire [3:0] A_OUT,B_OUT,C_OUT,D_OUT,E_OUT,F_OUT,G_OUT,H_OUT; wire [31:0] clk_div; wire [63:0] num; wire [31:0] out; wire start; clkdiv c0(.clk(clk), .rst(1'b0), .clk_div(clk_div));// creating a clokc signal // from left to right A.....H // register A Load_Gen LGA(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[7]),.Load_out(A_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegA(.clk(clk), .IN(A_IN), .Load(A_Load), .OUT(A_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASA(.A(A_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[31:28]),.Co(Co[31:28])); assign A_IN = (SW[9] == 1'b0) ? I[31:28]: 4'b0000;// used as 2-to-1 multiplexer // condition ? truevalue : falsevalue // register B Load_Gen LGB(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[6]),.Load_out(B_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegB(.clk(clk), .IN(B_IN), .Load(B_Load), .OUT(B_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASB(.A(B_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[27:24]),.Co(Co[27:24])); assign B_IN = (SW[9] == 1'b0) ? I[27:24]: 4'b0000;// used as 2-to-1 multiplexer // register C Load_Gen LGC(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[5]),.Load_out(C_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegC(.clk(clk), .IN(C_IN), .Load(C_Load), .OUT(C_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASC(.A(C_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[23:20]),.Co(Co[23:20])); assign C_IN = (SW[9] == 1'b0) ? I[23:20]: 4'b0000;// used as 2-to-1 multiplexer // register D Load_Gen LGD(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[4]),.Load_out(D_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegD(.clk(clk), .IN(D_IN), .Load(D_Load), .OUT(D_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASD(.A(D_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[19:16]),.Co(Co[19:16])); assign D_IN = (SW[9] == 1'b0) ? I[19:16]: 4'b0000;// used as 2-to-1 multiplexer // register E Load_Gen LGE(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[3]),.Load_out(E_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegE(.clk(clk), .IN(E_IN), .Load(E_Load), .OUT(E_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASE(.A(E_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[15:12]),.Co(Co[15:12])); assign E_IN = (SW[9] == 1'b0) ? I[15:12]: 4'b0000;// used as 2-to-1 multiplexer // register F Load_Gen LGF(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[2]),.Load_out(F_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegF(.clk(clk), .IN(F_IN), .Load(F_Load), .OUT(F_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASF(.A(F_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[11:8]),.Co(Co[11:8])); assign F_IN = (SW[9] == 1'b0) ? I[11:8]: 4'b0000;// used as 2-to-1 multiplexer // register G Load_Gen LGG(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[1]),.Load_out(G_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegG(.clk(clk), .IN(G_IN), .Load(G_Load), .OUT(G_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASG(.A(G_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[7:4]),.Co(Co[7:4])); assign G_IN = (SW[9] == 1'b0) ? I[7:4]: 4'b0000;// used as 2-to-1 multiplexer // register H Load_Gen LGH(.clk(clk), .clk_1ms(clk_div[17]), .btn_in(SW[0]),.Load_out(H_Load)); // why choose clk_div[17]? because it is near to 1ms?we need to consider clk MyRegister4b RegH(.clk(clk), .IN(H_IN), .Load(H_Load), .OUT(H_OUT)); // note that we set A_OUT to 0 in MyRegister module AddSub4b ASH(.A(H_OUT), .B(4'b0001), .Ctrl(SW[8]), .S(I[3:0]),.Co(Co[3:0])); assign H_IN = (SW[9] == 1'b0) ? I[3:0]: 4'b0000;// used as 2-to-1 multiplexer assign out = {A_OUT,B_OUT,C_OUT,D_OUT,E_OUT,F_OUT,G_OUT,H_OUT}; MyMC14495 MA(.D3(A_OUT[3]),.D2(A_OUT[2]),.D1(A_OUT[1]),.D0(A_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[56]),.b(num[57]),.c(num[58]),.d(num[59]),.e(num[60]),.f(num[61]),.g(num[62]),.p(num[63])); MyMC14495 MB(.D3(B_OUT[3]),.D2(B_OUT[2]),.D1(B_OUT[1]),.D0(B_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[48]),.b(num[49]),.c(num[50]),.d(num[51]),.e(num[52]),.f(num[53]),.g(num[54]),.p(num[55])); MyMC14495 MC(.D3(C_OUT[3]),.D2(C_OUT[2]),.D1(C_OUT[1]),.D0(C_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[40]),.b(num[41]),.c(num[42]),.d(num[43]),.e(num[44]),.f(num[45]),.g(num[46]),.p(num[47])); MyMC14495 MD(.D3(D_OUT[3]),.D2(D_OUT[2]),.D1(D_OUT[1]),.D0(D_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[32]),.b(num[33]),.c(num[34]),.d(num[35]),.e(num[36]),.f(num[37]),.g(num[38]),.p(num[39])); MyMC14495 ME(.D3(E_OUT[3]),.D2(E_OUT[2]),.D1(E_OUT[1]),.D0(E_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[24]),.b(num[25]),.c(num[26]),.d(num[27]),.e(num[28]),.f(num[29]),.g(num[30]),.p(num[31])); MyMC14495 MF(.D3(F_OUT[3]),.D2(F_OUT[2]),.D1(F_OUT[1]),.D0(F_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[16]),.b(num[17]),.c(num[18]),.d(num[19]),.e(num[20]),.f(num[21]),.g(num[22]),.p(num[23])); MyMC14495 MG(.D3(G_OUT[3]),.D2(G_OUT[2]),.D1(G_OUT[1]),.D0(G_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[8]),.b(num[9]),.c(num[10]),.d(num[11]),.e(num[12]),.f(num[13]),.g(num[14]),.p(num[15])); MyMC14495 MH(.D3(H_OUT[3]),.D2(H_OUT[2]),.D1(H_OUT[1]),.D0(H_OUT[0]),.LE(1'b0),.point(1'b1),.a(num[0]),.b(num[1]),.c(num[2]),.d(num[3]),.e(num[4]),.f(num[5]),.g(num[6]),.p(num[7])); GenerateStart G0(.clk(clk),.sw1(SW[0]),.sw2(SW[1]),.sw3(SW[2]),.sw4(SW[3]),.sw5(SW[4]),.sw6(SW[5]),.sw7(SW[6]),.sw8(SW[7]),.start(start)); LED_DRV LD(.clk(clk),.start(start),.clear(SW[14]),.SEG(num),.SEG_CLK(SEG_CLK),.SEG_CLR(SEG_CLR),.SEG_D0(SEG_D0),.SEG_EN(SEG_EN)); endmodule为了实现每次拨动相关的开关即可更新实验板上数码管显示的数值,使用GenerateStart模块实现每次拨动开关都会产生一个更新信号的功能。具体代码如下所示:
module GenerateStart( input wire clk, input wire sw1, input wire sw2, input wire sw3, input wire sw4, input wire sw5, input wire sw6, input wire sw7, input wire sw8, output reg start ); wire mark; reg mark_old; assign mark = sw1 | sw2 | sw3 | sw4 | sw5 | sw6 | sw7 | sw8; always @(posedge clk) begin mark_old3.2 仿真验证
仿真代码如下所示:
module Top_testbench; reg clk; reg [15:0] SW; wire SEG_CLK; wire SEG_CLR; wire SEG_D0; wire SEG_EN; Top Top_uut(.clk(clk),.SW(SW),.SEG_CLK(SEG_CLK),.SEG_CLR(SEG_CLR),.SEG_D0(SEG_D0),.SEG_EN(SEG_EN)); initial begin SW = 16'b0000000000000000; end initial forever begin clk = 0; #25; clk = 1; #25; end initial begin #100; SW = 16'b0000000010101111; // 10101111 // at 100 ns #75; SW = 16'b0000000000000000; // at 175 ns #25; SW = 16'b0000000010001101; // 20102212 // at 200 ns #75; SW = 16'b0000000000000000; // at 275 ns #25; SW = 16'b0000000010001100; // 30103312 // at 3000 ns #75; SW = 16'b0000000000000000; // at 375 ns #25; SW = 16'b0000000010001100; // 40104412 // at 400 ns #75; SW = 16'b0000000000000000; // at 475 ns #25; SW = 16'b0000000000000100; // 40104512 // at 500 ns; #75; SW = 16'b0000000000000000; // at 575 ns #25; SW = 16'b0000000000000100; // 40104612 // at 600 ns #75; SW = 16'b0000000000000000; // at 675 ns #25; SW = 16'b0000000000000100; // 40104712 // at 700 ns #75; SW = 16'b0000000000000000; // at 775 ns #225; SW = 16'b1000000000000000; // at 1000 ns #75; SW = 16'b0000000000000000; // at 1075 ns endendmodule 所得仿真波形如下所示:
(图片略)
3.3 下载验证
典型图片如下所示:
(图片略)
引脚约束文件如下所示:
create_clock -name clk100MHZ -period 10.0 [get_ports clk]set_property PACKAGE_PIN AC18 [get_ports clk]set_property IOSTANDARD LVCMOS18 [get_ports clk]# Switchset_property PACKAGE_PIN AA10 [get_ports {SW[0]}]set_property PACKAGE_PIN AB10 [get_ports {SW[1]}]set_property PACKAGE_PIN AA13 [get_ports {SW[2]}]set_property PACKAGE_PIN AA12 [get_ports {SW[3]}]set_property PACKAGE_PIN Y13 [get_ports {SW[4]}]set_property PACKAGE_PIN Y12 [get_ports {SW[5]}]set_property PACKAGE_PIN AD11 [get_ports {SW[6]}]set_property PACKAGE_PIN AD10 [get_ports {SW[7]}]set_property PACKAGE_PIN AE10 [get_ports {SW[8]}]set_property PACKAGE_PIN AE12 [get_ports {SW[9]}]set_property PACKAGE_PIN AF12 [get_ports {SW[10]}]set_property PACKAGE_PIN AE8 [get_ports {SW[11]}]set_property PACKAGE_PIN AF8 [get_ports {SW[12]}]set_property PACKAGE_PIN AE13 [get_ports {SW[13]}]set_property PACKAGE_PIN AF13 [get_ports {SW[14]}]set_property PACKAGE_PIN AF10 [get_ports {SW[15]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[0]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[1]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[2]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[3]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[4]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[5]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[6]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[7]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[8]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[9]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[10]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[11]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[12]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[13]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[14]}]set_property IOSTANDARD LVCMOS15 [get_ports {SW[15]}]# 7-Segment Serialset_property PACKAGE_PIN M24 [get_ports SEG_CLK]set_property PACKAGE_PIN M20 [get_ports SEG_CLR]set_property PACKAGE_PIN L24 [get_ports SEG_D0]set_property PACKAGE_PIN R18 [get_ports SEG_EN]set_property IOSTANDARD LVCMOS33 [get_ports SEG_CLK]set_property IOSTANDARD LVCMOS33 [get_ports SEG_CLR]set_property IOSTANDARD LVCMOS33 [get_ports SEG_D0]set_property IOSTANDARD LVCMOS33 [get_ports SEG_EN] (具体模块代码、仿真代码、仿真波形、下载验证结果分析详见四、实验结果分析部分。)
(该部分略,结合上面所编写的模块代码、仿真代码、引脚约束文件以及所得仿真结果、下载验证结果进行分析即可)
(该部分略,结合自己预习、实验、分析过程编写即可)