当前位置: 首页 > article >正文

VS Code下开发FPGA——FPGA开发体验提升__下

上一篇:IntelliJ IDEA下开发FPGA-CSDN博客

Type:Quartus

一、安装插件

        在应用商店先安装Digtal IDE插件

安装后,把其他相关的Verilog插件禁用,避免可能的冲突。重启后,可能会弹出下面提示

这是插件默认要求的工具链,在扩展设置中可以选择其他几个。这里遵循默认,进入Vivado网址,下载

安装教程可参考Vivado 安装教程 - Digital Lab 2024

安装完成后,可以在VS Code的设置里,找到扩展选项,再找到安装路径设置,注意斜杠的方向

不过在使用时,经常会报下面错误,应该是VS Code的日常bug吧

二、基本使用 

1,网表

        在编写的模块中,点击Netlist就可以生成网表

在开启右边设置里的渲染动画时,点击每条支路都会有流光动画

2,文档

        点击右上角,可以打开文档,里面有该模块的所有总结信息

生成的代码文档足够详细,甚至包含注释的信息

3、代码检查

        在语法解析完成的情况下,对代码的检查可谓是相当给力,点击下方的提示可自动转到

而且对System Verilog文件也能进行正常检查,不必担忧中文注释

基于这个代码检查,编写模块文件和测试文件都可以使用表达能力更好的System Verilog

4,git插件

        至于前篇提到的内置git不是很好用,在一些插件的帮助下,有了质的提升

5,文件纲要

6,代码格式化

        右键屏幕,点击格式化文档,即可自动对齐代码

三、自动流程

1,创建任务

        由于FPGA芯片为Intel类型,因此综合(或仿真)需要用到Quartus(或ModelSim)。如想达到如IntelliJ IDEA中非常方便的运行目标,需要配置任务

①创建模板

        选择模板创建

选择Others

然后会自动生成配置文件

        语法很简单,label是该任务的名称,type是任务的类型,command就是该任务的执行命令,也就是名为label的任务使用shell执行command。这些内容在上篇IntelliJ IDEA的配置运行目标中可以见到,只不过这里更为自由

②运行任务

        此时执行任务试试

可以看到输出台上

③配置为生成任务(构建)

        点击配置默认生成任务,在点击之前创建的任务即可(这里已经选择过了)

        在模板里可以看到,json里添加了新的两个选项(标签)

④使用快捷键

        由于VS Code的运行任务不像IntelliJ IDEA之间在上方显示,每次运行时都需要点击【运行】→【运行任务】→【xxx任务】。因此可以把需要执行的任务配置为默认生成任务,然后通过Ctrl + Shift + B快速执行

⑤任务启动插件

当然,这样依旧并不是很方便,比如现在有综合、仿真等任务,来回切换就有些不够清晰直观。为解决这个问题,首先要想的便是插件,可以看到丰富的插件

        这里就随便选择一个,比如Task Manager,安装之后左边会出现一个小图标,点击之后就会显示所有任务

光标悬停在任务上面,就会出现绿色的执行键,点击执行就会出现下面图标,简单好用

2,综合任务

①编写脚本

综合

        基于上面内容,现在我们可以轻松仿照上篇中关于综合任务的配置。其基本思路是,编写一个ps1脚本,让任务目标使用shell终端来执行ps1脚本,ps1脚本里则是各种终端命令。

                任务shell脚本工具命令

        现在先写一个ps1脚本,与前篇的一样(前篇有详细讲解和代码)

为了让脚本更加通用,工作目录可以通过参数的方式传入,项目名从工作目录里提取


param([Parameter(Mandatory=$true)] # 强制要求参数[string]$WORK_DIR        # 声明参数变量
)# 设置程序路径
$QUARTUS_BIN = "E:\Tools\Develop\Embedded\intelFPGA\quartus\bin64"# 从路径提取目录名
$PROJECT_NAME = (Get-Item $WORK_DIR).Name  # 初始化环境
$env:PATH = "$QUARTUS_BIN;$env:PATH"
Set-Location $WORK_DIR# 执行流程
$commands = @("quartus_map --read_settings_files=on --write_settings_files=off $PROJECT_NAME -c $PROJECT_NAME","quartus_fit --read_settings_files=off --write_settings_files=off $PROJECT_NAME -c $PROJECT_NAME","quartus_asm --read_settings_files=off --write_settings_files=off $PROJECT_NAME -c $PROJECT_NAME","quartus_sta $PROJECT_NAME -c $PROJECT_NAME","quartus_eda --read_settings_files=off --write_settings_files=off $PROJECT_NAME -c $PROJECT_NAME"
)foreach ($cmd in $commands) {Write-Host "Run: $cmd" -ForegroundColor CyanInvoke-Expression $cmdif ($LASTEXITCODE -ne 0) {Write-Host "[Error] $LASTEXITCODE" -ForegroundColor Redexit $LASTEXITCODE}
}

        任务脚本需要改一下,名称为sythesis,命令为脚本名称。args里是存放各种参数,逗号相当于空格,起分隔作用

{// See https://go.microsoft.com/fwlink/?LinkId=733558// for the documentation about the tasks.json format"version": "2.0.0","tasks": [{"label": "synthesis","type": "shell","command": "powershell.exe",  // 显式调用 PowerShell"args": ["-ExecutionPolicy", "Bypass", // 绕过权限限制"-File", "${workspaceFolder}/usr/scripts/powershell/synthesis.ps1", // 脚本路径"${workspaceFolder}"// 传入工作目录],"options": {"cwd": "${workspaceFolder}" // 设置工作目录为项目根目录},// 配置为生成任务"problemMatcher": [],"group": {"kind": "build","isDefault": true},}]
}

执行效果如下

添加报告

        为了综合后能显示一些重要信息,可以在上面的ps1脚本末尾添加一些提取信息的命令,通过正则表达式匹配信息。比如可以从output_files目录下的xxx.sta.rpt文件里提取Fmax

# 提取 Fmax 值
$reportPath = Join-Path $WORK_DIR "output_files\$PROJECT_NAME.sta.rpt"
if (Test-Path $reportPath) {$content = Get-Content $reportPath -Raw$pattern = '(?s); \w+\s+\d+mV\s+(?<temp>[0-9-]+C)\s+Model Fmax Summary.*?; (?<fmax>\d+\.\d+) MHz'$matches = [regex]::Matches($content, $pattern)if ($matches.Count -gt 0) {$data = @()foreach ($match in $matches) {$temp = $match.Groups["temp"].Value -replace "C", ""$fmax = $match.Groups["fmax"].Value$data += [PSCustomObject]@{temp = $tempFmax = "$fmax MHz"}}# 修正列宽计算方式$tempWidth = [Math]::Max(4, ($data.temp | ForEach-Object { $_.ToString().Length } | Measure-Object -Maximum).Maximum)$fmaxWidth = [Math]::Max(5, ($data.Fmax | ForEach-Object { $_.ToString().Length } | Measure-Object -Maximum).Maximum)# 输出彩色表格Write-Host "--------------------------------------------------"Write-Host "Fmax Report for $PROJECT_NAME" -ForegroundColor YellowWrite-Host "--------------------------------------------------"# 标题行Write-Host ("{0,-$tempWidth} {1,-$fmaxWidth}" -f "temp", "Fmax") -ForegroundColor CyanWrite-Host ("{0,-$tempWidth} {1,-$fmaxWidth}" -f "----", "-----------") -ForegroundColor DarkGray# 数据行foreach ($item in $data) {# 温度用绿色,Fmax用蓝色Write-Host ("{0,-$tempWidth}" -f $item.temp) -NoNewline -ForegroundColor GreenWrite-Host (" {0,-$fmaxWidth}" -f $item.Fmax) -ForegroundColor Blue}} else {Write-Host "Failed to find Fmax values in report" -ForegroundColor Red}
} else {Write-Host "Report file not found: $reportPath" -ForegroundColor Red
}

②查看报告

        生成的报告都在output_files目录,其中fit.map和map.rpt是我们需要关注的,在fit.map中,大概两百多行处就是资源消耗的总结报告

        由于没有什么rpt文件相关的插件,如果想要更详细的信息,那么还是到Quartus里查看比较好

资源消耗报告

        不过既然想做一站式开发,频繁切换开发环境并不好。因此我们可以同前面一样,在脚本后面加一些命令来解析rpt文件获取一些重要信息,比如掌管资源消耗的xxx.fit.rpt文件

        需注意,这些脚本的路径都是基于项目路径,只要项目路径传输正确并且output_files能正确在项目路径里生成(这一条是由Quartus自动生成的)

# 提取 资源消耗
$reportPath = Join-Path $WORK_DIR "output_files\$PROJECT_NAME.fit.rpt"
if (-not (Test-Path $reportPath)) {Write-Host "Report file not found: $reportPath" -ForegroundColor Redexit 1
}# 读取报告内容
$content = Get-Content $reportPath -Raw# 提取顶层实体名
if ($content -match '; Top-level Entity Name\s+;\s*(?<entity>\S+)\s*;') {$topEntity = $matches.entity
} else {$topEntity = "Unknown"
}# 定义要提取的关键资源项
$resourcePatterns = @{"Total Logic Elements"          = '; Total logic elements\s+;\s+(.*?)\s*;'"Total Registers"               = '; Total registers\*\s+;\s+(.*?)\s*;'"I/O Pins"                      = '; I/O pins\s+;\s+(.*?)\s*;'"Used LABs"                     = '; Total LABs:\s+partially or completely used\s+;\s+(.*?)\s*;'"Global Clocks"                 = '; Global clocks\s+;\s+(.*?)\s*;'"Peak Interconnect Usage"       = '; Peak interconnect usage.*?\s+;\s+(.*?)\s*;'"Max Fan-out"                   = '; Maximum fan-out\s+;\s+(.*?)\s*;'"Memory (M9Ks)"                 = '; M9Ks\s+;\s+(.*?)\s*;'"PLLs"                          = '; PLLs\s+;\s+(.*?)\s*;'"Average Interconnect Usage"    = '; Average interconnect usage.*?\s+;\s+(.*?)\s*;'
}# 提取数据
$resourceData = @{}
foreach ($key in $resourcePatterns.Keys) {if ($content -match $resourcePatterns[$key]) {$resourceData[$key] = $matches[1].Trim()} else {$resourceData[$key] = "N/A"}
}# 创建表格数据
$reportData = @()
foreach ($key in $resourceData.Keys) {$reportData += [PSCustomObject]@{Resource = $keyValue    = $resourceData[$key]}
}# 自动调整表格列宽
$maxResourceLength = ($reportData.Resource | Measure-Object -Maximum -Property Length).Maximum
$maxValueLength    = ($reportData.Value | Measure-Object -Maximum -Property Length).Maximum# 输出彩色表格
Write-Host "--------------------------------------------------"
Write-Host "Fitter Resource Usage Report for [$topEntity]" -ForegroundColor Yellow
Write-Host "--------------------------------------------------"# 标题行
Write-Host ("{0,-$maxResourceLength} {1,-$maxValueLength}" -f "Resource", "Value") -ForegroundColor Cyan
Write-Host ("{0,-$maxResourceLength} {1,-$maxValueLength}" -f "--------------------------------", "--------------------------------") -ForegroundColor DarkGrayforeach ($item in $reportData) {# 根据资源类型设置颜色$valueColor = if ($item.Value -match "\d+%\s*\)") { "Cyan" } else { "Magenta" }Write-Host ("{0,-$maxResourceLength}" -f $item.Resource) -NoNewline -ForegroundColor GreenWrite-Host (" {0,-$maxValueLength}" -f $item.Value) -ForegroundColor $valueColor
}Write-Host "--------------------------------------------------"

效果如下,需要什么效果就用正则表达式提取相应信息,生成想要的格式

3,仿真任务

        与前篇一致,插件仿真默认使用的是iverilog,那么对sv文件的支持就相当差了,点击爬虫没有反应,但对v文件有反应。

①ModelSim_GUI

        那么也如前面,创建一个仿真任务,在原任务下面即可,逗号不要忘记添加

{// See https://go.microsoft.com/fwlink/?LinkId=733558// for the documentation about the tasks.json format"version": "2.0.0","tasks": [{"label": "synthesis","type": "shell","command": "powershell.exe",  // 显式调用 PowerShell"args": ["-ExecutionPolicy", "Bypass", // 绕过权限限制"-File", "${workspaceFolder}/usr/scripts/powershell/synthesis.ps1", // 脚本路径"${workspaceFolder}"// 传入工作目录],"options": {"cwd": "${workspaceFolder}" // 设置工作目录为项目根目录},// 配置为生成任务"problemMatcher": [],"group": {"kind": "build","isDefault": true},},{"label": "modelsim_gui", "type": "shell","command": "quartus_sh","args": ["-t","E:/tools/develop/embedded/intelfpga/quartus/common/tcl/internal/nativelink/qnativesim.tcl", // TCL 脚本路径"--rtl_sim","${workspaceFolderBasename}", "${workspaceFolderBasename}"],"options": {"cwd": "${workspaceFolder}", // 设置工作目录// 添加环境变量"env": {"PATH": "E:/Tools/Develop/Embedded/intelFPGA/quartus/bin64;${env:PATH}"}},"problemMatcher": []    // 无错误匹配器}]
}

        执行效果如下

②ModelSim_CMD

        此时是让ModelSim以命令行的形式运行,原流程是quartus_sh自动读取tcl脚本,然后生成对应的do脚本,再让vsim以命令行的形式执行这个do脚本。如果改写tcl脚本的话,有些麻烦,于是准备使用ps1脚本,让其直接读取qsf文件中仿真的配置,然后生成do脚本,再让vsim执行do脚本。

        那么这个ps1脚本可以先使用正则表达式匹配到关键信息,再利用模板生成特定的do脚本

param([string]$ProjectFloder,[string]$QsfPath,[string]$DoScript,[string]$VsimFloderPath,[string]$SimMode = "RTL"
)# 设置环境变量
$env:PATH = "$VsimFloderPath;$env:PATH"# 强制覆写设置(移除了备份逻辑)
if (Test-Path $DoScript) {Write-Host "Force overwriting existing DO script [$DoScript]"Remove-Item $DoScript -Force
}# 2. 解析QSF文件
$Config = @{SimTool = ""    # ModelSim-Altera (SystemVerilog)TopEntity = "" # 顶层模块名TopEntityFile = ""ActiveTestbench = ""TestbenchFile = ""
}# 解析状态跟踪
$currentSection = $nullGet-Content $QsfPath | ForEach-Object {# 捕获section声明if ($_ -match '-section_id\s+([^\s]+)') {$currentSection = $matches[1]}switch -regex ($_) {# 关键参数解析'set_global_assignment\s+-name\s+EDA_SIMULATION_TOOL\s+"(.+)"' {$Config.SimTool = $matches[1]Write-Host "[SimTool]: $($matches[1])" -ForegroundColor Green}# 捕获顶层模块名'set_global_assignment\s+-name\s+TOP_LEVEL_ENTITY\s+(.+)' {$Config.TopEntity = $matches[1]Write-Host "[TopEntity]: $($matches[1])" -ForegroundColor Green}# 捕获顶层模块文件名'set_global_assignment\s+-name\s+(VERILOG_FILE|SYSTEMVERILOG_FILE)\s+(.+)' {if($($Config.TopEntityFile) -eq ""){$filePath = $matches[2]$fileName = [IO.Path]::GetFileNameWithoutExtension($filePath)if ($fileName -eq $Config.TopEntity) {$Config.TopEntityFile = $filePathWrite-Host "[TopEntityFile]: $filePath" -ForegroundColor Green}}}# 捕获激活的测试平台'set_global_assignment\s+-name\s+EDA_NATIVELINK_SIMULATION_TEST_BENCH\s+"?(.+?)"?\s' {if ($currentSection -eq 'eda_simulation') {$Config.ActiveTestbench = $matches[1]Write-Host "[ActiveTestbench]: $($matches[1])" -ForegroundColor Green}else {Write-Host "[Warning] Ignoring non-testbench section: $currentSection -> $($matches[1])"  -ForegroundColor Red}}# 捕获测试平台文件名'set_global_assignment\s+-name\s+EDA_TEST_BENCH_FILE\s+(.+)\s+-section_id\s+(.+)' {$filePath = $matches[1]$fileName = [IO.Path]::GetFileNameWithoutExtension($filePath)$testbenchName = $matches[2]# 测试激励文件名与测试激励名称应匹配if(-not $fileName -eq $testbenchName){throw "[Error]: Testbench file name mismatch: $fileName != $testbenchName"}# 匹配测试激励文件if($testbenchName -eq $($Config.ActiveTestbench)){$Config.TestbenchFile = $matches[1]Write-Host "[TestbenchFile]: $($matches[1])" -ForegroundColor Green}}}
}# 对Config里面的内容做一次检查
if($($Config.TopEntityFile) -eq ""){throw "[Error]: No top entity file found in QSF file"
}Write-Host ""# 3. 确定测试平台文件
if (-not [string]::IsNullOrEmpty($Config.ActiveTestbench)) {
}
else {throw "No active testbench found in QSF file"
}# 4. 生成DO脚本
$DoContent = @("transcript on","if {[file exists rtl_work]} {","    vdel -lib rtl_work -all","}","vlib rtl_work","vmap work rtl_work",""
)# 生成仿真命令
$fileDirectory = [IO.Path]::GetDirectoryName($($Config.TopEntityFile))
$logCmd1 = "vlog -sv -work work +incdir+$ProjectFloder/$fileDirectory {$ProjectFloder/$($Config.TopEntityFile)}"$fileDirectory = [IO.Path]::GetDirectoryName($($Config.TestbenchFile))
$logCmd2 = "vlog -sv -work work +incdir+$ProjectFloder/$fileDirectory {$ProjectFloder/$($Config.TestbenchFile)}"$simCmd ="vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L cycloneive_ver -L rtl_work -L work -voptargs=`"+acc`" $($Config.ActiveTestbench)"$DoContent += @("",$logCmd1,$logCmd2,$simCmd,"add wave *","view structure","view signals","run -all","quit"
)# 5. 安全写入文件
try {$DoContent = $DoContent -join "`r`n"$DoContent | Out-File $DoScript -Encoding ASCII -ForceWrite-Host "DO script generated: $DoScript"  -ForegroundColor Blue# 执行仿真if ($Config.SimTool -match "ModelSim") {Write-Host "Launching ModelSim..."  -ForegroundColor BlueStart-Process vsim.exe -ArgumentList "-c -do `"$DoScript`"" -Wait -NoNewWindow}
}
catch {if (Test-Path $DoBackupPath) {Move-Item $DoBackupPath $DoScript -ForceWrite-Host "Restored original DO script"}throw $_
}

同前面一样,再创建一个仿真任务

        {"label": "modelsim_cmd", "type": "shell","command": "powershell.exe",  // 显式调用 PowerShell"args": ["-ExecutionPolicy", "Bypass", // 绕过权限限制"-File", "${workspaceFolder}/usr/scripts/powershell/modelsim_cmd.ps1", // 脚本路径"${workspaceFolder}",// 传入工作目录"${workspaceFolder}/${workspaceFolderBasename}.qsf",// 传入qsf文件"${workspaceFolder}/simulation/modelsim/modelsim.do",// 设置do脚本的路径(自己随便设,不一定要在simulation路径)"E:/Tools/Develop/Embedded/intelFPGA/ModelSim/modelsim_ase/win32aloem"// 传入vsim路径],"options": {"cwd": "${workspaceFolder}/simulation/modelsim", // 设置工作目录},}

启动任务后,ModelSim就以命令行的形式调用,正常进行仿真

        需要说明的是,这种方式只生成了do脚本,与之配套的库之类的还是依赖Quartus的tcl脚本生成,也就意味着运行do脚本的目录需要放到simulation目录里,而且前面必须至少执行过一次modelsim_gui任务(确保运行过tcl脚本在simulation目录里生成相应的库)

③查看波形

        查看波形已经没必要再Surfer里去查看,因为插件自带一个查看vcd文件的功能。想要生成波形,测试激励文件里必须加上下面这句

initial begin$dumpfile("xxx.vcd");// 填写对应的名称$dumpvars;
end

点击生成的vcd文件后,会出现这样的一个波形图,此时空空如也。点击右上角

选择需要的信号

左边就会出现你需要的信号,右键信号会有一些配置选项

此时,需要点击信号(变亮就行,点亮后波形也更亮),再点击红色箭头指向的位置,移动到最左边,不然波形不一定能看得到(如果太短的话)

调整到合适的位置之后,箭头所指方向,有三种不同的显示方式,旁边还有数值的显示方式。想要调节,那么左边的信号必须被点亮

第一种是数字型,第二种是离散化,第三种是模拟

其他仿真波形,“?”是高阻态,即z。“x”是未知值,紫色是数据帧

4,qsf文件的基础分析

        qsf文件对于Quartus相当于CMakeLists或者makefile对于C项目的管理,而目前的自动化流程是在Quartus综合的基础上构建的,因此需要简单理解一些基础的命令来更快的辅助开发。同时为了避免过度修改导致工程出现问题,要么手动备份,要么使用版本控制。

        在qsf文件中我们可以看到这样的写法,“#”就是行注释,里面的命令不区分顺序,并且可以出现空行,命令要顶格写且选项参数遵循间要有空格(同时也方面ps1脚本解析)

        这些命令不需要强记,因为这里我只要会修改即可,而且仅从“-name”后面的内容就可以看出它大概是干什么的了。比如下面,显然,上面是芯片族,下面是具体芯片型号

set_global_assignment -name FAMILY "Cyclone IV E"
set_global_assignment -name DEVICE EP4CE6E22C8
①引脚绑定

        qsf文件里面的命令并不一定是整齐排列的,为了便于我们管理,可以主动整理。比如引脚信号,在不确定引脚不常改变的情况下,可以先整理一下引脚,备份引脚便于下次新建工程时或者切换模块时快速恢复引脚

        配置引脚时是需要使用Quartus里的引脚绑定窗口,这里只是提供一种备份的思路

②资源文件

        如果文件都放在同一目录下,在Quartus里添加文件并不是一件方便的事。我们可以找到类似于下面这样的命令,把它们放到一起,前面可以加上一些注释来表明。-name后面左边的是文件类型,右边是对应的文件

SYSTEMVERILOG_FILE说明它是.sv文件,VERILOG_FILE自然就是.v文件,SDC_FILE是时序约束文件

set_global_assignment -name SYSTEMVERILOG_FILE xxx.sv
set_global_assignment -name VERILOG_FILE xxx.v

        测试激励文件与前面类似,不过它只有一种类型EDA_TEST_BENCH_FILE,后面紧跟着文件名(相对路径,相对于项目根目录),-section_id后面跟着的是名称,需要确保测试模块名称、仿真文件名称和这里的名称相同

③顶层文件

        这里的顶层文件指的不仅有模块顶层文件,还有测试模块文件。TOP_LEVEL_ENTITY描述的是模块顶层文件,EDA_NATIVELINK_SIMULATION_TEST_BENCH描述的是选中的仿真文件。

        需要注意的是它们都是名称而非文件,只不过模块名称与文件名称需要相同罢了

# ========================================================================
#                                   Entity
# ========================================================================
set_global_assignment -name TOP_LEVEL_ENTITY regs
set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH regs_tb -section_id eda_simulation

        此外,由于前面脚本解析的原因,需要确保指定顶层模块的命令放在前面,至少在资源文件定义前面

④测试激励文件绑定

        针对于一个仿真测试模块,需要三条命令来约束

        连着不容易看懂,可以把它们每三个按空格隔开

        前面如果添加了这是激励文件,这里也要同步添加名称,这里的配置不常改,只要把三个复制一下然后改一下名称即可

相关文章:

VS Code下开发FPGA——FPGA开发体验提升__下

上一篇&#xff1a;IntelliJ IDEA下开发FPGA-CSDN博客 Type&#xff1a;Quartus 一、安装插件 在应用商店先安装Digtal IDE插件 安装后&#xff0c;把其他相关的Verilog插件禁用&#xff0c;避免可能的冲突。重启后&#xff0c;可能会弹出下面提示 这是插件默认要求的工具链&a…...

ffmpeg播放音视频流程

文章目录 &#x1f3ac; FFmpeg 解码播放流程概览&#xff08;以音视频文件为例&#xff09;1️⃣ 创建结构体2️⃣ 打开音视频文件3️⃣ 查找解码器并打开解码器4️⃣ 循环读取数据包&#xff08;Packet&#xff09;5️⃣ 解码成帧&#xff08;Frame&#xff09;6️⃣ 播放 / …...

SpringCloud微服务: 分布式架构实战

# SpringCloud微服务: 分布式架构实战 第一章&#xff1a;理解SpringCloud微服务架构 什么是SpringCloud微服务架构&#xff1f; 在当今互联网应用开发中&#xff0c;微服务架构已经成为业界的主流趋势。SpringCloud是一个基于Spring Boot的快速开发微服务架构的工具&#xff0…...

AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年4月11日第49弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀6-8个和值&#xff0c;可以做到100-300注左右。 (1)定…...

Spring其它知识点

33.Spring 源码用到了哪些设计模式&#xff1f; 工厂模式&#xff1a;通过BeanFactory或者ApplicationContext创建Bean对象。BeanFactory是延迟注入&#xff0c;使用到Bean的时候才注入。ApplicationContext是在容器启动时&#xff0c;一次性创建所有的Bean。单例模型&#xf…...

【models】Transformer 之 各种 Attention 原理和实现

Transformer 之 各种 Attention 原理和实现 本文将介绍Transformer 中常见的Attention的原理和实现&#xff0c;其中包括&#xff1a; Self Attention、Spatial Attention、Temporal Attention、Cross Attention、Grouped Attention、Tensor Product Attention、FlashAttentio…...

C++ 学习资源整理

awesome-cpp&#xff08;C 资源大全&#xff09; &#x1f517; https://github.com/fffaraz/awesome-cpp 收集了各种 C 库、框架、教程和示例代码。 CPlusPlusThings&#xff08;C 基础知识整理&#xff09; &#x1f517; https://github.com/Light-City/CPlusPlusThings 包…...

opengrok搭建与配置

前提条件 需要配置好docker与docker-compose环境 1.代码准备 mkdir -p /data/opengrok/{etc,src,data} cd /data/opengrok/src/ # 克隆一个测试项目 git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git 2.创建docker-compose.yml文件&…...

老硬件也能运行的Win11 IoT LTSC (OEM)物联网版

#记录工作 Windows 11 IoT Enterprise LTSC 2024 属于物联网相关的版本。 Windows 11 IoT Enterprise 是为物联网设备和场景设计的操作系统版本。它通常针对特定的工业控制、智能设备等物联网应用进行了优化和定制&#xff0c;以满足这些领域对稳定性、安全性和长期支持的需求…...

JavaScript 代码混淆与反混淆技术详解

一、代码混淆&#xff1a;让别人看不懂你的代码 混淆技术就是一种“代码伪装术”&#xff0c;目的是让别人很难看懂你的代码逻辑&#xff0c;从而保护你的核心算法或敏感信息。 1. 变量名压缩 原理&#xff1a;把变量名改成乱码&#xff0c;比如把calculatePrice改成a&#…...

数据库守护神-WAL机制

什么是WAL机制&#xff1f; WAL&#xff08;Write-Ahead Logging&#xff0c;预写日志&#xff09;是一种保证数据库操作原子性和持久性的核心机制。其核心原则可概括为&#xff1a; 任何数据修改操作&#xff0c;必须在对应的日志记录持久化到磁盘之后&#xff0c;才能将实际…...

Git开发

目录 Linux下Git安装Git基本指令分支管理远程仓库与本地仓库标签管理多人协作同一分支下不同分支下 企业级开发模型 -- git flow 模型 在现实中&#xff0c;当我们完成一个文档的初稿后&#xff0c;后面可能还需要对初稿进行反复修改&#xff0c;从而形成不同版本的文档。显然&…...

verilog有符号数的乘法

无符号整数的乘法 1、单周期乘法器&#xff08; 无符号整数 &#xff09; 对于低速要求的乘法器&#xff0c;可以简单的使用 * 实现。 module Mult(input wire [7:0] multiplicand ,input wire [7:0] multipliter ,output wire [7:0] product);as…...

【蓝桥杯】动态规划:背包问题

这篇文章主要记录动态规划方面的学习。 动态规划的核心思想: 把大问题分解成小问题,记住小问题的解,避免重复计算。 动态规划(DP)的三大特点: ①最优子结构:大问题的最优解可以由小问题的最优解推导出来 ②重叠子问题:在求解过程中会反复遇到相同的小问题 ③无后效…...

DevDocs:抓取并整理技术文档的MCP服务

GitHub&#xff1a;https://github.com/cyberagiinc/DevDocs 更多AI开源软件&#xff1a;发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - 小众AI DevDocs 是一个完全免费的开源工具&#xff0c;由 CyberAGI 团队开发&#xff0c;托管在 GitHub 上。它专为程序员和软件开发…...

第十四届蓝桥杯大赛软件赛国赛Python大学B组题解

文章目录 弹珠堆放划分偶串交易账本背包问题翻转最大阶梯最长回文前后缀贸易航线困局 弹珠堆放 递推式 a i a i − 1 i a_ia_{i-1}i ai​ai−1​i&#xff0c; n 20230610 n20230610 n20230610非常小&#xff0c;直接模拟 答案等于 494 494 494 划分 因为总和为 1 e 6 1e6…...

折叠屏手机:技术进步了,柔性OLED面板测试技术需求跟上了吗?

全球智能手机市场陷入创新焦虑&#xff0c;折叠屏手机被寄予厚望&#xff0c;2023 年出货量同比增长 62%。但在供应链技术狂欢背后&#xff0c;存在诸多问题。消费端数据显示&#xff0c;用户使用频率低&#xff0c;定价策略反常。产业链重构虽让部分企业获利&#xff0c;却推高…...

30天学Java第九天——线程

并行与并发的区别 并行是多核 CPU 上的多任务处理&#xff0c;多个任务在同一时间真正的同时执行并发是单核 CPU 上的多任务处理&#xff0c;多个任务在同一时间段内交替执行&#xff0c;通过时间片轮转实现交替执行&#xff0c;用于解决 IO 密集型任务的瓶颈 线程的创建方式…...

kotlin的takeIf使用

takeIf用于判断指定对象是否满足条件&#xff0c;满足就返回该对象自身&#xff0c;不满足返回null。因为可以返回对象自身&#xff0c;所以可以用作链式调用&#xff0c;以简化代码&#xff0c;又因takeIf可能返回空&#xff0c;所以常常和let结合使用&#xff0c;示例如下&am…...

计算机毕业设计指南

哈喽各位大四的小伙伴们&#xff0c;以下是一份详细的计算机专业毕业设计指南&#xff0c;涵盖选题、流程、技术选型、开发建议和常见问题解决方案&#xff0c;帮助你高效完成毕业设计&#xff0c;如有其他问题&#xff0c;欢迎点击文章末尾名片进行咨询&#xff0c;可免费赠送…...

自行搭建一个Git仓库托管平台

1.安装Git sudo apt install git 2.Git本地仓库创建&#xff08;自己选择一个文件夹&#xff09; git init 这里我在 /home/test 下面初始化了代码仓库 1. 首先在仓库中新建一个txt文件&#xff0c;并输入一些内容 2. 将文件添加到仓库 git add test.txt 执行之后没有任何输…...

LeeCode 409.最长回文串

给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回 通过这些字母构造成的 最长的 回文串 的长度。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。 示例 1: 输入:s "abccccdd" 输出:7 解释: 我们可以构造的…...

ARM处理器内核全解析:从Cortex到Neoverse的架构与区别

ARM处理器内核全解析&#xff1a;从Cortex到Neoverse的架构与区别 ARM作为全球领先的处理器架构设计公司&#xff0c;其内核产品线覆盖了从高性能计算到低功耗嵌入式应用的广泛领域。本文将全面解析ARM处理器的内核分类、架构特点、性能差异以及应用场景&#xff0c;帮助读者深…...

【前端分享】JavaScript异步编程详解!

JavaScript 的异步编程是其核心特性之一&#xff0c;主要用于处理非阻塞操作&#xff08;如网络请求、文件读写、定时任务等&#xff09;。由于 JavaScript 是单线程的&#xff0c;异步机制可以避免代码阻塞&#xff0c;提高性能和用户体验。以下是 JavaScript 异步编程的核心概…...

工厂模式(简单工厂,工厂方法,抽象工厂)

工厂模式 工厂模式是java中最常用的设计模式&#xff0c;主要是用来完成对象的创建&#xff0c;使得对象创建过程和对象使用过程分离。 简单来说是取消对象创建者和使用者的耦合&#xff0c;简化new 对象的创建。 优势 &#xff1a;对象的属性创建完整。 缺点&#xff1a; 创建…...

Unity Internal-DeferredShading 分析

1. 延迟渲染的原理 延迟渲染主要包含了两个Pass。在第一个Pass中&#xff0c;我们不进行任何光照计算&#xff0c;而是仅仅计算哪些片元是可见的&#xff0c;这主要是通过深度缓冲技术来实现&#xff0c;当发现一个片元是可见的&#xff0c;我们就把它的相关信息存储到G缓冲区…...

嵌入式面试题:C 语言核心考点经典例题

引言 在嵌入式系统开发的面试中&#xff0c;常常会考察候选人对 C 语言基础知识的掌握程度。以下将详细分析几道常见的嵌入式面试题&#xff0c;包括解题步骤、涉及的知识点以及相关拓展。 题目 1 main() {unsigned char z0;unsigned char x100;unsigned char y10;z (~x)*(…...

Axure RP9教程 【数据传输】(页面值传递)| 作用域 :全局变量、局部变量

文章目录 引言作用域:全局变量作用域>局部变量作用域I 基于全局变量实现一个简单的登陆操作设置变量值的交互动作打开链接的交互动作接收并显示变量值注意点see also共享原型引言 全局变量在交互效果作用是页面值传递 作用域:全局变量作用域>局部变量作用域 全局变量…...

IBM Rational Software Architect安装感受及使用初体验

1 安装感受 最近准备用UML 2.0绘制模型图。在读UML创始人之一Grady Booch写的书《Object-Oriented Analysis and Design with Applications》&#xff08;第3版&#xff09;1时&#xff0c;发现书中用的UML工具之一为IBM Rational Software Architect&#xff08;RSA&#xff…...

VRRP学习

虚拟路由器冗余技术【三层技术】&#xff1a;网关冗余VRRP设计了VRRP组的概念&#xff0c;在一个 VRRP 组中&#xff0c;多台路由器共同构成一个虚拟路由器。这个虚拟路由器拥有一个虚拟 IP 地址【VRRP-ID默认是8位二进制&#xff0c;范围是0~255&#xff0c;用以标识和区别不同…...