Build the Hack CPU with Verilog

从0到1构建计算机(5/12)--实现hack:计算机架构、内存、CPU和指令集 经过前两篇我们已经实现了所有的组合逻辑芯片和时序芯片,具备了实现hack计算机的基础,本篇是项目硬件部分的最后一篇,我们将在本篇定义hack能够执行的操作,即hack的指令集;实现hack的内存、CPU,然后将它们组合起来形成完整的计算机硬件架构。 计算机架构 hack是基于经典的冯·诺伊曼体系架构,它的关键组成部分是将中央处理单元和存储器,通过存储器中存储的程序指令控制中央处理器的执行,即存储程... 阅读详情

Build the Hack CPU with Verilog

陈硕 2009-04-18

http://blog.youkuaiyun.com/Solstice  giantchen_AT_gmail.com

最近手痒,买了一本《计算机系统要素:从零开始构建现代计算机》http://www.china-pub.com/33880,把书中讲到的Hack CPU用Verilog实现了一把。

原书在Amazon的页面是http://tinyurl.com/cc6582 《The Elements of Computing Systems: Building a Modern Computer from First Principles》。这本书除了讲CPU,还讲了数字逻辑、虚拟机、编译器等一些有意思的内容,中文翻译得也不错。

1       Hack CPU介绍

Hack是一个16-bit Harvard结构的CPU,指令和数据分开存放。数据总线是16-bit,地址总线是15-bit,只有三个寄存器A、D和PC,其中A和D都是16-bit,PC是15-bit。指令长度均为16-bit,每条指令都能在单周期内完成。从书的配套网站http://www1.idc.ac.il/tecs/plan.html 可下载讲义及部分章节,第五章讲了Hack CPU的设计,可以下载来看一看。这是Hack的接口框图:

 

 

module cpu(clk, nrst, inst_addr, inst, rdata, wdata, data_addr, we);

    input clk, nrst;

    input[15:0] inst;            // instruction

    input[15:0] rdata;       // inM

    output[14:0] inst_addr;  // pc

    output[14:0] data_addr;  // addressM

    output[15:0] wdata;      // outM

    output we;               // writeM

endmodule

代码1:Hack CPU的接口

书中给出的实现框图:

Hack CPU可以用几十块74 TTL搭出来,不过得更改时序以适应异步SRAM的读写。它的复杂度可能还比不上一般大学本科的《微机原理》课程中要求学生实现的CPU。其实,实现一个能自动执行指令的数字电路比想象中简单多了,很多事情就是这样,一开始看上去很难,一旦上手去做,捅破了那层窗户纸,会发现其实做个能玩的出来也没那么困难。操作系统、编译器、CPU莫不如此。

下面分几步把Hack CPU造出来。

2       实现Hack CPU

2.1     执行A指令,PC递增

Hack有两种类型的指令,A指令和C指令,A指令非常简单,它把指令的低15位存入寄存器A。我们先实现A指令,它的格式是:

 

指令的最高位是0,低15位是寄存器A的设置值。

 

 

module cpu(/* ... /*);

// 接口同“代码1”

    reg[14:0] pc;

    reg[15:0] a;

 

    wire load_a = !inst[15];

    wire sel_a = inst[15];

    wire[14:0] next_pc = pc + 15'b1;

    wire[15:0] next_a = sel_a ? 16b’x : {1'b0, inst[14:0]};

 

    assign inst_addr = pc;

 

    always @(posedge clk)

        if (!nrst) // 同步清零

            pc <= 15'b0;

        else

            pc <= next_pc;

 

    always @(posedge clk)

        if (load_a)

            a <= next_a;

 endmodule

 

测试用的Hack指令(Verilog数据格式,下同):

@0000

0000_0000_0000_0000  // A = 0

0000_0000_0100_0010  // A = 0x42

0101_0101_1010_1010  // A = 0x55AA

指令存储器

module rom(addr, data);

    input[7:0] addr;

    output[15:0] data;

 

    reg[15:0] memory[0:255];

 

    assign data = memory[addr];

endmodule

仿真波形

 

2.2     执行与内存无关的C指令

C指令基本上能做所有的事情,执行运算、输出结果、跳转等。这一节我们只实现与内存访问无关的C指令,即对A和D执行运算,并把结果存到A或D中。

 

C指令的格式:

 

 

逻辑框图,蓝色为新增加的部分:

 

要做运算,先得有ALU,原书第3章讲了ALU的设计,这里照搬过来。

module alu(x, y, out, fn, zero);

    input[15:0] x, y;

    input[5:0] fn;

    output[15:0] out;

    output zero;

 

    wire zx = fn[5];

    wire nx = fn[4];

    wire zy = fn[3];

    wire ny = fn[2];

    wire add = fn[1];

    wire no = fn[0];

 

    wire[15:0] x0 = zx ? 16'b0 : x;

    wire[15:0] y0 = zy ? 16'b0 : y;

    wire[15:0] x1 = nx ? ~x0 : x0;

    wire[15:0] y1 = ny ? ~y0 : y0;

    wire[15:0] out0 = add ? x1 + y1 : x1 & y1;

    assign out = no ? ~out0 : out0;

    assign zero = ~|out;

endmodule

然后是更新的Hack CPU设计,更新部分用蓝色标记。这一步主要是加了一个寄存器D,一个ALU,还有一些数据通路和控制信号。

module cpu(/* ... /*);

// 接口同“代码1”

    reg[14:0] pc;

    reg[15:0] a;

    reg[15:0] d;

 

    alu alu0(.x(d), .y(am), .out(alu_out), .fn(alu_fn), .zero(zero));

 

    wire load_a = !inst[15] || inst[5];

    wire load_d = inst[15] && inst[4];

    wire sel_a = inst[15];

    wire sel_am = inst[12];

    wire zero;

    wire[14:0] next_pc = pc + 15'b1;

    wire[15:0] next_a = sel_a ? alu_out : {1'b0, inst[14:0]};

    wire[15:0] next_d = alu_out;

    wire[15:0] am = sel_am ? 16'bx : a;

    wire[15:0] alu_out;

    wire[5:0] alu_fn = inst[11:6];

 

    assign inst_addr = pc;

 

    always @(posedge clk)

        if (!nrst) // 同步清零

            pc <= 15'b0;

        else

            pc <= next_pc;

 

    always @(posedge clk)

        if (load_a)

            a <= next_a;

 

    always @(posedge clk)

        if (load_d)

            d <= next_d;

 endmodule

 

2.3     完整的实现

剩下的工作是增加数据内存的访问功能,先定义Hack的RAM,这是一个同步的双口SRAM,可以用FPGA内置的存储单元实现。

module ram(clk, addr, rdata, wdata, we);

    input clk, we;

    input[7:0] addr;

    output[15:0] rdata;

    input[15:0] wdata;

 

    reg[15:0] memory[0:255];

 

    assign rdata = memory[addr];

 

    always @(posedge clk)

        if (we)

            memory[addr] <= wdata;

endmodule

然后添加 RAM读写的data path,并支持跳转指令,这样得到了最终的设计,与书上的一摸一样。


 


module cpu(clk, nrst, inst_addr, inst, rdata, wdata, data_addr, we);

    input clk, nrst;

    input[15:0] inst;

    input[15:0] rdata;

    output[14:0] inst_addr, data_addr;

    output[15:0] wdata;

    output we;

 

    reg[14:0] pc;

    reg[15:0] a;

    reg[15:0] d

 

    alu alu0(.x(d), .y(am), .out(alu_out), .fn(alu_fn), .zero(zero));

 

    wire load_a = !inst[15] || inst[5];

    wire load_d = inst[15] && inst[4];

    wire sel_a = inst[15];

    wire sel_am = inst[12];

    wire jump = (less_than_zero && inst[2])

                 || (zero && inst[1])

                 || (greater_than_zero && inst[0]);

    wire sel_pc = inst[15] && jump;

    wire zero;

    wire less_than_zero = alu_out[15];

    wire greater_than_zero = !(less_than_zero || zero);

    wire[14:0] next_pc = sel_pc ? a[14:0] : pc + 15'b1;

    wire[15:0] next_a = sel_a ? alu_out : {1'b0, inst[14:0]};

    wire[15:0] next_d = alu_out;

    wire[15:0] am = sel_am ? m : a;

    wire[15:0] alu_out;

    wire[5:0] alu_fn = inst[11:6];

    wire[15:0] m = rdata;

 

    assign inst_addr = pc;

    assign data_addr = a[14:0];

    assign wdata = alu_out;

    assign we = inst[15] && inst[3];

 

    always @(posedge clk)

        if (!nrst)

            pc <= 15'b0;

        else

            pc <= next_pc;

 

    always @(posedge clk)

        if (load_a)

            a <= next_a;

 

    always @(posedge clk)

        if (load_d)

            d <= next_d;

endmodule

描述整个Hack CPU只用了50行 Verilog代码。

下面是书上第4章计算1+2+...+100的程序的仿真波形,计算结果5050出现在数据读端口:

 

 

 

3       不足与改进

Hack CPU尽管简单,却能够执行一般CPU的大部分功能,比如读写内存,算数与逻辑运算,条件判断与跳转。当然,也有一些明显的值得改进的地方。

1.         不支持子程序调用,PC的值没法读出来并存到内存中。也就是说没法把返回地址存到函数调用栈中。这不难改进,只要在寄存器D之后放一个多路选择器,让PC+1的值也能参与运算。当然,需要扩充C指令的格式,把sel_dpc编码进去,可以用第13位。

 

 

2.         不支持相对跳转,PC总是跳转到A所指的地址。不便于编写可重定位的代码。这个也不难解决,可以引入一种新的J指令(可以以二进制10开头,区别A指令和C指令),包含跳转条件和跳转偏移量,数据通路修改如下,只要增加一个加法器和选择通路。

 

3.         不支持中断,没法实现高效的IO。这个我还没有设计出一个好的解决方案。

4       附录A:Verilog工具与心得

l  免费的Verilog仿真器:Icarus Verilog [ http://www.icarus.com/eda/verilog/ ]
Windows
版下载地址:http://bleyer.org/icarus/
我用的是iverilog-0.8.6_setup.exe

l  免费的波形查看器:GTKWave [ http://www.gpleda.org/tools/gtkwave/index.html ]
Windows
版下载地址:http://www.dspia.com/gtkwave.html

我上一次用Verilog来做数字电路设计是在4年多以前(AES加密算法的FPGA实现,加密16字节用11个周期),今后用它的机会也很少,这里写一点心得,算是留个纪念吧。

用Verilog的首要原则是,心中先有电路,再用Verilog把它描述(describe)出来,毕竟Verilog是硬件描述语言(Hardware description language),不是程序设计语言。运用Verilog要掌握几种平衡:哪些需要人脑精心设计,哪些可以留给综合器(synthesizer)去优化;是把代码写得更通用(general),还是使用特定器件做优化(例如使用LPM或megafunction)。一般来说,数据通路(data path)是需要精心考虑的,而组合逻辑(比如CPU里的控制逻辑)尽可留给综合器。毕竟布尔函数的最小化算法已经很成熟了,比如Quine–McCluskey algorithm和Espresso heuristic logic minimizer。综合器在实现组合逻辑方面有很多花招可玩,比如AES加密算法里的Rijndael S-box是个256字节的纯粹的查找表,好的综合器会根据器件的资源自动选择ROM或组合逻辑来实现。设计时更多是在考虑寄存器(通常是D触发器)的安排、数据在每一拍如何流动。这和程序设计类似,优先设计数据结构,然后让算法自然地浮现出来。

另外,Verilog的重要用途是写test bench。通过看仿真波形来除错是低效的,对于hack这样的小型设计还行,对于稍微复杂一点的设计非得用test bench不可。数字设计基本上是测试驱动的。

5       附录B:另几个容易实现的CPU

5.1     Petzold’s

在《编码的奥秘》[http://www.china-pub.com/680] 第17章中,作者Charles Petzold由一个程序控制的累加器出发,逐步实现了一个简单的通用CPU。这也是我见到的最简单的CPU设计了。这一章可从china-pub付费下载。

5.2     Beta

MIT 6.004课程讲授的一个32-bit类MIPS指令集的CPU:http://tinyurl.com/2ppws

5.3     Magic-1

一个用TTL搭出来的能运行Minix 2.0.4的16位CPU:http://www.homebrewcpu.com/

 

从NAND门到俄罗斯方块:自底向上构建完整计算机系统的硬核实践 计算机系统是一个由硬件和软件协同工作的复杂体系,其核心原理在于将高级抽象逐步转化为底层物理实现。理解这一过程的关键在于掌握从逻辑门到可运行程序的完整技术栈。通过硬件描述语言(HDL)定义数字逻辑电路,可以构建出算术逻辑单元(ALU)、中央处理器(CPU)和内存等核心组件,形成计算机的硬件基础。在此基础上,指令集架构定义了硬件与软件的交互界面,而汇编语言、虚拟机和编译器等技术则构成了将高级语言转化为机器指令的软件工具链。这种自底向上的构建方法具有极高的教育价值,能够帮助开发者打通软硬件知识隔阂,深刻理解程序在 阅读详情

相关推荐

从0到1构建计算机(3/12)--组合逻辑芯片:逻辑门、加法器、ALU

上篇说到:通过使用Nand门,我们可以实现任何逻辑门,进而实现可以一个CPU。后面我们就会搭建一个麻雀虽小但五脏俱全的计算机平台:hack。本篇我们开始第一步,实现搭建hack所需的一组芯片:组合逻辑芯片 组合逻辑芯片 一个最基本的CPU主要由两类芯片组成: 组合逻辑芯片(Combinational Chips):与、或、非门,加法器,ALU芯片等。这些芯片主要负责逻辑计算 时序芯片(Seque...

XA403 3845

Verilog实现Hack计算机

• C指令:111a cccccc ddd jjj(操作码+ALU控制+目标选择+跳转)→ D寄存器值 = D + A(假设初始MEM[5]=5,则D=5+5=10)• A指令:0vvv vvvv vvvv vvvv(加载立即数到A寄存器)• ALU操作数来自D寄存器和内存(通过A寄存器寻址)• 目标选择(dest)决定结果写入A/D/M寄存器。• 最终检查内存地址5的值是否为10(0x000A)• ALU的6位控制信号来自指令的comp字段。• A寄存器用于存储地址/数据。→ A寄存器加载值5。

qq_62784677的博客 458

Hack计算机CPU架构图.png

Hack计算机CPU架构图,根据《计算机系统要素》绘制,包含指令输入的连接,ALU、寄存器、程序计数器的连接

计算机系统要素-从零开始构建现代计算机--第五章,03-内存/CPU/HACK计算机电路图及HDL

从零开始构建现代计算机--第五章,03-内存/CPU/HACK计算机实现内存HDL电路图 本节将构建内存,CPU,以及完整的HACK计算机。 画图软件为ubuntu的dia 整个计算机只有两种基本电路:组合逻辑电路和时序电路,基本构件分别是NAND和DFF,而DFF也是由NAND构建得来的,只是连接方式稍有不同(参见第三章,01-D触发器与1比特存储器实现)。 从第一章到现在,从基本的与非门开始,所有的电路的连接,都是通过布尔代数指引的。足见布尔代数在计算机发展过程中的奠基性地位。 这些电路功能上都很简单,

qq_17065591的博客 2192

初级java笔试题-nand2tetris:创建一个通用计算机系统,从与非门一直到俄罗斯方块的实现

初级java笔试题nand2tetris 从第一性原理构建计算机; 从与非门开始,一直到构建可以玩俄罗斯方块的通用计算机。 硬件 该部分项目已完成。 NAND 门和 DFF 被用作基本单元来构建其他逻辑门、ALU、RAM、CPU,最后是通用计算机芯片。 所有硬件都是使用硬件描述语言设计的。 完成的芯片可以在文件夹 01 到 05 中找到。 软件 黑客汇编程序 用python写了一个Hack汇编语言的汇编程序,可以找到。 我也直接用Hack汇编语言写了一些简单的测试程序。 可以找到那些程序。 虚拟机翻译器 写了一个虚拟机翻译器(编译器后端),将基于堆栈的虚拟机代码(类似于Java虚拟机)翻译成Hack汇编语言。 这个程序是用python编写的,可以找到。 编译器前端 - 进行中 我用Clojure语言写了编译器前端(将面向对象的Jack语言翻译成虚拟机代码的部分)。 该程序由分词器、词法解析器以及虚拟机代码编写模块组成。 分词器和词法解析器是在 Clojure 中使用递归下降算法从头开始编写的。 没有使用像 Lex 和 Yacc 这样的工具来简化这个过程。 操作系统 我计划为通用计算机编

NAND2Tetris

NAND2俄罗斯方块 2020.04.25 异或 南德 多路复用器 DMux 不是16 And16 或16 多路复用器16 八路 Mux4Way16 Mux8Way16 DMux4Way DMux8Way 2020.04.28 半加器 FullAdder 新增16 inc16 ALU

《计算机系统要素》阅读总结及实现第五章——计算机体系结构

计算机系统要素第五章--计算机体系结构

z1997zc的博客 363

西门子OMAC PackML V2022在S7-1200/S7-1500中的状态机设计与应用实践

本文详细解析了西门子OMAC PackML V2022在S7-1200/S7-1500中的状态机设计与应用实践。通过实际案例和代码示例,介绍了状态机的基础认知、硬件配置、逻辑开发、调试技巧以及与MES系统集成的高级应用,帮助工程师高效实现设备自动化控制。

weixin_29255731的博客 531

The Element Of Computer System 笔记(第五周)

无

qq_49532777的博客 437

【SOC 芯片设计 DFT 学习专栏 -- DFT DRC规则检查】

在现代半导体设计中,DFT(Design for Test)技术的重要性不言而喻。它确保了芯片在制造完成后能够进行高效和可靠的测试。DFT设计规则检查(DRC)作为DFT流程中的一个关键环节,通过一系列自动化工具检测设计中的潜在问题,从而保证设计的可测试性和整体质量。在本文中,我们将详细探讨DFT DRC的概念、重要性、检查流程以及具体的规则和应用。Tessent是业界领先的DFT解决方案之一,其DRC工具通过一系列自动化检查,确保设计符合DFT要求。

CodingCos的博客 4168

Tomcat漏洞——弱口令爆破

靶机:CentOS7 IP:192.168.100.40。攻击机:kali IP:192.168.100.60。版 权 声 明:本博客所有文章除特别声明外,均采用。文章版权归作者所有,未经允许请勿转载!作 者:PeiyuJue。

weixin_57379923的博客 909

Build the Hack CPU with Verilog -- 陈硕

陈硕 2009-04-18http://blog.youkuaiyun.com/Solstice  giantchen_AT_gmail.com最近手痒,买了一本《计算机系统要素:从零开始构建现代计算机》http://www.china-pub.com/33880,把书中讲到的Hack CPU用Verilog实现了一把。原书在Amazon的页面是http://tinyurl.com/cc6

嵌入式开发小站 1815

软件缺陷(定义+表现形式+优先级+信息+产生原因),看完这篇文章就懂了

软件缺陷软件缺陷的定义软件缺陷的表现形式软件缺陷产生的原因软件缺陷的根源软件缺陷的费用软件缺陷的信息 软件缺陷的定义 IEEE 1983 of IEEE Stardard 729中软件缺陷做了一个标准的定义: 从产品内部看,软件缺陷是软件产品开发或维护过程中所存在的错误、毛病等各种问题;从外部看,软件缺陷是系统所需要实现的某种功能的失效或违背。 因此软件缺陷就是软件产品中所存在的问题,最终表现为用户所需要的功能没有完全实现,没有满足用户的需求。 缺陷不是bug,缺陷包含bug,缺陷的范围更大。 软件缺陷

qq_40676418的博客 1万+

QWQ-32B与DeepSeek-R1本地部署实战:架构差异、量化选型与四维性能评估

大语言模型本地部署已从‘能否跑通’进入‘如何选型’的深水区。理解模型底层架构(如双脑推理头、全栈对齐机制)是规避幻觉、延迟失控和显存溢出的关键前提。AWQ量化、ExLlamaV2引擎、FlashAttention-2分片加载等技术组合,正成为QWQ-32B等新型架构模型落地的刚需能力;而DeepSeek-R1的DPO多目标对齐则显著提升API开箱可用性。本文聚焦数学推理、长文档摘要、多轮状态保持与冷启动资源占用四大真实场景,提供可复现的四维压测方法论与混合部署策略,助力科研、工程与私有知识库场景下的理性选型

cunbei2644的博客 559

01 AUTOSAR CP标准文档阅读指南

01 AUTOSAR CP标准文档阅读指南

汽车软件工程师 | 好奇博主 | 处女座 1134

手把手教学|用飞书+扣子工作流实现自动化批量图片生成,效率提升99%!体验完整操作流程

在先前的文章中,我们已经深入探讨了扣子智能体的多种应用场景,以及如何创建和使用工作流进行高效管理。本文将引领大家通过一个具体案例,将扣子的工作流功能嵌入飞书应用中,实现操作的自动化与高效化。

weixin_66485800的博客 6028

【亲测免费】 推荐项目:espresso-logic-minimizer - 现代化的逻辑最小化工具

推荐项目:espresso-logic-minimizer - 现代化的逻辑最小化工具 1、项目介绍 espresso-logic-minimizer 是一个2017年的现代化重置版,源自经典的Espresso逻辑最小化器。这个开源项目由加州大学伯克利分校提供原始代码,并且可以编译运行在现代环境中。它为电子设计自动化(EDA)领域的逻辑综合提供了强大而高效的工具。 2、项目技术分析 该项目的核心是...

gitblog_00029的博客 1237

python实现ECMS算法

ECMS(Equivalent Consumption Minimization Strategy)算法是一种用于混合动力汽车能量管理系统的优化策略。它通过计算等效油耗来平衡电池电量消耗和燃油消耗,从而优化整体能耗。以下是一个简单的Python实现,用于演示ECMS算法的基本思想。这个实现假设了一个简单的混合动力汽车模型,其中电池电量和燃油消耗是主要的优化目标。

weixin_45570158的博客 922

计算机系统要素-从零开始构建现代计算机--第五章,02-HACK计算机硬件体系

第五章,02-HACK计算机硬件体系CPU控制逻辑的功能内存计算机 Hack平台的大部分行为都发生在CPU中,因此主要任务就是构建CPU,其他的主要是正确连接。 CPU CPU的实现目标是建立逻辑门结构,使其能执行指定的HACK指令和读取下一条要执行的指令。 CPU包括: ALU,执行HACK指令 一组寄存器 控制逻辑,用于指令获取和解码 下图给出除控制逻辑部分的连接方式: 控制逻辑的功能 指令解码(Instruction decoding),解析出指令所代表的意思(指令的功能) 指令执行(Inst

qq_17065591的博客 1135

这才是 Python 的正确玩法!用强化学习 (RL) 训练 AI 玩《王者荣耀》,胜率 90%!

大家打排位时,一定遇到过那种“意识神级、操作零失误”的对手,或者“走位呆滞、送人头”的队友。以前的“人机”是程序员写死的脚本(If 血量<20% Then 回城)。而现在的顶级 AI(如腾讯绝悟、OpenAI Five),是靠强化学习 (Reinforcement Learning)自己“左右互搏”练出来的。今天,我们不谈枯燥的数学公式,我将手把手教你用,搭建一个能玩 MOBA 游戏的 AI Agent。即使不能去 KPL 打职业,虐一下钻石局还是绰绰有余的!

BUG猿的博客 1182

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

化简逻辑函数的方法

之前从未听说过启发式逻辑压缩器(Espresso heuristic logic minimizer)这种东西,今天在寻找测试使用的Benchmark的时候突然遇到了这方面的东西,所以记录一下学习过程。 维基百科上对于启发式逻辑压缩器的定义为:这是一种用启发式和特定算法来高效缩减数字门电路复杂性的程序,是在1986年由IBM公司的Robert Brayton先生创造的,并且写了篇论文名为“Mul...

weixin_30666753的博客 1432

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Espresso Logic 项目使用教程

Espresso Logic 项目使用教程 1. 项目的目录结构及介绍 Espresso Logic 项目的目录结构如下: espresso-logic/ ├── espresso-src/ │ ├── bin/ │ ├── src/ │ └── ... ├── examples/ │ ├── example1/ │ ├── example2/ │ └── ... ├── ...

gitblog_00763的博客 461

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

推荐文章:探索逻辑简化的新境界——Espresso-Logic-Minimizer

推荐文章:探索逻辑简化的新境界——Espresso-Logic-Minimizer 在数字电路设计和可编程逻辑领域中,逻辑优化是一项至关重要的技术。今天,我们带来了一个值得您关注的开源宝藏——Espresso-Logic-Minimizer。这不仅是一款重温经典的工具,更是现代软件工程与古老智慧的完美结合。 项目介绍 Espresso-Logic-Minimizer,顾名思义,是Espresso启...

gitblog_00466的博客 1378
上一篇: 书摘几则
下一篇: C++ 标准库中的allocator是多余的
陈硕
博客等级 码龄26年 1万+粉丝 144原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值