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
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
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
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
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
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
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
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
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
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
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
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
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 */
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
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
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
這些基礎數字電路的Verilog描述應該很是熟悉,纔可以爲後面的學習打下紮實的基礎。
參考資料:[1]鋯石科技FPGA教程