Verilog 实际开发代码示例

FPGA中利用硬件描述语言进行分频(有时候硬件资源不足时,只能自己搭建分频)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
module top_module ();
reg clk=0;
always #5 clk = ~clk; // Create clock with period=10
initial `probe_start; // Start the timing diagram

`probe(clk); // Probe signal "clk"

// A testbench
reg rst=0;
reg en=0;
reg[2:0] sys_freSel;
wire out_clk;

initial begin
#10 rst <= 0;
#10 rst <= 1;
#20 rst <= 0;
sys_freSel<= 3'd6;
#20 rst <= 1;
en <= 1;

$display ("Hello world! The current time is (%0d ps)", $time);
#5000 $finish; // Quit the simulation
end

//invert inst1 (.in(rst),.clk(clk) ); // Sub-modules work too.
Frequency Fre(.sys_rst(rst),
.sys_clk(clk),
.sys_en(en),
.sys_freSel(sys_freSel),
.reg_clk(out_clk)
);
`probe(rst);
`probe(en);
`probe(sys_freSel);
`probe(out_clk);

endmodule

module Frequency(
input sys_rst, //系统复位信号
input sys_clk, //系统时钟信号
input sys_en, //系统使能
input [2:0] sys_freSel, //
output reg_clk
) ;

//--------port-----------------

reg [2:0] reg_FreSele; /* 分频选择器 */

reg reg_div2; /* 分频 */
reg reg_div4; /* 分频 */
reg reg_div8; /* 分频 */
reg reg_div16; /* 分频 */
reg reg_div32; /* 分频 */
reg reg_div64; /* 分频 */
reg reg_div128; /* 分频 */

reg reg_clk; /* 输出时钟 */

reg [24:0] sys_en_count;


wire internal_sys_clk; /* 内部系统时钟 */

assign internal_sys_clk = sys_clk & sys_en;


/* 参数初始化函数 */
always @(negedge sys_rst or posedge sys_en) begin
if (!sys_rst) begin
reg_FreSele <= 3'd7;
end
else if(sys_en) begin
reg_FreSele <= sys_freSel;
end
else begin
reg_FreSele <= 3'd7;
end
end

// /* 添加时钟延时同步, */
// always @(posedge sys_clk or negedge sys_clk or negedge sys_rst) begin
// if(!sys_rst) begin
// internal_sys_clk <= 1'b0;
// end
// else begin
// internal_sys_clk <= sys_clk;
// end
// end

//posedge 上升沿
//negedge 下降沿

//对时钟信号进行2分频操作 ——|_| ——|_|
always @(posedge sys_clk or negedge sys_rst) begin
if(!sys_rst) begin
reg_div2 <= 1'b0; //非阻塞赋值
end
else begin
reg_div2 <= !reg_div2;
end
end

//对时钟信号4分频操作
always @(posedge reg_div2 or negedge sys_rst) begin
if(!sys_rst) begin
reg_div4 <= 1'b0; //非阻塞赋值
end
else begin
reg_div4 <= !reg_div4;
end
end

//对时钟信号8分频操作
always @(posedge reg_div4 or negedge sys_rst) begin
if(!sys_rst) begin
reg_div8 <= 1'b0; //非阻塞赋值
end
else begin
reg_div8 <= !reg_div8;
end
end

//对时钟信号16分频操作
always @(posedge reg_div8 or negedge sys_rst) begin
if(!sys_rst) begin
reg_div16 <= 1'b0; //非阻塞赋值
end
else begin
reg_div16 <= !reg_div16;
end
end

//对时钟信号32分频操作
always @(posedge reg_div16 or negedge sys_rst) begin
if(!sys_rst) begin
reg_div32 <= 1'b0; //非阻塞赋值
end
else begin
reg_div32 <= !reg_div32;
end
end

//对时钟信号64分频操作
always @(posedge reg_div32 or negedge sys_rst) begin
if(!sys_rst) begin
reg_div64 <= 1'b0; //非阻塞赋值
end
else begin
reg_div64 <= !reg_div64;
end
end

//对时钟信号128分频操作
always @(posedge reg_div64 or negedge sys_rst) begin
if(!sys_rst) begin
reg_div128 <= 1'b0; //非阻塞赋值
end
else begin
reg_div128 <= !reg_div128;
end
end

/* 选择输出的时钟频率 */
always @(negedge internal_sys_clk or negedge sys_rst) begin
if(!sys_rst) begin
reg_clk <= 1'b0;
end
else if(sys_en) begin
case (reg_FreSele)
0: reg_clk <= reg_div2;
1: reg_clk <= reg_div4;
2: reg_clk <= reg_div8;
3: reg_clk <= reg_div16;
4: reg_clk <= reg_div32;
5: reg_clk <= reg_div64;
6: reg_clk <= reg_div128;
7: reg_clk <= reg_clk;
default: reg_clk <= reg_clk;
endcase
end
end

endmodule

测试地址:https://hdlbits.01xz.net/wiki/Iverilog