项目要求:
超声波模块测出的距离显示在数码管上
产生时钟使能信号的模块:
`timescale 1ns / 1ps
//产生1us为周期的时钟使能信号
//1us/20ns=50,div_cnt内部计数周期为0~49
module vlg_en(input sys_clk ,input rst_n ,output reg clk_en //clk_en的时钟周期为1us);reg [7:0] div_cnt ;//对输入时钟sys_clk做分频计数,产生1us的时钟使能信号always @(posedge sys_clk )if(!rst_n)div_cnt <= 0 ;else if ( div_cnt == 50 )div_cnt <= 0 ;elsediv_cnt <= div_cnt +1 ;//产生时钟使能信号always@(posedge sys_clk )if(!rst_n)clk_en <= 0 ;else if ( div_cnt == 49 )clk_en <= 1 ;elseclk_en <= 0 ;endmodule
产生trig信号的模块
`timescale 1ns / 1ps
module vlg_trig(input sys_clk ,input rst_n ,input clk_en , //1us为周期的时钟使能信号output reg trig );parameter trig_50000 = 16'd50_000 ;reg [16:0] trig_cnt ; // T=50ms t=1us 50ms/1us = 50000 位宽是16//trig_cnt计满50msalways@(posedge sys_clk)if(!rst_n)trig_cnt <= 0 ;else if ( clk_en == 1 && trig_cnt == trig_50000 -1 )trig_cnt <= 0 ;else if ( clk_en == 1 ) trig_cnt <= trig_cnt +1 ;elsetrig_cnt <= trig_cnt ;//产生保持10us的高脉冲trig信号always@(posedge sys_clk)if (!rst_n)trig <= 0 ;else if ( trig_cnt > 0 && trig_cnt < 4'd10)trig <= 1 ;elsetrig <= 0 ;endmodule
对echo信号高脉冲计时
`timescale 1ns / 1ps
module vlg_echo(input sys_clk ,input rst_n ,input clk_en ,input echo ,
// output reg[15:0] num_max ,output wire[15:0] distance );reg[15:0] num_max ;reg [1:0] r_echo ;//echo信号的边沿检测wire pos_echo ;wire neg_echo ;reg cnt_en ;reg [15:0] echo_cnt ;always@(posedge sys_clk)if(!rst_n)r_echo <= 0 ;elser_echo <= { r_echo[0],echo} ; // echo 是原始信号 r_echo[0] 是延迟一拍的echoassign pos_echo = r_echo[0] & ~r_echo[1] ; //这句话中的r_echo[0]是原始信号echo,r_echo[1]是是延迟一拍的echoassign neg_echo = ~r_echo[0] & r_echo[1] ; always @(posedge sys_clk)if(!rst_n)cnt_en <= 0 ;else if ( pos_echo ) cnt_en <= 1 ;else if ( neg_echo ) cnt_en <= 0 ;elsecnt_en <= cnt_en ;//对echo信号高脉冲计时,以us为单位always @(posedge sys_clk )if(!rst_n)echo_cnt <= 0 ;else if ( !cnt_en )echo_cnt <= 0 ;else if ( cnt_en )echo_cnt <= echo_cnt +1 ;elseecho_cnt <= 0 ;//对echo_cnt计数最大值进行锁存always@(posedge sys_clk)if( !rst_n )num_max <= 0 ;else if ( neg_echo )num_max <= echo_cnt ;assign distance = num_max * 20 /58 /1000 ;
endmodule
译码器模块:
`timescale 1ns / 1ps
module translate(input [3:0] num ,output reg[7:0] seg );always@(*)case(num)4'd0: seg = 8'h3f;4'd1: seg = 8'h06;4'd2: seg = 8'h5b;4'd3: seg = 8'h4f;4'd4: seg = 8'h66;4'd5: seg = 8'h6d;4'd6: seg = 8'h7d;4'd7: seg = 8'h07;4'd8: seg = 8'h7f;4'd9: seg = 8'h6f;default:; endcase endmodule
数码管模块
`timescale 1ns / 1ps
module state_SEG(input sys_clk ,input rst_n ,input [15:0] number ,output wire[3:0] DIG ,output wire[7:0] SEG );parameter MODE =0 ;reg [3:0] num ;reg [3:0] dig ;wire [7:0] seg ;//例化译码器模块 translate translate1(. num ( num ) ,. seg ( seg ) ); //数据提取wire [3:0] num_ge ;wire [3:0] num_shi ;wire [3:0] num_bai ;wire [3:0] num_qian ;assign num_ge = number%10 ;assign num_shi = number/10%10 ;assign num_bai = number/100%10 ;assign num_qian = number/1000%10 ;//状态机parameter TIME_1ms = 16'd50_00 ;localparam IDLE = 4'b0000 ;localparam GE = 4'b0001 ;localparam SHI = 4'b0010 ;localparam BAI = 4'b0100 ;localparam QIAN = 4'b1000 ;reg [3:0] cur_state ;reg [3:0] next_state ;reg [15:0] cnt_1ms ;always@(posedge sys_clk)if(!rst_n)cur_state <= IDLE ;elsecur_state <= next_state ;always@(*)case(cur_state)IDLE :beginnext_state = GE ;endGE : beginif ( cnt_1ms == TIME_1ms -1 )next_state = SHI ;elsenext_state = cur_state ;endSHI :beginif ( cnt_1ms == TIME_1ms -1 )next_state = BAI ;elsenext_state = cur_state ;endBAI :beginif ( cnt_1ms == TIME_1ms -1 )next_state = QIAN ;elsenext_state = cur_state ;endQIAN :beginif ( cnt_1ms == TIME_1ms -1 )next_state = GE ;elsenext_state = cur_state ;enddefault:;endcasealways@(posedge sys_clk)if(!rst_n)begincnt_1ms <= 0 ;dig <= 0 ;num <= 0 ;endelsecase(cur_state)IDLE :begincnt_1ms <= 0 ; dig <= 0 ; num <= 0 ; endGE :begindig <= 4'b1110 ;num <= num_ge ;if( cnt_1ms == TIME_1ms -1 )cnt_1ms <= 0 ;elsecnt_1ms <= cnt_1ms +1 ;endSHI :begindig <= 4'b1101 ;num <= num_shi ;if( cnt_1ms == TIME_1ms -1 )cnt_1ms <= 0 ;elsecnt_1ms <= cnt_1ms +1 ;end BAI :begindig <= 4'b1011 ;num <= num_bai ;if( cnt_1ms == TIME_1ms -1 )cnt_1ms <= 0 ;elsecnt_1ms <= cnt_1ms +1 ;end QIAN :begindig <= 4'b0111 ;num <= num_qian ;if( cnt_1ms == TIME_1ms -1 )cnt_1ms <= 0 ;elsecnt_1ms <= cnt_1ms +1 ;end default:; endcaseassign DIG = ( MODE == 0 ) ? dig :~dig ; assign SEG = ( MODE == 0 ) ? seg :~seg ; endmodule
顶层
`timescale 1ns / 1ps
module vlg_top(input sys_clk ,input rst_n ,input echo ,output trig , output wire[3:0] DIG ,output wire[7:0] SEG );//使能时钟产生模块wire clk_en ;vlg_en vlg_en1(. sys_clk (sys_clk) ,. rst_n (rst_n ) ,. clk_en (clk_en ) //clk_en的时钟周期为1us);//产生超声波测距模块的触发信号trigvlg_trig vlg_trig1(. sys_clk (sys_clk) ,. rst_n (rst_n ) ,. clk_en (clk_en ) , //1us为周期的时钟使能信号. trig (trig ));//回响信号echo的高电平时间采集wire[15:0] distance ;vlg_echo vlg_echo1( . sys_clk (sys_clk) ,. rst_n (rst_n ) ,. clk_en (clk_en ) ,. echo (echo ) ,. distance (distance) );//数码管模块state_SEG state_SEG1(. sys_clk (sys_clk) ,. rst_n (rst_n ) ,. number (distance ) ,. DIG ( DIG ) ,. SEG ( SEG ) );endmodule