Verilog HDL学习_1:分频器/PWM的实现

(一)参考学习资料

 

(二)实际操作

1. 相关变量计算:

 

First Initial

Second Initial

Upper case

H

X

ASCII (Dec)

72

88

Lengths of the pulse

   

Mu

Mu_1

2.5*105

Mu_2

2.5*105

k : mu

ku_1 : mu_1

1.2812:3.7188

ku_2 : mu_2

1.3438:3.6562

nu

nu_1

18

nu_2

18

Ku

Ku_1

64060

Ku_2

67190

Lower case

h

x

ASCII (Dec)

104

120

Lengths of the pulse

   

Ml

Ml_1

2.5*105

Ml_2

2.5*105

k : ml

kl_1 : ml_1

1.4063:3.5937

k : ml_2

1.4688:3.5312

nl

nl_1

18

nl_2

18

Kl

Kl_1

70315

Kl_2

73440

 

 

2. 第一版:

 1 module Assignment2(rst, CP, Z);
 2     input CP;
 3     input rst;  //1 for upper & 0 for lower
 4     
 5     reg turn = 0;
 6     reg [1:0] cyc = 0; //use for the number of cycles
 7     
 8     //constant parameters
 9     parameter k = 100, n = 8, K = 100;
10     parameter KK = K-1;
11     
12     //take parameters according to rst input
13     reg [7:0] M;
14     reg [7:0] MM;
15     reg [4:0] m;
16     //output of the lautch
17     output Z;
18     reg Z;
19     
20     
21     //parameters of upper case
22     parameter [7:0] Mu [0:1] = {128, 134};
23     parameter [4:0] mu [0:1] = {28, 34}; 
24     //parameter Ku_1 = k*Mu_1/(k+mu_1);
25     parameter [7:0] MMu [0:1] = {127, 133};
26     //Parameter []KKu_1 = Ku_1-1;
27     

34     //parameters of lower case
35     parameter [7:0] Ml [0:1] = {141, 147};
36     parameter [4:0] ml [0:1] = {41, 47}; 
37     parameter [7:0] MMl [0:1] = {127, 133};
38 
39     //Check rst to determine upper or lower.
40     //check the number of turn to determine the first two or the second.
41     always@(posedge CP)
42     begin
43         if(rst)
44             begin
45             M <= turn ? Mu[1]:Mu[0];
46             m <= turn ? mu[1]:mu[0];
47             MM <= turn ? MMu[1]:MMu[0];
48             end
49         else if(!rst)
50             begin
51             M <= turn ? Ml[1]:Ml[0];
52             m <= turn ? ml[1]:ml[0];
53             MM <= turn ? MMl[1]:MMl[0];
54             end
55     end
56     
57     //Latch
58     reg [n-1:0] Q = 0;
59     wire ld, cz;
60     assign ld = Q>=MM;
61     assign cz = (Q<KK)|ld;
62     
63     always@(posedge CP) 
64     begin
65         {Q,Z} <= {ld?0:Q+1, cz};
66         cyc = ld ? cyc+1 : cyc;
67         
68         if(cyc == 2) 
69             begin
70             turn <= 1;
71             cyc <= 0;
72             end
73         else begin
74             turn <= 0;
75             end
76     end
77         
78         
79 endmodule

 

  • 出现问题1:

解决方案:将如下部分的变量类型由reg改为了input,系统没有再次崩溃。

12     //take parameters according to rst input
13     reg [7:0] M;
14     reg [7:0] MM;
15     reg [4:0] m;
16     //output of the lautch
17     output Z;
18     reg Z;

原因:不明

补充:reg变量不可按位赋值,在二维数组中的赋值应为下图第一种方法。

// Correct
M <=Mu[1];

// Wrong
M <=Mu[1][7:0];

 

  • 出现问题2:vwf文件仿真时,M没有成功赋值

解决方案:修正了对reg宽度的定义。

补充:

1. Verilog中reg类型的宽度是自定义的,若无定义则默认为1bit。reg的宽度影响变量的取值,若赋值超出reg的范围,不会产生Error,reg变量的最大值将被默认为reg宽度。修改变量时应注意该变量的取值范围。

2. reg变量只能存储整数,允许的运算为加减乘除,若要实现浮点数需要以此为基础构建相关专门的模块。

 

3. 第二版:

 1 module Assignment2(rst, CP, Z, K);
 2     input CP;
 3     input rst;  //1 for upper & 0 for lower
 4     
 5     reg turn = 0; 
 6     //use to determine whether the first group of pulses or the second one
 7     reg [3:0] cyc = 0; 
 8     //use for the number of pulses in one 'turn'
 9     
10     ////constant parameters
11     parameter n = 18, M = 250000;
12     parameter MM = M-1;
13     
14     ////take parameters according to rst input
15     output [n-1:0] K;
16     reg [n-1:0] K = 0;
17 
18     ////output of the lautch
19     output Z;
20     reg Z;
21     
22     ////parameters of upper case
23     parameter Ku_1 = 64060; 
24     parameter Ku_2 = 67190; 
25 
26     ////parameters of lower case
27     parameter Kl_1 = 70315; 
28     parameter Kl_2 = 73440; 
29     
30     ////Latch
31     reg [n-1:0] Q;
32     wire ld, cz;
33     assign ld = Q>=MM;
34     assign cz = (Q<K-1)|ld;
35     
36     always@(posedge CP) 
37     begin
38         ////Check rst to determine upper or lower.
39         ////check the number of turn to determine the first two or the second.    
40         case(rst)
41         0: begin
42                 if(turn)K <= Kl_2;
43                 else if(!turn)K <= Kl_1;
44                 else K <= 100;
45             end
46         1: begin
47                 if(turn)K <= Ku_2;
48                 else if(!turn)K <= Ku_1;
49                 else K <= 200;
50             end
51         default: K <= 9999999;
52         endcase
53         
54         ////renew the state and output clock.
55         {Q,Z} <= {ld?0:Q+1, cz};
56         cyc = ld ? cyc+1 : cyc;
57         
58         ////1 cyc represent a pulse
59         ////2 cycles cause an increment in turn
60         ////4 cycles for an entire loop 
61         if(cyc == 2) 
62             begin
63             turn <= 1;
64             end
65         else if(cyc==4 && turn==1)
66             begin
67             turn <= 0;
68             cyc <= 0;
69             end
70 
71     end
72         
73 endmodule

 

  • 仿真结果://K的取值有修改。
  • 补充:在Z的第一个输出前有一小段空白期,测量为微秒级,第一个输出仍为5ms。感觉应该不影响时钟的使用,但没有经过硬件检测。

 

posted @ 2020-02-26 18:23  伏延  阅读(904)  评论(3编辑  收藏  举报