47.简易电压表的设计与验证(2)

(1)Verilog 代码:

复制代码
module adc_collect(
    input                   clk         ,
    input                   reset_n     ,
    input   [7:0]           adc_data    ,
    
    output                  clk_adc     
    
);
    wire                clk_adc_a       ;
    wire                clk_adc_turn    ;
    wire                locked          ;
    wire    [31:0]      n_volt          ;
    wire    [31:0]      p_volt          ;
    wire    [31:0]      data_n          ;
    wire    [31:0]      data_p          ;
    
    reg     [10:0]      ad_cnt          ;
    reg     [19:0]      sum_ad          ;
    reg     [27:0]      adc_mid         ;
    reg     [31:0]      volt_n          ;
    reg     [31:0]      volt_p          ;
    
 assign clk_adc = clk_adc_a  ; 

pll_20M         pll_20M_inst
(
    .clk_adc(clk_adc_a),                  // output clk_adc
    .clk_adc_turn(clk_adc_turn),        // output clk_adc_turn
    .resetn(reset_n),                    // input resetn
    .locked(locked),                    // output locked
    .clk(clk)                           // input clk
);      

ila_volt        ila_volt_inst
(
	.clk(clk),                       // input wire clk
	.probe0(n_volt),                // input wire [31:0]  probe0  
	.probe1(p_volt)                 // input wire [31:0]  probe1
);

//adc累加计数器
always@(posedge clk_adc_turn or negedge locked)
    if(!locked)    
        ad_cnt  <= 11'd0;
    else if(ad_cnt == 11'd1025)
        ad_cnt  <= 11'd1025;
    else 
        ad_cnt  <= ad_cnt + 11'd1;

//adc前1024个数据累加       
always@(posedge clk_adc_turn or negedge locked)
    if(!locked)
        sum_ad <= 20'd0;
    else if(ad_cnt <= 11'd1024)
        sum_ad <= sum_ad + adc_data;
    else    
        sum_ad <= sum_ad;

//adc中值计算     
always@(posedge clk_adc_turn or negedge locked)
    if(!locked)
        adc_mid <= 28'd0;
    else if(ad_cnt == 11'd1024)
        adc_mid <= sum_ad >> 10;
    else if(ad_cnt == 11'd1025)
        adc_mid <= adc_mid;
    else 
        adc_mid <= 28'd0;
        
//精度定义   显示数据为4位数,其中第一位为个位,后三位为十分位,百分位,千分位。     40960_000 = 5* 2^13 * 1000
    assign data_n = (ad_cnt == 11'd1025)? 40960_000/(adc_mid + 1) : 0;
    assign data_p = (ad_cnt == 11'd1025)? 40960_000/(256 - adc_mid) : 0;    
        
//电压计算
always@(posedge clk_adc_turn or negedge locked)
    if(!locked)
        volt_n <= 32'd0;
    else if((ad_cnt == 11'd1025) && (adc_data < adc_mid))
        volt_n <= (data_n * (adc_mid - adc_data)) >> 13;
    else    
        volt_n <= 32'd0;
        
always@(posedge clk_adc_turn or negedge locked)
    if(!locked)
        volt_p <= 32'd0;
    else if((ad_cnt == 11'd1025) && (adc_data >= adc_mid))
        volt_p <= (data_n * (adc_data - adc_mid)) >> 13;
    else    
        volt_p <= 32'd0;   

//传入ILA
    assign n_volt = volt_n;
    assign p_volt = volt_p;
        
endmodule

(2)仿真文件:

复制代码
`timescale 1ns / 1ps

module adc_collect_tb;

reg         clk         ;
reg         clk_sample  ;
reg         reset_n     ;
reg   [7:0] adc_data    ;
reg   [7:0] data_reg    ;
reg         data_en     ;

wire        clk_adc     ;

initial clk = 1'd1;
always #10 clk = ~clk;

initial clk_sample = 1'd1;
always #25 clk_sample = ~clk_sample;

initial begin
    reset_n <= 1'd0;
    #25;
    reset_n <= 1'd1;
    #200; 
    data_en <= 1'd0;
    #2000000;
    data_en <= 1'd1;    
    #2000000;
    $stop;
end

    always@(posedge clk_sample or negedge reset_n)
        if(!reset_n)
            data_reg <= 8'd0;
        else if(data_en)
            data_reg <= data_reg + 8'd1;
        else 
            data_reg <= 8'd0;
            
    always@(posedge clk_sample or negedge reset_n)
        if(!reset_n)
            adc_data <= 8'd0;
        else if(!data_en)
            adc_data <= 8'd125;
        else 
            adc_data <= data_reg ;
            
adc_collect     adc_collect_inst(
    .clk         (clk),
    .reset_n     (reset_n),
    .adc_data    (adc_data),

    .clk_adc     (clk_adc)
    
);


endmodule

(3)仿真波形(仿真前先把ILA注释掉):

  • 整体波形图:
  • PLL时钟波形图:

  • 求中值中,累加计数器和中间值的计算:

  • 后续dac数据的赋值以及精度的波形:

  • 数值波形:

(4)XDC文件:

复制代码
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports clk_adc]
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports reset_n]
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {adc_data[2]}]
set_property PACKAGE_PIN W19 [get_ports clk]
set_property PACKAGE_PIN N15 [get_ports reset_n]
set_property PACKAGE_PIN L13 [get_ports {adc_data[0]}]
set_property PACKAGE_PIN M13 [get_ports {adc_data[1]}]
set_property PACKAGE_PIN M16 [get_ports {adc_data[2]}]
set_property PACKAGE_PIN M15 [get_ports {adc_data[3]}]
set_property PACKAGE_PIN M20 [get_ports {adc_data[4]}]
set_property PACKAGE_PIN N20 [get_ports {adc_data[5]}]
set_property PACKAGE_PIN M22 [get_ports {adc_data[6]}]
set_property PACKAGE_PIN N22 [get_ports {adc_data[7]}]
set_property PACKAGE_PIN L14 [get_ports clk_adc]

(5)实验现象:

编译遇到报错:

解决方法:

未接线,0v时,ILA波形:

-2.3v时,ILA波形:

-1.5v时,ILA波形:

0.5v时,ILA波形:

2.7v时,ILA波形:

3.75v时,ILA波形:

4.85v时,ILA波形:

相关推荐
爱吃汽的小橘11 小时前
异步串口通信和逻辑分析仪
运维·服务器·网络·单片机·嵌入式硬件·fpga开发
bnsarocket16 小时前
Verilog和FPGA的自学笔记3——仿真文件Testbench的编写
笔记·fpga开发·verilog·自学
Eloudy1 天前
Verilog可综合电路设计:重要语法细节指南
fpga开发
ARM+FPGA+AI工业主板定制专家1 天前
基于ZYNQ FPGA+AI+ARM 的卷积神经网络加速器设计
人工智能·fpga开发·cnn·无人机·rk3588
szxinmai主板定制专家1 天前
基于 ZYNQ ARM+FPGA+AI YOLOV4 的电网悬垂绝缘子缺陷检测系统的研究
arm开发·人工智能·嵌入式硬件·yolo·fpga开发
ooo-p1 天前
FPGA学习篇——Verilog学习之计数器的实现
学习·fpga开发
bnsarocket2 天前
Verilog和FPGA的自学笔记1——FPGA
笔记·fpga开发·verilog·自学
最遥远的瞬间2 天前
一、通用的FPGA开发流程介绍
fpga开发
weixin_450907282 天前
第八章 FPGA 片内 FIFO 读写测试实验
fpga开发
cycf2 天前
以太网接口(一)
fpga开发