文章目錄
- 一、認識SystemVerilog
- SystemVerilog的語言特性
- SystemVerilog的應用領域
- SystemVerilog的優勢
- SystemVerilog的未來發展方向
- 二、流水燈代碼
- 流水燈部分
- testbench仿真文件
- 三、用systemVerilog實現超聲波測距
- 計時器
- 測距部分
- led部分
- 數碼管部分
- 采樣部分
- 頂層文件
- 引腳綁定
- 效果
- 四、SysTemVerilog與verilog的區別
- 1.語言功能的增強
- 2.設計流程的優化
- 3.工具社區的支持
一、認識SystemVerilog
? SystemVerilog是一種功能強大的硬件描述語言和驗證語言。隨著電子設計自動化(EDA)技術的不斷進步,以及對數字系統設計和驗證要求的提高,SystemVerilog應運而生.
SystemVerilog的語言特性
- 數據類型與建模能力:SystemVerilog提供了豐富的數據類型和強大的建模能力,這使得設計者能夠精確地描述硬件的行為和結構。這種高級的數據類型支持,讓設計更加靈活且易于理解和維護。
- 面向對象的特性:與傳統的Verilog相比,SystemVerilog增加了面向對象編程的概念,如類、繼承和多態等。這使得代碼模塊性更強,更易于管理和復用,大大提高了開發效率和可維護性。
- 并發處理的支持:SystemVerilog支持并發處理,允許設計者模擬真實的硬件并行操作環境,這對于描述復雜的硬件系統至關重要。
- 接口和連接:通過引入接口這一概念,SystemVerilog簡化了模塊間的通信方式,提高了設計的清晰度和模塊間的互操作性。
SystemVerilog的應用領域
- ASIC與FPGA設計:SystemVerilog被廣泛應用于ASIC和FPGA的設計流程中,支持從邏輯綜合到驗證的各個階段,能夠滿足不同規模和復雜度的設計需求。
- 驗證環境構建:SystemVerilog的驗證功能特別強大,它為驗證工程師提供了構建全面測試套件和驗證環境的能力,特別是在復雜的系統級驗證中表現出色。
- 新興領域的應用:隨著技術的發展,SystemVerilog開始在自動駕駛、人工智能、云計算等新興領域中得到應用,用于構建和驗證復雜的系統模型。
SystemVerilog的優勢
- 模塊化和可重用性:面向對象的特性使得SystemVerilog的設計更加模塊化,易于維護和重用,這有助于縮短產品開發周期并降低成本。
- 集成的驗證功能:SystemVerilog不僅是一個設計語言,它還集成了豐富的驗證功能,如約束隨機生成、功能覆蓋率分析等,這些都是提高驗證效率和質量的關鍵工具。
- 豐富的生態系統:眾多EDA廠商和開源社區的支持,為SystemVerilog提供了強大的工具鏈和生態系統,從而使得開發者能夠更加便捷地進行設計和驗證工作。
SystemVerilog的未來發展方向
-
應用領域的拓展:隨著技術的進步和市場需求的變化,SystemVerilog預計將進一步拓展其在多個新興領域的應用,如物聯網、5G通信等。
-
語言特性的增強:為了跟上技術發展的步伐,SystemVerilog將持續更新其語言特性,包括增強建模能力、擴展驗證功能等,以適應更加復雜的設計需求。
-
工具鏈的優化與集成:EDA廠商將繼續優化SystemVerilog相關工具的性能,提供更加集成化的解決方案,以便為用戶提供更加高效和便捷的開發體驗。
? 總之,SystemVerilog作為一種先進的硬件描述和驗證語言,它的出現極大地推動了數字系統設計和驗證領域的發展。通過提供模塊化、面向對象的特性,以及集成的驗證功能,SystemVerilog不僅提高了設計的質量和效率,還為應對日益增長的設計復雜性提供了強有力的工具。
二、流水燈代碼
流水燈部分
module led_water_light(input wire clk, // 時鐘信號input wire rst_n, // 復位信號,低電平有效output reg [7:0] led // 8個LED燈
);// 內部邏輯
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginled <= 8'b00000000; // 復位時所有LED熄滅end else begininteger i; // 聲明整數變量for (i = 0; i < 8; i++) beginled <= (8'b00000001 << i); // 點亮第i位LED#125; // 等待一個時鐘周期,假設為20ns,則0.5s需要250個周期endend
endendmodule
testbench仿真文件
// tb_led_water_light.sv
module tb_led_water_light();// Parameters
parameter CLK_PERIOD = 20; // 定義時鐘周期參數// Inputs
logic clk;
logic rst_n;// Outputs
wire [7:0] led;// 實例化被測試模塊
led_water_light uut (.clk(clk),.rst_n(rst_n),.led(led)
);// 時鐘信號生成
always #(CLK_PERIOD / 2) clk = ~clk;// 測試序列
initial begin// 初始化信號clk = 0;rst_n = 0;// 等待一個時鐘周期#(CLK_PERIOD * 10);// 釋放復位信號rst_n = 1;// 等待足夠的時間來觀察LED的變化#(CLK_PERIOD * 1000); // 等待50個時鐘周期,即2ms// 再次觸發復位rst_n = 0;#(CLK_PERIOD * 10);rst_n = 1;// 繼續觀察LED變化#(CLK_PERIOD * 1000); // 再次等待50個時鐘周期,即2ms// 結束仿真$finish;
end// 監控輸出變化
initial begin$monitor("Time = %t, rst_n = %b, led = %b", $time, rst_n, led);
endendmodule
這里加速了一下,實際每個燈亮0.5秒
三、用systemVerilog實現超聲波測距
關于HC-SR04模塊可以參考我之前stm32的博客https://blog.csdn.net/cbm2001/article/details/139374257?spm=1001.2014.3001.5501
下面是代碼:
計時器
module clk_us(input logic clk , //system clock 50MHzinput logic rst_n , //reset ,low valid output logic clk_us //
);
//Parameter Declarationsparameter CNT_MAX = 19'd50;//1us的計數值為 50 * Tclk(20ns)//Interrnal wire/reg declarationslogic [5:00] cnt ; //Counter logic add_cnt ; //Counter Enablelogic end_cnt ; //Counter Reset //Logic Descriptionalways @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 'd0; end else if(add_cnt)begin if(end_cnt)begin cnt <= 'd0; end else begin cnt <= cnt + 1'b1; end end else begin cnt <= cnt; end end assign add_cnt = 1'b1; assign end_cnt = add_cnt && cnt >= CNT_MAX - 19'd1;assign clk_us = end_cnt;endmodule
測距部分
module Echo(input logic clk , //clock 50MHzinput logic clk_us , //system clock 1MHzinput logic rst_n , //reset ,low valid input logic echo , //output logic [18:00] data_o //檢測距離,保留3位小數,*1000實現
);
/* S(um) = 17 * t --> x.abc cm */
//Parameter Declarationsparameter T_MAX = 16'd60_000;//510cm 對應計數值//Interrnal wire/reg declarationslogic r1_echo,r2_echo; //邊沿檢測 logic echo_pos,echo_neg; //logic [15:00] cnt ; //Counter logic add_cnt ; //Counter Enablelogic end_cnt ; //Counter Reset logic [18:00] data_r ;
//Logic Description//如果使用clk_us 檢測邊沿,延時2us,差值過大always @(posedge clk or negedge rst_n)begin if(!rst_n)begin r1_echo <= 1'b0;r2_echo <= 1'b0;end else begin r1_echo <= echo;r2_echo <= r1_echo;end endassign echo_pos = r1_echo & ~r2_echo;assign echo_neg = ~r1_echo & r2_echo;always @(posedge clk_us or negedge rst_n)begin if(!rst_n)begin cnt <= 'd0; end else if(add_cnt)begin if(end_cnt)begin cnt <= cnt; end else begin cnt <= cnt + 1'b1; end end else begin //echo 低電平 歸零cnt <= 'd0; end end assign add_cnt = echo; assign end_cnt = add_cnt && cnt >= T_MAX - 1; //超出最大測量范圍則保持不變,極限always @(posedge clk or negedge rst_n)begin if(!rst_n)begin data_r <= 'd2;end else if(echo_neg)begin data_r <= (cnt << 4) + cnt;end else begin data_r <= data_r;end end //always endassign data_o = data_r >> 1;endmodule
led部分
module Trig(input logic clk_us , //system clock 1MHzinput logic rst_n , //reset ,low valid output logic trig //觸發測距信號
);
//Parameter Declarationsparameter CYCLE_MAX = 19'd300_000;//Interrnal wire/reg declarationslogic [18:00] cnt ; //Counter logic add_cnt ; //Counter Enablelogic end_cnt ; //Counter Reset //Logic Description always @(posedge clk_us or negedge rst_n)begin if(!rst_n)begin cnt <= 'd0; end else if(add_cnt)begin if(end_cnt)begin cnt <= 'd0; end else begin cnt <= cnt + 1'b1; end end else begin cnt <= cnt; end end assign add_cnt = 1'b1; assign end_cnt = add_cnt && cnt >= CYCLE_MAX - 9'd1; assign trig = cnt < 15 ? 1'b1 : 1'b0;endmodule
數碼管部分
module seg(input logic clk ,input logic rst_n ,input logic [18:0] data_o ,output logic [6:0] hex1 ,output logic [6:0] hex2 ,output logic [6:0] hex3 ,output logic [6:0] hex4 ,output logic [6:0] hex5 ,output logic [6:0] hex6 ,output logic [6:0] hex7 ,output logic [6:0] hex8
);parameter NOTION = 4'd10,FUSHU = 4'd11;
parameter MAX20us = 10'd1000;
logic [9:0] cnt_20us;
logic [7:0] sel_r;
logic [3:0] number;
logic [6:0] seg_r;
logic [6:0] hex1_r;
logic [6:0] hex2_r;
logic [6:0] hex3_r;
logic [6:0] hex4_r;
logic [6:0] hex5_r;
logic [6:0] hex6_r;
logic [6:0] hex7_r;
logic [6:0] hex8_r;//20微妙計數器
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_20us <= 10'd0;endelse if (cnt_20us == MAX20us - 1'd1) begincnt_20us <= 10'd0;endelse begincnt_20us <= cnt_20us + 1'd1;end
end//單個信號sel_r位拼接約束
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsel_r <= 8'b11_11_11_10;endelse if (cnt_20us == MAX20us - 1'd1) beginsel_r <= {sel_r[6:0],sel_r[7]};endelse beginsel_r <= sel_r;end
end/*拿到數字*/
always @(*) begincase (sel_r)8'b11_11_11_10: number = NOTION ;8'b11_11_11_01: number = data_o/10_0000 ;8'b11_11_10_11: number = (data_o%10_0000)/1_0000 ;8'b11_11_01_11: number = ((data_o%10_0000)%1_0000)/1000 ;8'b11_10_11_11: number = FUSHU ;8'b11_01_11_11: number = (((data_o%10_0000)%1_0000)%1000)/100 ;8'b10_11_11_11: number = ((((data_o%10_0000)%1_0000)%1000)%100)/10 ;8'b01_11_11_11: number = ((((data_o%10_0000)%1_0000)%1000)%100)%10 ;default: number = 4'd0 ;endcase
end/*通過數字解析出seg值*/
always @(*) begincase (number)4'd0 : seg_r = 7'b100_0000;4'd1 : seg_r = 7'b111_1001;4'd2 : seg_r = 7'b010_0100;4'd3 : seg_r = 7'b011_0000;4'd4 : seg_r = 7'b001_1001;4'd5 : seg_r = 7'b001_0010;4'd6 : seg_r = 7'b000_0010;4'd7 : seg_r = 7'b111_1000;4'd8 : seg_r = 7'b000_0000;4'd9 : seg_r = 7'b001_0000;NOTION : seg_r = 7'b111_1111;FUSHU : seg_r = 7'b011_1111;default : seg_r = 7'b111_1111;endcase
endalways @(*) begincase (sel_r)8'b11_11_11_10: hex1_r = seg_r;8'b11_11_11_01: hex2_r = seg_r;8'b11_11_10_11: hex3_r = seg_r;8'b11_11_01_11: hex4_r = seg_r;8'b11_10_11_11: hex5_r = seg_r;8'b11_01_11_11: hex6_r = seg_r;8'b10_11_11_11: hex7_r = seg_r;8'b01_11_11_11: hex8_r = seg_r;default: seg_r = seg_r;endcase
endassign hex1 = hex1_r;
assign hex2 = hex2_r;
assign hex3 = hex3_r;
assign hex4 = hex4_r;
assign hex5 = hex5_r;
assign hex6 = hex6_r;
assign hex7 = hex7_r;
assign hex8 = hex8_r;endmodule
采樣部分
module Trig(input logic clk_us , //system clock 1MHzinput logic rst_n , //reset ,low valid output logic trig //觸發測距信號
);
//Parameter Declarationsparameter CYCLE_MAX = 19'd300_000;//Interrnal wire/reg declarationslogic [18:00] cnt ; //Counter logic add_cnt ; //Counter Enablelogic end_cnt ; //Counter Reset //Logic Description always @(posedge clk_us or negedge rst_n)begin if(!rst_n)begin cnt <= 'd0; end else if(add_cnt)begin if(end_cnt)begin cnt <= 'd0; end else begin cnt <= cnt + 1'b1; end end else begin cnt <= cnt; end end assign add_cnt = 1'b1; assign end_cnt = add_cnt && cnt >= CYCLE_MAX - 9'd1; assign trig = cnt < 15 ? 1'b1 : 1'b0;endmodule
頂層文件
module top (input logic clk ,input logic rst_n ,input logic echo ,output logic [3:0]led,output logic trig , output logic [6:0] hex1 ,output logic [6:0] hex2 ,output logic [6:0] hex3 ,output logic [6:0] hex4 ,output logic [6:0] hex5 ,output logic [6:0] hex6 ,output logic [6:0] hex7 ,output logic [6:0] hex8
);wire [18:0] data_o;Trig inster_Trig(
.clk_us (clk_us ), //system clock 1MHz
.rst_n (rst_n ), //reset ,low valid
.trig (trig ) //觸發測距信號
);clk_us insert_clk_us(
.clk (clk ),
.rst_n (rst_n),
.clk_us (clk_us)
);Echo inster_Echo(
.clk (clk ),
.clk_us (clk_us ),
.rst_n (rst_n ),
.echo (echo ),
.data_o (data_o )
);LED inster_LED(
.clk (clk ) ,
.rst_n (rst_n) ,
.dis (data_o ) ,
.led (led )
);seg inster_seg(.clk (clk ) ,.rst_n (rst_n ) ,.data_o (data_o) ,.hex1 (hex1) ,.hex2 (hex2) ,.hex3 (hex3) ,.hex4 (hex4) ,.hex5 (hex5 ) ,.hex6 (hex6 ) ,.hex7 (hex7 ) ,.hex8 (hex8 )
);
endmodule
引腳綁定
注意HC-SR04模塊的連線以自己接線為準
效果
距離<10cm,亮兩個燈,那個減號是小數點
距離在10~20cm亮一個燈
距離>20cm,亮三個燈
四、SysTemVerilog與verilog的區別
? SystemVerilog并不是與Verilog完全相同,而是Verilog的擴展和超集。雖然SystemVerilog繼承了Verilog的基本結構和語法,但是它通過引入面向對象編程、動態線程控制、高層抽象數據類型等先進特性,極大地擴展了Verilog的功能。下面是SystemVerilog相對于Verilog的幾個主要差異:
1.語言功能的增強
- 面向對象的特性:SystemVerilog引入了類、繼承、多態等面向對象的概念,這不僅提高了代碼的重用性和模塊化,還使得測試平臺的構建更為靈活和強大。
- 并發模型的改進:SystemVerilog提供了fork-join語法,支持更加精細的并發控制,這對于復雜的驗證環境尤其重要。
- 數據類型的豐富:除了基本的wire和reg類型,SystemVerilog還新增了如logic、enum、struct等多種數據類型,支持更廣泛的設計需求。
- 驗證能力的提升
約束隨機生成:SystemVerilog支持帶約束的隨機生成技術,這可以自動產生更多樣化的測試場景,極大地提高驗證的覆蓋率和效率。 - 功能覆蓋率分析:內置的功能覆蓋率分析工具幫助驗證工程師精確地量化驗證進度,確保設計滿足所有功能要求。
- 斷言的支持:通過SVA(SystemVerilog Assertions),SystemVerilog允許設計者在代碼中直接嵌入斷言,以監測設計行為的特定屬性,這對排查問題和確保設計的正確性至關重要。
2.設計流程的優化
- 接口的概念:SystemVerilog中的接口是一種強大的結構,它允許設計者將相關的信號組合在一起,簡化模塊間的連接,提高設計的清晰度和可維護性。
- 時間精度的控制:SystemVerilog提供了更為精確的時間控制機制,支持從秒到飛秒的多種時間單位,這有助于處理高速設計中的時間精度問題。
3.工具社區的支持
- 更多的工具支持:由于其強大的功能和廣泛的應用,多數現代EDA工具都原生支持SystemVerilog,為用戶提供了豐富的設計和驗證工具鏈。
- 活躍的開發社區:圍繞SystemVerilog形成了一個活躍的開發社區,許多開源項目和論壇都在不斷促進這一語言的發展和完善。
,支持更廣泛的設計需求。
- 驗證能力的提升
約束隨機生成:SystemVerilog支持帶約束的隨機生成技術,這可以自動產生更多樣化的測試場景,極大地提高驗證的覆蓋率和效率。 - 功能覆蓋率分析:內置的功能覆蓋率分析工具幫助驗證工程師精確地量化驗證進度,確保設計滿足所有功能要求。
- 斷言的支持:通過SVA(SystemVerilog Assertions),SystemVerilog允許設計者在代碼中直接嵌入斷言,以監測設計行為的特定屬性,這對排查問題和確保設計的正確性至關重要。