我是靠谱客的博主 美好流沙,这篇文章主要介绍Verilog RTL代码新手上路教程1. 多路选择器2. 交叉开关3.优先编码器4. 多路译码器8.乘法器9.计数器10.状态机11.移位寄存器,现在分享给大家,希望可以做个参考。

1. 多路选择器

 

学生实验

做一个4选1的mux,并且进行波形仿真 和2选1的mux对比,观察资源消耗的变化

复制代码
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
//MUX21 module top(   IN0       ,   // input 1   IN1       ,   // input 2   SEL       ,   // select   OUT       );  // out data parameter WL = 16;      // 输入输出数据信号位宽 input [WL-1:0] IN0, IN1;// 选择器的两个输入数据信号 input SEL;              // 通道选通的控制信号 output[WL-1:0] OUT;     // 选择器的输入数据信号 reg   [WL-1:0] OUT; // 生成组合逻辑的代码 always @ (IN0 or IN1 or SEL) begin   if(SEL) // SEL为1 选择输入1     OUT = IN1;   else    // SEL为0 选择输入0     OUT = IN0; end endmodule
复制代码
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
//MUX41 // module  top41, 选择器(mux41)的代码, module top41(   IN0       ,   // input 1   IN1       ,   // input 2   IN2       ,   // input 3   IN3       ,   // input 4   SEL       ,   // select1,2   OUT       );  // out data parameter WL = 16;      // 输入输出数据信号位宽 input [WL-1:0] IN0, IN1, IN2, IN3;// 选择器的两个输入数据信号 input [1:0] SEL;              // 通道选通的控制信号 output[WL-1:0] OUT;     // 选择器的输入数据信号 reg   [WL-1:0] OUT; // 生成组合逻辑的代码 always @ (IN0 or IN1 or IN2 or IN3 or SEL) begin   //if(SEL=3) // SEL为1 选择输入1     //OUT = IN1;   //else    // SEL为0 选择输入0     //OUT = IN0;   case(SEL)       0: OUT=IN0;           1: OUT=IN1;           2: OUT=IN2;           3: OUT=IN3;           default: OUT=0;           endcase end endmodule // endmodule top

图像对比

4选1资源消耗是2选1MUX的两倍

2. 交叉开关

学生实验

编写一个4X4路交叉开关的RTL,然后编译,看RTL View 比较2x2与4x4之间消耗资源的区别。通过对比资源,你有什么结论? 返回顶部

复制代码
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
// module  top, a 2x2 crossbar switch circuit module top(   IN0       ,   // input 1   IN1       ,   // input 2   SEL0      ,   // select the output0 source   SEL1      ,   // select the output1 source   OUT0      ,   // output data 0   OUT1      );  // output data 1 parameter WL = 16; input [WL-1:0] IN0, IN1; input SEL0, SEL1; output[WL-1:0] OUT0, OUT1; reg   [WL-1:0] OUT0, OUT1; // get the OUT0 always @ (IN0 or IN1 or SEL0) begin   if(SEL0)     OUT0 = IN1;   else     OUT0 = IN0; end // get the OUT1 always @ (IN0 or IN1 or SEL1) begin   if(SEL1)     OUT1 = IN1;   else     OUT1 = IN0; end endmodule
复制代码
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
// module  top, a 4x4 crossbar switch circuit module top(   IN0       ,   // input 1   IN1       ,   // input 2   IN2       ,   // input 3   IN3       ,   // input 4   SEL0      ,   // select the output0 source   SEL1      ,   // select the output1 source   SEL2      ,   // select the output2 source   SEL3      ,   // select the output3 source   OUT0      ,   // output data 0   OUT1      ,   // output data 1   OUT2      ,   // output data 2   OUT3      );  // output data 3 parameter WL = 16; input [WL-1:0] IN0, IN1, IN2, IN3; input SEL0, SEL1, SEL2, SEL3; output[WL-1:0] OUT0, OUT1, OUT2, OUT3; reg   [WL-1:0] OUT0, OUT1, OUT2, OUT3; // get the OUT0 always @ (IN0 or IN1 or IN2 or IN3 or SEL0 or SEL1) begin   if(SEL0==0&&SEL1==0)     OUT0 = IN0;   else if(SEL0==0&&SEL1==1)     OUT0 = IN1;   else if(SEL0==1&&SEL1==0)     OUT0 = IN2;   else     OUT0 = IN3; end // get the OUT1 always @ (IN0 or IN1 or IN2 or IN3 or SEL1 or SEL2) begin   if(SEL1==0&&SEL2==0)     OUT1 = IN0;   else if(SEL1==0&&SEL2==1)     OUT1 = IN1;   else if(SEL1==1&&SEL2==0)     OUT1 = IN2;   else     OUT1 = IN3; end // get the OUT2 always @ (IN0 or IN1 or IN2 or IN3 or SEL2 or SEL3) begin   if(SEL2==0&&SEL3==0)     OUT2 = IN0;   else if(SEL2==0&&SEL3==1)     OUT2 = IN1;   else if(SEL2==1&&SEL3==0)     OUT2 = IN2;   else     OUT2 = IN3; end // get the OUT3 always @ (IN0 or IN1 or IN2 or IN3 or SEL0 or SEL3) begin   if(SEL0==0&&SEL3==0)     OUT3 = IN0;   else if(SEL0==0&&SEL3==1)     OUT3 = IN1;   else if(SEL0==1&&SEL3==0)     OUT3 = IN2;   else     OUT3 = IN3; end endmodule

  

 

  资源对比:

3.优先编码器

学生实验

  • 编写一个8输入的优先编码器,然后编译,看RTL View
复制代码
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
// module top, 4 input priority encoder with zero input check module top(   IN        ,   // input    OUT       );  // output input [3:0] IN; output[2:0] OUT; reg   [2:0] OUT; // get the OUT always @ (IN) begin    if(IN[3])       // 第一优先      OUT = 3'b011;    else if(IN[2])  // 第二优先      OUT = 3'b010;    else if(IN[1])  // 第三优先      OUT = 3'b001;    else if(IN[0])  // 第四优先      OUT = 3'b000;    else            // 什么都没有检测到      OUT = 3'b111; // 输出值可自定义,不和上面的输出值混淆即可 end endmodule
复制代码
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
// module top, 8 input priority encoder with zero input check module top(   IN        ,   // input    OUT       );  // output input [7:0] IN; output[3:0] OUT; reg   [3:0] OUT; // get the OUT always @ (IN) begin    if(IN[7])       // 第一优先      OUT = 4'b0111;    else if(IN[6])  // 第二优先      OUT = 4'b0110;    else if(IN[5])  // 第三优先      OUT = 4'b0101;    else if(IN[4])  // 第四优先      OUT = 4'b0100;    else if(IN[3])  // 第五优先      OUT = 4'b0011;    else if(IN[2])  // 第六优先      OUT = 4'b0010;    else if(IN[1])  // 第七优先      OUT = 4'b0001;    else if(IN[0])  // 第八优先      OUT = 4'b0000;    else            // 什么都没有检测到      OUT = 4'b1111; // 输出值可自定义,不和上面的输出值混淆即可 end endmodule

4. 多路译码器

学生实验

  • 编写一个4-16的译码器,编译
  • 和3-8译码器对比资源开销
  • 看RTL View
复制代码
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
// module top, 3 to 8 decoder module top(   IN        ,   // input    OUT       );  // output input [2:0] IN; output[7:0] OUT; reg   [7:0] OUT; // get the OUT always @ (IN) begin   case(IN)     3'b000: OUT = 8'b0000_0001;     3'b001: OUT = 8'b0000_0010;     3'b010: OUT = 8'b0000_0100;     3'b011: OUT = 8'b0000_1000;     3'b100: OUT = 8'b0001_0000;     3'b101: OUT = 8'b0010_0000;     3'b110: OUT = 8'b0100_0000;     3'b111: OUT = 8'b1000_0000;     //  full case 不需要写default,否则一定要有default   endcase end endmodule
复制代码
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
​ // module top, 4 to 16 decoder module top(   IN        ,   // input    OUT       );  // output input [3:0] IN; output[15:0] OUT; reg   [15:0] OUT; // get the OUT always @ (IN) begin   case(IN)     4'b0000: OUT = 16'b0000_0000-0000_0001;     4'b0001: OUT = 16'b0000_0000-0000_0010;     4'b0010: OUT = 16'b0000_0000-0000_0100;     4'b0011: OUT = 16'b0000_0000-0000_1000;     4'b0100: OUT = 16'b0000_0000-0001_0000;     4'b0101: OUT = 16'b0000_0000-0010_0000;     4'b0110: OUT = 16'b0000_0000-0100_0000;     4'b0111: OUT = 16'b0000_0000-1000_0000;      4'b1000: OUT = 16'b0000_0001-0000_0000;     4'b1001: OUT = 16'b0000_0010-0000_0000;     4'b1010: OUT = 16'b0000_0100-0000_0000;     4'b1011: OUT = 16'b0000_1000-0000_0000;     4'b1100: OUT = 16'b0001_0000-0000_0000;     4'b1101: OUT = 16'b0010_0000-0000_0000;     4'b1110: OUT = 16'b0100_0000-0000_0000;     4'b1111: OUT = 16'b1000_0000-0000_0000;     //  full case 不需要写default,否则一定要有default   endcase end endmodule

5.无符号加法器

输入和输出数据都是无符号的整数,常用于计数器累加和计算地址序号

要点

  • 目测一下,可以发现加法器的输入数据和对应结果在时间上是有延迟的,这是组合逻辑门的延迟造成的。(请估算一下延迟长度)
  • 在相邻的两个正确的输出结果之间是有些“毛刺”结果的,而且“毛刺”的时间长度还不同
  • 请思考,2比特的信号,00翻转成11,两个位能做到绝对的同时翻转么?
  • 请思考,对比一下,00翻转成11,和 00翻转成 10,哪个变化的多?哪个翻转过程中的过渡状态多?
  • 注意输入和输出的信号位宽数
  • 请思考,如果本例中,所有输入信号和输出信号宽度都是4比特,那么输出结果会一直正确么?

学生实验

  • 把加法器的输出信号改成4比特位宽,编译,波形仿真。观察输出结果,说出输出和输入的对应关系。
  • 把加法器的输入信号改成8比特位宽,编译,波形仿真。观察加法器的输出延迟,和4比特输入位宽的情况对比,你有什么结论,为什么?
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//module top,unsigned adder 4 bit module top(   IN1   ,   IN2   ,   OUT   ); input[3:0] IN1, IN2; output[4:0] OUT; reg[4:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块   OUT = IN1 + IN2; end endmodule

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//module top,unsigned adder 8 bit module top(   IN1   ,   IN2   ,   OUT   ); input[7:0] IN1, IN2; output[7:0] OUT; reg[8:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块   OUT = IN1 + IN2; end endmodule

1.延迟12-14ns左右

2.2比特的信号,00翻转成11,两个位不能做到绝对的同时翻转。

3. 00翻转成10翻转过程中的过渡状态多。

8bit输入延迟大于4bit输入延迟。因为8bit输入涉及的位数更多,每一位的延迟叠加,自然会使延迟更大。

6.补码加法器

输入和输出数据都是2补码形式的有符号数,常用于数字信号处理电路

学生实验

把加法器的输出信号改成4比特位宽,编译,波形仿真。观察输出结果,观察输出结果在什么时候是正确的?。 把加法器的输入信号改成8比特位宽,编译,波形仿真。观察加法器的输出延迟,和4比特输入位宽的情况对比,你有什么结论,为什么?

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module top(   IN1   ,   IN2   ,   OUT   ); input signed [3:0] IN1, IN2; output signed [4:0] OUT; reg signed [4:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块   OUT = IN1 + IN2; end endmodule

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//4bit module top(   IN1   ,   IN2   ,   OUT   ); input signed [3:0] IN1, IN2; output signed [3:0] OUT; reg signed [3:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块   OUT = IN1 + IN2; end endmodule

4比特位宽的输出最高位为符号位,而输出范围为:-7~7,即输出值在-7~7内计算结果正确,但超出该范围则计算错误。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//输入为8bit module top(   IN1   ,   IN2   ,   OUT   ); input signed [7:0] IN1, IN2; output signed [7:0] OUT; reg signed [12:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块   OUT = IN1 + IN2; end endmodule

 观察可得,8bit输入与4bit输入延迟差别不大。
7.带流水线的加法器

 

学生实验

不改变流水线的级数,把加法器的输入信号改成8比特位宽,编译,波形仿真,和不带流水线的情况对比一下,你有什么结论? 在8比特输入位宽的情况下,在输入上再添加一级流水线,观察编译和仿真的结果,你有什么结论?

复制代码
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
//4bit带宽 module top(   IN1   ,   IN2   ,   CLK   ,   OUT   ); input  [3:0] IN1, IN2; input CLK; output  [4:0] OUT; reg [3:0] in1_d1R, in2_d1R; reg  [4:0] adder_out, OUT; always@(posedge CLK) begin // 生成D触发器的always块   in1_d1R <= IN1;   in2_d1R <= IN2;   OUT     <= adder_out; end always@(in1_d1R or in2_d1R) begin // 生成组合逻辑的always 块   adder_out = in1_d1R + in2_d1R; end endmodule

带流水线的波形

不带流水线的波形

可以观察到,带流水线的波形毛刺明显少于不带流水线的波形。而带流水线的加法器输入数据和其对应的结果不在一个时钟周期。
 

复制代码
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
//8bit带宽带流水线的波形 module top(   IN1   ,   IN2   ,   CLK   ,   OUT   ); input  [7:0] IN1, IN2; input CLK; output  [12:0] OUT; reg [7:0] in1_d1R, in2_d1R; reg  [12:0] adder_out, OUT; always@(posedge CLK) begin // 生成D触发器的always块   in1_d1R <= IN1;   in2_d1R <= IN2;   OUT     <= adder_out; end always@(in1_d1R or in2_d1R) begin // 生成组合逻辑的always 块   adder_out = in1_d1R + in2_d1R; end endmodule

不改变流水线的级数,把加法器的输入信号改成8比特位宽,编译,波形仿真,和不带流水线的情况对比一下,与4比特位宽和不带流水线的波形无差别。

复制代码
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
在8比特输入位宽的情况下,在输入上再添加一级流水线 module top(   IN1   ,   IN2   ,   CLK   ,   OUT   ); input  [7:0] IN1, IN2; input CLK; output  [12:0] OUT; reg [7:0] in1_d1R, in2_d1R, in1_d2R, in2_d2R; reg  [12:0] adder_out, OUT; always@(posedge CLK) begin // 生成D触发器的always块   in1_d1R <= IN1;   in2_d1R <= IN2;   in1_d2R <= in1_d1R;   in2_d2R <= in2_d1R;   OUT     <= adder_out; end always@(in1_d1R or in2_d1R) begin // 生成组合逻辑的always 块   adder_out = in1_d2R + in2_d2R; end endmodule

对比发现,流水线的个数越多,毛刺越少,实验会逐次增加一个时钟周期。

8.乘法器

 

学生实验

  • 改变乘法器的输入位宽为8比特,编译,波形仿真,观察信号毛刺的时间长度。
  • 选一款没有硬件乘法器的FPGA芯片(例如Cyclone EP1C6)对比8比特的乘法器和加法器两者编译之后的资源开销(Logic Cell的数目)
  • 编写一个输入和输出都有D触发器的流水线乘法器代码,编译后波形仿真,观察组合逻辑延迟和毛刺的时间,和不带流水线的情况下对比。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  无符号4比特的乘法器  / module top(   IN1   ,   IN2   ,   OUT   );  input [3:0] IN1, IN2;  output [7:0] OUT;  reg [7:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块   OUT = IN1 * IN2; end endmodule

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  无符号8比特的乘法器  / module top(   IN1   ,   IN2   ,   OUT   );  input [7:0] IN1, IN2;  output [12:0] OUT;  reg [12:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块   OUT = IN1 * IN2; end endmodule

观察可知,毛刺数量非常多。

2.换成没有硬件乘法器的芯片

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
///一个输入和输出都有D触发器的流水线乘法器代码/// module top(   CLK   ,   IN1   ,   IN2   ,   OUT   ); input [3:0] IN1, IN2; input CLK; output [7:0] OUT; reg [3:0] in1, in2; reg [7:0] D_out, OUT; always @ (posedge CLK) begin  in1 <= IN1;  in2 <= IN2;  OUT <= D_out; end always @ (in1 or in2) begin // 生成组合逻辑的always 块  D_out = in1 * in2; end endmodule 

9.计数器

 

学生实验

请完成以下设计实验,编译电路并且进行波形仿真。

  • 设计一个最简单的计数器,只有一个CLK输入和一个OVerflow输出,当计数到最大值的时钟周期CLK输出1
  • 设计复杂的计数器,和本例相似,带有多种信号,其中同步清零CLR的优先级最高,使能EN次之,LOAD最低。
复制代码
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
//最简单的计数器代码  // module top(   CLK   , // 时钟,上升沿有效   CNTVAL,   OV  );// 计数溢出信号,计数值为最大值时该信号为1 input CLK; output [3:0] CNTVAL; output OV;   reg [3:0] CNTVAL, cnt_next; reg OV; // 电路编译参数,最大计数值 parameter CNT_MAX_VAL = 15; always @ (posedge CLK ) begin  CNTVAL <= CNTVAL + 1; end // 组合逻辑,生成OV always @ (CNTVAL) begin   if(CNTVAL == CNT_MAX_VAL)     OV = 1;   else     OV = 0; end endmodule

复制代码
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
复杂计数器代码  / //同步清零CLR的优先级最高,使能EN次之,LOAD最低 module top(   RST   , // 异步复位, 高有效   CLK   , // 时钟,上升沿有效   EN    , // 输入的计数使能,高有效   CLR   , // 输入的清零信号,高有效   LOAD  , // 输入的数据加载使能信号,高有效   DATA  , // 输入的加载数据信号   CNTVAL, // 输出的计数值信号   OV    );// 计数溢出信号,计数值为最大值时该信号为1 input RST   , CLK   , EN    , CLR   , LOAD  ; input [3:0] DATA ; output [3:0] CNTVAL; output OV;   reg [3:0] CNTVAL, cnt_next; reg OV; // 电路编译参数,最大计数值 parameter CNT_MAX_VAL = 9; // 组合逻辑,生成cnt_next //同步清零CLR的优先级最高,使能EN次之,LOAD最低 always @(EN or CLR or LOAD or DATA or CNTVAL) begin   if(CLR) begin // 清零有效       cnt_next = 0;     end     else begin //      if(EN) begin    // 使能有效       if(LOAD) begin // 加载有效         cnt_next = DATA;       end       else begin     // 加载无效,正常计数         // 使能有效,清零和加载都无效,根据当前计数值计算下一值         if(CNTVAL < CNT_MAX_VAL) begin // 未计数到最大值, 下一值加1           cnt_next = CNTVAL + 1'b1;         end         else begin // 计数到最大值,下一计数值为0           cnt_next = 0;         end       end // else LOAD      end // if EN    else begin  // 使能无效,计数值保持不动      cnt_next = CNTVAL;    end // else EN  end  // else CLR end // 时序逻辑 更新下一时钟周期的计数值 // CNTVAL 会被编译为D触发器 always @ (posedge CLK or posedge RST) begin   if(RST)     CNTVAL <= 0;   else     CNTVAL <= cnt_next; end // 组合逻辑,生成OV always @ (CNTVAL) begin   if(CNTVAL == CNT_MAX_VAL)     OV = 1;   else     OV = 0; end endmodule

10.状态机

学生实验

设计一个用于识别2进制序列“1011”的状态机

  • 基本要求:
  • 电路每个时钟周期输入1比特数据,当捕获到1011的时钟周期,电路输出1,否则输出0
  • 使用序列101011010作为输出的测试序列
  • 扩展要求:
  • 给你的电路添加输入使能端口,只有输入使能EN为1的时钟周期,才从输入的数据端口向内部获取1比特序列数据。
复制代码
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
  三段式状态机代码设计一个用于识别2进制序列“1011”的状态机  /// module top(   CLK       ,   // clock   RST       ,   // reset   EN        ,   // en   CENT1IN   ,   // input 1 cent coin   TINOUT    );  // output 1 tin cola input  CLK       ; input  RST       ; input  EN,CENT1IN   ; output TINOUT    ; parameter ST_0_CENT = 0; parameter ST_1_CENT = 1; parameter ST_2_CENT = 2; parameter ST_3_CENT = 3; parameter ST_4_CENT = 4; reg [4-2:0]stateR       ; reg [4-2:0]next_state   ; reg        TINOUT       ; // calc next state always @ (CENT1IN or stateR) begin   if(EN) begin   case (stateR)     ST_0_CENT :begin if(CENT1IN==1) next_state = ST_1_CENT ; else next_state = ST_0_CENT; end     ST_1_CENT :begin if(CENT1IN==0) next_state = ST_2_CENT ; else next_state = ST_0_CENT; end     ST_2_CENT :begin if(CENT1IN==1) next_state = ST_3_CENT ; else next_state = ST_0_CENT; end     ST_3_CENT :begin if(CENT1IN==1) next_state = ST_4_CENT ; else next_state = ST_0_CENT; end     ST_4_CENT :begin next_state = ST_0_CENT; end   endcase   end   else   next_state = ST_0_CENT; end // calc output always @ (stateR) begin   if(stateR == ST_4_CENT)     TINOUT = 1'b1;   else     TINOUT = 1'b0; end // state DFF always @ (posedge CLK or posedge RST)begin   if(RST)     stateR <= ST_0_CENT;   else     stateR <= next_state; end endmodule

 

 

11.移位寄存器

学生实验

设计一个如本节“电路描述”部分的“带加载使能和移位使能的并入串出”的移位寄存器,电路的RTL结构图如“电路描述”部分的RTL结构图所示。

复制代码
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
“带加载使能和移位使能的并入串出”的移位寄存器 / module top(   RST   ,   // 异步复位, 高有效   CLK   ,   // 时钟,上升沿有效   EN    ,   // 输入数据串行移位使能   LOAD  ,   // 输入数据带加载使能   IN    ,   // 输入串行数据   OUT   );  // 并行输出数据 input RST, CLK, EN, LOAD; input [3:0]IN; output[3:0] OUT; reg [3:0] shift_R; assign OUT[3:0] = shift_R[3:0]; // 时序逻辑 根据输入使能进行串行移位 // shift_R 会被编译为D触发器 always @ (posedge CLK or posedge RST or posedge LOAD) begin   if(RST)     shift_R[3:0] <= 0;   else begin     if(LOAD) begin       shift_R[3:0] <= IN[3:0];     end     else begin       if(EN) begin // 串行移位的使能有效         shift_R[3:1] <= shift_R[2:0];         shift_R[0]   <= 0;       end       else begin // 使能无效保持不动         shift_R[3:0] <= shift_R[3:0];       end      end    end end // always endmodule

最后

以上就是美好流沙最近收集整理的关于Verilog RTL代码新手上路教程1. 多路选择器2. 交叉开关3.优先编码器4. 多路译码器8.乘法器9.计数器10.状态机11.移位寄存器的全部内容,更多相关Verilog内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(72)

评论列表共有 0 条评论

立即
投稿
返回
顶部