FPGA project :HDMI

实验目标:驱动HdMI显示十色等宽彩条。

本实验的重点是:

1掌握TMDS通信协议。

2rgb565转rgb888。

3编写HDMI驱动程序。

4学会看流程图编写代码。

值得注意的事情

1注意数据与解析数据的信号(比如传入的数据中0或者1的个数),要在时序上与数据进行对齐。

如果解析数据的信号是时序信号,那么它将会滞后数据一个clk。如果后面要用到,数据与对应的解析数据的信号同时做条件,那么需要对数据进行打一拍处理。用打拍过后的数据与解析数据的信号作为条件去做判断。

2如果一个数据是有符号位的,那么判断它的正负,就不能用简单的 > 0 来判断。

比如本实验中cnt就是5位宽的有符号数,判断其正负(cnt[4] == 1) 为负数;(cnt[4] == 0) 为正数。如果是cnt < 0 表述负数的话,那么cnt永远不会被判定为负数。

看仿真波形的经验之谈:

1在本实验与官方的编码模块代码,那么在通过功能方正,验证自己编写的编码模块代码是否正确时,可以把官方的模块例化进工程,然后仿真对比波形是否一致,即可判断自己编写的代码是否正确。

2在遇到不一致的时候,比如输入信号都一致,某个输出信号不一致。

先不要着急看去检查哪些信号会直接影响这个输出信号赋值,因为前面的一些信号,会间接影响输出信号赋值。比如影响直接影响输出信号赋值的信号。

那么此时应该先检查一些直接受输入信号影响的信号,是否正确,是否和官方给的代码波形一致;

然后再看一些”条件“波形是否正确;

也就是说由输入信号逐渐到输出信号这个过程中一次产生(你编写代码的顺序)去检查这些信号是否正确。(自顶向下)。慢慢检查。

3实在检查不出来,看看自己的代码和官方的代码编写的差在哪里。

TMDS通信协议:

一种传输视频/音频/辅助数据的传输技术:最小化传输差分信号。

采用DIV编码。附上几张图:

8bit像素信息到最小化传输直流均衡10bit数据,编码流程:

信源端与接收端的数据传输框图:由图可知,3路差分信号传输,由rgb888转10bit的数据。一路差分信号传输clock。

下面两路ddc信号是从接收端读取硬件工作模式相关信息的,本实验没有用到。(IIC通信协议。)

 模块框图:

时序图:

代码:

/*********************功能: 将8位rgb信号,转换成10位信号。编码cnt 当前时钟的值cnt(t - 1) 相对于当前时钟,上一个时钟周期的值
*/module encode(input       wire            clk_25  ,input       wire            rst_n   ,input       wire    [7:0]   data_in ,input       wire            hsync   , input       wire            vsync   ,input       wire            DE      ,output      wire    [9:0]   data_out 
);reg     [7:0]   data_in_reg1 ;reg     [3:0]   data_in_n1  ; // 保存传入数据1的个数.wire            crtl_1      ; // 一个判断条件,data_in中1的个数大于4 or 个数等于4且data_in[0] == 0wire    [8:0]   q_m         ;reg     [8:0]   q_m_reg1    ;reg             DE_reg1     ;reg             DE_reg2     ;reg             C0_reg1     ; // 行同步信号,打拍,为了和数据对齐。reg             C1_reg1     ; // 场同步信号,打拍,为了和数据对齐。reg             C0_reg2     ; reg             C1_reg2     ; reg     [9:0]   q_out       ; // 最终要输出的10为数据,经过一系列编码。wire            ctrl_2      ;wire            ctrl_3      ;reg     [4:0]   cnt         ; // 这是一个用于跟踪数据流差异的寄存器。正值表示已传输的“1”的超额数量。负值表示已传输的“0”的超额数量。reg     [3:0]   q_m_n1      ; // q_m中1的个数。cnt的最高位是符号位。有符号位的数据不能简单通过是否大于小于0来判断正负,应该判断最高位符号位的0/1(1负数,0正数)reg     [3:0]   q_m_n0      ; // q_m中0的个数。/**********************************************************************************/// 产生第一个条件:计算输入数据中1的个数。always @(posedge clk_25 or negedge rst_n) begin  // 计算传入数据1的个数.if(~rst_n) begindata_in_n1 <= 4'd0 ;end else begindata_in_n1 <= data_in[0] + data_in[1]+ data_in[2] + data_in[3] + data_in[4] + data_in[5] + data_in[6]+ data_in[7] ;endend// 对输入数据打一拍,以对齐数据data_in_n1。always @(posedge clk_25 or negedge rst_n) beginif(~rst_n) begindata_in_reg1 <= 8'd0 ;end else begindata_in_reg1 <= data_in ;endend// 根据data_in_n1与输入数据的打拍信号,描述出crtl_1判断条件。assign crtl_1 = ( data_in_n1 > 4 || (data_in_n1 == 4 && data_in_reg1[0] == 1'b0) ) ? 1'b1 : 1'b0 ;// 8bit 到 9bit 编码逻辑。assign q_m[0] = data_in_reg1[0] ;assign q_m[1] = (crtl_1) ? q_m[0]~^data_in_reg1[1] : q_m[0]^data_in_reg1[1] ;assign q_m[2] = (crtl_1) ? q_m[1]~^data_in_reg1[2] : q_m[1]^data_in_reg1[2] ;assign q_m[3] = (crtl_1) ? q_m[2]~^data_in_reg1[3] : q_m[2]^data_in_reg1[3] ;assign q_m[4] = (crtl_1) ? q_m[3]~^data_in_reg1[4] : q_m[3]^data_in_reg1[4] ;assign q_m[5] = (crtl_1) ? q_m[4]~^data_in_reg1[5] : q_m[4]^data_in_reg1[5] ;assign q_m[6] = (crtl_1) ? q_m[5]~^data_in_reg1[6] : q_m[5]^data_in_reg1[6] ;assign q_m[7] = (crtl_1) ? q_m[6]~^data_in_reg1[7] : q_m[6]^data_in_reg1[7] ;assign q_m[8] = (crtl_1) ? 1'b0 : 1'b1 ;/********************* 对q_out和cnt赋值,用到的条件 ***************************/// 数据q_m中1的个数和0的个数。always @(posedge clk_25 or negedge rst_n) begin  if(~rst_n) beginq_m_n1 <= 4'd0 ;q_m_n0 <= 4'd0 ;end else beginq_m_n1 <=  q_m[0] +  q_m[1] +  q_m[2] +  q_m[3] +  q_m[4] +  q_m[5] +  q_m[6] +  q_m[7] ;// q_m_n0 <= ~q_m[0] + ~q_m[1] + ~q_m[2] + ~q_m[3] //             + ~q_m[4] + ~q_m[5] + ~q_m[6] + ~q_m[7] ;q_m_n0 <= 4'd8 - (q_m[0] +  q_m[1] +  q_m[2] +  q_m[3] +  q_m[4] +  q_m[5] +  q_m[6] +  q_m[7]) ;endend// 根据cnt和q_m_n1 q_m_n2 产生判断条件ctrl_2,ctrl_3。assign ctrl_2 = ((cnt == 5'd0) || (q_m_n1 == q_m_n0)) ? 1'b1 : 1'b0 ; // 其实可以直接写逻辑运算关系式。assign ctrl_3 = (((~cnt[4]) && (q_m_n1 > q_m_n0)) || ((cnt[4]) && (q_m_n1 < q_m_n0))) ? 1'b1 : 1'b0 ;// reg     [8:0]   q_m_reg1    ;// 由于q_m_n1 q_m_n0 是时序逻辑,相对于q_m就延后了一个时钟周期,为了保证qm数据与q_m_n1 q_m_n0 对齐,所以要对qm打一拍。always @(posedge clk_25 or negedge rst_n) beginif(~rst_n) beginq_m_reg1 <= 8'd0 ;end else beginq_m_reg1 <= q_m ;endend// reg             DE_reg1     ;// reg             DE_reg2     ;// DE 逐渐的要与q_m_reg1对齐always @(posedge clk_25 or negedge rst_n) beginif(~rst_n) beginDE_reg1 <= 1'b0 ;DE_reg2 <= 1'b0 ; end else beginDE_reg1 <= DE      ;DE_reg2 <= DE_reg1 ; endend// reg             C0_reg1     ; // 行同步信号,打拍,为了和数据对齐。// reg             C0_reg2     ; // 行场同步信号,也是要与q_m_reg1对齐。always @(posedge clk_25 or negedge rst_n) beginif(~rst_n) beginC0_reg1 <= 1'b0 ;C0_reg2 <= 1'b0 ; end else beginC0_reg1 <= hsync   ;C0_reg2 <= C0_reg1 ; endend// reg             C1_reg1     ; // 场同步信号,打拍,为了和数据对齐。// reg             C1_reg2     ;always @(posedge clk_25 or negedge rst_n) beginif(~rst_n) beginC1_reg1 <= 1'b0 ;C1_reg2 <= 1'b0 ; end else beginC1_reg1 <= vsync   ;C1_reg2 <= C1_reg1 ; endend// 对q_out 与 cnt 赋值// q_outalways @(posedge clk_25 or negedge rst_n) beginif(~rst_n) beginq_out <= 10'd0 ;cnt   <=  5'd0 ;end else beginif(DE_reg2 == 1'b0) begincase ({C1_reg2 ,C0_reg2})2'b00: q_out[9:0] <= 10'b11010_10100 ;2'b01: q_out[9:0] <= 10'b00101_01011 ;2'b10: q_out[9:0] <= 10'b01010_10100 ;2'b11: q_out[9:0] <= 10'b10101_01011 ;default: q_out[9:0] <= 10'b11010_10100 ; // 随便挑一个。endcasecnt   <=  5'd0 ;end else beginif(ctrl_2 == 1'b1) beginq_out[9] <= ~q_m_reg1[8] ; // q_out[9] <= ~q_m_reg1[8] ;q_out[8] <=  q_m_reg1[8] ; // q_out[8] <=  q_m_reg1[8] ;q_out[7:0] <= (q_m_reg1[8] == 1'b1) ? q_m_reg1[7:0] : ~q_m_reg1[7:0] ; // q_out[7:0] = (q_m_reg1[8] == 1'b1) ? q_m_reg1[7:0] : ~q_m_reg1[7:0] ;if(q_m_reg1[8] == 1'b0) begincnt <= cnt + q_m_n0 - q_m_n1 ;end else begincnt <= cnt - q_m_n0 + q_m_n1 ;endend else beginif(ctrl_3 == 1'b1) beginq_out[9] <= 1'b1 ;q_out[8] <= q_m_reg1[8] ;q_out[7:0] <= ~q_m_reg1[7:0] ;cnt <= cnt + {q_m_reg1[8], 1'b0} + q_m_n0 - q_m_n1 ; // 2 乘以 1位宽的数据,相当于把该数据左移一位。 + {q_m_reg1[8],0} + end else beginq_out[9] <= 1'b0 ;q_out[8] <= q_m_reg1[8] ;q_out[7:0] <= q_m_reg1[7:0] ;cnt <= cnt - {~q_m_reg1[8], 1'b0} - q_m_n0 + q_m_n1 ;endendendendend/************output signal descrable **************/assign data_out = q_out ;
endmodule
// 10位并行数据信号转换为,串行差分信号。
module par_to_ser(input       wire            clk_125 ,input       wire            rst_n   ,input       wire    [9:0]   data_out, // 应该在一个周期内把并行转串行?应该用到流水线技术?output      wire            ser_p   ,output      wire            ser_n   
);/**********************************************************************************//     // wire signal define
//     wire            dataout_flag ;
//     wire    [3:0]   datain_h_num ;
//     wire    [3:0]   datain_l_num ;
//     // reg signal define
//     reg             datain_h ;
//     reg             datain_l ;
//     reg     [3:0]   cnt_bit ;
//     reg     [9:0]   data_out_reg1 ;// 
//     // wire            dataout_flag ;
//     assign dataout_flag = (data_out != data_out_reg1) ? 1'b1 : 1'b0 ;
//     assign datain_h_num = 2'd2*cnt_bit ;
//     assign datain_l_num = 2'd2*cnt_bit + 1'b1 ;
//     // reg             datain_h ;
//     always @(posedge clk_125 or negedge rst_n) begin
//         if(~rst_n) begin
//             datain_h <= 1'b0 ;
//         end else begin
//             datain_h <= data_out_reg1[datain_h_num] ; // 其实这里可能有一个问题,datain_h_num如果计算慢了,那么datain_h将会滞后一个clk_125.
//         end
//     end
//     // reg             datain_l ;
//     always @(posedge clk_125 or negedge rst_n) begin
//         if(~rst_n) begin
//             datain_l <= 1'b0 ;
//         end else begin
//             datain_l <= data_out_reg1[datain_l_num] ;
//         end
//     end
//     // reg     [3:0]   cnt_bit ;
//     always @(posedge clk_125 or negedge rst_n) begin
//         if(~rst_n) begin
//             cnt_bit <= 4'd0 ;
//         end else begin
//             if(dataout_flag == 1'b1 || cnt_bit == 4'd4) begin
//                 cnt_bit <= 4'd0 ;
//             end else begin
//                 cnt_bit <= cnt_bit + 1'b1 ; 
//             end
//         end
//     end
//     // reg     [9:0]   data_out_reg1 ;
//     always @(posedge clk_125 or negedge rst_n) begin
//         if(~rst_n) begin
//             data_out_reg1 <= 10'd0 ;
//         end else begin
//             data_out_reg1 <= data_out ;
//         end
//     end
************************************************************************************//***********************************************************************************/
// 野火教程里的方法,10bit并行数据转串行数据。// wire signal deginewire            dataout_flag ;wire    [4:0]   data_rise    ;wire    [4:0]   data_fall    ;// reg signal definereg     [3:0]   cnt_shift     ;reg     [9:0]   data_out_reg1 ;reg     [4:0]   data_rise_s   ;reg     [4:0]   data_fall_s   ;// [4:0]   data_rise  ;assign data_rise = {data_out[8],data_out[6],data_out[4],data_out[2],data_out[0]} ;// [4:0]   data_fall  ;assign data_fall = {data_out[9],data_out[7],data_out[5],data_out[3],data_out[1]} ;// wire dataout_flag;assign dataout_flag = (data_out != data_out_reg1) ? 1'b1 : 1'b0 ;// reg     [9:0]   data_out_reg1 ;always @(posedge clk_125 or negedge rst_n) beginif(~rst_n) begindata_out_reg1 <= 10'd0 ;end else begindata_out_reg1 <= data_out ;endend// reg     [3:0]   cnt_shift        ;always @(posedge clk_125 or negedge rst_n) beginif(~rst_n) begincnt_shift <= 4'd0 ;end else beginif(dataout_flag == 1'b1 || cnt_shift == 4'd4) begincnt_shift <= 4'd0 ;end else begincnt_shift <= cnt_shift + 1'b1 ; endendend// reg     [4:0]   data_rise_s   ;// reg     [4:0]   data_fall_s   ;always @(posedge clk_125 or negedge rst_n) beginif(~rst_n) begindata_rise_s <= 5'd0 ;data_fall_s <= 5'd0 ;end else beginif(cnt_shift == 4'd4) begindata_rise_s <= data_rise ;data_fall_s <= data_fall ;end else begindata_rise_s <= data_rise_s[4:1] ; // 相当于右移1位。data_fall_s <= data_fall_s[4:1] ;endendend// 单沿到双沿采样,通过调用ddio_out实现。相当于把采样时钟翻倍。
ddio_out	ddio_out_inst0 (.datain_h ( data_rise_s[0] ), // 在outclk上升沿对datain_h采样传给data_out。1bit的串行数据。.datain_l ( data_fall_s[0] ), // 在outclk下降沿对datain_l采样传给data_out。1bit的串行数据。.outclock ( ~clk_125       ), // 采样时钟。.dataout  ( ser_p          )  
);ddio_out	ddio_out_inst1 (.datain_h ( ~data_rise_s[0] ), // 单端到差分之间的转换。.datain_l ( ~data_fall_s[0] ), .outclock ( ~clk_125        ), .dataout  ( ser_n           ) 
);endmodule

只放了两个新模块的代码。

`timescale 1ns/1ns
module test();reg             sys_clk     ;reg             sys_rst_n   ;wire            clk_p       ;wire            clk_n       ;wire            r_p         ;wire            r_n         ;wire            g_p         ;wire            g_n         ;wire            b_p         ;wire            b_n         ;wire            DDC_SCL     ;wire            DDC_SDA     ;top top_insert(.sys_clk                ( sys_clk   ) ,.sys_rst_n              ( sys_rst_n ) ,.clk_p                  ( clk_p     ) ,.clk_n                  ( clk_n     ) ,.r_p                    ( r_p       ) ,.r_n                    ( r_n       ) ,.g_p                    ( g_p       ) ,.g_n                    ( g_n       ) ,.b_p                    ( b_p       ) ,.b_n                    ( b_n       ) ,.DDC_SCL                ( DDC_SCL   ) ,.DDC_SDA                ( DDC_SDA   )      
);parameter CYCLE = 20 ;initial beginsys_clk  = 1'b1 ;sys_rst_n = 1'b0 ;#( CYCLE ) ;sys_rst_n = 1'b1 ;endalways #( CYCLE / 2 ) sys_clk = ~sys_clk ;
endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/150915.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV实现人脸检测(Haar特征)

学习目标 原理 实现 import cv2 as cv print(cv.__file__) 路径&#xff1a;E:\Anaconda3\envs\test_py3.6\Lib\site-packages\cv2\data 代码实现 import cv2 as cv import matplotlib.pyplot as plt from pylab import mplmpl.rcParams[font.sans-serif] [SimHei] #1&#x…

语义分割,实例分割,全景分割梳理

语义分割&#xff08;semantic segmentation&#xff09; 实例分割&#xff08;instance segmentation&#xff09; 全景分割&#xff08;Panoptic Segmentation&#xff09; 下面基于《Panoptic Segmentation 》这篇论文进行这几个概念的梳理 论文链接&#xff1a;https:/…

【算法刷题】【反转链表】给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

题目 解决&#xff1a; import java.util.*;/** public class ListNode {* int val;* ListNode next null;* public ListNode(int val) {* this.val val;* }* }*/public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#x…

gin路由相关方法

c.Request.URL.Path 拿到请求的路径 package mainimport ( "fmt" "github.com/gin-gonic/gin" "net/http")//路由重定向&#xff0c;请求转发&#xff0c;ANY &#xff0c;NoRoute&#xff0c;路由组func main() { r : gin.Default() // -------…

DVWA-内容安全策略绕过

内容安全策略绕过 ​ 内容安全策略&#xff08;Content Security Policy&#xff0c;简称CSP&#xff09;是一种以可信白名单作机制&#xff0c;来限制网站是否可以包含某些来源内容&#xff0c;缓解广泛的内容注入漏洞&#xff0c;是一种用于增强网页的安全性的安全策略机制。…

React18学习

17、React_JSX的注意事项 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>JSX的注意</title><script src"./script/react.development.js"></script><script src"…

数据结构-优先级队列(堆)

文章目录 目录 文章目录 前言 一 . 堆 二 . 堆的创建(以大根堆为例) 堆的向下调整(重难点) 堆的创建 堆的删除 向上调整 堆的插入 三 . 优先级队列 总结 前言 大家好,今天给大家讲解一下堆这个数据结构和它的实现 - 优先级队列 一 . 堆 堆&#xff08;Heap&#xff0…

林沛满-Wireshark的提示

本文整理自&#xff1a;《Wireshark网络分析的艺术 第1版》 作者&#xff1a;林沛满 著 出版时间&#xff1a;2016-02 最近有不少同事开始学习 Wireshark&#xff0c;他们遇到的第一个困难就是理解不了主界面上的提示信息&#xff0c;于是跑来问我。问的人多了&#xff0c;我也…

VMProtect使用教程(VC++MFC中使用)

VMProtect使用教程(VCMFC中使用) VMProtect是一种商业级别的代码保护工具&#xff0c;可以用于保护VC MFC程序。以下是使用VMProtect保护VC MFC程序的步骤&#xff1a; 1. 下载并安装VMProtect,C包含库及目录。 2. 在VC MFC项目中添加VMProtectSDK.h头文件&#xff0c;并在需…

小谈设计模式(18)—适配器模式

小谈设计模式&#xff08;18&#xff09;—适配器模式 专栏介绍专栏地址专栏介绍 适配器模式角色分析目标接口&#xff08;Target&#xff09;源接口&#xff08;Adaptee&#xff09;适配器&#xff08;Adapter&#xff09; 核心思想应用场景Java程序实现输出结果程序分析123 优…

R语言通过接口获取网上数据平台的免费数据

大家好&#xff0c;我是带我去滑雪&#xff01; 作为一名统计学专业的学生&#xff0c;时常和数据打交道&#xff0c;我深知数据的重要性。数据是实证研究的重要基础&#xff0c;每当在完成一篇科研论文中的实证研究部分时&#xff0c;我都能深刻体会实证研究最复杂、最耗时的工…

零基础,想做一名网络安全工程师,我可以去哪里学,或者有什么建议?

这应该是全网最全的网络安全扫盲帖了&#xff01;发CSDN也有一段时间了&#xff0c;经常会有朋友在后台问我各种问题&#xff0c;比如“应该如何选方向”、“网络安全前景如何”、“怎么选适合的安全岗位”等等。于是今天借这个问题来给大家好好说说&#xff0c;如果你是零基础…

软件定制开发的细节|网站搭建|APP小程序定制

软件定制开发的细节|网站搭建|APP小程序定制 在定制开发的过程中&#xff0c;一些小的细节往往能够影响到最终的产品质量和用户体验。下面我将为大家介绍一些软件定制开发的细节。 第一&#xff0c;明确需求。在定制开发之前&#xff0c;我们需要明确客户的需求和目标。只有明确…

微信、支付宝、百度、抖音开放平台第三方代小程序开发总结

大家好&#xff0c;我是小悟 小伙伴们都开启小长假了吧&#xff0c;值此中秋国庆双节之际&#xff0c;小悟祝所有的小伙伴们节日快乐。 支付宝社区很用心&#xff0c;还特意给寄了袋月饼&#xff0c;愿中秋节的圆月带给你身体健康&#xff0c;幸福团圆&#xff0c;国庆节的旗帜…

【生成模型】解决生成模型面对长尾类型物体时的问题 RE-IMAGEN: RETRIEVAL-AUGMENTED TEXT-TO-IMAGE GENERATOR

介绍 尽管最先进的模型可以生成常见实体的高质量图像&#xff0c;但它们通常难以生成不常见实体的图像&#xff0c;例如“Chortai&#xff08;狗&#xff09;”或“Picarones&#xff08;食物&#xff09;”。为了解决这个问题&#xff0c;我们提出了检索增强文本到图像生成器…

漏刻有时数据可视化大屏引导页设计2(偏移卡片、动态数字翻牌、countUp.min.js)

引入外部文件 <title>漏刻有时引导页</title><script src="js/jquery-3.3.1.min.js"></script><script src="js/countUp.min.js"></script><link rel="stylesheet" href="css/common.css">…

乌班图20.04简易部署k8s+kuboard第三方面板

1. 问题&#xff1a; 使用官方只能说步骤挺全。 &#x1f604;出错&#xff1f;出错不管&#xff0c;无论是系统问题&#xff0c;版本兼容问题&#xff0c;网络插件问题&#xff0c;还是防火墙问题&#xff0c;我只能说特异性问题分析检索起来很难很难。 新人很难搞懂&#x…

玩转ChatGPT:DALL·E 3生成图像

一、写在前面 好久不更新咯&#xff0c;因为没有什么有意思的东西分享的。 今天更新&#xff0c;是因为GPT整合了自家的图像生成工具&#xff0c;名字叫作DALLE 3。 DALLE 3是OpenAI推出的一种生成图像的模型&#xff0c;它基于GPT-3架构进行训练&#xff0c;但是它的主要目…

ubuntu系统开机黑屏(只显示logo、左上角光标闪烁)问题

问题背景 在使用pycharm的时候&#xff0c;我使用了pycharm的快捷键ctrlaltF7&#xff0c;结果进入了ubuntu的ttf界面&#xff0c;由于之前不知道这个东西&#xff0c;百度一顿乱搜&#xff0c;以为显卡驱动出问题了&#xff0c;就把驱动删了&#xff0c;其实我完全可以ctrlal…

黑马JVM总结(二十七)

&#xff08;1&#xff09;synchronized代码块 synchronized代码块的底层原理&#xff0c;它是给一个对象进行一个加锁操作&#xff0c;它是如何保证如果你出现了synchronized代码块中出现了问题&#xff0c;它需要给这个对象有一个正确的解锁操作呢&#xff0c;加锁解锁是成对…