如何做到一套FPGA工程无缝兼容两款不同的板卡?

原创 电子电路开发学习 2023-11-08 11:50
试想这样一种场景,有两款不同的FPGA板卡,它们的功能代码90%都是一样的,但是两个板卡的管脚分配完全不同,一般情况下,我们需要设计两个工程,两套代码,之后还需要一直维护两个版本。
那么有没有一种自动化的方式,实现一个工程,编译出一个程序文件,下载到这两个不同的板卡上,都可以正常运行呢?
本文以开发板A和开发板B为例,介绍如何实现一套FPGA工程无缝兼容两款管脚不同的板卡?
两款开发板的时钟信号分别为clk_a和clk_b,分别位于两个不同的芯片管脚,两个开发板的FPGA型号完全一致,外部时钟的频率也一样。
首先需要判断当前是哪款板卡?实现方式是通过两个计数器,分别对时钟信号进行计数,由于两款板子的时钟信号分别位于不同的管脚,所以只有一个计数器会累加,并达到目标值,这样就实现了板卡型号的自动区分。
具体代码如下:
/*********************************************************************
 * Copyright © blog.csdn.net/whik1194
 * ModuleName : board_sel.v 
 * CreateTim  : 2023年11月5日 19:16:48
 * Author     : mcu149
 * Function   : function
 * Version    : v1.0
 *      Version | Modify
 *      ----------------------------------
 *       v1.0   | first version
 *********************************************************************/


module board_sel(
    //Inputs
    input clk_a,        //100MHz
    input clk_b,        //100MHz

    //Outputs
    output reg [1:0] sel = 2'd0,
    output reg rst_n = 1'b0
)
;

//1.parameter 
// parameter LATCH_TIME = 10_000_000 / 10;     //10ms
// parameter RESET_TIME = 100_000_000 / 10;    //100ms
// for simulation
parameter LATCH_TIME = 5_000 / 10;     //simulation, 5 us
parameter RESET_TIME = 10_000 / 10;    //simulation, 10 us

//2.localparam 
localparam BOARD_A = 2'd1;
localparam BOARD_B = 2'd2;

//3.reg
reg [31:0] cnt_a = 0;
reg [31:0] cnt_b = 0;

//4.wire 

//5.assign

//6.always 
always @ (posedge clk_a) begin
    if(cnt_a < LATCH_TIME + RESET_TIME)
        cnt_a <
= cnt_a + 1;
end

always @ (posedge clk_b) begin
    if(cnt_b < LATCH_TIME + RESET_TIME)
        cnt_b <
= cnt_b + 1;
end

always @ (*) begin
    if(cnt_a == LATCH_TIME)
        sel <
= BOARD_A; 
    else if(cnt_b == LATCH_TIME)
        sel <= BOARD_B;
end

always @ (*) begin
    if((cnt_a == LATCH_TIME + RESET_TIME) || (cnt_b == LATCH_TIME + RESET_TIME))
        rst_n <
1;
end

//7.instance

endmodule   //board_sel end
这里的代码,使用了寄存器定义时赋初值0的一个小技巧,一般工程不建议这么使用。
板卡区分之后,再根据区分的结果即sel的值对输出、输入分别进行选择。
具体实现如下:
/*********************************************************************
 * Copyright © blog.csdn.net/whik1194
 * ModuleName : board_sel.v 
 * CreateTim  : 2023年11月5日 19:40:48
 * Author     : mcu149
 * Function   : function
 * Version    : v1.0
 *      Version | Modify
 *      ----------------------------------
 *       v1.0   | first version
 *********************************************************************/


module board_dock(
    //Inputs
    input [1:0] sel,       

    input clk_a,
    input clk_b,
    input uart_txd,
    input led1,

    //Outputs
    output clk,
    output uart_txd_a,
    output uart_txd_b,
    output led1_a,
    output led1_b
)
;

//1.parameter 

//2.localparam 
localparam BOARD_A = 2'd1;
localparam BOARD_B = 2'd2;
localparam DEFAULT_OUT_VALUE = 1'b1;

//3.reg

//4.wire 

//5.assign
assign clk        = (sel == 2'd0   ) ? DEFAULT_OUT_VALUE : ((sel == BOARD_B) ? clk_b : clk_a );
assign uart_txd_a = (sel == BOARD_A) ? uart_txd : DEFAULT_OUT_VALUE;
assign uart_txd_b = (sel == BOARD_B) ? uart_txd : DEFAULT_OUT_VALUE;
assign led1_a     = (sel == BOARD_A) ? led1     : DEFAULT_OUT_VALUE;
assign led1_b     = (sel == BOARD_B) ? led1     : DEFAULT_OUT_VALUE;

//6.always 

//7.instance

endmodule   //board_dock end
仿真文件:
`timescale 1ns/1ps

`define BRD_A
// `define BRD_B

module top_tb;

localparam PERIOD = 10;      //10ns
localparam BOARD_A = 2'd1;
localparam BOARD_B = 2'd2;

reg clk_a;
reg clk_b;
reg uart_txd;
reg led1;

wire [1:0] sel;
wire rst_n;

`ifdef BRD_A
    always #(PERIOD/2) clk_a <= !clk_a;
`endif

`ifdef BRD_B
    always #(PERIOD/2) clk_b <= !clk_b;
`endif

initial begin
    $display("testbench: %s""top_tb");

    clk_a = 0;
    clk_b = 0;
    uart_txd = 0;
    led1 = 0;

end

always #(500_000) uart_txd <= !uart_txd;
always #(200_000) led1 <= !led1;

board_sel board_sel_ut0(
    //Inputs
    .clk_a(clk_a)
,        //100MHz
    .clk_b(clk_b),        //100MHz

    //Outputs
    .sel(sel),
    .rst_n(rst_n)
)
;

board_dock board_dock_ut0(
    //Inputs
    .sel(sel)
,      
    .clk_a(clk_a),
    .clk_b(clk_b),
    .uart_txd(uart_txd),
    .led1(led1),

    //Outputs
    .clk(clk),
    .uart_txd_a(uart_txd_a),
    .uart_txd_b(uart_txd_b),
    .led1_a(led1_a),
    .led1_b(led1_b)
)
;

endmodule   //top_tb end

总结

本文所提出的方式,可以在某些应用场景对板卡实现一定的兼容性,比如用来固件在线升级所使用的Golden镜像工程,不同的板子共用此工程,以后只需要维护一套代码即可。
当然这种方式也有一定的局限性,比如需要两款板卡的FPGA芯片型号一致、晶振频率一致,比如同样为XC7K325T,外部输入单端50M时钟。
也可以根据需要做到部分兼容,比如公用一套RTL代码,但是因为芯片型号不同,需要创建两个不同的工程,比如XC7K325T和XC7A75T。

更多精选

  • Xilinx FPGA芯片内部时钟和复位信号使用

  • 强大的JTAG边界扫描5-FPGA边界扫描应用

  • 强大的JTAG边界扫描4-STM32边界扫描应用

  • 强大的JTAG边界扫描3-常用边界扫描测试软件

  • 强大的JTAG边界扫描2-BSDL文件

  • 强大的JTAG边界扫描1-基本原理

  • 用JLink和OpenOCD来下载Xilinx FPGA程序

  • 获取Xilinx FPGA芯片IDCODE的4种方法(支持任何FPGA型号)

  • Xilinx FPGA Multiboot设计与实现(Spartan-6和Kintex-7示例)

  • 业余无线电是什么?

电子电路开发学习 单片机点灯小能手,电子行业从业者。开发板评测、嵌入式开源项目分享、学习笔记记录。可能不会经常更新,但每一篇都是精心编写。
评论
  • 随着工业自动化和智能化的发展,电机控制系统正向更高精度、更快响应和更高稳定性的方向发展。高速光耦作为一种电气隔离与信号传输的核心器件,在现代电机控制中扮演着至关重要的角色。本文将详细介绍高速光耦在电机控制中的应用优势及其在实际工控系统中的重要性。高速光耦的基本原理及优势高速光耦是一种光电耦合器件,通过光信号传递电信号,实现输入输出端的电气隔离。这种隔离可以有效保护电路免受高压、电流浪涌等干扰。相比传统的光耦,高速光耦具备更快的响应速度,通常可以达到几百纳秒到几微秒级别的传输延迟。电气隔离:高速光
    晶台光耦 2024-12-20 10:18 209浏览
  • 国产数字隔离器已成为现代电子产品中的关键部件,以增强的性能和可靠性取代了传统的光耦合器。这些隔离器广泛应用于医疗设备、汽车电子、工业自动化和其他需要强大信号隔离的领域。准确测试这些设备是确保其质量和性能的基本步骤。如何测试数字隔离器测试数字隔离器需要精度和正确的工具集来评估其在各种条件下的功能和性能。以下设备对于这项任务至关重要:示波器:用于可视化信号波形并测量时序特性,如传播延迟、上升时间和下降时间。允许验证输入输出信号的完整性。频谱分析仪:测量电磁干扰(EMI)和其他频域特性。有助于识别信号
    克里雅半导体科技 2024-12-20 16:35 157浏览
  • //```c #include "..\..\comm\AI8051U.h"  // 包含头文件,定义了硬件寄存器和常量 #include "stdio.h"              // 标准输入输出库 #include "intrins.h"         &n
    丙丁先生 2024-12-20 10:18 120浏览
  • 汽车行业的变革正愈演愈烈,由交通工具到“第三生活空间”。业内逐渐凝聚共识:汽车的下半场在于智能化。而智能化的核心在于集成先进的传感器,以实现高等级的智能驾驶乃至自动驾驶,以及更个性、舒适、交互体验更优的智能座舱。毕马威中国《聚焦电动化下半场 智能座舱白皮书》数据指出,2026年中国智能座舱市场规模将达到2127亿元,5年复合增长率超过17%。2022年到2026年,智能座舱渗透率将从59%上升至82%。近日,在SENSOR CHINA与琻捷电子联合举办的“汽车传感系列交流会-智能传感专场”上,艾
    艾迈斯欧司朗 2024-12-20 19:45 265浏览
  • ALINX 正式发布 AMD Virtex UltraScale+ 系列 FPGA PCIe 3.0 综合开发平台 AXVU13P!这款搭载 AMD 16nm 工艺 XCVU13P 芯片的高性能开发验证平台,凭借卓越的计算能力和灵活的扩展性,专为应对复杂应用场景和高带宽需求而设计,助力技术开发者加速产品创新与部署。随着 5G、人工智能和高性能计算等领域的迅猛发展,各行业对计算能力、灵活性和高速数据传输的需求持续攀升。FPGA 凭借其高度可编程性和实时并行处理能力,已成为解决行业痛点的关
    ALINX 2024-12-20 17:44 186浏览
  • 汽车驾驶员监控系统又称DMS,是一种集中在车辆中的技术,用于实时跟踪和评估驾驶员状态及驾驶行为。随着汽车产业智能化转型,整合AI技术的DMS逐渐成为主流,AI模型通过大量数据进行持续训练,使得驾驶监控更加高效和精准。 驾驶员监测系统主要通过传感器、摄像头收集驾驶员的面部图像,定位头部姿势、人脸特征及行为特征,并通过各种异常驾驶行为检测模型运算来识别驾驶员的当前状态。如果出现任何异常驾驶行为(如疲劳,分心,抽烟,接打电话,无安全带等),将发出声音及视觉警报。此外,驾驶员的行为数据会被记录
    启扬ARM嵌入式 2024-12-20 09:14 111浏览
  • 光耦合器,也称为光隔离器,是用于电气隔离和信号传输的多功能组件。其应用之一是测量电路中的电压。本文介绍了如何利用光耦合器进行电压测量,阐明了其操作和实际用途。使用光耦合器进行电压测量的工作原理使用光耦合器进行电压测量依赖于其在通过光传输信号的同时隔离输入和输出电路的能力。该过程包括:连接到电压源光耦合器连接在电压源上。输入电压施加到光耦合器的LED,LED发出的光与施加的电压成比例。光电二极管响应LED发出的光由输出侧的光电二极管或光电晶体管检测。随着LED亮度的变化,光电二极管的电阻相应减小,
    腾恩科技-彭工 2024-12-20 16:31 179浏览
  • 百佳泰特为您整理2024年12月各大Logo的最新规格信息。——————————USB▶ 百佳泰获授权进行 USB Active Cable 认证。▶ 所有符合 USB PD 3.2 标准的产品都有资格获得USB-IF 认证——————————Bluetooth®▶ Remote UPF Testing针对所有低功耗音频(LE Audio)和网格(Mesh)规范的远程互操作性测试已开放,蓝牙会员可使用该测试,这是随时测试产品的又一绝佳途径。——————————PCI Express▶ 2025年
    百佳泰测试实验室 2024-12-20 10:33 181浏览
  • 耳机虽看似一个简单的设备,但不仅只是听音乐功能,它已经成为日常生活和专业领域中不可或缺的一部分。从个人娱乐到专业录音,再到公共和私人通讯,耳机的使用无处不在。使用高质量的耳机不仅可以提供优良的声音体验,还能在长时间使用中保护使用者听力健康。耳机产品的质量,除了验证产品是否符合法规标准,也能透过全面性的测试和认证过程,确保耳机在各方面:从音质到耐用性,再到用户舒适度,都能达到或超越行业标准。这不仅保护了消费者的投资,也提升了该公司在整个行业的产品质量和信誉!客户面临到的各种困难一家耳机制造商想要透
    百佳泰测试实验室 2024-12-20 10:37 257浏览
  • Supernode与艾迈斯欧司朗携手,通过Belago红外LED实现精准扫地机器人避障;得益于Belago出色的红外补光功能,使扫地机器人能够大大提升其识别物体的能力,实现精准避障;Belago点阵照明器采用迷你封装,兼容标准无铅回流工艺,适用于各种3D传感平台,包括移动设备、物联网设备和机器人。全球领先的光学解决方案供应商艾迈斯欧司朗(瑞士证券交易所股票代码:AMS)近日宣布,与国内领先的多行业三维视觉方案提供商超节点创新科技(Supernode)双方联合推出采用艾迈斯欧司朗先进Belago红
    艾迈斯欧司朗 2024-12-20 18:55 175浏览
  • 光耦固态继电器(SSR)作为现代电子控制系统中不可或缺的关键组件,正逐步取代传统机械继电器。通过利用光耦合技术,SSR不仅能够提供更高的可靠性,还能适应更加复杂和严苛的应用环境。在本文中,我们将深入探讨光耦固态继电器的工作原理、优势、挑战以及未来发展趋势。光耦固态继电器:如何工作并打破传统继电器的局限?光耦固态继电器通过光电隔离技术,实现输入信号与负载之间的电气隔离。其工作原理包括三个关键步骤:光激活:LED接收输入电流并发出与其成比例的光信号。光传输:光电传感器(如光电二极管或光电晶体管)接收
    腾恩科技-彭工 2024-12-20 16:30 138浏览
  •                                                窗        外       年底将近,空气变得格外寒冷,估计这会儿北方已经是千里
    广州铁金刚 2024-12-23 11:49 146浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦