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

======

运行调试

不降采样调试

降采样调试

配置不同采样频率

查看效果

======

======

======

======

相关推荐
坏孩子的诺亚方舟13 天前
FPGA系统架构设计实践15_高云Arora V系列时钟体系
fpga开发·系统架构
FPGA小徐13 天前
入门 CNN 结构全解析|从流程图理论到 FPGA Verilog 硬件实现(含习题带讲解)
fpga开发
FPGA小徐13 天前
FPGA 数字信号处理:并行 FIR 与串行滤波器设计原理、对比与完整 Verilog 实现
fpga开发
Saniffer_SH14 天前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
zlinear数据采集卡14 天前
双核架构深度解析:ARM+FPGA如何让数据采集卡实现500Ksps高性能?
arm开发·fpga开发·架构
9527华安14 天前
FPGA实现GTH Transceivers Wizard传输2路视频,基于aurora 8b10b编解码架构,提供4套工程源码和技术支持
fpga开发·gth·aurora 8b10b·transceivers
FPGA小徐15 天前
FPGA 数字信号处理(二):并行 FIR 滤波器的 Verilog 全流程设计与实现
fpga开发
国科安芯15 天前
基于AS32S601ZIT2型抗辐照MCU的商业航天卫星姿态确定与控制系统研究
单片机·嵌入式硬件·安全·fpga开发·架构·risc-v
ALINX技术博客15 天前
【黑金云课堂】FPGA技术教程FPGA基础:I2C 总线通信技术
fpga开发·i2c
Hello-FPGA15 天前
Xilinx KU040 FPGA Camera Link 图像采集
c++·fpga开发