完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
VERILOG
1 verilog的历史1.1 传统的数字系统设计方式—原理图设计 在传统的设计方法中,当设计工程师设计一个新的硬件、一个新的数字电路或一个数字逻辑系统时,他或许在CAE 工作站上做设计,为了能在CAE工作站做设计,设计者必须为设计画一张线路图,通常地,线路图是由表示信号的线和表示基本设计单元的符号连在一起组成线路图,符号取自设计者用于构造线路图的零件库。若设计者是用标准逻辑器件(如 74系列等)做板极设计线路图,那么在线路图中,符号取自标准逻辑零件符号库;若设计是进行ASIC设计,则这些符号取自ASIC库的可用的专用宏单元。这就是传统的原理图设计方法。对线路图的逻辑优化,设计者或许利用一些EDA工具或者人工地进行逻辑的布尔函数逻辑优化。为了能够对设计进行验证,设计者必须通过搭个硬件平台(如电路板),对设计进行验证。 1.2 硬件语言描述方式—verilog 随着电子设计技术的飞速发展,设计的集成度、复杂度越来越高,传统的设计方法已满足不了设计的要求,因此要求能够借助当今先进的EDA工具,使用一种描述语言,对数字电路和数字逻辑系统能够进行形式化的描述,这就是硬件描述语言。硬件描述语言HDL(Hardware Description Language)是一种用形式化方法来描述数字电路和数字逻辑系统的语言。数字逻辑电路设计者可利用这种语言来描述自己的设计思想,然后利用EDA工具进行仿真,再自动综合到门级电路,最后用ASIC或FPGA实现其功能。举个例子,在传统的设计方法中,对2输入的与门,我们可能需到标准器件库中调个74系列的器件出来,但在硬件描述语言中,“&”就是一个与门的形式描述,“C = A & B”就是一个2输入与门的描述。而“and ”就是一个与门器件。硬件描述语言发展至今已有二十多年历史,当今业界的标准中(IEEE标准)主要有VHDL和Verilog HDL这两种硬件描述语言。 Verilog HDL语言最初是于1983年由Gateway Design Automation公司为其模拟器产品开发的硬件建模语言。那时它只是一种专用语言。由于他们的模拟、仿真器产品的广泛使用,Verilog HDL作为一种便于使用且实用的语言逐渐为众多设计者所接受 。在一次努力增加语言普及性的活动中,Verilog HDL语言于1990年被推向公众领域。Open Verilog International(OVI)是促进Verilog发展的国际性组织。1992年,OVI决定致力于推广Verilog OVI标准成为IEEE标准。这一努力最后获得成功,Verilog语言于1995年成为IEEE标准,称为IEEE Std1364-1995 。完整的标准在Verilog硬件描述语言参考手册中有详细描述。 Verilog HDL即verilog硬件硬件描述语言,它主要应用于数字电路和系统设计、数字电路和系统仿真等,即利用计算机和相关软件对 VERILOG HDL等硬件语言建模的复杂数字电路设计进行仿真验证,再利用综合软件将设计的数字电路自动综合,以得到符合功能需求并且在相应的硬件结构止可以映射实现的数字逻辑网表,然后布局布线,根据网表和选定的实现器件工艺特性自动生成具体电路,同时软件生成选定器件的延时模型,经过仿真验证确定无误后,用来制造ASIC芯片或者写入FPGA和CPLD器件中,最终实现电路设计。 Verilog HDL语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构组成以及包含响应监控和设计验证方面的时延和波形产生机制。所有这些都使用同一种建模语言。此外,Verilog HDL语言提供了编程语言接 口,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义 。因此,用这种语言编写的模型能够使用Verilog仿真器进行验证。语言从C编程语言中继承了多种操作符和结构。Verilog HDL提供了扩展的建模能力,其中许多扩展最初很难理解。但是,Verilog HDL语言的核心子集非常易于学习和使用,这对大多数建模应用来说已经足够。当然,完整的硬件描述语言足以对从最复杂的芯片到完整的电子系统进行描述。 2 综合器和仿真器 图 5 Verilg是硬件描述语言,顾名思义,就是用代码的形式描述硬件的功能。而我们最终是要在电路上实现该功能的 。当Verilog描述出硬件功能后,我们需要综合器对Verilog代码进行解释,将代码转化成实际的电路来表示,最终实际的电路,我们称之为网表。这种将Verilog代码转成网表的工具,就是综合器。上图左上角是一份verilog代码,该代码描述了一个加法器功能。该代码经过综合器解释后,转化成一个加法器电路。QUARTUS、ISE和VIVADO都是综合器,集成电路常用的综合器是DC。 我们在FPGA设计的过程中,不可避免会出现各种BUG。如果我们编写好代码,综合成电路,烧写到FPGA后,才看到问题,此时去定位问题就会非常地困难了。在综合前,我们可以在电脑里对代码进行仿真测试一下,把BUG找出来解决,最后才烧写进FPGA。我们可以认为,没有经过仿真验证的代码,一定是存在BUG的。 为了模拟真实的情况,我们需要编写测试文件。该文件也是用verilog编写的,描述了仿真对象的输入激励情况。该激励力求模仿最真实的情况,产生最将近的激励信号,将该信号的波形输入给仿真对象,查看仿真对象的输出是否 与预期一致。 为了做仿真验证,我们编写了测试文件。将测试文件和被测试对象加入到仿真器中。仿真器对测试文件和被测试对象的代码进行解释。根据测试文件,产生测试激励,输入给被测试对象;根据补测试对象的代码,产生被测试对象的输出。需要注意的是,在仿真过程中,没有将代码转成电路,仿真器只是对代码进行仿真验证。至于该电路是否可转成 电路,仿真器是不关心的。 常用的仿真器是MODELSIM和VCS等。 由此可见,verilog的代码不仅可以描述电路,还可以用于测试。事实上,Verilog定义的语法非常之多,但绝大部分 都是为了仿真测试来使用的。只有少部分才是用于电路设计,详细可以参考本书的“可综 合逻辑设计”一节 。 Verilog中用于设计的语法,才是学习的重点。掌握好设计的语法,熟练应用于各种复杂的项目,这是技能的核 心。其他测试用的语法,需要时查找和参考就已经足够了。 本书着重点,是用于本科、研究生的教学用途,因此将重点讲解设计用的语法。 3 Verilog HDL基本语法 本节介绍Verilog HDL语言的一些基本要素,包括标识符、注释、格式、数字值集合、两种数据类型、运算符和表达式和一些基本的语句如IF语句等。 3.1 标识符 verilog HDL的源文本文件是由一串词法标识符构成的,一个词法标识符包含一个或若干个字符。源文件中这些标识符的排放格式很自由,也就是说,在句法上间隔和换行只是将这些标识符分隔开来并不具有重要意义,转意标识符除外。 verilog HDL语言中词法标识符的类型有以下几种:间隔符、注释符、算子、数值、字符串、标识符、关键词。 接下来对这些标识符一一进行说明 3.1.1 间隔符 间隔符包括空格字符,制表符,换行以及换页符。这些字符除了起到与其它词法标识符相分隔的作用外可以被忽略。 注意的是,在“字符串”中的空白和制表符会被认为是有意义的字符。 3.1.2 注释符 Verilog HDL中有两种注释的方式:单行注释和段注释(多行)。 单行注释以两个字符“//”起始,以新的一行作为结束。也就是注释一行。 段注释是以“/*”符号开始,“*/”结束,在两个符号之间的语句都是注释语句,因此可扩展到多行。如:
3.1.3 算子 算子是由单个、两个或三个字符组成的序列串,分别称之为一元算子、二元算子和条件算子。它用在表达式中。 例如“ | a”等都是一元算子。该例子是“a的所有比特相或”。假如 a是三位信号并且值为011,则“|a”就是“0|1| 1” 等于 1。 例如“a & b”、“a|b等是二元算子。该两个例子分别是a与 b按位相与、a与b按位相或。 例如“a==1? b:c ”,则是条件算子。该例子是说“ 当a等于1时,选择b,否则选择c”。 3.1.4 标识符 标识符是用户在描述时给Verilog对象起的名字,用这个标识符来提及相应的对象。 标识符可以是字母、数字、$符和下划线_字符的任意组合序列,但它必须以字母(a-z,A-Z)或下划线(_)开头,不能是数字或 $符。后面可以是字母、数字或者_。例如abc_123,_abc等。非法命名如下_abc,24abc。 标识符最长可以是1023个字符。 标识符是区分大小写的。例如sel和SEL是不同的标识符。 3.1.5 关键字 Verilog HDL定义了一系列保留字,叫做关键词。这些关键字都有一定的用途。 a. 下表列出了语言中的所有保留字。 b. 注意只有小写的关键词才是保留字。例如,标识符always(这是个关键词)与标识符ALWAYS(非关键 词)是不同的。 c. 在给信号命名时,不要用关键字。
3.1.6 系统任务标识符 系统任务标识符:$,其中$表示引入一个语言结构,其后所跟的标识符是系统任务或系统函数的名称。
每次a或b信号的值发生变化,这一系统任务的调用负责显示当前仿真时间,二进制格式的a信号和十六进制格式的 b信号。 注意,系统任务还有很多,在此不一一列出。但系统任务一般用于仿真测试用途,读者没必要重点学习,在学习工作过程中,如果需要用到时,再查找一下就可以了。 3.2 数字3.2.1 数字表示方式 在Verilog中的数字表示方式,最常用的格式是: <位宽>’<基数><数值>,如,4’b1011。 位宽:描述常量所含位数的十进制整数,是可选项。4’b1011中的4就是位宽。通俗理解就是4根线。如果没有这一项,可以从常量的值推断出。例如’b1011 可知位宽是4;’b10010可推断出位宽为5。 基数:表示数值是多少进制。可以是b,B, d,D,o,O,h或者H,分别表示二进制、十进制、八进 制和十六进 制。如果没有此项,则缺省默认为十进制数。 例如,二进制的4’b1011 ,可以写成十进制的4’d11,也可以写成十六进制的4’hb,或者八进制的4’o13, 还可以不写基数直接写成11。不管怎么样,只要二进数相同,写成十进制、八进制和十六进制,都是同样的数字。 数值:是由基数所决定的表示常量真实值的一串ASCII码。如果基数定义为b或B,数值可以是0,1,x,X,z或Z。如果基数定义为o或O,数值 还可以是2,3,4,5,6,7。如果基数定义为h或H,数值还可以是8,9,a,b,c,d,e,f,A,B,C,D,E,F。对于基数为d或者D的情况,数值符可以是任意的十进制数:0到9。但不可以是x或z。 例如,4’b12是错误的,因为b表示二进制,数值只能是0、1、 x或者z,不有是2。 32’h12等同于 32’h00000012,也就是数值未写完整时,高位补 0。 3.1.2 二进制是基础 在数字电路中,如果芯片A给芯片B传递数据,例如传递0或者1信息。可以将芯片A和芯片B,通过一个管脚进行相连。然后由芯片A控制该管脚为高电平或者低电平,通过高低电平来表示0和1。例如,芯片B检测到该管脚为低电平时,表示收到0;当芯片B检测到该管脚为高电平时,表示收到1。 图 6 如果用低电平表示收到1,用高电平表示收到0,这可不可以呢?当然可以,只要芯片A和芯片B事先协定。芯片A要发数字1时,会将该管脚置为低电平。芯片B检测到该管脚为低电平,知道收到了数字1,通信完成。 图 7 一个管脚拥有高低电平两种状态,可以分别表示数字0和1两种情况。如果芯片A要发数字0、1、2、3给芯片B,那该怎么办呢? 可以让芯片A和芯片B连接两根管脚,即两条线,a和b。当两条线都为低电平时,表示发送数字0;当a为高电平,b为低电平时,表示发送数字1;当a为低电平,b为高电平时,表示发送数字2;当两条线都是高电平时,表示数字3。 图 8 按照同样的道理,芯片A要发送数据4,5,6,7给芯片B的时候,只要再添加一条线就可以了。三根线一共有8种状态,可以表示8个数字。 综上所述,我们可能通过线的不同电平状态,表示不同的含义。有多少个不同状态 ,就可以表示多少个数字。 如果芯片A要发送+1,-1,0,+2等数字给芯片B,这里有正负了,那又该如何表示呢?参考前面的思想,线的高低电平表示的含义,是由芯片双方向事先约定好的。既然是这样,那么我们拿一根线出来,例如低电平表示正数,高电平表示负数。 图 9 上面就是三根线,我们用线c表示正负,0表示正数,1表示负数。用线a和线b表示数值。 3’b111,可以解释为十进制数7,也可以解释为有符号数原码“-3”,也可以解释为有符号数补码“- 1”,这取决于工程师对二进制数的定义。只要这个定义不影响到电路之间的通信那就绝对不会有问题。 所以,数字中的“0”和“1”不仅可以表示含义,也可以表示其他意义,如正负符号等。同样的道理, 在数字电路中,二进制数是其他如八进制、十进制、十六进制、有符号数、无符号数、小数等的根本。在FPGA设计中,不清楚小数、有符号数的计算方法,最根本的原因是不清楚这些数据所对应的二进制值。只要理解了它所对应的二进制值,很多问题都可以解决。 例如,有初学者经常问,FPGA中如何实现小数计算,如“0.5+0.25 ”这个功能。 首先,众所周知的,0.5+0.25的结果为0.75。 其次,我们可以考虑,0.5、 0.25和 0.75用二进制该如何表示?这取决于工程师的做法 ,因为这种表示方法有很多种,例如定点小数,浮点小数,甚至如前面所讨论,用几根线自行来定义,只要能正常通信,那就绝对没有问题。 假设,某工程师用三根线,自行定义了二进制值所表示的小数值。 表 1
为了说明二进制值的意义是可以随便定义的,我特意将数字顺序打乱。当然,有读者可能说为什么只有这几种小数呢?这是因为我假定本系统就只有这几种数字,如果想表示更多数字,那就增加线就行了。 有了上面定义之后,要实现“0.5+0.25 ”就很容易了,其实就是3’b001和3’b100“相加 ”,期望得到3’b010。如果我们直接使用3’b001 + 3’b100,结果为“101”了,不是想要的结果。那怎么办呢?可以这么写:
当然,这是其中一种写法。总之,只要能实现所对应的功能,结果正确就可以。 有读者问,按上面的表格0.1+0.8 应该为 0.9,但上面没有0.9的表示 。这个其实是设计者这个表格定义有缺陷,或者设计者认为不会出现这个情况吧。总之,笔者要表达的是,只要定义好所对应的二进制数,很多功能是很容易设计的。 当然,实际的工程中,我们通常会遵守约定成俗的做法,没必要自己搞得另类。例如下面是常用的定点小数的定义。 表 2
现在要实现0+0.5=0.5,也就是3’b000和3’b100相加,期望能得到3’b100。我们发现直接用二进制3’b000+3’b100就可以得到3’b100。 要实现0.125+0.75=0.8725,也就是3’b001和3’b110相加,期望能得到3’b111。我们发现直接用二进制3’b001+3’b110就可以得到3’b111。 要0.5+0.75=1.25,这个1.25已经超出了表示范围,要不就增加信号位宽,要不只能表示小数位。如果只是表示小数位,那结果就是0.25。也就是3’b100和3’b110相加,期望得到3’b010。我们发现 3’b100 + 3’b110 = 4’b1010 ,用3位表示就是3’b010,也就是0.25了。 综上所述,对于定点小数的计算很简单,就是直接相加。 3.2.3 不定态 前面讲过,数字电路只有高电平和低电平,分别表示1和0。但代码中经常能看到x和z,如1’bx,1’bz。那么这个 x和z是什么电平呢?答案是没有实际的电平来对应。这个x和z是更多地用来表示设计者的意图或者用于仿真目的,告诉仿真器和综合器怎么解释这段代码。 X态,称之为不定态,设计者常用于判断条件,用于告诉综合工具,设计者不关心它的电平是多少,是0还是1都可以。
上面的例子,条件是din==4 ’b10x0,这个条件等价于din==4’b1000|| din==4’b1010,其中“||”是“ 或”符号。
明德扬则建议,直接写成din==4’b1000|| din==4’b1010,好于写成“din==4’b10x0”,直接简单明了。 仿真的时候,有些信号产生了不定态,那么设计者就要认真分析,这个不定态是不是应该的。如果真的不关心它是0还是1,那么可以不解决。但明德扬建议,所有信号都不应该处于不定态,是0还是1,写清楚,不要给设计添加“思考”的麻烦。 3.2.4 高阻态 Z态,一般称之为高阻态,表示设计者不驱动这个信号(既不给0也不给1),通常用于三态门接口当中。 图 10 上图就是三态总线的应用案例。图中的连接总线对于CPU和FPGA来说,既当作输入又当作输出,是双向接口。一般的硬件电路中,会将该线接上一个上拉电阻(弱上拉)或下拉电阻(弱下拉)。 当CPU和FPGA都不驱动该总线时,A点保持为高电平。当FPGA不驱动该总线,CPU驱动该总线时,A点的值就由CPU决定。当 CPU不驱动该总线,FPGA驱动该总线时,A点的值就由FPGA决定。 FPGA和CPU不能同时驱动该总线,否则A的电平就不确定了。通常FPGA和CPU何时驱动总线,是按协议事先协商好的。 图 11 上图是典型的I2C的时序。I2C的总线SDA就是一个三态信号。I2C协议已规定好上面的时间中,哪段时间是由主设备驱动,哪段时间是由从设备驱动,双方都要遵守协议,不能存在同时驱动的情况。 那么FPGA在设计中,是如何做到“不驱动”这一行为呢?这是因为FPGA内部有三态门。 图 12 三态门是一个硬件,上图是它的典型结构。三态门有四个接口,例如上图中的写使能wr_en、写数据wr_data、读数据rd_data和与外面器件相连的三态信号data。 注意写使能信号,当该信号有效时,三态门会将wr_data的值赋给三态线data,此时data的值由wr_data决定,当wr_data为0时,data值就为0;当wr_data为1时,data值就为1。 当写使能信号无效时,则不管wr_data值是多少,都不会对外面的data值有影响,也就是不驱动。 那么在Verilog中,是通过如下两行代码来描述这一功能的。
综合器看到这两行代码,就知道要综合成三态门了。 这个高阻z的作用就在于这里。而且注意到,硬件上用三态线是为了减少管脚,而在FPGA内部没有必要减少连线,所以使用三态信号是没有意义的 。 也就是说,明德扬的设计建议,FPGA内部不要使用高阻态“z”,没有必要给自己添加“思考”的麻烦。当然,使 用了也不会报错,也能实现功能。 总结一点,高阻态“z”是表 示“不驱动总线”这个行为,实际上数字电路就是高电平或者低电平,不存在其他电平的 情况。 3.3 数据类型 Verilog HDL的信号类型有很多种,但主要包括两种数据类型:线网类型 (net type)和寄存器类型(reg type)。明德扬的设计,也是只会使用这两个 类型 。 3.3.1 线网类型wire 线网类型用于对结构化器件之间的物理连线的建模。如器件的管脚,内部器件如与门的输出等。以上面的加法器为例,输入信号A,B是由外部器件所驱动,异或门X1的输出S1是与异或门X2输入脚相连的物理连接线,它由异或门X1所驱动。 由于线网类型代表的是物理连接线,因此它不存贮逻辑值。必须由器件所驱动。通常由assign进行赋值。如assign A = B ^ C; wire 类型定义语法如下: wire [m***: l***] wire1, wire2, . . .,wireN; 1 m***和l***定义了范围,表示了位宽。例如[7:0]是8位位宽,也就是可以表示成8’b0至8’b1111_1111; 2 m***和l***必须为常数值; 3 如果没有定义范围,缺省值为1位; 4 信号没有定义数据类型时,缺省为wire类型。 5 对数组类型,请按降序方式,如[7: 0];不要写成[0:7]。 wire [3:0] Sat; // S a t 为4 位线型信号 wire Cnt; //1 位线型信号 wire [0:31] Kisp, Pisp, Lisp ;// Kisp, Pisp, Lisp 都是32位的线型信号,不建议这样定义。 3.3.2 寄存器类型reg reg是最常用的寄存器类型,寄存器类型通常用于对存储单元的描述,如D型触发 器、ROM等。存储器类型的信号当在某种触发机制下分配了一 个值,在分配下一个值之时保留原值。但必须注意的是,reg类型的变量,不一定是存储单元,如在always语句中进行描述的必须用reg类型的变量。 reg类型定义语法如下: reg [m***: l***] reg1, reg2, . . . r e g N; 1 m***和l***定义了范围,表示了位宽。例如 [7:0] 是8位位宽,也就是可以表示成8’b0至8’b1111_1111; 2 m***和l***必须为常数值; 3 如果没有定义范围,缺省值为1位; 4 信号没有定义数据类型时,缺省为wire类型,不是reg型。 5 对数组类型,请按降序方式,如[7:0];不要写成[0:7]。 例如 : reg [3:0] Sat; // S a t 为4位寄存器。 reg Cnt; //1 位寄存器。 reg [1:32] Kisp,Pisp, Lisp ; 3.3.3 Wire和reg定义的场合区分 Reg型信号不一定生成寄存器。那么什么时候使用wire类型,什么时候用reg类型,明德扬总结出一套方法:在本模块中,使用always设计的信号都定义为reg型;其他都用wire型。
上面代码中,cnt1是用always设计的,所以要用reg型。Add_cnt1和end_cnt不是由always产生的,所以定义为wire型。
上面代码中,x是用always设计的,所以要定义为reg型。注意,实际的电路中,x不是寄存器,但我们仍然定义为 reg型。
上面是例化的代码,其中df是例化模块的输出。由于df不是由always产生的,而是例化产生的,所以要定义成wire型。 3.4 运算符和表达式3.4.1 算术运算符 常用的算术运算符主要有:加法“ +”,减 法“- ”和乘法 “*”。 注意,上面没有除法运算符。这是由于除法不是简单的门逻辑可搭建起来的,它所对应的硬件电路比较大。我们在小学时就知道,加减是最简单的运算,而乘法可以拆解成多个加法运算,加减法、乘法所对应的电路都比较小。而除法就不同了,回想下除法步骤,那是涉及到多次乘法、移位、加减法,所以除法对应的电路是不简单的,这也要求我们 ,Verilg中要慎用除法。 3.4.1.1 加法运算符 加法运算符,可以在Verilog代码中,直接使用符号“+”。
其电路示意图: 图 13 加法运算符,综合器可以识别加法运算符,将其转成如上面的电路。 二进制的加法运算和十进制的加法相似的,十进制是逢十进一,而二进制是逢二进 一。 下面是二进制加法的基本运算:
2位的二进制加法
在写代码时,需要注意信号的位宽,最终的结果取决于“+”号左边信号的位宽,保存低位,丢弃高位。例如:
C的位宽为1,所以运算的结果最终保存最低1位,所以c的值为1’b0。由于d的位宽有2位,所以运算的结果可以保存低2位,所以d的值为2’b10。由于e的位宽有3位,所以运算的结果可以保存低3位,所以e的值为3’b010。“1”默认是32位,1+1的结果也是32位,但由于f的位宽有3位,所以运算的结果可以保存低3位,所以f的值为3’b010。 3.4.1.2 减法运算符 减法运算符,可以在Verilog代码中,直接使用符号“-”。
其电路示意图: 图 14 减法运算符,综合器可以识别减法运算符,将其直接转成上面电路。 二进制的减法运算和十进制的减法运算是相似的,也有借位的概念。十进制是借一当十,二进制则是一当二。1位减法基本运算如下:
在写代码时,需要注意信号的位宽,最终的结果取决于“-”号左边信号的位宽,保存低位,丢弃高位。
“0-1”得到的二进制值是“1111111111….”,但保存结果取决于“-”号左边信号的位宽。C的位宽是1,保存最低1位,所以c的值为1’b1 。由于d的位宽有2位,结果保存低2位,所以d的值为2’b11。由于e的位宽有3位,结果保存低3位,所以e的值为3’b111。f的位宽有4位,所以运算的结果可以保存低4位,所以f的值为4’b1111。 3.4.1.3 乘法运算符 乘法运算符,可以在Verilog代码中直接使用符号 “*”。
其电路示意图: 图 15 综合器可以识别乘法运算符,将其直接转成上面电路。 二进制的乘法运算和十进制的乘法运算是相似的,其计算过程是相同的。 1位乘法基本运算如下:
多位数之间相乘,与十进制计算过程是相同的。例如2’b11 * 3’b101,其计算过程如下: |
|||
|
|||
1586 浏览 1 评论
1351 浏览 0 评论
矩阵4x4个按键,如何把识别结果按编号01-16(十进制)显示在两个七段数码管上?
1563 浏览 0 评论
930 浏览 0 评论
2361 浏览 0 评论
1470 浏览 37 评论
5681 浏览 113 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 17:44 , Processed in 0.846441 second(s), Total 65, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号