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

======

运行调试

不降采样调试

降采样调试

配置不同采样频率

查看效果

======

======

======

======

相关推荐
南檐巷上学6 小时前
基于FPGA的正弦信号发生器、滤波器的设计(DAC输出点数受限条件下的完整正弦波产生器)
fpga开发·数字信号处理·dsp·dds
嵌入式-老费11 小时前
Linux Camera驱动开发(fpga + csi rx/csi tx)
fpga开发
ALINX技术博客1 天前
【202601芯动态】全球 FPGA 异构热潮,ALINX 高性能异构新品预告
人工智能·fpga开发·gpu算力·fpga
JJRainbow1 天前
SN75176 芯片设计RS-232 转 RS-485 通信模块设计原理图
stm32·单片机·嵌入式硬件·fpga开发·硬件工程
s9123601011 天前
FPGA眼图
fpga开发
北京青翼科技1 天前
【PCIe732】青翼PCIe采集卡-优质光纤卡- PCIe接口-万兆光纤卡
图像处理·人工智能·fpga开发·智能硬件·嵌入式实时数据库
minglie11 天前
verilog信号命名规范
fpga开发
XINVRY-FPGA1 天前
中阶FPGA效能红线重新划定! AMD第2代Kintex UltraScale+登场,记忆体频宽跃升5倍
嵌入式硬件·fpga开发·硬件工程·dsp开发·fpga
南檐巷上学2 天前
基于FPGA的音频信号监测识别系统
fpga开发·音频·verilog·fpga·傅立叶分析·fft·快速傅里叶变换
Aaron15882 天前
基于RFSOC的数字射频存储技术应用分析
c语言·人工智能·驱动开发·算法·fpga开发·硬件工程·信号处理