概述
文章目录
- Verilog HDL 实验
- 实验一 Modelsim的使用
- 1.实现一个2选1数据选择器
- 2.D触发器
- 3.设计4选1的数据选择器电路
- 实验二 数据选择器的设计与vivado集成开发环境
- 1.用VerilogHDL语言设计实现4位二选一数据选择器电路,完成功能仿真
- 2.设计顶层电路,关联外设,在vivado下完成综合等设计步骤,下载至Sword实验系统验证电路功能,熟悉vivado操作流程。
- 实验三 数字加法器的设计
- 1.用VerilogHDL语言设计实现4位串行数字加法器和4位并行加法器,在ModelSim上仿真实现。
- 2.生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
- 实验四 数码管显示
- 1.采用VerilogHDL语言编程实现输入4位BCD码,输出是8位数码管显示码。
- 2.用Modelsim进行功能仿真。
- 实验五 计数/定时器的设计
- 1.用VerilogHDL语言设计实现32位加法/减法二进制计数器,在ModelSim上实现功能仿真。
- 2. 生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
- 实验六 移位寄存器的设计
- 1.用VerilogHDL语言设计实现8位带并行输入的右移移位寄存器,在ModelSim上实现功能仿真。
- 2.生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
- 实验七 有限状态机设计
- 1.理解并掌握检测连续接收“111”的Moore型和Mealy型有限状态机设计
- 2. 设计并实现掌握检测连续接收“1111”的Moore型和Mealy型状态机设计。
- 3.在完成基本实验的基础上,尝试设计检测接收“1011”的Moore型和Mealy型有限状态机的状态转移图。然后编写代码,在modelsim上仿真测试验证结果。
- 实验八 有限状态机设计
- 1. 用Verilog HDL设计深度为32、位宽为8 bit的单端口RAM,在Modelsim上仿真测试。
- 2.用Verilog HDL设计深度为8、位宽为8 bit的ROM。在Modelsim上仿真测试。
- 3.用Xilinx ISE/Vivado 生成单端口RAM的IP,并编写测试文件,调试通过。
- 4. 用Xilinx ISE/Vivado 生成单端口ROM的IP,并编写测试文件,调试通过。
- 5.将设计的RAM下载到FPGA板子上验证。
Verilog HDL 实验
实验一 Modelsim的使用
1.实现一个2选1数据选择器
2.D触发器
3.设计4选1的数据选择器电路
实验二 数据选择器的设计与vivado集成开发环境
1.用VerilogHDL语言设计实现4位二选一数据选择器电路,完成功能仿真
2.设计顶层电路,关联外设,在vivado下完成综合等设计步骤,下载至Sword实验系统验证电路功能,熟悉vivado操作流程。
实验三 数字加法器的设计
1.用VerilogHDL语言设计实现4位串行数字加法器和4位并行加法器,在ModelSim上仿真实现。
2.生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
实验四 数码管显示
1.采用VerilogHDL语言编程实现输入4位BCD码,输出是8位数码管显示码。
2.用Modelsim进行功能仿真。
3.分别设计4位BCD码自动生成模块和BCD码的译码模块。
4.在顶层文件将2个电路模块实例化,并进行相应的连线。
5. 在顶层文件将2个电路模块实例化,并进行相应的连线。
实验五 计数/定时器的设计
1.用VerilogHDL语言设计实现32位加法/减法二进制计数器,在ModelSim上实现功能仿真。
2. 生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
实验六 移位寄存器的设计
1.用VerilogHDL语言设计实现8位带并行输入的右移移位寄存器,在ModelSim上实现功能仿真。
2.生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
实验七 有限状态机设计
1.理解并掌握检测连续接收“111”的Moore型和Mealy型有限状态机设计
parameter ST0 = 4‘b000; //接收到零个1的状态
parameter ST1 = 4’b001; //接收到一个1的状态
parameter ST2 = 4‘b010; //接收到两个1的状态
parameter ST3 = 4’b100; //接收到三个1的状态
2. 设计并实现掌握检测连续接收“1111”的Moore型和Mealy型状态机设计。
要求:画出Moore型和Mealy型的状态转移图,并编写代码在modelsim上仿真实现。
3.在完成基本实验的基础上,尝试设计检测接收“1011”的Moore型和Mealy型有限状态机的状态转移图。然后编写代码,在modelsim上仿真测试验证结果。
实验八
1.用Verilog HDL设计深度为32、位宽为8 bit的单端口RAM,在Modelsim上仿真测试。
2.用Verilog HDL设计深度为8、位宽为8 bit的ROM。在Modelsim上仿真测试。
3.用Xilinx ISE/Vivado 生成单端口RAM的IP,并编写测试文件,调试通过。
4.用Xilinx ISE/Vivado 生成单端口ROM的IP,并编写测试文件,调试通过。
5.用Xilinx ISE/Vivado 生成单端口ROM的IP,并编写测试文件,调试通过。
实验一 Modelsim的使用
1.实现一个2选1数据选择器
设计代码
module mux21(in1,in2,sel,out);
input[3:0]in1,in2;
input sel;
output[3:0]out;
wire[3:0]out;
assign out = (!sel)?in1:in2;
endmodule
测试代码
module mux21_tb;
reg in1,in2;
reg sel;
wire out;
mux21 uut(.in1(in1), .in2(in2),.sel(sel),.out(out));
initial
begin
in1 = 0; in2 = 0; sel = 0;
#100 in1 = 1; in2 = 0; sel = 0;
#100 in1 = 1; in2 = 1; sel = 1;
#100 in1 = 0; in2 = 1; sel = 1;
end
endmodule
2.D触发器
设计代码
module dff(din,clk,q);
input din,clk;
output q;
reg q;
always @(posedge clk)
q<=din;
endmodule
测试代码
`timescale 1ns/1ns
module dff_tb;
reg clk,data_in;
wire data_out;
dff U1(data_in,clk,data_out);
always #5 clk=~clk;
initial
begin
clk=0;
data_in=0;
#20 data_in=1;
#20 data_in=0;
#20 data_in=1;
#15 data_in=0;
#15 data_in=1;
end
endmodule
3.设计4选1的数据选择器电路
设计代码
module mux41(
input wire in0,
input wire in1,
input wire in2,
input wire in3,
input wire [1:0] sel,
output reg out);
always@(*)
case(sel)
2'b00: out=in0;
2'b01: out=in1;
2'b10: out=in2;
2'b11: out=in3;
default: out=1'b0;
endcase
endmodule
测试代码
module mux41_tb;
reg in0,in1,in2,in3;
reg [1:0] sel;
wire out;
mux41 uut(.in0(in0), .in1(in1), .in2(in2), .in3(in3),
.sel(sel), .out(out));
initial
begin
in0=0;in1=0;in2=0;in3=0; sel=2'b00;
#100 in0=1;in1=0;in2=0;in3=0; sel=2'b00;
#100 in0=1;in1=0;in2=0;in3=0; sel=2'b01;
#100 in0=1;in1=1;in2=0;in3=0; sel=2'b01;
#100 in0=1;in1=1;in2=0;in3=0; sel=2'b10;
#100 in0=1;in1=1;in2=1;in3=0; sel=2'b10;
#100 in0=1;in1=1;in2=1;in3=0; sel=2'b11;
#100 in0=1;in1=1;in2=1;in3=1; sel=2'b11;
end
endmodule
实验二 数据选择器的设计与vivado集成开发环境
1.用VerilogHDL语言设计实现4位二选一数据选择器电路,完成功能仿真
设计代码
module mux21(in1,in2,sel,out);
input[3:0]in1,in2;
input sel;
output[3:0]out;
assign out = (!sel)?in1:in2;
endmodule
2.设计顶层电路,关联外设,在vivado下完成综合等设计步骤,下载至Sword实验系统验证电路功能,熟悉vivado操作流程。
Vivado顶层代码
`timescale 1ns / 1ps
module Prep_IO(input wire clk_100mhz,
input wire[15:0]SW,
output wire led_clk,
output wire led_clrn,
output wire led_sout,
output wire LED_PEN
);
wire[31:0]Div;
wire[15:0]LED_DATA;
wire CK;
wire[3:0]out;
mux21 u1(SW[0],SW[1],SW[2],out);
clk_div U8(clk_100mhz,1'b0,SW[2],Div,CK);
LED_P2S #(.DATA_BITS(16),.DATA_COUNT_BITS(4))
PLED (clk_100mhz,
1'b0,
Div[20],
LED_DATA,
led_clk,
led_clrn,
led_sout,
LED_PEN
);
assign LED_DATA = ~{out[0],out[1],out[2],out[3],1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0};
endmodule
实验三 数字加法器的设计
1.用VerilogHDL语言设计实现4位串行数字加法器和4位并行加法器,在ModelSim上仿真实现。
2.生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
4位串行进位的全加器
module Fbs_add(
input[3:0] Ra,
input[3:0] Rb,
input Cin,
output reg[3:0] sum,
output reg cout
);
reg [4:0]C;
integer i;
always@(Ra,Rb,Cin)
begin
C[0]=Cin;
for(i=0;i<4;i=i+1)
begin
sum[i]=Ra[i]^Rb[i]^C[i];
C[i+1]=(Ra[i]&Rb[i])|((Ra[i]^Rb[i])&C[i]);
end
cout=C[4];
end
endmodule
4位并行进位的全加器
module Fbf_add(sum_out,c_out,a,b,c_in);
input[3:0] a,b;
input c_in;
output[3:0] sum_out;
output c_out;
wire[4:0] c;
wire[3:0] g,p;
assign c[0]=c_in;
assign p=a^b;
assign g=a&b;
assign c[1]=g[0]|(p[0]&c[0]);
assign c[2]=g[1]|(p[1]&(g[0]|(p[0]&c[0])));
assign c[3]=g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))));
assign c[4]=g[3]|(p[3]&(g[2]|(p[2]&(g[1]|(p[1]&(g[0]|(p[0]&c[0])))))));
assign sum_out=p^c[3:0];
assign c_out=c[4];
endmodule
设计完成I/O引脚分配,选择sw0-sw3给出第一个加数,sw4-sw7给出第二个加数,sw[15]为Ci的输入,和在led0-led3显示,进位位用led4显示。
① 4位串行进位的全加器:
module adder(input wire clk_100mhz,
input wire[15:0]SW,
output wire led_clk,
output wire led_clrn,
output wire led_sout,
output wire LED_PEN
);
wire[31:0]Div;
wire[15:0]LED_DATA;
wire CK;
clk_div U8(clk_100mhz,1'b0,SW[2],Div,CK);
LED_P2S #(.DATA_BITS(16),.DATA_COUNT_BITS(4))
PLED (clk_100mhz,
1'b0,
Div[20],
LED_DATA,
led_clk,
led_clrn,
led_sout,
LED_PEN
);
wire[4:0] out;
Fbs_add u9(SW[3:0],SW[7:4],SW[15],out[3:0],out[4]);
assign LED_DATA = ~{out[0],out[1],out[2],out[3],out[4],
1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0};
endmodule
② 4位并行进位的全加器
module adder(input wire clk_100mhz,
input wire[15:0]SW,
output wire led_clk,
output wire led_clrn,
output wire led_sout,
output wire LED_PEN
);
wire[31:0]Div;
wire[15:0]LED_DATA;
wire CK;
clk_div U8(clk_100mhz,1'b0,SW[2],Div,CK);
LED_P2S #(.DATA_BITS(16),.DATA_COUNT_BITS(4))
PLED (clk_100mhz,
1'b0,
Div[20],
LED_DATA,
led_clk,
led_clrn,
led_sout,
LED_PEN
);
wire[4:0]out;
Fbf_add u9(out[3:0],out[4],SW[3:0],SW[7:4],SW[15]);
assign LED_DATA = ~{out[0],out[1],out[2],out[3],out[4],
1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0};
endmodule
(4)生成FPGA文档,并下载到实验板上物理运行,检查设计结果。
实验四 数码管显示
1.采用VerilogHDL语言编程实现输入4位BCD码,输出是8位数码管显示码。
程序代码如下:
module Seg7BCD(out, in);
output [7:0] out;
input [3:0] in;
reg [7:0] out;
always@(in)
begin
case(in)
4'h0: out = 8'b00000011;
4'h1: out = 8'b10011111;
4'h2: out = 8'b00100101;
4'h3: out = 8'b00001101;
4'h4: out = 8'b10011001;
4'h5: out = 8'b01001001;
4'h6: out = 8'b01000001;
4'h7: out = 8'b00011111;
4'h8: out = 8'b00000001;
4'h9: out = 8'b00001001;
4'hA: out = 8'b00010001;
4'hB: out = 8'b11000001;
4'hC: out = 8'b01100011;
4'hD: out = 8'b10000101;
4'hE: out = 8'b01100001;
4'hF: out = 8'b01110001;
default: out = 8'hFE;
endcase
end
endmodule
2.用Modelsim进行功能仿真。
测试代码
module Seg7BCD_tb;
reg [3:0] in;
wire [7:0] out;
Seg7BCD bcd(.in(in),.out(out));
initial
begin
in = 4'h0;
#20 in = 4'h1;
#20 in = 4'h2;
#20 in = 4'h3;
#20 in = 4'h4;
#20 in = 4'h5;
#20 in = 4'h6;
#20 in = 4'h7;
#20 in = 4'h8;
#20 in = 4'h9;
#20 in = 4'hA;
#20 in = 4'hB;
#20 in = 4'hC;
#20 in = 4'hD;
#20 in = 4'hE;
#20 in = 4'hF;
end
endmodule
仿真结果:
3.分别设计4位BCD码自动生成模块和BCD码的译码模块。
4位BCD码生成模块:
module BCDCode( input clk,
input rst,
output reg [3:0] BCDCode
);
always @ (posedge clk)
if (rst) BCDCode = 0;
else BCDCode = BCDCode + 1;
endmodule
BCD码的译码模块:
module Seg7BCD(out, in);
output [7:0] out;
input [3:0] in;
reg [7:0] out;
always@(in)
begin
case(in)
4'h0: out = 8'b00000011;
4'h1: out = 8'b10011111;
4'h2: out = 8'b00100101;
4'h3: out = 8'b00001101;
4'h4: out = 8'b10011001;
4'h5: out = 8'b01001001;
4'h6: out = 8'b01000001;
4'h7: out = 8'b00011111;
4'h8: out = 8'b00000001;
4'h9: out = 8'b00001001;
4'hA: out = 8'b00010001;
4'hB: out = 8'b11000001;
4'hC: out = 8'b01100011;
4'hD: out = 8'b10000101;
4'hE: out = 8'b01100001;
4'hF: out = 8'b01110001;
default: out = 8'hFE;
endcase
end
endmodule
4.在顶层文件将2个电路模块实例化,并进行相应的连线。
5. 在顶层文件将2个电路模块实例化,并进行相应的连线。
实验五 计数/定时器的设计
1.用VerilogHDL语言设计实现32位加法/减法二进制计数器,在ModelSim上实现功能仿真。
(1)用Verilog完成32bit加法计数器的行为描述设计。
module counter32(
input clk,
input rst_n,
input select,
output reg [31:0] clk_div
);
always @(posedge clk)
begin
if(rst_n)
clk_div <= 32'b0;
else if(select) //select:1加计数,0减计数
clk_div <= clk_div + 1'b1 ;
else
clk_div <= clk_div - 1'b1;
end
endmodule
(2)完成modelsim下电路的功能仿真,验证电路功能。
测试代码:
module counter32_tb;
reg clk;
reg rst_n;
reg select;
wire[31:0] clk_div;
always #50 clk = ~clk;
counter32 u1(clk,rst_n,select,clk_div);
initial
begin
select = 1'b1; clk = 1'b0; rst_n = 1'b1;
#100 select = 1'b0; rst_n = 1'b0;
end
endmodule
仿真结果:
(3)设计完成I/O引脚分配。
系统时钟为100MHz,作为计数时钟。
采用sw[0]作为reset信号,将32bit的计数值在实验板的八个七段数码管上显示。
clk_div U10(clk_100mhz,1'b0,SW[2],Div,CK);
tranform u11(Div[24],SW[0],seg);
//计数器实例化
jishuqi u1(Div[24],SW[0],SW[1],out);
//数码管译码实例化
bcd_smg u9(out[3:0],seg[63:56]);
bcd_smg u8(out[7:4],seg[55:48]);
bcd_smg u7(out[11:8],seg[47:40]);
bcd_smg u6(out[15:12],seg[39:32]);
bcd_smg u5(out[19:16],seg[31:24]);
bcd_smg u4(out[23:20],seg[23:16]);
bcd_smg u3(out[27:24],seg[15:8]);
bcd_smg u2(out[31:28],seg[7:0]);
2. 生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
在上述基础上,完成32位加减法计数器。首先完成modelsim下的加减法计数器功能仿真,其次采用sw[1]作为方向选择信号,将加减法计数器的计数值在数码管上显示。
计数器实现:
always @(posedge clk)
begin
if(rst_n)
clk_div <= 32'b0;
else if(select) //select:1加计数,0减计数
clk_div <= clk_div + 1'b1 ;
else
clk_div <= clk_div - 1'b1;
//计数器实例化(top.v)
jishuqi u1(Div[24],SW[0],SW[1],out);
//数码管译码实例化(top.v)
bcd_smg u9(out[3:0],seg[63:56]);
bcd_smg u8(out[7:4],seg[55:48]);
bcd_smg u7(out[11:8],seg[47:40]);
bcd_smg u6(out[15:12],seg[39:32]);
bcd_smg u5(out[19:16],seg[31:24]);
bcd_smg u4(out[23:20],seg[23:16]);
bcd_smg u3(out[27:24],seg[15:8]);
bcd_smg u2(out[31:28],seg[7:0]);
加计数:
减计数:
实验六 移位寄存器的设计
1.用VerilogHDL语言设计实现8位带并行输入的右移移位寄存器,在ModelSim上实现功能仿真。
(1)用Verilog语言采用结构描述或者行为描述方法设计一个仅带有8bit并行输入的右移移位寄存器。
module shiftregist1(D,clk,reset,Q);
parameter shiftregist_width=8;
output [shiftregist_width-1:0] D;
input [shiftregist_width-1:0] Q;
input clk,reset;
reg [shiftregist_width-1:0] D;
initial
D=8'b00001111;
always @(posedge clk or negedge reset)
if(!reset)
D<=Q;
else
D<={D[shiftregist_width-2:0],D[shiftregist_width-1]};
endmodule
(2)编写测试模块,完成modelsim下电路的功能仿真,验证电路功能。
测试模块:
module shiftregist1_tb();
wire [7:0] D;
reg [7:0] Q;
reg clk,reset;
always #20 clk = ~clk;
shiftregist1 u2(D,clk,reset,Q);
initial
begin
clk = 0;
reset = 1;
end
endmodule
仿真结果如下:
3)建立完成I/O引脚分配。
系统时钟为100MHz,从提供的clkdiv引出clkdiv[24]作为移位控制时钟。
测试移位寄存器时采用开关SW[0]~ SW[7]作为移位寄存器的并行输入,SW[15]作为clr信号,将输出显示在led[0]~led[7]上(或同时显示到led和数码管上)。设置相应的约束文件。
shiftregist1 U1(Q,Div[25],SW[0],SW[8:1]);
clk_div U8(clk_100mhz,1'b0,SW[2],Div,CK);
Seg8BCD U0(re[7:0],Q[0]);
Seg8BCD U2(re[15:8],Q[1]);
Seg8BCD U3(re[23:16],Q[2]);
Seg8BCD U4(re[31:24],Q[3]);
Seg8BCD U5(re[39:32],Q[4]);
Seg8BCD U6(re[47:40],Q[5]);
Seg8BCD U7(re[55:48],Q[6]);
Seg8BCD U9(re[63:56],Q[7]);
assign LED_DATA = ~{Q,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0};
2.生成FPGA设计文件,下载到Sword实验系统上验证电路功能。
设计结果:
在完成实验的基础上,设计实现实验原理中图2“带有并行输入的移位寄存器”电路模块,并在modelsim下完成电路仿真。
电路设计模块:
module shiftregister(
input [7:0] data,
input din,
input clk,
input clr,
input sel,
output reg[7:0]q
);
wire [7:0] temp;
always@(posedge clk)
begin
if(sel) //串行输入
begin
if(!clr) //置0
q <= 8'b00000000;
else
q <= {din,q[7:1]}; //右移
end
else //
begin
if(!clr) //置数
q <= data;
else
q <= {q[0],q[7:1]}; //右移
end
end
endmodule
仿真测试模块:
module shiftregister_tb;
reg[7:0] data;
reg din;
reg clk;
reg clr;
reg sel;
wire[7:0]q;
shiftregister u1( .data(data),
.din(din),
.clk(clk),
.clr(clr),
.sel(sel),
.q(q)
);
always # 50 clk=~clk;
initial
begin
sel = 1'b1; clr = 1'b0; clk = 1'b0;
#100 clr = 1'b1; din = 1'b1;
#100 clr = 1'b1; din = 1'b1;
#400 sel = 1'b0; clr = 1'b0; data = 8'b10010101;
#200 clr = 1'b1;
#100 clr = 1'b1; din = 1'b1;
#100 clr = 1'b1; din = 1'b1;
#400 sel = 1'b0; clr = 1'b0; data = 8'b10101001;
#200 clr = 1'b1;
end
endmodule
仿真结果:
代码
1.shiftregist1.v
module shiftregist1(D,clk,reset,Q);
parameter shiftregist_width=8;
output [shiftregist_width-1:0] D;
input [shiftregist_width-1:0] Q;
input clk,reset;
reg [shiftregist_width-1:0] D;
initial
D=8'b00001111;
always @(posedge clk or negedge reset)
if(!reset)
D <= Q;
else
D <= {D[shiftregist_width-2:0],D[shiftregist_width-1]};
endmodule
2.shiftregist1_tb.v
module shiftregist1_tb();
wire [7:0] D;
reg [7:0] Q;
reg clk,reset;
always #20 clk = ~clk;
shiftregist1 u2(D,clk,reset,Q);
initial
begin
clk = 0;
reset = 1;
end
endmodule
3.shifter_top.v
`timescale 1ns / 1ps
module shifter_top(input wire clk_100mhz,
// I/O:
input wire[15:0]SW,
output wire led_clk,
output wire led_clrn,
output wire led_sout,
output wire LED_PEN,
output wire seg_clk,
output wire seg_clrn,
output wire seg_sout,
output wire SEG_PEN
);
wire[31:0]Div;
wire[15:0]LED_DATA;
wire CK;
wire[7:0]Q;
wire [63:0] re;
shiftregist1 U1(Q,Div[25],SW[0],SW[8:1]);
Seg8BCD U0(re[7:0],Q[0]);
Seg8BCD U2(re[15:8],Q[1]);
Seg8BCD U3(re[23:16],Q[2]);
Seg8BCD U4(re[31:24],Q[3]);
Seg8BCD U5(re[39:32],Q[4]);
Seg8BCD U6(re[47:40],Q[5]);
Seg8BCD U7(re[55:48],Q[6]);
Seg8BCD U9(re[63:56],Q[7]);
clk_div U8(clk_100mhz,1'b0,SW[2],Div,CK);
LED_P2S #(.DATA_BITS(16),.DATA_COUNT_BITS(4))
PLED (clk_100mhz,
1'b0,
Div[20],
LED_DATA,
led_clk,
led_clrn,
led_sout,
LED_PEN
);
/* P2S #(.DATA_BITS(64),.DATA_COUNT_BITS(6))
P7SEG (clk_100mhz,
1'b0,
Div[20],
disp_data,
seg_clk,
seg_clrn,
seg_sout,
SEG_PEN
);*/
assign LED_DATA = ~{Q,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0};
endmodule
4.Seg8BCD.v
module Seg8BCD(out,in);
output [7:0] out;
input [3:0] in;
reg [7:0] out;
always @(in)
begin
case(in)
4'h0: out = 8'b00000011;
4'h1: out = 8'b10011111;
4'h2: out = 8'b00100101;
4'h3: out = 8'b00001101;
4'h4: out = 8'b10011001;
4'h5: out = 8'b01001001;
4'h6: out = 8'b01000001;
4'h7: out = 8'b00011111;
4'h8: out = 8'b00000001;
4'h9: out = 8'b00001001;
4'hA: out = 8'b00010001;
4'hB: out = 8'b11000001;
4'hC: out = 8'b01100011;
4'hD: out = 8'b10000101;
4'hE: out = 8'b01100001;
4'hF: out = 8'b01110001;
default: out = 8'hFF;
endcase
end
endmodule
实验七 有限状态机设计
1.理解并掌握检测连续接收“111”的Moore型和Mealy型有限状态机设计
Moore型:
//Moore状态机的输出仅依赖于当前状态而与输入无关。
module seqdata_moore(
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [1:0] curr_state;
reg [1:0] next_state;
parameter ST0 = 2'b00;
parameter ST1 = 2'b01;
parameter ST2 = 2'b10;
parameter ST3 = 2'b11;
always@(posedge clk or negedge rst)
begin
if(!rst)
curr_state <= ST0;
else
curr_state <= next_state;
end
always@(*)
begin
case(curr_state)
ST0: if(din == 1)
next_state <= ST1;
else
next_state <= ST0;
ST1: if(din == 1)
next_state <= ST2;
else
next_state <= ST0;
ST2: if(din == 1)
next_state <= ST3;
else
next_state <= ST0;
ST3: if(din == 1)
next_state <= ST3;
else
next_state <= ST0;
default:
next_state <= ST0;
endcase
end
// 体现了Moore机的特点:输出由当前状态决定
always@(*)
begin
if(curr_state == ST3)
dout <= 1;
else
dout <= 0;
end
endmodule
Mealy型:
//Mealy状态机的输出与当前状态和输入有关。
module seqdata_mealy(
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [1:0] curr_state;
reg [1:0] next_state;
parameter ST0 = 2'b00;
parameter ST1 = 2'b01;
parameter ST2 = 2'b11;
always@(posedge clk or negedge rst)
begin
if(!rst)
curr_state <= ST0;
else
curr_state <= next_state;
end
always@(*)
begin
case(curr_state)
ST0: if(din == 1)
begin
next_state <= ST1;
dout <= 0;
end
else
begin
next_state <= ST0;
dout <= 0;
end
ST1: if(din == 1)
begin
next_state <= ST2;
dout <= 0;
end
else
begin
next_state <= ST0;
dout <= 0;
end
ST2: if(din == 1)
begin
next_state <= ST2;
dout <= 1;
end
else
begin
next_state <= ST0;
dout <= 0;
end
default:
begin
next_state <= ST0;
dout <= 0;
end
endcase
end
endmodule
2. 设计并实现掌握检测连续接收“1111”的Moore型和Mealy型状态机设计。
要求:画出Moore型和Mealy型的状态转移图,并编写代码在modelsim上仿真实现。
Moore型:
设计代码:
module seqdata1111_moore(
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [2:0] curr_state;
reg [2:0] next_state;
parameter ST0 = 3'b000;
parameter ST1 = 3'b001;
parameter ST2 = 3'b010;
parameter ST3 = 3'b011;
parameter ST4 = 3'b100;
always@(posedge clk or negedge rst)
begin
if(!rst)
curr_state <= ST0;
else
curr_state <= next_state;
end
always@(*)
begin
case(curr_state)
ST0: if(din == 1)
next_state <= ST1;
else
next_state <= ST0;
ST1: if(din == 1)
next_state <= ST2;
else
next_state <= ST0;
ST2: if(din == 1)
next_state <= ST3;
else
next_state <= ST0;
ST3: if(din == 1)
next_state <= ST4;
else
next_state <= ST0;
ST4: if(din == 1)
next_state <= ST4;
else
next_state <= ST0;
default: next_state <= ST0;
endcase
end
always@(*)
begin
if(curr_state == ST4)
dout = 1;
else
dout = 0;
end
endmodule
测试代码:
module seqdata1111_moore_tb();
wire dout;
reg clk;
reg rst;
reg din;
seqdata1111_moore U1(.dout(dout),
.clk(clk),
.rst(rst),
.din(din)
);
always #10 clk = ~clk;
initial
begin
clk = 0;rst = 0;din =0;
#50 rst = 1;
#20 din = 1;
#20 din = 0;
#20 din = 1;
#40 din = 1;
#20 din = 1;
#60 din = 1;
#20 din = 0;
end
endmodule
仿真结果:
Mealy型:
设计代码:
module seqdata1111_mealy(
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [2:0] curr_state;
reg [2:0] next_state;
parameter ST0 = 3'b000;
parameter ST1 = 3'b001;
parameter ST2 = 3'b010;
parameter ST3 = 3'b011;
always@(posedge clk or negedge rst)
begin
if(!rst)
curr_state <= ST0;
else
curr_state <= next_state;
end
always@(*)
begin
case(curr_state)
ST0: if(din == 1)
next_state <= ST1;
else
next_state <= ST0;
ST1: if(din == 1)
next_state <= ST2;
else
next_state <= ST0;
ST2: if(din == 1)
next_state <= ST3;
else
next_state <= ST0;
ST3: if(din == 1)
next_state <= ST3;
else
next_state <= ST0;
default: next_state <= ST0;
endcase
end
always@(*)
begin
if(curr_state == ST3)
dout = 1;
else
dout = 0;
end
endmodule
测试代码:
module seqdata1111_mealy_tb();
wire dout;
reg clk;
reg rst;
reg din;
seqdata1111_mealy U1(.dout(dout),
.clk(clk),
.rst(rst),
.din(din)
);
always #10 clk = ~clk;
initial
begin
clk = 0;rst = 0;din =0;
#50 rst = 1;
#20 din = 1;
#20 din = 0;
#20 din = 1;
#40 din = 1;
#20 din = 1;
#60 din = 1;
#20 din = 0;
end
endmodule
仿真结果:
下板验证:(Moore型)
3.在完成基本实验的基础上,尝试设计检测接收“1011”的Moore型和Mealy型有限状态机的状态转移图。然后编写代码,在modelsim上仿真测试验证结果。
Moore型:
设计代码:
module seqdata1011_moore(
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [3:0] curr_state;
reg [3:0] next_state;
parameter ST0 = 4'b0000;
parameter ST1 = 4'b0001;
parameter ST2 = 4'b0011;
parameter ST3 = 4'b0111;
parameter ST4 = 4'b1111;
always @(posedge clk or negedge clk)
begin
if(!rst)
curr_state <= ST0;
else
curr_state <= next_state;
end
always @(*)
begin
case(curr_state)
ST0: if(din == 1)
next_state <= ST1;
else
next_state <= ST0;
ST1: if(din == 0)
next_state <= ST2;
else
next_state <= ST1;
ST2: if(din == 1)
next_state <= ST3;
else
next_state <= ST0;
ST3: if(din == 1)
next_state <= ST4;
else
next_state <= ST2;
ST4: if(din == 1)
next_state <= ST1;
else
next_state <= ST2;
default: next_state <= ST0;
endcase
end
always @(*)
begin
if(curr_state == ST4)
dout = 1;
else
dout = 0;
end
endmodule
测试代码:
module seqdata1011_moore_tb();
wire dout;
reg clk;
reg rst;
reg din;
seqdata1011_moore U1(.dout(dout),
.clk(clk),
.rst(rst),
.din(din)
);
always #10 clk = ~clk;
initial
begin
clk = 0; rst = 0; din = 0;
#50 rst = 1;
#20 din = 0;
#20 din = 0;
#20 din = 1;
#20 din = 0;
#20 din = 1;
#40 din = 1;
#20 din = 0;
#20 din = 1;
#20 din = 1;
#20 din = 0;
end
endmodule
仿真结果:
Mealy型:
设计代码:
module seqdata1011_mealy(
output reg dout,
input wire clk,
input wire rst,
input wire din
);
reg [2:0] curr_state;
reg [2:0] next_state;
parameter ST0 = 3'b000;
parameter ST1 = 3'b001;
parameter ST2 = 3'b011;
parameter ST3 = 3'b111;
always @(posedge clk or negedge clk)
begin
if(!rst)
curr_state <= ST0;
else
curr_state <= next_state;
end
always @(*)
begin
case(curr_state)
ST0:
if(din == 1)
begin
next_state <= ST1;
dout = 0;
end
else
begin
next_state <= ST0;
dout = 0;
end
ST1:
if(din == 0)
begin
next_state <= ST2;
dout = 0;
end
else
begin
next_state <= ST0;
dout = 0;
end
ST2:
if(din == 1)
begin
next_state <= ST3;
dout = 0;
end
else
begin
next_state <= ST0;
dout = 0;
end
ST3:
if(din == 1)
begin
next_state <= ST3;
dout = 1;
end
else
begin
next_state <= ST0;
dout = 0;
end
default: next_state <= ST0;
endcase
end
endmodule
测试代码:
module seqdata1011_mealy_tb();
wire dout;
reg clk;
reg rst;
reg din;
seqdata1011_mealy U1(.dout(dout),
.clk(clk),
.rst(rst),
.din(din)
);
always #10 clk = ~clk;
initial
begin
clk = 0; rst = 0; din = 0;
#50 rst = 1;
#20 din = 0;
#20 din = 0;
#20 din = 1;
#20 din = 0;
#20 din = 1;
#40 din = 1;
#20 din = 0;
#20 din = 1;
#20 din = 1;
#20 din = 0;
end
endmodule
仿真结果:
实验八 有限状态机设计
1. 用Verilog HDL设计深度为32、位宽为8 bit的单端口RAM,在Modelsim上仿真测试。
设计代码:
module RAM_signal(
input clk,
input[4:0]addm,
input cs_n,
input we_n,
input[7:0]din,
output[7:0]dout
);
reg[7:0]ram[31:0];
always@(posedge clk)
begin
if(cs_n)
dout <= 8'bzzzz_zzzz;
else
begin
if(we_n)
dout <= ram[addm];
else
ram[addm] <= din;
end
end
endmodule
测试代码:
module RAM_signal_tb();
//Inputs:
reg clk;
reg[4:0]addm;
reg cs_n;
reg we_n;
reg[7:0]din;
//Outputs:
wire[7:0]dout;
//Instantiate the:
RAM_signal U1(.clk(clk),
.addm(addm),
.cs_n(cs_n),
.we_n(we_n),
.din(din),
.dout(dout)
);
initial
begin
//Initialize Inputs
clk=0;addm=0;
cs_n=1;we_n=0;
din = 0;
#5 cs_n=0;
#315 we_n=1;
end
always #10 clk=~clk;
initial
begin
repeat(7)
begin
#40 addm=addm+1;
din=din+1;
end
#40 repeat(7)
#40 addm=addm-1;
end
endmodule
仿真结果:
2.用Verilog HDL设计深度为8、位宽为8 bit的ROM。在Modelsim上仿真测试。
设计代码:
module ROM(
input clk,
input cs_n, //0有效
input[2:0]addm,
output reg[7:0]dout);
reg[7:0]rom[7:0]; //存储器型变量声明
initial
begin
rom[0]=8'h0;
rom[1]=8'h1;
rom[2]=8'h2;
rom[3]=8'h3;
rom[4]=8'h4;
rom[5]=8'h5;
rom[6]=8'h6;
rom[7]=8'h7;
end
always@(posedge clk)
begin
if(cs_n)
dout <= 8'bzzzz_zzzz;
else
dout <= rom[addm];
end
endmodule
测试代码:
module ROM_tb();
//Inputs:
reg clk;
reg cs_n;
reg[2:0]addm;
//Outputs:
wire[7:0]dout;
//Instantiate the Unit
ROM U1(.clk(clk),
.cs_n(cs_n),
.addm(addm),
.dout(dout)
);
initial
begin
//Initialize Inputs:
clk=0;
addm=0;
cs_n=0;
end
always #10 clk=~clk;
initial
begin
repeat(7)
#20 addm=addm+1;
end
endmodule
仿真结果:
3.用Xilinx ISE/Vivado 生成单端口RAM的IP,并编写测试文件,调试通过。
测试代码:
module RAMIP_tb();
//Inputs:
reg[3:0]a;
reg[7:0]d;
reg clk;
reg we;
//Outputs:
wire[7:0]spo;
//Instantiate the Unit Test(u1)
dist_mem_gen_0 u1 (
.a(a), // input wire [3 : 0] a
.d(d), // input wire [7 : 0] d
.clk(clk), // input wire clk
.we(we), // input wire we
.spo(spo) // output wire [7 : 0] spo
);
always#20 clk=~clk;
initial
begin
clk=0;a=0;we=0;d=8'h0f;
#640 we=1;
#680 we=0;
end
initial
begin
repeat(16) #40 a=a+1;
#40 repeat(16)
begin
#40 a=a+1;
d=d-1;
end
#40 repeat(16) #40 a=a+1;
end
endmodule
仿真结果:
4. 用Xilinx ISE/Vivado 生成单端口ROM的IP,并编写测试文件,调试通过。
测试代码:
module ROMIP_tb();
reg[3:0]a;
wire[7:0]spo;
dist_mem_gen_0 u1(
.a(a),
.spo(spo)
);
always #20 a=a+1;
initial
begin
a=0;
end
endmodule
仿真结果:
5.将设计的RAM下载到FPGA板子上验证。
顶层模块:
`timescale 1ns / 1ps
module RAM_top(input wire clk_100mhz,
// I/O:
input wire[15:0]SW,
output wire led_clk,
output wire led_clrn,
output wire led_sout,
output wire LED_PEN,
output wire seg_clk,
output wire seg_clrn,
output wire seg_sout,
output wire SEG_PEN );
wire[31:0]Div;
wire[15:0]LED_DATA;
wire CK;
wire[7:0]Q;
clk_div U8(clk_100mhz,1'b0,SW[2],Div,CK);
LED_P2S #(.DATA_BITS(16),.DATA_COUNT_BITS(4))
PLED (clk_100mhz,
1'b0,
Div[20],
LED_DATA,
led_clk,
led_clrn,
led_sout,
LED_PEN);
RAM_signal U1(Div[24],SW[15:11],SW[10],SW[9],SW[7:0],Q[7:0]);
assign LED_DATA = ~{Q[7],Q[6],Q[5],Q[4],Q[3],Q[2],Q[1],Q[0],
1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,1'b0,Div[24]};
endmodule
实验结果:
在00001号存储单元写入数据8’b11011101,再读出到LED灯显示。
最后
以上就是稳重犀牛为你收集整理的Verilog HDL 实验题Verilog HDL 实验的全部内容,希望文章能够帮你解决Verilog HDL 实验题Verilog HDL 实验所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复