基础数字电路的Verilog写法

  Verilog是硬件描述电路,我对此一直稀里糊涂,因而将锆石科技开发板附带的的一些基础数字电路Verilog程序整理记录下来,而且查看他们的RTL视图,总算有点理解了。git

  1.基本运算符ide

 1 module Example_Operation  2 (  3     input  [3:0] a ,  4     input  [3:0] b ,  5     input  [3:0] c ,  6     
 7     output [3:0] c1 ,  8     output [3:0] c2 ,  9     output [5:0] c3 , 10     output [3:0] c4 , 11     output [3:0] c5 , 12     output [3:0] d1 , 13     output [3:0] d2 , 14     output [3:0] d3 , 15     output [3:0] d4 , 16     output [3:0] e1 , 17     output [3:0] e2 , 18     output [3:0] e3 , 19     output [3:0] f1 , 20     output [3:0] f2 , 21     output [3:0] d11 , 22     output [3:0] c11 , 23     output [3:0] c22 , 24     output [3:0] c33 , 25     output [3:0] c44 , 26     output [3:0] c55 , 27     output [3:0] c66 , 28     output [3:0] e11 , 29     output [3:0] e22 , 30     output [7:0] f11 , 31     output [7:0] f22 32 ); 33 
34 //== waveform1 算数运算符 35 //======================================================================
36 assign c1 = a + b;      //
37 assign c2 = a - b;      //
38 assign c3 = a * b;      //
39 assign c4 = a / b;      //
40 assign c5 = a % b;      //求余 41 
42 //== waveform2 关系运算符 43 //======================================================================
44 assign d1 = a >  b;     //大于
45 assign d2 = a <  b;     //小于
46 assign d3 = a >= b;     //大于等于
47 assign d4 = a <= b;     //小于等于 48 
49 //== waveform3 逻辑运算符 50 //======================================================================
51 assign e1 = !a;         //
52 assign e2 = a && b;     //
53 assign e3 = a || b;     //54 
55 //== waveform4 逻辑等式运算符 56 //======================================================================
57 assign f1 = a == b;     //判断相等
58 assign f2 = a != b;     //判断不等 59 
60 //== waveform5 三目条件运算符 61 //======================================================================
62 assign d11 = a ? b : c; //a为真,则d11 = b 63                         //a为假,则d11 = c 64 
65 //== waveform6 位运算符 66 //======================================================================
67 assign c11 = ~a;        //取反
68 assign c22 = a & b;     //按位与
69 assign c33 = a | b;     //按位或
70 assign c44 = a ^ b;     //按位异或
71 assign c55 = a ~^ b;    //按位同或
72 assign c66 = a ^~ b;    //按位同或 73 
74 //== waveform7 移位运算符 75 //======================================================================
76 assign e11 = a << b;    //左移
77 assign e22 = a >> b;    //右移 78 
79 //== waveform8 位拼接运算符 80 //======================================================================
81 assign f11 = {a , b};   //拼接a和b,a和b位宽均为4,f11位宽为8
82 assign f22 = {2'd2{b}}; //拼接b低2位
83 
84 endmodule
View Code

 

  2.三人表决器 --- 结构描述方式模块化

 1 module Example_Structure  2 (  3     input       A   ,   //模块的输入端口A
 4     input       B   ,   //模块的输入端口B
 5     input       C   ,   //模块的输入端口C
 6     output      L       //模块的输出端口L
 7 );  8 
 9 //== 信号定义 10 //======================================================================
11 wire AB,BC,AC;          //内部信号声明AB,BC,AC
12 
13 and U1(AB,A,B);         //与门(A,B信号进入)(A与B信号即AB输出) 
14 and U2(BC,B,C);         //与门 同上
15 and U3(AC,A,C);         //与门 同上
16   
17 or  U4(L,AB,BC,AC);     //或门 同上
18      
19 endmodule
View Code

 

  3.三人表决器 --- 数据流描述方式学习

 1 module Example_Dataflow  2 (  3     input   A   ,     //模块的输入端口A
 4     input   B   ,     //模块的输入端口B
 5     input   C   ,     //模块的输入端口C
 6     output  L         //模块的输出端口L
 7 );  8 
 9 assign L = ((!A) & B & C) | (A & (!B) & C) | (A & B & (!C)) | (A & B & C); 10 
11 endmodule
View Code

 

  4.三人表决器 --- 行为描述方式编码

 1 module Example_Behavior  2 (  3     input           A   ,    //模块的输入端口A
 4     input           B   ,    //模块的输入端口B
 5     input           C   ,    //模块的输入端口C
 6     output reg      L        //模块的输出端口L
 7 );  8 
 9 always @(A,C,B)begin        //敏感列表只须要A、B、C,也能够写成always @(*)
10     case({A,B,C})           //注意{A,B,C}是位拼接,合成一条总线
11         3'b000: L = 1'b0; 12         3'b001: L = 1'b0; 13         3'b010: L = 1'b0; 14         3'b011: L = 1'b1; 15         3'b100: L = 1'b0; 16         3'b101: L = 1'b1; 17         3'b110: L = 1'b1; 18         3'b111: L = 1'b1; 19         default:L = 1'bx; //default不要省略
20     endcase
21 end
22 
23 endmodule
View Code

 

   5.模块化设计实现半加器spa

 1 module Example_Module  2 (  3     input a ,  4     input b ,  5     output s ,  6     output c  7 );  8 
 9 //== 实例化 与门 10 //======================================================================
11 Example_yumen yumen_module 12 ( 13  .yumen_a(a), 14  .yumen_b(b), 15  .yumen_c(c) 16 ); 17 
18 //== 实例化 异或 19 //======================================================================
20 Example_yihuo yihuo_module 21 ( 22  .yihuo_a(a), 23  .yihuo_b(b), 24  .yihuo_s(s) 25 ); 26 
27 endmodule
Top

 

 1 module Example_yihuo  2 (  3     input yihuo_a ,  4     input yihuo_b ,  5     output yihuo_s  6 );  7 
 8 assign yihuo_s = yihuo_a ^ yihuo_b;  9 
10 endmodule
Yihuo

 

 1 module Example_yumen  2 (  3     input yumen_a ,  4     input yumen_b ,  5     output yumen_c  6 );  7 
 8 assign yumen_c = yumen_a && yumen_b;  9 
10 endmodule
Yumen

 

6.8-1数据选择器设计

 1 module Digital_Selector  2 (  3     input D0 ,  4     input D1 ,  5     input D2 ,  6     input D3 ,  7     input D4 ,  8     input D5 ,  9     input D6 , 10     input D7 , 11     input      [ 2:0] A , 12     output reg [ 7:0] Y 13 ); 14 
15 always @(*)begin
16     case(A) 17         3'b000 : Y = D0;
18         3'b001 : Y = D1;
19         3'b010 : Y = D2;
20         3'b011 : Y = D3;
21         3'b100 : Y = D4;
22         3'b101 : Y = D5;
23         3'b110 : Y = D6;
24         3'b111 : Y = D7;
25         default: Y = 1'b0;
26     endcase
27 end
28 
29 endmodule
View Code

 

 

7.8-3编码器3d

 1 module Digital_Encoder  2 (  3     input      [ 7:0] I ,  4     output reg [ 2:0] A  5 );  6 
 7 //== case判断I,8位数转为3位数  8 //======================================================================
 9 always @(*)begin
10     case(I) 11         8'b0000_0001 : A = 3'b000; 12         8'b0000_0010 : A = 3'b001; 13         8'b0000_0100 : A = 3'b010; 14         8'b0000_1000 : A = 3'b011; 15         8'b0001_0000 : A = 3'b100; 16         8'b0010_0000 : A = 3'b101; 17         8'b0100_0000 : A = 3'b110; 18         8'b1000_0000 : A = 3'b111; 19         default:       A = 3'b000;
20     endcase
21 end
22 
23 
24 /*
25 //== if...else优先级写法,优先级从上到下 26 //====================================================================== 27 always @(*)begin 28  if(I[7] == 1'b0) A = 3'b000; 29  else if(I[6] == 1'b0) A = 3'b001; 30  else if(I[5] == 1'b0) A = 3'b010; 31  else if(I[4] == 1'b0) A = 3'b011; 32  else if(I[3] == 1'b0) A = 3'b100; 33  else if(I[2] == 1'b0) A = 3'b101; 34  else if(I[1] == 1'b0) A = 3'b110; 35  else if(I[0] == 1'b0) A = 3'b111; 36  else A = 3'b000; 37 end 38 */
39 
40 endmodule
View Code

 

8.3-8译码器code

 1 module Digital_Decoder  2 (  3     input      [ 2:0] A ,  4     output reg [ 7:0] I  5 );  6 
 7 always @(*)begin
 8     case(A)  9         3'b000 : I = 8'b01111111; 10         3'b001 : I = 8'b10111111; 11         3'b010 : I = 8'b11011111; 12         3'b011 : I = 8'b11101111; 13         3'b100 : I = 8'b11110111; 14         3'b101 : I = 8'b11111011; 15         3'b110 : I = 8'b11111101; 16         3'b111 : I = 8'b11111110; 17         default: I = 8'b11111111;
18     endcase
19 end
20 
21 endmodule
View Code

 

9.D触发器orm

 1 module Digital_Data_Flip_Flop  2 (  3     input clk ,  4     input rst_n ,  5     input D ,  6     output reg Q  7 );  8 
 9 always @(posedge clk or negedge rst_n)begin
10     if(!rst_n) 11         Q <= 1'b0;
12     else
13         Q <= D; 14 end
15 
16 endmodule
View Code

 

10.4bit移位寄存器

 1 module Digital_Shift_Reg  2 (  3     input clk ,  4     input rst_n ,  5     input data_in ,  6     input data_en ,  7     output reg [ 3:0] data_out ,  8     output reg [ 3:0] data_out_n  9 ); 10 
11 //== 时序逻辑,寄存data_out_n的值,因此看起来比data_out_n慢一拍 12 //======================================================================
13 always @(posedge clk or negedge rst_n)begin
14     if(!rst_n) 15         data_out <= 4'b0;
16     else
17         data_out <= data_out_n; 18 end
19 
20 //== 组合逻辑,不断移位 21 //======================================================================
22 always @(*)begin
23     if(data_en) 24         data_out_n = {data_out[2:0],data_in}; 25     else
26         data_out_n = data_out; 27 end
28 
29 /*---------------------------------------------------------------------- 30 --补充:若是要实现循环右移,则写成[data_in,data_out[3:1]] 31 ----------------------------------------------------------------------*/
32 
33 
34 endmodule
View Code

 

11.反馈回环的正误解析

 1 //== 错误写法:data_out既是条件又是结果  2 //======================================================================
 3 module Example_Feedback  4 (  5     input data_in1 ,  6     input data_in2 ,  7     output data_out  8 );  9                             //data_out是最终结果,可又是造成条件
10 assign data_out = (data_in2) ? data_in1 : (~data_out | data_in1); 11 
12 endmodule
13 
14 
15 /*
16 //== 正确写法:用data_out_r寄存一下,再给data_out 17 //====================================================================== 18 module Example_Feedback 19 ( 20  input clk , 21  input rst_n , 22  input data_in1 , 23  input data_in2 , 24  output data_out 25 ); 26 
27 //信号定义 28 reg data_out_r ; 29 
30 //时序逻辑,寄存结果 31 always @ (posedge clk or negedge rst_n) 32 begin 33  if(!rst_n) 34  data_out_r <= 1'b0; 35  else 36  data_out_r <= (data_in2) ? (data_in1) : (~data_out_r | data_in1); 37 end 38 
39 //寄存后的结果再输出 40 assign data_out = data_out_r; 41 
42 endmodule 43 */
View Code

12.阻塞赋值和非阻塞赋值

 1 module Example_Block  2 (  3     input clk ,  4     input block_in ,  5     output block_out1 ,  6     output block_out2 ,  7     output no_block_out1 ,  8     output no_block_out2  9 ); 10 
11 //block模块例化
12 block block_init 13 ( 14  .clk (clk ), 15  .block_in (block_in ), 16  .block_out1 (block_out1 ), 17  .block_out2 (block_out2 ) 18 ); 19 
20 //no_block模块例化
21 no_block no_block_init 22 ( 23  .clk (clk ), 24  .no_block_in (block_in ), 25  .no_block_out1 (no_block_out1 ), 26  .no_block_out2 (no_block_out2 ) 27 ); 28 
29 endmodule
Top

 

 1 module block  2 (  3     input clk ,  4     input block_in ,  5     output reg block_out1 ,  6     output reg block_out2  7 );  8 
 9 always @(posedge clk)begin
10     block_out1 = block_in; 11     block_out2 = block_out1; 12 end
13 
14 endmodule
Block

 

 1 module no_block  2 (  3     input clk ,  4     input no_block_in ,  5     output reg no_block_out1 ,  6     output reg no_block_out2  7 );  8 
 9 always @(posedge clk)begin
10     no_block_out1 <= no_block_in; 11     no_block_out2 <= no_block_out1; 12 end
13 
14 endmodule
no_Block

 

 

  这些基础数字电路的Verilog描述应该很是熟悉,才可以为后面的学习打下扎实的基础。

 

参考资料:[1]锆石科技FPGA教程

相关文章
相关标签/搜索