为了帮助大家更好学习FPGA硬件语言,创立此资源
包含文件有:实验报告、仿真文件,资料很全,有问题可以私信
一、实验内容
1、利用QuartusII和Modelsim实现100进制可逆计数器编码显示实验。
二、实验步骤
(1)安装软件
事先安装好QuartusII和Modelsim两个软件。
(2)创建工程

(3)编写代码
编写的.v顶层文件:
- module counter_1(
- input clk,
- input rst,
- input flag,
- output out_c
- );
-
-
-
- reg [9:0] count;
-
-
-
- always@(posedge clk or negedge rst)begin
- if(!rst)begin
- count <= 0; //复位
-
- end
- else if(flag==1)begin
- if(count<99)
- count <= count + 1; //flag为1,是加法计数器
-
- else
-
- count <= 0; //计到99复位
-
- end
- else begin
- if(count==0)
- count <= 99; //计到0复位
-
- else
-
- count <= count - 1; //flag为0,是减法计数器
-
- end
-
-
-
- end
-
-
-
-
-
-
-
- endmodule
-
- 编写的textbench文件:
-
- `timescale 1 ns/ 1 ps
- module counter_tb();
-
- // constants
-
- // general purpose registers
-
- // test vector input registers
-
- reg clk;
-
- reg flag;
-
- reg rst;
-
- // wires
-
- wire out_c;
-
-
-
- // assign statements (if any)
-
- counter_1 i1 (
- // port map - connection between master ports and signals/registers
- .clk(clk),
- .flag(flag),
- .out_c(out_c),
- .rst(rst)
- );
-
- initial
-
- begin
-
- // code that executes only once
-
- // insert code here --> begin
-
- clk = 0;
-
- rst = 0;
-
- #100 rst = 1;
-
- flag = 1;
-
- #1000 flag =0; //初始化
-
-
-
- // --> end
-
- end
-
-
-
- always #5000 flag = ~flag; //每5000ns之后flag翻转
-
- always #10 clk = ~clk; //时钟周期20ns
-
- endmodule
三、实验结果

一、实验内容
(1)十字路口有 x、y 方向两组交通信号灯,每组有红、黄、绿灯各一个;
(2)设计一个交通灯控制电路,模拟十字路口交通灯工作情况,红灯亮 35s,黄灯亮 5s,绿 灯亮 30s;
(3)设系统时钟频率为 50MHz,要求用数码管显示计时结果;
(4)掌握 Verilog HDL 的状态机编程,红、黄、绿灯点亮转换用如下的状态转换图实现。

二、实验步骤
(1)编写代码
编写的.v顶层文件:
-
- 1. module traffic(
- 2. input clk,
- 3. input rst,
- 4.
- 5. output reg LEDR_Y,
- 6. output reg LEDY_Y,
- 7. output reg LEDG_Y,
- 8. output reg LEDR_X,
- 9. output reg LEDY_X,
- 10. output reg LEDG_X
- 11.
- 12. );
- 13. parameter N = 25000000;
- 14. parameter S1 = 0;
- 15. parameter S2 = 1;
- 16. parameter S3 = 2;
- 17. parameter S4 = 3;
- 18. reg [25:0] count;
- 19. reg CLK_1Hz;
- 20. reg [2:0] cnt5;
- 21. reg [4:0] cnt30;
- 22. reg [1:0]state;//状态
- 23.
- 24. //生成1Hz时钟
- 25. always@(posedge clk or negedge rst)begin
- 26. if(!rst)begin
- 27. count <= 0;
- 28. CLK_1Hz <= 0;
- 29. end
- 30. else if(count
-1)begin - 31. count <= count +1;
- 32. CLK_1Hz <= CLK_1Hz;
- 33. end
- 34. else begin
- 35. count <= 0;
- 36. CLK_1Hz <= ~CLK_1Hz;
- 37. end
- 38. end
- 39.
- 40. //生成5进制计数器
- 41. always@(posedge CLK_1Hz or negedge rst)begin
- 42. if(!rst)begin
- 43. cnt5 <= 0;
- 44. end
- 45. else if(cnt5<4)begin
- 46. cnt5 <= cnt5 + 1;
- 47. end
- 48. else
- 49. cnt5 <= 0;
- 50. end
- 51.
- 52. //生成30进制计数器
- 53. always@(posedge CLK_1Hz or negedge rst)begin
- 54. if(!rst)begin
- 55. cnt30 <= 0;
- 56. end
- 57. else if(cnt30 < 29)begin
- 58. cnt30 <= cnt30 + 1;
- 59. end
- 60. else
- 61. cnt30 <= 0;
- 62. end
- 63.
- 64. //状态迁移
- 65. always@(posedge clk or negedge rst)begin
- 66. if(!rst)begin
- 67. state <= 0;
- 68. end
- 69. else begin
- 70. case(state)
- 71.
- 72. S1:
- 73. if(cnt30==29) state <= S3;
- 74. else state <= S1;
- 75. S2:
- 76. if(cnt30==29) state <= S4;
- 77. else state <= S2;
- 78. S3:
- 79. if(cnt5==4) state <= S2;
- 80. else state <= S3;
- 81. S4:
- 82. if(cnt5==4) state <= S1;
- 83. else state <= S4;
- 84. default: state <= S1;
- 85. endcase
- 86. end
- 87. end
- 88.
- 89. //状态
- 90. always@(posedge clk or negedge rst)begin
- 91. if(!rst)begin //刚开始全灭
- 92. LEDR_Y <= 0;
- 93. LEDY_Y <= 0;
- 94. LEDG_Y <= 0;
- 95. LEDR_X <= 0;
- 96. LEDY_X <= 0;
- 97. LEDG_X <= 0;
- 98. end
- 99. else begin
- 100. case(state)
- 101. S1: begin //Y方向绿灯亮,X方向红灯亮
- 102. LEDR_Y <= 0;
- 103. LEDY_Y <= 0;
- 104. LEDG_Y <= 1;
- 105. LEDR_X <= 1;
- 106. LEDY_X <= 0;
- 107. LEDG_X <= 0;
- 108. end
- 109. S2: begin //X方向绿灯亮,Y方向红灯亮
- 110. LEDR_Y <= 1;
- 111. LEDY_Y <= 0;
- 112. LEDG_Y <= 0;
- 113. LEDR_X <= 0;
- 114. LEDY_X <= 0;
- 115. LEDG_X <= 1;
- 116. end
- 117. S3: begin //X方向红灯亮,Y方向黄灯亮
- 118. LEDR_Y <= 0;
- 119. LEDY_Y <= 1;
- 120. LEDG_Y <= 0;
- 121. LEDR_X <= 1;
- 122. LEDY_X <= 0;
- 123. LEDG_X <= 0;
- 124. end
- 125. S4: begin //X方向黄灯亮,Y方向红灯亮
- 126. LEDR_Y <= 1;
- 127. LEDY_Y <= 0;
- 128. LEDG_Y <= 0;
- 129. LEDR_X <= 0;
- 130. LEDY_X <= 1;
- 131. LEDG_X <= 0;
- 132. end
- 133. default: begin //全灭
- 134. LEDR_Y <= 0;
- 135. LEDY_Y <= 0;
- 136. LEDG_Y <= 0;
- 137. LEDR_X <= 0;
- 138. LEDY_X <= 0;
- 139. LEDG_X <= 0;
- 140. end
- 141. endcase
- 142. end
- 143.
- 144. end
- 145.
- 146. endmodule
-
-
- 编写的textbench文件:
- 1. `timescale 1 ns/ 1 ps
- 2. module traffic_tb();
- 3. // constants
- 4. // general purpose registers
- 5.
- 6. reg clk;
- 7. reg rst;
- 8. // wires
- 9. wire LEDG_X;
- 10. wire LEDG_Y;
- 11. wire LEDR_X;
- 12. wire LEDR_Y;
- 13. wire LEDY_X;
- 14. wire LEDY_Y;
- 15.
- 16. // assign statements (if any)
- 17. traffic i1 (
- 18. // port map - connection between master ports and signals/registers
- 19. .LEDG_X(LEDG_X),
- 20. .LEDG_Y(LEDG_Y),
- 21. .LEDR_X(LEDR_X),
- 22. .LEDR_Y(LEDR_Y),
- 23. .LEDY_X(LEDY_X),
- 24. .LEDY_Y(LEDY_Y),
- 25. .clk(clk),
- 26. .rst(rst)
- 27. );
- 28. initial
- 29. begin
- 30. clk = 0;
- 31. rst = 0;
- 32. #100 rst = 1;
- 33.
- 34. end
- 35.
- 36. always #10 clk <= ~clk;
- 37.
- 38. endmodule
编写的textbench文件:
- `timescale 1 ns/ 1 ps
- module traffic_tb();
- // constants
- // general purpose registers
-
- reg clk;
- reg rst;
- // wires
- wire LEDG_X;
- wire LEDG_Y;
- wire LEDR_X;
- wire LEDR_Y;
- wire LEDY_X;
- wire LEDY_Y;
-
- // assign statements (if any)
- traffic i1 (
- // port map - connection between master ports and signals/registers
- .LEDG_X(LEDG_X),
- .LEDG_Y(LEDG_Y),
- .LEDR_X(LEDR_X),
- .LEDR_Y(LEDR_Y),
- .LEDY_X(LEDY_X),
- .LEDY_Y(LEDY_Y),
- .clk(clk),
- .rst(rst)
- );
- initial
- begin
- clk = 0;
- rst = 0;
- #100 rst = 1;
-
- end
-
- always #10 clk <= ~clk;
-
- endmodule
三、实验结果
S1到S3的转换:

S3到S2的转换:

S2到S4的转换:

S4到S1的转换:

一、实验内容
1、仿真实验:正弦信号发生器,学习IP核的使用;
2、拓展要求:三角波信号发生器,熟悉仿真、状态机的使用。
跳过创建工程的过程。
(1)编写正弦波仿真实验代码
首先我们生成正弦波是提前把正弦波的数据保存在ROM文件(.mif)文件中,然后通过调用ROM的IP核,最后通过读取ROM的数据输出正弦波数据。
创建单端ROM的IP核。

设置ROM的位宽和长度。这里是8位64个信号

添加.mif文件

编写的.v顶层文件:
- module waveform(
- input clk,
- input rst,
- output [7:0]data_out,
- output reg [6:0]data_tri
- );
- parameter S1 = 0;
- parameter S2 = 1;
- reg [5:0]addr;
- reg [1:0]state;
- reg [1:0]next_state;
- always@(posedge clk or negedge rst)begin
- if(!rst)
- addr <= 0;
- else
- addr <= addr + 1;
- end
- sinROM U1(
- .address(addr),
- .clock(clk),
- .q(data_out));
-
-
-
-
-
-
- endmodule
(2)编写三角波发生器仿真实验代码
编写的状态机源码:
- //状态迁移
- always@(posedge clk or negedge rst)begin
- if(!rst)
- state <= S1;
- else
- state <= next_state;
- end
-
- //状态事件
- always@(posedge clk or negedge rst)begin
- if(!rst)
- next_state <= 0;
- else begin
- case(state)
- S1: begin
- if(data_tri >= 98)
- next_state <= S2;
- else
- next_state <= state;
- end
- S2: begin
- if(data_tri <= 2)
- next_state <= S1;
- else
- next_state <= state;
- end
- default: next_state <= S1;
-
- endcase
- end
- end
-
- always@(posedge clk or negedge rst)begin
- if(!rst)begin
- data_tri <= 0;
- end
- else begin
- case(state)
- S1 : data_tri <= data_tri + 1;
- S2 : data_tri <= data_tri - 1;
- default: data_tri <= 0;
- endcase
- end
- end
编写的测试文件:
- `timescale 1 ns/ 1 ps
- module waveform_tb();
- // constants
- // general purpose registers
- // test vector input registers
- reg clk;
- reg rst;
- // wires
- wire [7:0] data_out;
- wire [6:0] data_tri;
-
- // assign statements (if any)
- waveform i1 (
- // port map - connection between master ports and signals/registers
- .clk(clk),
- .data_out(data_out),
- .data_tri(data_tri),
- .rst(rst)
- );
- initial
- begin
- clk = 0;
- rst = 0;
- #100 rst = 1;
- end
- always #10 clk <= ~clk;
- // optional sensitivity list
- // @(event1 or event2 or .... eventn)
-
- endmodule
三、实验结果
正弦波波形:

三角波波形:

注意事项:在正弦波形的仿真过程中遇到过读取ROM的数一直为零的情况,后来查询发现是因为.mif文件与工程不在同一目录。
本文大部分内容都属于原创,如需转载,请附上本文网站,
如果需要相关的仿真图、程序代码等资料可以直接私信我,我会及时回复。