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

======

运行调试

不降采样调试

降采样调试

配置不同采样频率

查看效果

======

======

======

======

相关推荐
FPGA小迷弟1 小时前
基于FPGA开发高速ADC/DAC芯片笔记
图像处理·fpga开发·数据采集·fpga·adc
ZYNQRFSOC18 小时前
基于XCKU5P纯逻辑 NVME测试
fpga开发
FPGA小迷弟1 天前
使用FPGA开发高速AD/DA芯片的接口学习
fpga开发
stars-he1 天前
FPGA学习笔记(6)逻辑设计小结与以太网发送前置
笔记·学习·fpga开发
燎原星火*1 天前
FPGA 逻辑级数
fpga开发
175063319452 天前
Vivado Zynq7020 生成正弦波(查表法) + 行为级仿真
fpga开发
Terasic友晶科技2 天前
4-DE10-Nano的HDMI方块移动案例——I2C通信协议
fpga开发·i2c·hdmi·de10-nano·i2c通信协议
云雾J视界2 天前
FPGA在AI时代的角色重塑:硬件可重构性与异构计算的完美结合
fpga开发·边缘计算·gpu·vitis·ai推理·azure云·异构编程
s09071363 天前
FPGA中CIC设计注意事项
算法·fpga开发·cic滤波器