基礎數字電路的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教程

相關文章
相關標籤/搜索