设计背景:
rom是读写的的静态存储单元,在我们的设计中我们会经常用到,数码管模块同样的大大小小的设计还是工程应用中都有这至关重要的作用。
设计原理:
前几节我们学习了rom存储器的设计,还有数码管模块的设计,为了我们联系这两个模块的应用我们今天将设计一个按键来控制读取rom中的数据,来显示到数码管上。
因为我们的数码管模块的显示频率是10K,所以我们应该小于10K的频率给一个rom地址,从而出一个数据,我们的设计是0.5s出一个数据,这样我们就能在数码管上显示随着地址的增加,数据同样也在变化。
第一步我们要先设计我们的.mif文件,我们在前10个地址是上写入0 -- 10,然后建立一个rom 的ip核,添加进去从而便于后面的例化。
设计模块,我们前面讲过数码管模块,这样就可以直接拿过来用了,今天我们将主要给大家展示我们的rom控制模块。
设计架构图:
设计代码:
顶层模块
0 module rom_seg (clk, rst_n, key, sel, seg_n);
1
2 input clk, rst_n;
3 input key;
4 output [7:0] seg_n; //段选信号
5 output [2:0] sel; //位选信号
6
7 wire [3:0] data;
8 wire [23:0] hex;
9
10 //在6个数码管上显示同样的数据
11 assign hex[23:0] = {data[3:0],data[3:0],data[3:0],data[3:0],data[3:0],data[3:0]};
12
13 rom rom_inst ( //rom控制模块的例化
14 .key(key),
15 .clk(clk),
16 .rst_n(rst_n),
17 .data(data)
18 );
19
20
21 seg SEG( //数码管模块的裂化
22 .clk(clk),
23 .rst_n(rst_n),
24 .sel(sel),
25 .seg7(seg_n),
26 .data_in(hex)
27 );
28
29
30 endmodule
设计模块
0 module rd_rom (key, clk, rst_n, addr);
1
2 input clk; //输入系统时钟
3 input rst_n; //输入系统复位
4 input key; //按键控制
5
6 output reg [3:0] addr;
7 reg [31:0] cnt;
8
9 always @ (posedge clk or negedge rst_n)
10 begin
11 if(!rst_n) //异步复位
12 addr <= 0;
13 else if (addr < 15 && key == 0 && cnt == 50000000/2 - 1)
14 addr <= addr + 1'b1; //地址加1
15 else
16 addr <= addr;
17 end
18
19 always @ (posedge clk or negedge rst_n)
20 begin
21 if(!rst_n)
22 begin
23 cnt<=0;
24 end
25 else
26 begin
27 if(cnt < 50000000/2 - 1) // 50000000/10000/2 1hz的一 28 cnt <=cnt + 1;
29 else
30 cnt <= 0;
31 end
32 end
33 endmodule
测试模块
0 `timescale 1ns/1ps
1
2 module rom_seg_tb;
3
4 reg clk;
5 reg rst_n;
6 reg key;
7
8 wire [2:0] sel;
9 wire [7:0] seg_n;
10
11 initial begin
12 clk = 0;
13 rst_n = 0;
14 key = 1;
15
16 #200.1 rst_n=1;
17 #200
18 forever
19 begin
20 #50 key = 1; //模拟按键
21 #50 key = 0;
22 end
23 end
24
25 always #10 clk = ~clk;
26
27 rom_seg rom_seg_dut( //例化顶层模块
28 .clk(clk),
29 .rst_n(rst_n),
30 .key(key),
31 .sel(sel),
32 .seg_n(seg_n)
33 );
34
35 endmodule
仿真图:
在设计我们可以看到我们读出了第一个数,然后下面的数我们可以调整我们的计数单元来通过显示。
数码管模块我们可以用我们以前的 或者下面的:
0 module seg(clk,rst_n,sel,seg7,data_in); //端口定义
1
2 input clk;
3 input rst_n;
4 input [23:0] data_in; //输入6个灯的数据
5
6 output reg [2:0] sel;
7 output reg [7:0] seg7;
8
9 parameter s0 = 3'b000;
10 parameter s1 = 3'b001;
11 parameter s2 = 3'b010;
12 parameter s3 = 3'b011;
13 parameter s4 = 3'b100;
14 parameter s5 = 3'b101;
15
16 //`define T1ms 50_000 //定义1k的计数值
17 `define T1ms 5
18 reg [15:0] count;
19 wire flag;
20 always @ (posedge clk or negedge rst_n)
21 if(!rst_n)
22 begin
23 count <= 15'b0;
24 end
25 else
26 if(count == `T1ms - 1) //计数到1MS
27 begin
28 count <= 15'b0;
29 end
30 else
31 begin
32 count <= count + 1'b1;
33 end
34
35 assign flag =(count == `T1ms - 1) ? 1'b1 : 1'b0; //标志位赋值
36
37 reg [2:0] state;
38 reg [3:0] num;
39 always @ (posedge clk or negedge rst_n)
40 if(!rst_n)
41 begin
42 sel <= 3'b0;
43 state <= 3'b0;
44 num <= 4'b0;
45 end
46 else
47 begin
48 case (state)
49 s0:begin
50 if(flag)
51 state <= s1; //亮第一个灯,给24位数据的 4位
52 else
53 begin
54 sel <= 3'b000;
55 num <= data_in[23:20];
56 end
57 end
58 s1:begin
59 if(flag) ////亮第2个灯,给24位数据 的4位
60 state <= s2;
61 else
62 begin
63 sel <= 3'b001;
64 num <= data_in[19:16];
65 end
66 end
67 s2:begin
68 if(flag) //亮第3个灯,给24位数据的 4位
69 state <= s3;
70 else
71 begin
72 sel <= 3'b010;
73 num <= data_in[15:12];
74 end
75 end
76 s3:begin
77 if(flag) //亮第4个灯,给24位数据的4位
78 state <= s4;
79 else
80 begin
81 sel <= 3'b011;
82 num <= data_in[11:8];
83 end
84 end
85 s4:begin
86 if(flag) //亮第5个灯,给24位数据的4位
87 state <= s5;
88 else
89 begin
90 sel <= 3'b100;
91 num <= data_in[7:4];
92 end
93 end
94 s5:begin
95 if(flag) //亮第6个灯,给24位数据的4位
96 state <= s0;
97 else
98 begin
99 sel <= 3'b101;
100 num <= data_in[3:0];
101 end
102 end
103 default:state <= s0;
104 endcase
105 end
106
107 always @ (*) //数码管的译码模块
108 begin
109 case (num)
110 0:seg7 = 8'b1100_0000;
111 1:seg7 = 8'b1111_1001;
112 2:seg7 = 8'b1010_0100;
113 3:seg7 = 8'b1011_0000;
114 4:seg7 = 8'b1001_1001;
115 5:seg7 = 8'b1001_0010;
116 6:seg7 = 8'b1000_0010;
117 7:seg7 = 8'b1111_1000;
118 8:seg7 = 8'b1000_0000;
119 9:seg7 = 8'b1001_0000;
120 10:seg7 = 8'b1000_1000;
121 11:seg7 = 8'b1000_0011;
122 12:seg7 = 8'b1100_0110;
123 13:seg7 = 8'b1010_0001;
124 14:seg7 = 8'b1000_0110;
125 15:seg7 = 8'b1000_1110;
126 default:;
127 endcase
128 end
129 endmodule
全部0条评论
快来发表一下你的评论吧 !