赞
踩
SystemVerilog是一种功能强大的硬件描述语言和验证语言。随着电子设计自动化(EDA)技术的不断进步,以及对数字系统设计和验证要求的提高,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) begin if (!rst_n) begin led <= 8'b00000000; // 复位时所有LED熄灭 end else begin integer i; // 声明整数变量 for (i = 0; i < 8; i++) begin led <= (8'b00000001 << i); // 点亮第i位LED #125; // 等待一个时钟周期,假设为20ns,则0.5s需要250个周期 end end end endmodule
// 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); end endmodule
这里加速了一下,实际每个灯亮0.5秒
关于HC-SR04模块可以参考我之前stm32的博客https://blog.csdn.net/cbm2001/article/details/139374257?spm=1001.2014.3001.5501
下面是代码:
module clk_us( input logic clk , //system clock 50MHz input logic rst_n , //reset ,low valid output logic clk_us // ); //Parameter Declarations parameter CNT_MAX = 19'd50;//1us的计数值为 50 * Tclk(20ns) //Interrnal wire/reg declarations logic [5:00] cnt ; //Counter logic add_cnt ; //Counter Enable logic end_cnt ; //Counter Reset //Logic Description always @(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 50MHz input logic clk_us , //system clock 1MHz input 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 Declarations parameter T_MAX = 16'd60_000;//510cm 对应计数值 //Interrnal wire/reg declarations logic r1_echo,r2_echo; //边沿检测 logic echo_pos,echo_neg; // logic [15:00] cnt ; //Counter logic add_cnt ; //Counter Enable logic 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 end assign 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 end assign data_o = data_r >> 1; endmodule
module Trig( input logic clk_us , //system clock 1MHz input logic rst_n , //reset ,low valid output logic trig //触发测距信号 ); //Parameter Declarations parameter CYCLE_MAX = 19'd300_000; //Interrnal wire/reg declarations logic [18:00] cnt ; //Counter logic add_cnt ; //Counter Enable logic 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) begin if (!rst_n) begin cnt_20us <= 10'd0; end else if (cnt_20us == MAX20us - 1'd1) begin cnt_20us <= 10'd0; end else begin cnt_20us <= cnt_20us + 1'd1; end end //单个信号sel_r位拼接约束 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin sel_r <= 8'b11_11_11_10; end else if (cnt_20us == MAX20us - 1'd1) begin sel_r <= {sel_r[6:0],sel_r[7]}; end else begin sel_r <= sel_r; end end /*拿到数字*/ always @(*) begin case (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 @(*) begin case (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 end always @(*) begin case (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 end assign 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 1MHz input logic rst_n , //reset ,low valid output logic trig //触发测距信号 ); //Parameter Declarations parameter CYCLE_MAX = 19'd300_000; //Interrnal wire/reg declarations logic [18:00] cnt ; //Counter logic add_cnt ; //Counter Enable logic 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完全相同,而是Verilog的扩展和超集。虽然SystemVerilog继承了Verilog的基本结构和语法,但是它通过引入面向对象编程、动态线程控制、高层抽象数据类型等先进特性,极大地扩展了Verilog的功能。下面是SystemVerilog相对于Verilog的几个主要差异:
,支持更广泛的设计需求。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。