VIVADO VLA VIO 硬件调试 降采样

目录

新建工程

添加源文件

编辑源文件

编辑source文件

添加 (* MARK_DEBUG="true" *)

[Run Analysis -> Schematic](#Run Analysis -> Schematic)

[SYNTHESIS -> Run Synthesis](#SYNTHESIS -> Run Synthesis)

管脚约束

时序约束

[添加VIO IP](#添加VIO IP)

[Set Up Debug](#Set Up Debug)

[生成Bit Stream](#生成Bit Stream)

[下载Bit Stream](#下载Bit Stream)

调试

[添加 VIO dashboard](#添加 VIO dashboard)

运行调试

不降采样调试

降采样调试

配置不同采样频率


======

新建工程

======

======

======

添加源文件

design source

===

constrain source

======

编辑源文件

编辑source文件

复制代码
// Encoding: GB2312
// Generate_PWM.v
/*
实际设计要点与建议
(一)端口声明规则:
牢记输入端口和双向端口只能是 wire 型
输出端口则根据驱动方式决定:若在过程块内赋值,声明为 output reg;若用 assign 驱动,声明为 output wire(或直接省略 wire)
(二)变量选择原则:
先根据设计意图(组合逻辑还是时序逻辑)选择使用 assign 还是 always 块。
再根据赋值位置决定变量类型,在 always 块中操作的变量应声明为 reg,即使最终综合出来的是组合逻辑
(三)避免常见陷阱:
不可在 always 块中对 wire 型变量进行赋值
不可使用 assign 语句对 reg 型变量进行赋值
用于描述时序逻辑的 always 块中,推荐使用非阻塞赋值 (<=) 来避免仿真竞争风险。
(四)理解这些关键字的关键在于跳出"软件编程"思维,时刻思考其对应的硬件电路结构:
wire 是导线,            assign 是连接关系;
reg 是存储单元或中间变量, always 是根据条件触发的行为描述。
只有清晰地区分连续赋值(wire+assign)与过程赋值(reg+always/initial)这两大范式,才能更准确地用 Verilog 来描述所需的硬件功能。
*/
`timescale 1ns / 1ps

module Generate_PWM #(
    parameter CLK_FREQ   = 50_000_000,  // 输入时钟频率 (50MHz)
    parameter PWM_FREQ   = 1_000,       // 目标PWM频率 (1KHz)
    parameter DUTY_CYCLE = 50           // 占空比百分比 (0-100)
) (
    input wire clk_sys,  // 输入时钟
    (* MARK_DEBUG="true" *) output reg pwm_o  // PWM输出  (* MARK_DEBUG="true" *)
);

  // 计算计数器位宽和阈值
  localparam COUNTER_MAX = CLK_FREQ / PWM_FREQ - 1;
  localparam COUNTER_WIDTH = $clog2(COUNTER_MAX + 1);
  localparam DUTY_COUNT = (COUNTER_MAX + 1) * DUTY_CYCLE / 100;

  (* MARK_DEBUG="true" *) wire [0:0] rst_sys;  //(* MARK_DEBUG="true" *)
  wire [7:0] VLASampleFreqDivSetByVIO;

  reg [COUNTER_WIDTH-1:0] counter;

  always @(posedge clk_sys or negedge rst_sys) begin
    if (!rst_sys) begin
      counter <= 'd0;
      pwm_o   <= 1'b0;
    end else begin
      // 循环计数
      if (counter == COUNTER_MAX) begin
        counter <= 'd0;
      end else begin
        counter <= counter + 1'b1;
      end
      // 生成PWM波形
      if (counter < DUTY_COUNT) begin
        pwm_o <= 1'b1;
      end else begin
        pwm_o <= 1'b0;
      end
    end
  end

  (* MARK_DEBUG="true" *) reg [7:0] vla_trigger_counter;  // (* MARK_DEBUG="true" *)
  wire vla_trigger;
  always @(posedge clk_sys or negedge rst_sys) begin
    if (!rst_sys) begin
      vla_trigger_counter <= 0;
    end else if (vla_trigger_counter >= VLASampleFreqDivSetByVIO - 1) begin
      vla_trigger_counter <= 0;
    end else begin
      vla_trigger_counter <= vla_trigger_counter + 1;
    end
  end

  assign vla_trigger = (vla_trigger_counter == VLASampleFreqDivSetByVIO - 1);

endmodule

添加 (* MARK_DEBUG="true" *)

======

Run Analysis -> Schematic

===

SYNTHESIS -> Run Synthesis

======

管脚约束

时序约束

约束文件中多了时序约束的语句

复制代码
set_property IOSTANDARD LVCMOS33 [get_ports clk_sys]
set_property IOSTANDARD LVCMOS33 [get_ports pwm_o]
set_property PACKAGE_PIN U18 [get_ports clk_sys]
set_property PACKAGE_PIN T14 [get_ports pwm_o]
create_clock -period 20.000 -name clk_sys -waveform {0.000 10.000} [get_ports clk_sys]

======

添加VIO IP

把复制的代码添加到源文件最后,并做如下修改

复制代码
  vio_0 instance_vio_0_0 (
      .clk       (clk_sys),                  // input wire clk
      .probe_out0(rst_sys),                  // output wire [15 : 0] probe_out0
      .probe_out1(VLASampleFreqDivSetByVIO)  // output wire [15 : 0] probe_out0
  );

完整代码如下

复制代码
// Encoding: GB2312
// .v
/*
实际设计要点与建议
(一)端口声明规则:
牢记输入端口和双向端口只能是 wire 型
输出端口则根据驱动方式决定:若在过程块内赋值,声明为 output reg;若用 assign 驱动,声明为 output wire(或直接省略 wire)
(二)变量选择原则:
先根据设计意图(组合逻辑还是时序逻辑)选择使用 assign 还是 always 块。
再根据赋值位置决定变量类型,在 always 块中操作的变量应声明为 reg,即使最终综合出来的是组合逻辑
(三)避免常见陷阱:
不可在 always 块中对 wire 型变量进行赋值
不可使用 assign 语句对 reg 型变量进行赋值
用于描述时序逻辑的 always 块中,推荐使用非阻塞赋值 (<=) 来避免仿真竞争风险。
(四)理解这些关键字的关键在于跳出"软件编程"思维,时刻思考其对应的硬件电路结构:
wire 是导线,            assign 是连接关系;
reg 是存储单元或中间变量, always 是根据条件触发的行为描述。
只有清晰地区分连续赋值(wire+assign)与过程赋值(reg+always/initial)这两大范式,才能更准确地用 Verilog 来描述所需的硬件功能。
*/
`timescale 1ns / 1ps

module Generate_PWM #(
    parameter CLK_FREQ   = 50_000_000,  // 输入时钟频率 (50MHz)
    parameter PWM_FREQ   = 1_000,       // 目标PWM频率 (1KHz)
    parameter DUTY_CYCLE = 50           // 占空比百分比 (0-100)
) (
    input wire clk_sys,  // 输入时钟
    (* MARK_DEBUG="true" *) output reg pwm_o  // PWM输出  (* MARK_DEBUG="true" *)
);

  // 计算计数器位宽和阈值
  localparam COUNTER_MAX = CLK_FREQ / PWM_FREQ - 1;
  localparam COUNTER_WIDTH = $clog2(COUNTER_MAX + 1);
  localparam DUTY_COUNT = (COUNTER_MAX + 1) * DUTY_CYCLE / 100;

  (* MARK_DEBUG="true" *) wire [0:0] rst_sys;  //(* MARK_DEBUG="true" *)
  wire [7:0] VLASampleFreqDivSetByVIO;

  reg [COUNTER_WIDTH-1:0] counter;

  always @(posedge clk_sys or negedge rst_sys) begin
    if (!rst_sys) begin
      counter <= 'd0;
      pwm_o   <= 1'b0;
    end else begin
      // 循环计数
      if (counter == COUNTER_MAX) begin
        counter <= 'd0;
      end else begin
        counter <= counter + 1'b1;
      end
      // 生成PWM波形
      if (counter < DUTY_COUNT) begin
        pwm_o <= 1'b1;
      end else begin
        pwm_o <= 1'b0;
      end
    end
  end



  (* MARK_DEBUG="true" *) reg [7:0] vla_trigger_counter;  // (* MARK_DEBUG="true" *)
  wire vla_trigger;
  always @(posedge clk_sys or negedge rst_sys) begin
    if (!rst_sys) begin
      vla_trigger_counter <= 0;
    end else if (vla_trigger_counter >= VLASampleFreqDivSetByVIO - 1) begin
      vla_trigger_counter <= 0;
    end else begin
      vla_trigger_counter <= vla_trigger_counter + 1;
    end
  end

  assign vla_trigger = (vla_trigger_counter == VLASampleFreqDivSetByVIO - 1);

  vio_0 instance_vio_0_0 (
      .clk       (clk_sys),                  // input wire clk
      .probe_out0(rst_sys),                  // output wire [15 : 0] probe_out0
      .probe_out1(VLASampleFreqDivSetByVIO)  // output wire [15 : 0] probe_out0
  );
  

endmodule

======

Set Up Debug

点OK关闭,通过SYNSIS -> Set Up Debug 配置Debug

配置前先保存并综合一下

======

生成Bit Stream

======

下载Bit Stream

======

调试

添加 VIO dashboard

======

运行调试

不降采样调试

降采样调试

配置不同采样频率

查看效果

======

======

======

======

相关推荐
仲南音2 天前
Xilinx FPGA——时钟IP核MMCM、PLL
fpga开发
I'm a winner2 天前
基于Xilinx FPGA的LVDS高速串行通信系统(三)--数据训练及握手机制【文末源码】
fpga开发
upper20203 天前
coremark移植坑之-nostartfiles -nostdlib参数
学习·fpga开发·coremark移植·riscv设计
Eloudy3 天前
Vivado 纯命令行构建 FPGA 项目教程
fpga开发
Rambo.xia3 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
upper20203 天前
FPGA部署卷积神经网络识别MINST图片
fpga开发·卷积神经网络·minst·minst识别·部署神经网络·神经网络识别图片
你是我的解忧王子3 天前
嵌入式 ADC采样 原始数据分析上层(平均值 波动率 正态分布 线性补偿 系统误差)
fpga开发·数据挖掘·数据分析
9527华安4 天前
FPGA纯verilog代码ISP图像处理培训教程,基于IMX214,提供工程源码+视频教程+FPGA开发板
图像处理·fpga开发·isp·imx214·mipi
千寻xun4 天前
二、实战篇-NVME SSD控制之ZYNQ实现(六)-读写NVME SSD硬盘数据
fpga开发·nvme·nvme ssd
千寻xun4 天前
二、实战篇-NVME SSD控制之ZYNQ实现(三)
fpga开发·nvme ssd·nvme协议