1 //动态数码管扫描,通过这种方式可以节约引脚
2 //可以使用三八译码器来切换数码管位
3 //要求每个数码管每20ms都要点亮一次,20/8=2.5ms
4 //源代码1用的是组合逻辑
5 module hex8(
6 clk,
7 reset_n,
8 disp_data,
9 sel,
10 seg
11 );
12 input clk;
13 input reset_n;
14 input [31:0] disp_data;
15 output reg [7:0] sel;
16 output reg [7:0] seg;
17
18
19 reg clk_1k;
20 reg [14:0]div_cnt;
21 //设置分频计数时钟
22 always@(posedge clk or negedge reset_n)
23 if(!reset_n)
24 div_cnt <= 0;
25 else if(div_cnt >= 24999)
26 div_cnt <= 0;
27 else
28 div_cnt <= div_cnt + 1'b1;
29 //定义1ms的时钟(1khz)
30 always@(posedge clk or negedge reset_n)
31 if(!reset_n)
32 clk_1k <= 0;
33 else if(div_cnt >= 24999)
34 clk_1k <= !clk_1k;
35 //这种门时钟在绝大多数不推荐使用
36 reg [2:0] num_cnt;
37 always@(posedge clk_1k or negedge reset_n)
38 if(!reset_n)
39 num_cnt <= 0;
40 else
41 num_cnt <= num_cnt + 1'b1;
42
43 //书写3—8译码器
44 always@(*)begin
45 case(num_cnt)
46 0:sel <= 8'b0000_0001;
47 1:sel <= 8'b0000_0010;
48 2:sel <= 8'b0000_0100;
49 3:sel <= 8'b0000_1000;
50 4:sel <= 8'b0001_0000;
51 5:sel <= 8'b0010_0000;
52 6:sel <= 8'b0100_0000;
53 7:sel <= 8'b1000_0000;
54 endcase
55 end
56
57 reg [3:0] dis_tmp;
58 always@(*)begin
59 case(num_cnt)
60 7:dis_tmp <= disp_data[31:28];
61 6:dis_tmp <= disp_data[27:24];
62 5:dis_tmp <= disp_data[23:20];
63 4:dis_tmp <= disp_data[19:16];
64 3:dis_tmp <= disp_data[15:12];
65 2:dis_tmp <= disp_data[11:8];
66 1:dis_tmp <= disp_data[7:4];
67 0:dis_tmp <= disp_data[3:0];
68 endcase
69 end
70
71 always@(*)begin
72 case(dis_tmp)
73 0:seg <= 8'hc0;
74 1:seg <= 8'hf9;
75 2:seg <= 8'ha4;
76 3:seg <= 8'hb0;
77 4:seg <= 8'h99;
78 5:seg <= 8'h92;
79 6:seg <= 8'h82;
80 7:seg <= 8'hf8;
81 8:seg <= 8'h80;
82 9:seg <= 8'h90;
83 4'ha:seg <= 8'h88;
84 4'hb:seg <= 8'h83;
85 4'hc:seg <= 8'hc6;
86 4'hd:seg <= 8'ha1;
87 4'he:seg <= 8'h86;
88 4'hf:seg <= 8'h8e;
89 endcase
90 end
91 endmodule
92
93 //源代码2用的是时序逻辑
94 module hex8_2(
95 clk,
96 reset_n,
97 disp_data,
98 sel,
99 seg
100 );
101 input clk;
102 input reset_n;
103 input [31:0] disp_data;
104 output reg [7:0] sel;
105 output reg [7:0] seg;
106
107
108 reg clk_1k;
109 reg [14:0]div_cnt;
110 //设置分频计数时钟
111 always@(posedge clk or negedge reset_n)
112 if(!reset_n)
113 div_cnt <= 0;
114 else if(div_cnt >= 49999)
115 div_cnt <= 0;
116 else
117 div_cnt <= div_cnt + 1'b1;
118 //这种门控时钟在绝大多数场合不允许使用
119 //定义1ms的时钟(1khz)
120 // always@(posedge clk or negedge reset_n)
121 // if(!reset_n)
122 // clk_1k <= 0;
123 // else if(div_cnt >= 24999)
124 // clk_1k <= !clk_1k;
125
126 //使能时钟
127 always@(posedge clk or negedge reset_n)
128 if(!reset_n)
129 clk_1k <= 0;
130 else if(div_cnt >= 49999)
131 clk_1k <= 1;
132 else
133 clk_1k <= 0;
134
135 reg [2:0] num_cnt;
136 always@(posedge clk or negedge reset_n)
137 if(!reset_n)
138 num_cnt <= 0;
139 else if(clk_1k)//这里面使用的就是使能时钟
140 num_cnt <= num_cnt + 1'b1;
141
142 //书写3—8译码器
143 always@(posedge clk)begin//将组合逻辑用时序的时钟,结果更加精确。
144 case(num_cnt)
145 0:sel <= 8'b0000_0001;
146 1:sel <= 8'b0000_0010;
147 2:sel <= 8'b0000_0100;
148 3:sel <= 8'b0000_1000;
149 4:sel <= 8'b0001_0000;
150 5:sel <= 8'b0010_0000;
151 6:sel <= 8'b0100_0000;
152 7:sel <= 8'b1000_0000;
153 endcase
154 end
155
156 reg [3:0] dis_tmp;
157 always@(posedge clk)begin
158 case(num_cnt)
159 7:dis_tmp <= disp_data[31:28];
160 6:dis_tmp <= disp_data[27:24];
161 5:dis_tmp <= disp_data[23:20];
162 4:dis_tmp <= disp_data[19:16];
163 3:dis_tmp <= disp_data[15:12];
164 2:dis_tmp <= disp_data[11:8];
165 1:dis_tmp <= disp_data[7:4];
166 0:dis_tmp <= disp_data[3:0];
167 endcase
168 end
169
170 always@(posedge clk)begin
171 case(dis_tmp)
172 0:seg <= 8'hc0;
173 1:seg <= 8'hf9;
174 2:seg <= 8'ha4;
175 3:seg <= 8'hb0;
176 4:seg <= 8'h99;
177 5:seg <= 8'h92;
178 6:seg <= 8'h82;
179 7:seg <= 8'hf8;
180 8:seg <= 8'h80;
181 9:seg <= 8'h90;
182 4'ha:seg <= 8'h88;
183 4'hb:seg <= 8'h83;
184 4'hc:seg <= 8'hc6;
185 4'hd:seg <= 8'ha1;
186 4'he:seg <= 8'h86;
187 4'hf:seg <= 8'h8e;
188 endcase
189 end
190 endmodule
191
192
193
194 //仿真文件
195 `timescale 1ns / 1ps
196 module hex8_tb();
197 reg clk;
198 reg reset_n;
199 reg [31:0] disp_data;
200 wire [7:0] sel;
201 wire [7:0] seg;
202 hex8 hex8_inst0(
203 clk,
204 reset_n,
205 disp_data,
206 sel,
207 seg
208 );
209 initial clk = 1;
210 always #10 clk = !clk;
211
212 initial begin
213 reset_n = 0;
214 disp_data = 32'h00000000;
215 #201;
216 reset_n = 1;
217 #2000;
218 disp_data = 32'h12345678;
219 #10000000;
220 disp_data = 32'h9abcdef0;
221 #10000000;
222 $stop;
223
224 end
225 endmodule
226
227 //板级实验所用的测试文件,只有AX735才能班级实验,这个是扩展板
228
229 module hex8_test(
230 clk,
231 reset_n,
232 sel,
233 seg
234 );
235 input clk;
236 input reset_n;
237 output [7:0] sel;
238 output [7:0] seg;
239
240 wire [31:0] disp_data;
241
242 hex8_2 hex8_2_inst0(
243 clk,
244 reset_n,
245 disp_data,
246 sel,
247 seg
248 );
249 assign disp_data = 32'h13579bdf;
250
251 endmodule
使用门控时钟,将门控时钟直接作为DFF的工作时钟,没有ENA的情况下忽略ENA

使用使能时钟的情况,DFF的工作时钟继续使用全局的高质量时钟,而将使能时钟作为DFF的使能信号使用。
2023-03-28 21:10:13
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)