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 标签:reset,cnt,clk,数码管,verilog,reg,小梅哥,时钟 From: https://www.cnblogs.com/wangwinwin4/p/17265449.html