首页 > 其他分享 >自己动手写CPU - 4

自己动手写CPU - 4

时间:2025-01-06 11:30:35浏览次数:3  
标签:out1 20 in1 in2 自己 动手 eq CPU op

自己动手写CPU - 1-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/weixin_46766770/article/details/144933071自己动手写CPU - 2-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/weixin_46766770/article/details/144935050自己动手写CPU - 3-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/weixin_46766770/article/details/144935080

书接上文.

上一节中有一个问题未解决: 仔细看了下, 应该还无法完成从1加到10的任务. 没有条件跳转, 需要利用CMP的结果来控制跳转, 例如: 比较循环次数到了10了没? 小于10则继续循环.

这一节补上它, 只加了四五行代码吧. 直接上代码.

增加了两个指令, 相等则跳, 不相等则跳, 不满足条件时输出R7+1

新加了eq寄存器, 如果op是5则更新它, 用in1==in2是否成立

6/7两个新加的指令, 按代码的逻辑看, 也不一定只能作用于R7, 它也可以作用于R0-R6, 但它在不成立时返回的是in1+1, 操作R0/R6似乎没有明确的含义(没有使用场合), 写程序时只用来操作R7.

全部代码如下(仿真时发现没有rst无法仿真, 全部信号是xxxxx, 也加上了rst)

module cpu(
    input clk,rst,
    input [15:0]op,     //[15:11]指令 [10:8]目标Reg索引 [7:0]立即数或源Reg索引
    output reg eq,
    output reg[7:0]R[8] // R0-R7组织成寄存器组,  方便用寄存器索引 选择
);

reg [7:0] in1,in2, out1;
always @ (*) begin
    in1 = R[op[10:8]];
    in2 = !op[11]? R[op[2:0]] : op[7:0];
end

always @ (*) begin 
    case(op[15:12])
        0: out1 = in2;          // ldr
        1: out1 = in1 + in2;    // add
        2: out1 = in1 - in2;    // sub
        3: out1 = in1 & in2;    // and
        4: out1 = in1 | in2;    // or
        5: out1 = in1;          // cmp
        6: out1 =  eq ? in2:in1+1;// jeq
        7: out1 = !eq ? in2:in1+1;// jne
        default: out1 = 0;
    endcase
end

wire [7:0]sel;
decode38 decode38_inst1(
    .abc(op[10:8]),
    .out(sel)
);

always @(posedge clk or negedge rst) begin
    if (!rst) begin
        eq=0; R[0:7]={0,0,0,0,0,0,0,0};
    end else begin
    if(op[15:12]==5) eq=(in1==in2);
    if(sel[0]) R[0]=out1;
    if(sel[1]) R[1]=out1;
    if(sel[2]) R[2]=out1;
    if(sel[3]) R[3]=out1;
    if(sel[4]) R[4]=out1;
    if(sel[5]) R[5]=out1;
    if(sel[6]) R[6]=out1;
    if(sel[7]) 
        R[7]=out1;
    else  
        R[7]=R[7]+1;
    end
end

endmodule

生成的RTL变化也不大, 下图将增加的单元也标注了出来.

RTL逻辑电路图

直接使用vivado跑测试, 测试代码

//`timescale 1ns / 1ps
module tb_cpu();

reg clk,rst;
reg [15:0]op;
wire eq;
wire [7:0]R[8];

cpu cpu_inst1(
    .clk(clk),
    .rst(rst),
    .op(op),
    .eq(eq),
    .R(R)
);

initial begin
    clk = 0; 
    rst=0;
    #5  rst=1;
        op = 'h0001+'h0800; //ldr R0, #1
    #20 op = 'h0111+'h0800; //ldr R1, #11
    #20 op = 'h0222+'h0800; //ldr R2, #22
    #20 op = 'h0666+'h0800; //ldr R6, #66
    #20 op = 'h0602;        //mov R6, R2
    #20 op = 'h1022+'h0800; //add R0, #22
    #20 op = 'h1106;        //add R1, R6
    #20 op = 'h2100;        //sub R1, R0
    #20 op = 'h5101;        //cmp R1, R1
    #20 op = 'h6701+'h0800; //beq #01
    #20 op = 'h5102;        //cmp R1, R2
end

always #10 clk = ~clk;

endmodule

测试代码比较简单, 先例化一个cpu, 连上信号线. 设好时钟, 每20个时间单位给一条指令, 然后观察R0-R7以及eq状态的变化. 仿真图如下:

可以看到, ldr add sub 执行的都是对的, cmp可以影响到eq状态, beq也成功修改了R7的值.

一开始提出的目标可以实现.

(数了下, 一共53行代码. 周六下午开始写, 写到凌晨.
周日本来不写了, 天黑时又有了想法, 还是把它写完吧, 正好0点收工)

标签:out1,20,in1,in2,自己,动手,eq,CPU,op
From: https://blog.csdn.net/weixin_46766770/article/details/144959479

相关文章

  • 定义自己的注解,用aop完成日志操作
    1.引入依赖<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency>2.定义注解类//表示该注解使用的位置TYPE:类,接口FIELD:属性METHOD:方法......
  • 一文玩转生成式AI新星DeepSeek-V3,带你5分钟配置自己的随身AI
    前言在人工智能领域,模型的性能与能力一直是衡量其价值的重要标准。近期,DeepSeek-V3在多项评测中表现优异,超越了Qwen2.5-72B和Llama-3.1-405B等其他开源模型,并与世界顶尖的闭源模型GPT-4o以及Claude-3.5-Sonnet不相上下。以下是官方给出的能力对比图:一、DeepSee......
  • 有哪些方法可以禁止别人调试自己的前端代码?
    禁止别人调试自己的前端代码是一个具有挑战性的任务,因为前端代码在客户端执行,用户总有一定的访问和修改权限。然而,你可以采取一些措施来增加调试的难度或减少调试的可能性。以下是一些建议的方法:代码混淆:使用工具如Obfuscator等来混淆你的JavaScript代码。这可以将变量名、函......
  • 深度学习CUDA环境安装教程---动手学深度学习
    首先说明我安装的是《动手学深度学习》中的环境本人是小白,一次安装,可能有不对的地方,望包含。安装CUDA因为我们是深度学习,很多时候要用到gpu进行训练,所以我们需要一种方式加快训练速度。通俗地说,CUDA是一种协助“CPU任务分发+GPU并行处理”的编程模型/平台,用于加速GPU和CPU之......
  • 2025年,为自己充电的最好方式
    商业咨询顾问刘润谈及一件事。过去的一年里,他跟许多创业者在聊天时,他们都会说同一句话:太累了。这些人像是电池没电了一样,陷入了一种心力缺失的状态。因此,刘润特地拜访了上海交通大学研究生命科学的仇子龙教授,请教了一个问题:如何给自己充电?仇子龙教授说了四个自我充电的......
  • 献给自己技术成长的第五年
    献给自己技术成长的第五年又面试不包装去魅了多沉淀碎碎念年度总结语:想要得到一些东西,那就注定要放弃一些东西回望这一年的生活,应该算得上是除开找实习那一年外变化最大的了,毕竟我离开了待了近四年的城市,离开的还有认识的那群小伙伴。又面试没错,我又在准备面......
  • CPU负载均衡之WALT
    前言本文继续整理CPU调度WALT相关内容,主要整理如下内容:WALT是什么?WALT计算?WALT计算数据如何使用?1.WALT是什么?WALT:Windows-AssistLoadTracing的缩写:从字面意思来看,是以window作为辅助项来跟踪CPULOAD;实质上是一种计算方法,用数据来表现CPU当前的loading情况,用于后......
  • 动手深度学习-PyTorch(第二版)PDF、EPUB免费下载
    电子版仅供预览,下载后24小时内务必删除,支持正版,喜欢的请购买正版书籍点击原文去下载书籍信息作者:阿斯顿·张(AstonZhang)/李沐(MuLi)/[美]扎卡里·C.立顿(ZacharyC.Lipton)/[德]亚历山大·J.斯莫拉(AlexanderJ.Smola)出版社:人民邮电出版社出品方:异步图书译......
  • 升级服务器数据盘大小、内存和CPU是否会丢失数据
    用户计划升级服务器的数据盘大小、内存和CPU,但担心这些操作会导致现有数据丢失。特别是对于网站程序和数据库文件的安全性表示担忧。解决方案:问题解决方案升级数据盘是否会丢失数据正常情况下,升级数据盘不会导致数据丢失。只要按照正确步骤操作,原有数据将保持完整。......
  • CompletionFormer-环境配置+推理自己的数据集
    CompletionFormer配置环境Ubuntu20.04,Python3.8,PyTorch1.10.1,CUDA11.3配置:Intel®Xeon®Gold6226RCPU@2.90GHz×64TeslaT4/PCIe/SSE2*4原作者提出的安装依赖项如下condacreate-ncompletionformerpython=3.8condaactivatecompletionformer......