Xilinx FPGA:vivado利用单端RAM/串口传输数据实现自定义私有协议
一、项目要求
实现自定义私有协议,如:pc端产生数据:02 56 38 ,“02”代表要发送数据的个数,“56”“38”需要写进RAM中。当按键信号到来时,将“56”“38”读出返回给PC端。
二、信号流向图

三、状态转换图

四、程序设计:
按键消抖模块:
`timescale 1ns / 1ps
module key_debounce(input sys_clk ,input rst_n ,input key ,output key_flag );parameter delay = 100;//_000_0 ; //10msreg[25:0] cnt ;always@(posedge sys_clk )if(!rst_n)cnt <= 0 ;else if ( key == 0 )beginif ( cnt == delay - 1 )cnt <= cnt ;elsecnt <= cnt +1 ;endelsecnt <= 0 ;assign key_flag = ( cnt == delay - 2 )?1:0 ;endmodule
接收端模块:
`timescale 1ns / 1ps
module uart_rx(input sys_clk ,input rst_n ,input rx_data ,output reg[7:0] uart_data ,output reg rx_done );parameter SYSCLK = 50_000_000 ;parameter Baud = 115200 ; parameter COUNT = SYSCLK/Baud;parameter MID = COUNT/2 ;///start_flagreg rx_reg1 ;reg rx_reg2 ;wire start_flag ;always@(posedge sys_clk )if(!rst_n)beginrx_reg1 <= 1 ;rx_reg2 <= 1 ;endelsebeginrx_reg1 <= rx_data ;rx_reg2 <= rx_reg1 ;endassign start_flag = ~rx_reg1 & rx_reg2 ;//rx_flagreg rx_flag ;reg[4:0] cnt_bit ;reg[9:0] cnt ;always@(posedge sys_clk )if(!rst_n)rx_flag <= 0 ;else if ( start_flag == 1 )rx_flag <= 1 ;else if ( cnt_bit == 10 && cnt == MID - 1 )rx_flag <= 0 ;elserx_flag <= rx_flag ;cntalways@(posedge sys_clk )if(!rst_n)cnt <= 0 ;else if ( rx_flag == 1 )beginif ( cnt == COUNT - 1 )cnt <= 0 ;elsecnt <= cnt +1 ;endelsecnt <= 0 ;cnt_bitalways@(posedge sys_clk )if(!rst_n)cnt_bit <= 0 ;else if ( rx_flag == 1 )beginif ( cnt == COUNT - 1 )beginif( cnt_bit == 10 )cnt_bit <= 0 ;elsecnt_bit <= cnt_bit +1 ;endelsecnt_bit <= cnt_bit ;endelsecnt_bit <= 0 ;///data_reg reg[8:0] data_reg ; //data_reg:01234567 [8]always@(posedge sys_clk ) //cnt_bit:[0]12345678[9][10]if(!rst_n)data_reg <= 0 ;else if ( rx_flag == 1 )beginif ( cnt_bit > 0 && cnt_bit < 10 && cnt == MID - 1)data_reg[cnt_bit - 1 ] <= rx_data ;elsedata_reg <= data_reg ;endelsedata_reg <= 0 ;checkreg check ;always@(posedge sys_clk )if(!rst_n)check <= 0 ;else if ( rx_flag == 1 )beginif ( cnt_bit == 10 )check <= ^data_reg ;elsecheck <= 0 ;endelsecheck <= 0 ;uart_dataparameter MODE_CHECK = 0 ;always@(posedge sys_clk )if(!rst_n)uart_data <= 0 ;else if ( rx_flag == 1 )beginif ( cnt_bit == 10 && cnt == 10 && check == MODE_CHECK)uart_data <= data_reg[7:0] ;elseuart_data <= uart_data ;endelseuart_data <= uart_data ;rx_donealways@(posedge sys_clk )if(!rst_n)rx_done <= 0 ;else if ( rx_flag == 1 )beginif ( cnt_bit == 10 && cnt == MID/2 - 1 )rx_done <= 1 ;elserx_done <= 0 ;endelserx_done <= 0 ;//做测试用的
// wire tx_done ;
// wire tx_data ;
// uart_tx uart_tx_u1(
// . sys_clk (sys_clk ) ,
// . rst_n (rst_n ) ,
// . ram_out (uart_data ) , //uart_data(douta)
// . tx_start (rx_done) , //rx_done
// . tx_done (tx_done ) ,
// . tx_data (tx_data )
// ); endmodule
发送端模块:
`timescale 1ns / 1ps
module uart_tx(input sys_clk ,input rst_n ,input [7:0] ram_out , //uart_data(douta)input tx_start , //rx_doneoutput reg tx_done ,output reg tx_data );parameter SYSCLK = 50_000_000 ;parameter Baud = 115200 ;parameter COUNT = SYSCLK/Baud ;parameter MID = COUNT/2 ;//start_flagreg tx_reg1 ;reg tx_reg2 ;wire start_flag ;always@(posedge sys_clk )if(!rst_n)begintx_reg1 <= 0 ;tx_reg2 <= 0 ;endelsebegintx_reg1 <= tx_start ;tx_reg2 <= tx_reg1 ;endassign start_flag = tx_reg1 & ~tx_reg2 ;///tx_flagreg tx_flag ;reg[9:0] cnt ;reg[4:0] cnt_bit ;always@(posedge sys_clk )if(!rst_n) tx_flag <= 0 ;else if ( start_flag == 1 )tx_flag <= 1 ;else if ( cnt_bit == 10 && cnt == COUNT -1 )
// else if ( cnt_bit == 10 && cnt == MID -1 )tx_flag <= 0 ;elsetx_flag <= tx_flag ;cntalways@(posedge sys_clk )if(!rst_n)cnt <= 0 ;else if ( tx_flag == 1 )beginif ( cnt == COUNT - 1 )cnt <= 0 ;elsecnt <= cnt +1 ;endelsecnt <= 0 ;//cnt_bitalways@(posedge sys_clk )if(!rst_n)cnt_bit <= 0 ;else if ( tx_flag == 1 )beginif ( cnt == COUNT - 1 )beginif ( cnt_bit == 10 )cnt_bit <= 0 ;elsecnt_bit <= cnt_bit +1 ;endelsecnt_bit <= cnt_bit ;endelsecnt_bit <= 0 ;///tx_dataparameter MODE_CHECK = 0 ;always@( posedge sys_clk )if(!rst_n)tx_data <= 1 ;else if ( tx_flag == 1 )beginif ( cnt_bit > 0 && cnt_bit < 9 )tx_data <= ram_out[cnt_bit -1] ;else if ( cnt_bit == 0 )tx_data <= 0 ;else if ( cnt_bit == 9 ) tx_data <= ( MODE_CHECK == 0 )? ^ram_out :~^ram_out ;else if ( cnt_bit == 10 )tx_data <= 1 ;elsetx_data <= tx_data ;endelsetx_data <= 1 ;//tx_done always@(posedge sys_clk )if(!rst_n)tx_done <= 0 ;else if ( tx_flag == 1 )beginif ( cnt_bit == 10 && cnt == COUNT - 1 )
// if ( cnt_bit == 10 && cnt == MID/2 - 1 )tx_done <= 1 ;elsetx_done <= 0 ;endelsetx_done <= 0 ;endmodule
RAM模块:
`timescale 1ns / 1ps
module private_ram_ctrl(input sys_clk ,input rst_n ,input key_flag ,input [7:0] uart_data ,input rx_done ,input tx_done ,output reg[7:0] ram_out , output reg tx_start );reg wea ;reg[3:0] addra ;reg[7:0] dina ;wire[7:0] douta ;//状态机localparam IDLE = 3'd0 ;localparam WR_D = 3'd1 ;localparam WAIT = 3'd2 ;localparam TX_FIR = 3'd3 ;localparam TX_D = 3'd4 ;reg[2:0] cur_state ;reg[2:0] next_state ;reg[7:0] wr_len ;reg[7:0] wr_cnt ;always@(posedge sys_clk )if(!rst_n)cur_state <= IDLE ;else cur_state <= next_state ;always@(*)case(cur_state)IDLE : beginif (rx_done)//指令数据的接收完成信号next_state = WR_D ;elsenext_state = cur_state ;endWR_D :beginif( wr_len == wr_cnt )next_state = WAIT ;elsenext_state = cur_state ;endWAIT :beginif( key_flag )next_state = TX_FIR ;elsenext_state = cur_state ;endTX_FIR :beginnext_state = TX_D ;endTX_D :beginif ( wr_len == wr_cnt )next_state = IDLE ;elsenext_state = cur_state ;enddefault:;endcasealways@(posedge sys_clk )if(!rst_n)beginwr_len <= 0 ;wr_cnt <= 0 ;wea <= 0 ;addra <= 4'hf ;利用溢出功能 15dina <= 0 ;tx_start <= 0 ;ram_out <= 0 ; ///ram_out <= doutaendelsecase(cur_state)IDLE : beginwr_len <= 0 ; wr_cnt <= 0 ; wea <= 0 ; dina <= 0 ; addra <= 4'hf ;tx_start <= 0 ;if(rx_done)wr_len <= uart_data ;elsewr_len <= wr_len ;end WR_D :begintx_start <= 0 ;if ( rx_done )beginaddra <= addra +1 ;wea <= 1 ;wr_cnt <= wr_cnt +1 ;dina <= uart_data ;endelsewea <= 0 ;//其他的不用写会自动保持endWAIT :begintx_start <= 0 ;addra <= 0 ;//保证发送数据的时候是从0开始发的dina <= 0 ;wr_cnt <= 0 ;endTX_FIR: //只待一个时钟周期begintx_start <= 1 ;addra <= addra + 1 ; //addra从0开始加wr_cnt <= wr_cnt +1 ;ram_out <= douta ;endTX_D :beginif(tx_done)begintx_start <= 1 ;addra <= addra +1 ;wr_cnt <= wr_cnt +1; ram_out <= douta ;endelsetx_start <= 0 ;enddefault:;endcasesingle_ram your_instance_name (.clka(sys_clk), // input wire clka.wea(wea), // input wire [0 : 0] wea.addra(addra), // input wire [3 : 0] addra.dina(dina), // input wire [7 : 0] dina.douta(douta) // output wire [7 : 0] douta
);
endmodule
顶层模块:
`timescale 1ns / 1ps
module TOP(input sys_clk ,input rst_n ,input key ,input rx_data ,output tx_data );///key_debouncewire key_flag ;key_debounce key_debounce_u1(. sys_clk (sys_clk ) ,. rst_n (rst_n ) ,. key (key ) ,. key_flag (key_flag) );//private_ram_ctrlwire[7:0] uart_data ;wire rx_done ;wire tx_done ;wire[7:0] ram_out ; wire tx_start ;private_ram_ctrl private_ram_ctrl_u1(. sys_clk (sys_clk ) ,. rst_n (rst_n ) ,. key_flag (key_flag ) ,. uart_data (uart_data) ,. rx_done (rx_done ) ,. tx_done (tx_done ) ,. tx_start (tx_start) ,. ram_out (ram_out ) );/uart_rxuart_rx uart_rx_u2(. sys_clk (sys_clk ) , . rst_n (rst_n ) , . rx_data (rx_data ) , . uart_data (uart_data) , . rx_done (rx_done ) ); uart_txuart_tx uart_tx_u1(. sys_clk (sys_clk ), //sys_clk ,. rst_n (rst_n ), //rst_n ,. ram_out (ram_out ), //ram_out , //uart_data(douta). tx_start (tx_start), //tx_start , //rx_done. tx_done (tx_done ), //tx_done ,. tx_data (tx_data ) //tx_data );endmodule
五、仿真结果
仿真uart_rx模块:
`timescale 1ns / 1ps
module test_uart_rx( );reg sys_clk ;reg rst_n ;reg rx_data ;wire[7:0] uart_data ;wire rx_done ;parameter SYSCLK = 50_000_000 ;parameter Baud = 115200 ;parameter COUNT = SYSCLK/Baud;parameter MID = COUNT/2 ;initialbeginsys_clk = 0 ;rst_n = 0 ;#10rst_n = 1 ;endalways #1 sys_clk = ~sys_clk ;initialbeginuart_out ( 8'hCC );uart_out ( 8'hC8 );uart_out ( 8'h18 );uart_out ( 8'h78 );uart_out ( 8'h66 );uart_out ( 8'h1E );uart_out ( 8'hCC );uart_out ( 8'h9F );uart_out ( 8'h66 );uart_out ( 8'h9F );uart_out ( 8'h33 );uart_out ( 8'h1E );uart_out ( 8'hCC );uart_out ( 8'h9F );uart_out ( 8'h18 );uart_out ( 8'h33 );uart_out ( 8'hCC );end//任务函数task uart_out ;input [8:0] DATA ;beginrx_data = 1 ; ///空闲位初始#20rx_data = 0 ;#(COUNT*2) rx_data = DATA[0] ;#(COUNT*2) rx_data = DATA[1] ;#(COUNT*2) rx_data = DATA[2] ;#(COUNT*2) rx_data = DATA[3] ;#(COUNT*2) rx_data = DATA[4] ;#(COUNT*2) rx_data = DATA[5] ;#(COUNT*2) rx_data = DATA[6] ;#(COUNT*2) rx_data = DATA[7] ;#(COUNT*2) rx_data = 0 ;#(COUNT*2) rx_data = 1 ;#(COUNT*2) ;endendtaskuart_rx uart_rx_u1(. sys_clk (sys_clk ) ,. rst_n (rst_n ) ,. rx_data (rx_data ) ,. uart_data (uart_data) ,. rx_done (rx_done ));
endmodule
仿真TOP模块:
`timescale 1ns / 1ps
module test_TOP( );reg sys_clk ;reg rst_n ;reg key ;reg rx_data ;wire tx_data ;parameter SYSCLK = 50_000_000 ;parameter Baud = 115200 ;parameter COUNT = SYSCLK/Baud;parameter MID = COUNT/2 ;initialbeginsys_clk = 0 ;rst_n = 0 ;key = 1 ;#10rst_n = 1 ;#200000//ns 200uskey = 0 ;
// #200000
// key = 1 ;
// #200000
// key = 0 ;
// #200000
// key = 1 ;endalways #1 sys_clk = ~sys_clk ;initialbegin
// uart_out ( 8'hf );//0f 0000_1111
// uart_out ( 8'h0f );
// uart_out ( 8'hff );uart_out ( 8'h0f );uart_out ( 8'h33 );
// uart_out ( 8'hff );//1111_1111uart_out ( 8'h18 );//0001_1000uart_out ( 8'h78 );uart_out ( 8'h66 );uart_out ( 8'h1E );uart_out ( 8'hCC );uart_out ( 8'h9F );uart_out ( 8'h66 );uart_out ( 8'h9F );uart_out ( 8'h33 );uart_out ( 8'h1E );uart_out ( 8'hCC );uart_out ( 8'h9F );uart_out ( 8'h18 );uart_out ( 8'h33 );end//任务函数task uart_out ;input [8:0] DATA ;beginrx_data = 1 ; ///空闲位初始#20rx_data = 0 ;#(COUNT*2) rx_data = DATA[0] ;#(COUNT*2) rx_data = DATA[1] ;#(COUNT*2) rx_data = DATA[2] ;#(COUNT*2) rx_data = DATA[3] ;#(COUNT*2) rx_data = DATA[4] ;#(COUNT*2) rx_data = DATA[5] ;#(COUNT*2) rx_data = DATA[6] ;#(COUNT*2) rx_data = DATA[7] ;#(COUNT*2) rx_data = 0 ;#(COUNT*2) rx_data = 1 ;#(COUNT*2) ;endendtaskTOP TOP_u1(. sys_clk (sys_clk) ,. rst_n (rst_n ) ,. key (key ) ,. rx_data (rx_data) ,. tx_data (tx_data) );endmodule

这里记录一些小小的问题:
(1)
仿真的复位信号一定不要和数据的关键信号(使能/开始)重复。
这个是正常没重复的:

这个是由于复位拉高的时间过长造成重复了的:

(2)



因此我们可以做出如下的修改:



现在就正常了
相关文章:
Xilinx FPGA:vivado利用单端RAM/串口传输数据实现自定义私有协议
一、项目要求 实现自定义私有协议,如:pc端产生数据:02 56 38 ,“02”代表要发送数据的个数,“56”“38”需要写进RAM中。当按键信号到来时,将“56”“38”读出返回给PC端。 二、信号流向图 三、状态…...
Spark on k8s 源码解析执行流程
Spark on k8s 源码解析执行流程 1.通过spark-submit脚本提交spark程序 在spark-submit脚本里面执行了SparkSubmit类的main方法 2.运行SparkSubmit类的main方法,解析spark参数,调用submit方法 3.在submit方法里调用doRunMain方法,最终调用r…...
粤港联动,北斗高质量国际化发展的重要机遇
今年是香港回归27周年,也是《粤港澳大湾区发展规划纲要》公布5周年,5年来各项政策、平台不断为粤港联动增添新动能。“十四五”时期的粤港澳大湾区,被国家赋予了更重大的使命,国家“十四五”《规划纲要》提出,以京津冀…...
Chrome导出cookie的实战教程
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...
视频文字转语音经验笔记
自媒体视频制作的一些小经验,分享给大家。 一、音频部分: 1、文字转语音阐述: 微软语音识别 云希-青年男, 0.5-0.8变速 。注:云泽-中年男(不支持长音频录制), 适合郑重场合&#…...
视频融合共享平台LntonCVS统一视频接入平台智慧安防应用方案
安防视频监控平台LntonCVS是一款拥有强大拓展性和灵活部署能力的综合管理平台。它支持多种主流标准协议,包括国标GB28181、RTSP/Onvif、RTMP等,同时兼容各厂家的私有协议和SDK,如海康Ehome、海大宇等。LntonCVS不仅具备传统安防视频监控功能&…...
使用Python绘制动态螺旋线:旋转动画效果
文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame绘制螺旋线函数主循环 完整代码 引言 螺旋线是一个具有美学和数学魅力的图形。通过编程,我们可以轻松创建动态旋转的螺旋线动画。在这篇博客中,我们将使用Python和Pygame库来实现…...
Symfony实战手册:PHP框架的高级应用技巧
引言 Symfony是一个功能强大且广泛应用于PHP应用程序开发的框架,它提供了许多高级特性和工具,可以帮助开发人员更高效地构建和管理复杂的Web应用程序。以下是Symfony框架的几个关键方面及其高级应用技巧: 1. 路由和控制器 Symfony的路由组…...
TOGAF培训什么内容?参加TOGAF培训有什么好处?考试通过率多少?
TOGAF培训什么内容?参加TOGAF培训有什么好处?考试通过率多少? TOGAF培训哪些内容? 通过本课程,你将掌握TOGAF的理论和实践,理解企业架构的影响,能够评估、启动、设 计、执行新一轮企业和IT架构…...
keepalived HA nginx方案
安装 centos: yum -y install epel-release yum -y install nginx keepalivedkeepalived配置解析 /etc/keepalived/keepalived.conf ! Configuration File for keepalived # 全局变量 global_defs {router_id nginx_ha # 主从保持一致script_user root # 执行健康检查的…...
报错:pathspec ‘xxx‘ did not match any file(s) known to git
在 escode 中进行分支切换时报如下错误 PS > git checkout xxx error: pathspec xxx did not match any file(s) known to git远程分支已经在 gitlab 客户端手动创建,在 escode 中也使用了拉取之类的操作,但是切换分支时依然报错。 解决方案 查看分…...
sed 保持空间命令之 x 的执行逻辑
目录 1. 将模式空间和保持空间的内容互换并打印 2. 将保持空间的内容交换回模式空间 3. 使用保持空间保存状态信息 4. 交换模式空间与保持空间隔行匹配 sed 有两个内置的缓存空间: 模式空间:该空间是 sed 内置的一个缓冲区,是 sed 执行的…...
按位异或^
在 Python 中,a ^ b 表示按位异或运算符。按位异或运算符对整数的每一位进行运算,如果对应位上的两个二进制数字不同,则结果为 1,否则为 0。 示例 a 5 # 二进制: 0101 b 3 # 二进制: 0011result a ^ b print(result) # 输…...
《企业实战分享 · 常用运维中间件》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,如需交流ÿ…...
PyCharm 2024.1简介
PyCharm 2024.1 是JetBrains公司发布的Python集成开发环境(IDE)的最新版本。作为一个深受开发者欢迎的工具,PyCharm以其强大的功能和高效的开发体验著称。以下是PyCharm 2024.1的主要特性和改进: 1. **性能提升**: …...
终身免费的Navicat数据库,不需要破解,官方支持
终身免费的Navicat数据库,不需要破解,官方支持 卸载了Navicat,很不爽上干货,Navicat免费版下载地址 卸载了Navicat,很不爽 公司不让用那些破解的数据库软件,之前一直使用Navicat。换了几款其他的数据库试了…...
Spring Boot中的模板引擎选择与配置
Spring Boot中的模板引擎选择与配置 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来聊聊Spring Boot中的模板引擎选择与配置。模板引擎是生成动态网页…...
4、音视频封装格式---FLV
FLV FLV是一种容器封装格式,是由Adobe公司发布和维护的,用于将视频编码流与音频编码流进行封装。对于任意一种封装格式,都有其头部区域与数据区域,在FLV中,称之为FLV Header与Body。 对于FLV Header,一个FL…...
vscode 前行复制到下一行
目录 Ctrl d 会把当前行复制到下一行 步骤1:打开键绑定设置 目录 Ctrl d 会把当前行复制到下一行 步骤1:打开键绑定设置 使用VS Code设置换行 Ctrl d 会把当前行复制到下一行 步骤1:打开键绑定设置 打开 VS Code。按 CtrlShiftP 打开命…...
什么是文档透明加密|好用的文档透明加密软件有哪些?
在当今日益数字化和信息化的时代,数据安全问题愈发受到企业和个人的关注。文档作为信息的重要载体,其安全性不言而喻。为了保障文档的机密性和完整性,文档透明加密技术应运而生。本文将对文档透明加密进行详细介绍,并探讨一些好用…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
