天天看點

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計

  • 多路選擇器
    • 一.實驗内容
    • 二.實驗步驟
  • 交叉開關
    • 一.實驗内容
    • 二.實驗步驟
  • 優先編碼器
    • 一.實驗内容
    • 二.實驗步驟
  • 多路譯碼器
    • 一.實驗内容
    • 二.實驗步驟
  • 加法器
    • 無符号加法器
      • 一.實驗内容
      • 二.實驗步驟
    • 補碼加法器
      • 一.實驗内容
      • 二.實驗步驟
    • 帶流水線的加法器
      • 一.實驗内容
      • 二.實驗步驟
  • 乘法器
    • 一.實驗内容
    • 二.實驗步驟
  • 計數器
    • 一.實驗内容
    • 二.實驗步驟
  • 狀态機
    • 一.實驗内容
    • 二.實驗步驟
  • 移位寄存器
    • 一.實驗内容
    • 二.實驗步驟

多路選擇器

一.實驗内容

1.做一個4選1的多路選擇器,并進行波形仿真。

2.将4選1多路選擇器同2選1多路選擇器對比,觀察資源消耗的變化。

二.實驗步驟

1.建立項目

建立項目的過程與前幾篇文章相同,不再贅述。

2.添加Verilog HDL檔案

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

3.編寫Verilog HDL代碼

具體代碼如下:

// module  top, 選擇器(mux)的代碼,
module top(
  IN0       ,   // input 1
  IN1       ,   // input 2
  IN2       ,   // input 3
  IN3       ,   // input 4
  SEL       ,   // select 
  OUT       );  // out data
  
input [15:0] IN0, IN1, IN2, IN3;// 選擇器的輸入資料信号
input [1:0] SEL;              // 通道選通的控制信号
output[15:0] OUT;     // 選擇器的輸入資料信号

reg   [15:0] OUT;
// 生成組合邏輯的代碼
always @ (IN0 or IN1 or IN2 or IN3 or SEL) begin
  if(SEL==0) // SEL為0 選擇輸入0
    OUT = IN0;
  else  if(SEL==1)  // SEL為1 選擇輸入1
    OUT = IN1;
  else  if(SEL==2)  // SEL為2 選擇輸入2
	OUT = IN2;
  else  if(SEL==3)  // SEL為3 選擇輸入3
	OUT = IN3;
end
endmodule
// endmodule top
           

4.編譯代碼

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

5.添加并配置Vector Waveform File

添加Vector Waveform檔案并配置仿真輸入波形的方法在之前的文章已說明過了,此處直接展示仿真的結果。

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

從仿真波形中可以看到:當SEL端的信号變化時,輸出端會選擇相應的輸入信号進行輸出。

6.4選1多路選擇器的RTL結構

對于Quartus工具,可以按照如下路徑找到RTL Viewer:Tools -> Netlist Viewer -> RTL Viewer

本實驗代碼生成的RTL結構如下圖:

第一頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

第二頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

7.2選1多路選擇器的RTL結構

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

8.兩種多路選擇器的資源消耗對比

2選1多路選擇器:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

4選1多路選擇器:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

可見4選1多路選擇器相比2選1多路選擇器消耗更大的硬體資源。

交叉開關

一.實驗内容

1.編寫一個4X4路交叉開關的Verilog代碼,然後編譯,進行波形仿真。

2.觀察RTL View,比較2x2路交叉開關與4x4路交叉開關之間消耗資源的差別。

二.實驗步驟

1.編寫Verilog HDL代碼

// 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

input [15:0] IN0, IN1, IN2, IN3;
input [1:0] SEL0, SEL1, SEL2, SEL3;
output[15:0] OUT0, OUT1, OUT2, OUT3;

reg   [15:0] OUT0, OUT1, OUT2, OUT3;
// get the OUT0
always @ (IN0 or IN1 or IN2 or IN3 or SEL0) begin
  if(SEL0==0)
    OUT0 = IN0;
  else if(SEL0==1)
    OUT0 = IN1;
  else if(SEL0==2)
    OUT0 = IN2;
  else if(SEL0==3)
    OUT0 = IN3;
end
// get the OUT1
always @ (IN0 or IN1 or IN2 or IN3 or SEL1) begin
  if(SEL1==0)
    OUT1 = IN0;
  else if(SEL1==1)
    OUT1 = IN1;
  else if(SEL1==2)
    OUT1 = IN2;
  else if(SEL1==3)
    OUT1 = IN3;
end
// get the OUT2
always @ (IN0 or IN1 or IN2 or IN3 or SEL2) begin
  if(SEL2==0)
    OUT2 = IN0;
  else if(SEL2==1)
    OUT2 = IN1;
  else if(SEL2==2)
    OUT2 = IN2;
  else if(SEL2==3)
    OUT2 = IN3;
end
// get the OUT3
always @ (IN0 or IN1 or IN2 or IN3 or SEL3) begin
  if(SEL3==0)
    OUT3 = IN0;
  else if(SEL3==1)
    OUT3 = IN1;
  else if(SEL3==2)
    OUT3 = IN2;
  else if(SEL3==3)
    OUT3 = IN3;
end
endmodule
// endmodule top
           

2.波形仿真

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

3.檢視4×4交叉開關的RTL結構

第一頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

第二頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

第三頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

第四頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

第五頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

第六頁:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

4.檢視2×2交叉開關的RTL結構*

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

5.兩種交叉開關的資源消耗對比

2×2交叉開關的資源消耗:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

4×4交叉開關的資源消耗:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

可見,4×4交叉開關的邏輯單元消耗是2×2交叉開關的4倍。

優先編碼器

一.實驗内容

1.編寫一個8輸入的優先編碼器,然後編譯,檢視RTL View。

二.實驗步驟

1.編寫Verilog HDL代碼

// 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'b111;
   else if(IN[6])  // 第二優先級
     OUT = 4'b110;
   else if(IN[5])  // 第三優先級
     OUT = 4'b101;
   else if(IN[4])  // 第四優先級
     OUT = 4'b100;
   else if(IN[3])  // 第五優先級
     OUT = 4'b011;
   else if(IN[2])  // 第六優先級
     OUT = 4'b010;
   else if(IN[1])  // 第七優先級
     OUT = 4'b001;
   else if(IN[0])  // 第八優先級
     OUT = 4'b000;
   else            // 什麼都沒有檢測到
     OUT = 4'b1111; // 輸出值可自定義,不和上面的輸出值混淆即可
end
endmodule
           

2.波形仿真

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

3.檢視RTL View

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

多路譯碼器

一.實驗内容

1.編寫一個4-16的譯碼器,編譯,仿真。

2.檢視RTL View,并和3-8譯碼器對比資源開銷。

二.實驗步驟

1.編寫Verilog HDL代碼

// module top, 4-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
           

2.波形仿真

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

3.檢視RTL View

4-16譯碼器:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

3-8譯碼器:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

4.對比資源開銷

3-8譯碼器:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

4-16譯碼器:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

4-16譯碼器的資源消耗約為3-8譯碼器的2倍。

加法器

無符号加法器

一.實驗内容

1.把加法器的輸入信号和輸出信号都改成4比特位寬,編譯,波形仿真。觀察輸出結果,說出輸出和輸入的對應關系。

2.把加法器的輸入信号改成8比特位寬,編譯,波形仿真。觀察加法器的輸出延遲,和4比特輸入位寬的情況對比。

二.實驗步驟

1.編寫Verilog HDL代碼

module top(
  IN1   ,
  IN2   ,
  OUT   );
input[3:0] IN1, IN2;
output[3:0] OUT;
reg[3:0] OUT;
always@(IN1 or IN2) begin // 生成組合邏輯的always 塊
  OUT = IN1 + IN2;
end
endmodule 
           

2.仿真波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

由上圖可知,當加法器的輸入信号和輸出信号位寬相同時加法器得到的結果可能會丢失最高位的進位,即所得結果溢出,導緻計算結果出錯。當最高位無進位時輸出等于兩個輸入的和,而當最高位有進位時則輸出比兩個輸入的和小16(24)。

3.輸入信号為8位寬的加法器的Verilog HDL代碼

module top(
  IN1   ,
  IN2   ,
  OUT   );
input[7:0] IN1, IN2;
output[8:0] OUT;
reg[8:0] OUT;
always@(IN1 or IN2) begin // 生成組合邏輯的always 塊
  OUT = IN1 + IN2;
end
endmodule 
           

4.8位寬加法器仿真波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

從以上兩張波形圖可以看出4位寬加法器和8位寬加法器的輸出延遲差别不大,基本都在8ns左右。

補碼加法器

一.實驗内容

1.把加法器的輸出信号改成4比特位寬,編譯,波形仿真。觀察輸出結果,觀察輸出結果在什麼時候是正确的?

2. 把加法器的輸入信号改成8比特位寬,編譯,波形仿真。觀察加法器的輸出延遲,和4比特輸入位寬的情況對比。

二.實驗步驟

1.編寫4比特位寬輸出加法器的Verilog HDL代碼

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
           

2.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

從仿真結果可知,當兩個輸入信号的和大于7或小于-8時計算結果會出錯,這是由于次高位進位使得符号位變化導緻的。

3.編寫8比特位寬輸出加法器的Verilog HDL代碼

module top(
  IN1   ,
  IN2   ,
  OUT   );
input signed [7:0] IN1, IN2;
output signed [8:0] OUT;
reg signed [8:0] OUT;
always@(IN1 or IN2) begin // 生成組合邏輯的always 塊
  OUT = IN1 + IN2;
end
endmodule
           

4.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

由仿真波形可知,4位補碼加法器和8位補碼加法器的延遲時間相差不多,基本都是8ns。

帶流水線的加法器

一.實驗内容

1.不改變流水線的級數,把加法器的輸入信号改成8比特位寬,編譯,波形仿真,和不帶流水線的情況對比一下,你有什麼結論?

2.在8比特輸入位寬的情況下,在輸入上再添加一級流水線,觀察編譯和仿真的結果,你有什麼結論?

二.實驗步驟

1.編寫8位輸入帶一級流水線的加法器的Verilog HDL代碼

module top(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
input  [7:0] IN1, IN2;
input CLK;
output  [8:0] OUT;
reg [7:0] in1_d1R, in2_d1R;
reg  [8: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 
           

2.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

帶有流水線的加法器相較于沒有流水線的加法器擁有更短的毛刺,但輸出延時更長。

3.RTL View

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

4.編寫8位輸入帶兩級級流水線的加法器的Verilog HDL代碼

module top(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
input  [7:0] IN1, IN2;
input CLK;
output  [8:0] OUT;
reg [7:0] in1_d1R, in2_d1R, in1_d2R, in2_d2R;
reg  [8:0] adder_out, OUT;
always@(posedge CLK) begin // 生成D觸發器的always塊
  in1_d1R <= IN1;
  in1_d2R <= in1_d1R;
  in2_d1R <= IN2;
  in2_d2R <= in2_d1R;
  OUT     <= adder_out;
end
always@(in1_d2R or in2_d2R) begin // 生成組合邏輯的always塊
  adder_out = in1_d2R + in2_d2R;
end
endmodule 
           

5.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

增加一級流水線後使得毛刺的時間長度進一步減小,但是輸出延遲變得更大。

6.RTL View

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

乘法器

一.實驗内容

1.改變乘法器的輸入位寬為8比特,編譯,波形仿真,觀察信号毛刺的時間長度。

2.選一款沒有硬體乘法器的FPGA晶片(例如Cyclone EP1C6)對比8比特的乘法器和加法器兩者編譯之後的資源開銷(Logic Cell的數目)

3.編寫一個輸入和輸出都有D觸發器的流水線乘法器代碼,編譯後波形仿真,觀察組合邏輯延遲和毛刺的時間,和不帶流水線的情況下對比。

二.實驗步驟

1.編寫8位輸入的乘法器的Verilog HDL代碼

有符号的2補碼乘法器  /
module top(
  IN1   ,
  IN2   ,
  OUT   );
 input signed[7:0] IN1, IN2;
 output signed [15:0] OUT;
 reg signed[15:0] OUT;
 always@(IN1 or IN2) begin // 生成組合邏輯的always 塊
  OUT = IN1 * IN2;
end
endmodule
           

2.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

從圖中可得,毛刺信号約占4ns。

3.沒有硬體乘法器的FPGA晶片的8比特加法器和乘法器的資源開銷對比

加法器資源開銷:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

乘法器硬體開銷:

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

由上圖可見,乘法器相較加法器更加消耗資源。

4.輸入和輸出都有D觸發器的流水線乘法器的Verilog HDL代碼

帶有流水線的補碼乘法器  /
module top(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
 input signed[7:0] IN1, IN2;
 input CLK;
 output signed [15:0] OUT;
 reg signed[15:0] OUT;
 reg signed[7:0] in1_d1R, in2_d1R;
 reg signed[15:0] mul_out;
always@(posedge CLK) begin // 生成D觸發器的always塊
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  OUT     <= mul_out;
end
 always@(in1_d1R or in2_d1R) begin // 生成組合邏輯的always 塊
  mul_out = in1_d1R * in2_d1R;
end
endmodule 
           

5.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

有仿真波形可得:帶有流水線的乘法器的組合邏輯延遲和毛刺的時間約為2ns,相比不帶流水線的乘法器要減少了一半。

計數器

一.實驗内容

1.設計一個最簡單的計數器,隻有一個CLK輸入和一個Overflow輸出,當計數到最大值的時鐘周期CLK輸出1

2.設計複雜的計數器,和本例相似,帶有多種信号,其中同步清零CLR的優先級最高,使能EN次之,LOAD最低。

二.實驗步驟

1.編寫簡單計數器的Verilog HDL代碼

計數器代碼  /
module top(
  CLK   , // 時鐘,上升沿有效
  OV    );// 計數溢出信号,計數值為最大值時該信号為1
input CLK ;
output OV;   
reg OV;
reg [3:0] CNTVAL, cnt_next;
// 電路編譯參數,最大計數值
parameter CNT_MAX_VAL = 9;
// 組合邏輯,生成cnt_next
always @(CNTVAL) begin
  if(CNTVAL < CNT_MAX_VAL) begin // 未計數到最大值, 下一值加1
    cnt_next = CNTVAL + 1'b1;
  end
  else begin // 計數到最大值,下一計數值為0
    cnt_next = 0;
  end
end
// 時序邏輯 更新下一時鐘周期的計數值
// CNTVAL 會被編譯為D觸發器
always @ (posedge CLK) begin
    CNTVAL <= cnt_next;
end
// 組合邏輯,生成OV
always @ (CNTVAL) begin
  if(CNTVAL == CNT_MAX_VAL) 
    OV = 1;
  else
    OV = 0;
end
endmodule
           

2.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

如波形圖所示,當經過9個周期的時鐘信号後OV端口輸出一個高電平的溢出信号。

3.編寫複雜計數器的Verilog HDL代碼

計數器代碼  /

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
// 1st clr ,2nd en , 3rd 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 // 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
           

4.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

由仿真結果可知,計數器按照同步清零CLR的優先級最高,使能EN次之,LOAD最低的設定工作。

狀态機

一.實驗内容

1.設計一個用于識别2進制序列“1011”的狀态機

基本要求:

電路每個時鐘周期輸入1比特資料,當捕獲到1011的時鐘周期,電路輸出1,否則輸出0

使用序列101011010作為輸出的測試序列

擴充要求:

給你的電路添加輸入使能端口,隻有輸入使能EN為1的時鐘周期,才從輸入的資料端口向内部擷取1比特序列資料。

二.實驗步驟

1.繪制狀态跳轉邏輯表

目前狀态 IN EN 次态
ST_0 ST_0
ST_0 1 ST_0
ST_0 1 ST_0
ST_0 1 1 ST_0
ST_1 ST_1
ST_1 1 ST_2
ST_1 1 ST_1
ST_1 1 1 ST_1
ST_2 ST_2
ST_2 1 ST_0
ST_2 1 ST_2
ST_2 1 1 ST_3
ST_3 ST_3
ST_3 1 ST_2
ST_3 1 ST_3
ST_3 1 1 ST_4
ST_4 X X ST_0

2.繪制輸出邏輯表

目前狀态 輸出
ST_0
ST_1
ST_2
ST_3
ST_4 1

3.編寫Verilog HDL代碼

三段式狀态機代碼  /
module top(
  CLK       ,   // clock
  RST       ,   // reset
  IN        ,   // input
  EN        ,   // EN
  OUT       );  // output 

input  CLK       ; 
input  RST       ; 
input  EN        ; 
input  IN        ;
output OUT       ;

parameter ST_0 = 0;
parameter ST_1 = 1;
parameter ST_2 = 2;
parameter ST_3 = 3;
parameter ST_4 = 4;

reg [2:0]stateR       ;
reg [2:0]next_state   ;
reg OUT               ;

// calc next state
always @ (IN or EN or stateR) begin
  case (stateR)
    ST_0 :begin if(IN==0&&EN==0) next_state = ST_0 ; else if(IN==0&&EN==1) next_state = ST_0; else if(IN==1&&EN==0) next_state = ST_0; else if(IN==1&&EN==1) next_state = ST_1; end
    ST_1 :begin if(IN==0&&EN==0) next_state = ST_1 ; else if(IN==0&&EN==1) next_state = ST_2; else if(IN==1&&EN==0) next_state = ST_1; else if(IN==1&&EN==1) next_state = ST_1; end
    ST_2 :begin if(IN==0&&EN==0) next_state = ST_2 ; else if(IN==0&&EN==1) next_state = ST_0; else if(IN==1&&EN==0) next_state = ST_2; else if(IN==1&&EN==1) next_state = ST_3; end
    ST_3 :begin if(IN==0&&EN==0) next_state = ST_3 ; else if(IN==0&&EN==1) next_state = ST_2; else if(IN==1&&EN==0) next_state = ST_3; else if(IN==1&&EN==1) next_state = ST_4; end
    ST_4 :begin next_state = ST_0; end
  endcase
end

// calc output
always @ (stateR) begin
  if(stateR == ST_4) 
    OUT = 1'b1;
  else 
    OUT = 1'b0;
end

// state DFF
always @ (posedge CLK or posedge RST)begin
  if(RST)
    stateR <= ST_0;
  else
    stateR <= next_state;
end

endmodule
           

4.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

移位寄存器

一.實驗内容

設計一個帶加載使能和移位使能的并入串出的移位寄存器,電路的RTL結構圖如下圖圖所示。

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

二.實驗步驟

1.編寫移位寄存器代碼

///PISO WITH EN_LOAD AND EN_SHIFT
module top(
  CLK         , //時鐘信号
  RST         , //複位信号輸入
  EN_LOAD     , //加載輸入資料使能
  EN_SHIFT    , //移位使能
  IN          , //并行輸入資料
  OV          , //一組資料完全移出提示
  OUT         );//穿行輸出
  
input RST, CLK, EN_LOAD, EN_SHIFT;
input [7:0] IN;
output OUT,OV;
reg shift_R,OV;
reg [7:0] shift_V;
reg [3:0] n;//移位次數計數

assign OUT = shift_R;//最右端移出資料

always @ (posedge CLK or posedge RST) begin
  if(RST) begin
    shift_R <= 0;
    shift_V <= 0;
    n <= 0;
  end
  else begin
    if(EN_SHIFT) begin
	  if(EN_LOAD) begin
		shift_V <= IN;并行輸入載入
	  end
	  else begin
	    shift_R <= shift_V[0];
	    shift_V[6:0] <= shift_V[7:1];
	    shift_V[7] <= 0;//一次移位完成
	    n <= n + 1;//移位次數+1
	  end
	end
	else begin
	  shift_R <= shift_R;//未使能移位,保持不動
	end
  end
end
always @ (n) begin
  if(n==8)  //當移完一組(8bit)資料後OV端口輸出1提示
	OV = 1;
  else
	OV = 0;
end
endmodule
           

2.仿真結果波形

【EDA】實驗4:常用元件的 Verilog RTL 代碼設計多路選擇器交叉開關優先編碼器多路譯碼器加法器乘法器計數器狀态機移位寄存器

繼續閱讀