热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【学习笔记】RISC架构下的存储程序机电路设计深入解析(第五部分)

在本篇学习笔记中,我们将继续深入探讨RISC架构下存储程序机的电路设计。通过详细分析关键组件的工作原理和设计方法,旨在为读者提供更全面的技术理解和实践指导。本部分将重点讨论指令执行流程、数据通路设计以及控制单元的优化策略,进一步提升系统的性能和效率。

前言

继续来~~~~~~~~~~~~~~~~~~~~~~

 

【读书笔记】RISC存储程序机的电路设计(1)

【读书笔记】RISC存储程序机的电路设计(2)

【读书笔记】RISC存储程序机的电路设计(3)

【读书笔记】RISC存储程序机的电路设计(4)

【读书笔记】RISC存储程序机的电路设计(5)

【读书笔记】RISC存储程序机的电路设计(6)

 

图放好~~~~~~~~~~~~~~~~~~~~~~

我这个顺序说实话没有太掌握好,应该在前面就把Processor的代码贴全的,不过没关系,经过前面的完整分析,我们已经直接拼出来Processor的代码啦,进而得到全部编码。


Processor完整代码


子模块

所有需要的子模块代码:

`ifndef PROC_UNIT
`define PROC_UNITmodule reg_unit #(`include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] data_out,input [WORD_WD -1:0] data_in,input load, clk, rst_n
);always &#64;(posedge clk)beginif(rst_n &#61;&#61; 1&#39;b0)begindata_out <&#61; {WORD_WD{1&#39;b0}};endelse if(load &#61;&#61; 1&#39;b1)beginif(DISPLAY_EN &#61;&#61; 1) $display("%0t, %m, data_out update to &#39;b%8b(&#39;h%2h-&#39;d%0d)", $realtime, data_in, data_in, data_in);data_out <&#61; data_in;endelse begindata_out <&#61; data_out;endendendmodule//: reg_unitmodule program_count #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] count_out,input [WORD_WD -1:0] count_in,input load, incr, clk, rst_n
);always &#64;(posedge clk)beginif(rst_n &#61;&#61; 1&#39;b0)begincount_out <&#61; {WORD_WD{1&#39;b0}};endelse if(load &#61;&#61; 1&#39;b1)begincount_out <&#61; count_in;endelse if(incr &#61;&#61; 1&#39;b1)begincount_out <&#61; count_out &#43; &#39;h1;endelse begincount_out <&#61; count_out;endendendmodule//: program_countmodule mux_5sel1 #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] mux_out,input [WORD_WD -1:0] mux_in0, mux_in1, mux_in2, mux_in3, mux_in4,input [SEL1_WD -1:0] sel
);always &#64;(*)begincase(sel)&#39;h0: mux_out &#61; mux_in0;&#39;h1: mux_out &#61; mux_in1;&#39;h2: mux_out &#61; mux_in2;&#39;h3: mux_out &#61; mux_in3;&#39;h4: mux_out &#61; mux_in4;default: mux_out &#61; {WORD_WD{1&#39;bx}};endcase endendmodule//: mux_5sel1module mux_3sel1 #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] mux_out,input [WORD_WD -1:0] mux_in0, mux_in1, mux_in2,input [SEL2_WD -1:0] sel
);always &#64;(*)begincase(sel)&#39;h0: mux_out &#61; mux_in0;&#39;h1: mux_out &#61; mux_in1;&#39;h2: mux_out &#61; mux_in2;default: mux_out &#61; {WORD_WD{1&#39;bx}};endcase endendmodule//: mux_3sel1module alu_unit #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output reg [WORD_WD -1:0] alu_out,output zero_flag,input [WORD_WD -1:0] alu_in1, alu_in2,input [OPCODE_WD -1:0] opcode
);always &#64;(*)begincase(opcode)NOP: alu_out &#61; &#39;h0;ADD: alu_out &#61; alu_in2 &#43; alu_in1;SUB: alu_out &#61; alu_in2 - alu_in1; AND: alu_out &#61; alu_in2 & alu_in1;NOT: alu_out &#61; ~alu_in2;default:alu_out &#61; &#39;hx;endcaseendassign zero_flag &#61; ~(|alu_out);endmodule//: alu_unit
&#96;endif

Processor层代码

&#96;ifndef PROCESSING_UNIT
&#96;define PROCESSING_UNITmodule processing_unit #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(output [WORD_WD -1:0] instruction ,//to ctloutput zero_flag ,//to ctloutput [ADDR_WD -1:0] addr ,//to mem, addressoutput [WORD_WD -1:0] bus1 ,//to mem, data_ininput [WORD_WD -1:0] mem_word ,//from mem, data_outinput load_R0, load_R1, load_R2, load_R3,input load_PC, input load_IR,input load_reg_Y,input load_reg_Z,input load_add_R,input inc_PC,input [SEL1_WD -1:0] mux1_sel_to_bus1,input [SEL2_WD -1:0] mux2_sel_to_bus2,input clk, rst_n
);wire [WORD_WD -1:0] bus2;wire [WORD_WD -1:0] R0_out, R1_out, R2_out, R3_out;wire [WORD_WD -1:0] alu_out;wire [WORD_WD -1:0] Y_out;wire [WORD_WD -1:0] PC_out;wire alu_zero_flag; wire [OPCODE_WD -1:0] opcode;assign opcode &#61; instruction[(WORD_WD -1) : (WORD_WD -OPCODE_WD)];reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R0(.data_out(R0_out), .data_in(bus2), .load(load_R0), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R1(.data_out(R1_out), .data_in(bus2), .load(load_R1), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R2(.data_out(R2_out), .data_in(bus2), .load(load_R2), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_R3(.data_out(R3_out), .data_in(bus2), .load(load_R3), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_REG_Y(.data_out(Y_out), .data_in(bus2), .load(load_reg_Y), .clk(clk), .rst_n(rst_n)); reg_unit #(.WORD_WD(1)) U_REG_Z(.data_out(zero_flag), .data_in(alu_zero_flag), .load(load_reg_Z), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_IR(.data_out(instruction), .data_in(bus2), .load(load_IR), .clk(clk), .rst_n(rst_n));reg_unit #(.WORD_WD(WORD_WD), .DISPLAY_EN(1)) U_ADD_R(.data_out(addr), .data_in(bus2), .load(load_add_R), .clk(clk), .rst_n(rst_n));program_count #(.WORD_WD(WORD_WD)) U_PC(.count_out(PC_out), .count_in(bus2), .load(load_PC), .incr(inc_PC), .clk(clk), .rst_n(rst_n));mux_5sel1 #(.WORD_WD(WORD_WD), .SEL1_WD(SEL1_WD)) U_MUX1(.mux_out(bus1), .mux_in0(R0_out), .mux_in1(R1_out), .mux_in2(R2_out), .mux_in3(R3_out),.mux_in4(PC_out),.sel(mux1_sel_to_bus1));mux_3sel1 #(.WORD_WD(WORD_WD), .SEL1_WD(SEL2_WD)) U_MUX2(.mux_out(bus2), .mux_in0(alu_out), .mux_in1(bus1), .mux_in2(mem_word), .sel(mux2_sel_to_bus2));alu_unit #(.WORD_WD(WORD_WD), .OPCODE_WD(OPCODE_WD)) U_ALU(.alu_out(alu_out),.zero_flag(alu_zero_flag),.alu_in1(Y_out),.alu_in2(bus1),.opcode(opcode));
endmodule//: processing_unit&#96;endif

感觉这代码写的还是挺好看的&#xff0c;甚至不需要做太多解释&#xff0c;具体实现可以参考1。


顶层代码

已经完成全部子模块代码了&#xff0c;那么就可以直接拼接定层了&#xff0c;先把参数文件贴一下&#xff1a;

parameter WORD_WD &#61; 8,
parameter MEM_SIZE &#61; 256,
parameter ADDR_WD &#61; $clog2(MEM_SIZE),
parameter OPCODE_NUM &#61; 9,
parameter OPCODE_WD &#61; $clog2(OPCODE_NUM),
parameter SRC_WD &#61; 2,
parameter DEST_WD &#61; 2,parameter SEL1_NUM &#61; 5,
parameter SEL2_NUM &#61; 3,
parameter SEL1_WD &#61; $clog2(SEL1_NUM),
parameter SEL2_WD &#61; $clog2(SEL2_NUM),parameter NOP &#61; &#39;b0000,
parameter ADD &#61; &#39;b0001,
parameter SUB &#61; &#39;b0010,
parameter AND &#61; &#39;b0011,
parameter NOT &#61; &#39;b0100,
parameter RD &#61; &#39;b0101,
parameter WR &#61; &#39;b0110,
parameter BR &#61; &#39;b0111,
parameter BRZ &#61; &#39;b0111,parameter STATE_NUM &#61; 12,
parameter STATE_WD &#61; $clog2(STATE_NUM),
parameter S_IDLE &#61; &#39;h0,
parameter S_FET1 &#61; &#39;h1,
parameter S_FET2 &#61; &#39;h2,
parameter S_DEC &#61; &#39;h3,
parameter S_EX1 &#61; &#39;h4,
parameter S_RD1 &#61; &#39;h5,
parameter S_RD2 &#61; &#39;h6,
parameter S_WR1 &#61; &#39;h7,
parameter S_WR2 &#61; &#39;h8,
parameter S_BR1 &#61; &#39;h9,
parameter S_BR2 &#61; &#39;ha,
parameter S_HALT &#61; &#39;hb,parameter SEL_R0 &#61; 0,
parameter SEL_R1 &#61; 1,
parameter SEL_R2 &#61; 2,
parameter SEL_R3 &#61; 3,parameter DISPLAY_EN &#61; 0

接下来就是定层代码&#xff1a;

module RISC_SPM #(&#96;include "C:/Users/gaoji/Desktop/RISC_SPM/src/para_def.v"
)(input clk, rst_n
);wire ctrl2proc_load_R0;wire ctrl2proc_load_R1;wire ctrl2proc_load_R2;wire ctrl2proc_load_R3;wire ctrl2proc_load_PC;wire ctrl2proc_load_IR;wire ctrl2proc_load_reg_Y;wire ctrl2proc_load_reg_Z;wire ctrl2proc_load_add_R;wire ctrl2proc_inc_PC;wire [SEL1_WD -1:0] ctrl2proc_mux1_sel_to_bus1;wire [SEL2_WD -1:0] ctrl2proc_mux2_sel_to_bus2;wire ctrl2mem_write;wire [WORD_WD -1:0] mem2proc_data;wire [WORD_WD -1:0] proc2ctrl_instruction;wire proc2ctrl_zero_flag;wire [ADDR_WD -1:0] proc2mem_addr;wire [WORD_WD -1:0] proc2mem_data;ctrl_unit U_CTRL(.load_R0(ctrl2proc_load_R0), .load_R1(ctrl2proc_load_R1), .load_R2(ctrl2proc_load_R2), .load_R3(ctrl2proc_load_R3),.load_PC(ctrl2proc_load_PC), .load_IR(ctrl2proc_load_IR),.load_reg_Y(ctrl2proc_load_reg_Y),.load_reg_Z(ctrl2proc_load_reg_Z),.load_add_R(ctrl2proc_load_add_R),.inc_PC(ctrl2proc_inc_PC), .mux1_sel_to_bus1(ctrl2proc_mux1_sel_to_bus1),.mux2_sel_to_bus2(ctrl2proc_mux2_sel_to_bus2),.write(ctrl2mem_write),.instruction(proc2ctrl_instruction),.zero_flag(proc2ctrl_zero_flag),.clk(clk),.rst_n(rst_n));processing_unit U_PROCESSING(.instruction(proc2ctrl_instruction),.zero_flag(proc2ctrl_zero_flag),.addr(proc2mem_addr),.bus1(proc2mem_data),.mem_word(mem2proc_data),.load_R0(ctrl2proc_load_R0), .load_R1(ctrl2proc_load_R1), .load_R2(ctrl2proc_load_R2), .load_R3(ctrl2proc_load_R3),.load_PC(ctrl2proc_load_PC), .load_IR(ctrl2proc_load_IR),.load_reg_Y(ctrl2proc_load_reg_Y),.load_reg_Z(ctrl2proc_load_reg_Z),.load_add_R(ctrl2proc_load_add_R),.inc_PC(ctrl2proc_inc_PC),.mux1_sel_to_bus1(ctrl2proc_mux1_sel_to_bus1),.mux2_sel_to_bus2(ctrl2proc_mux2_sel_to_bus2),.clk(clk), .rst_n(rst_n));mem_unit #(.DISPLAY_EN(1)) U_MEM(.data_out(mem2proc_data),.data_in(proc2mem_data),.addr_in(proc2mem_addr),.write_en(ctrl2mem_write),.clk(clk),.rst_n(rst_n));endmodule

可以很清楚的看到&#xff0c;定层只有两个接口信号&#xff1a;clk和rst_n&#xff0c;也就是说软件与处理器交互&#xff0c;全部都是通过mem中存储指令&#xff0c;再从mem中读取结果来完成的。


推荐阅读
  • 探讨了一个关于Windows C++开发中遇到的乱码问题,特别是在处理宽字符时出现的情况。本文通过一个具体的示例——一个简单的窗口应用程序,展示了如何正确地使用宽字符以避免乱码。 ... [详细]
  • 本文详细介绍了 C# 编程语言中 Main 方法的作用、不同形式及其使用场景,帮助开发者更好地理解和应用这一重要概念。 ... [详细]
  • 学习目的:1.了解android线程的使用2.了解主线程与子线程区别3.解析异步处理机制主线程与子线程:所谓主线程,在Windows窗体应用程序中一般指UI线程,这个是程序启动的时 ... [详细]
  • 本文针对公司项目中普遍存在的IE浏览器兼容性问题,特别是IE9及以下版本,提出了具体的解决方案,确保用户在这些旧版浏览器中也能顺利实现图片上传预览功能。 ... [详细]
  • 手把手教你构建简易JSON解析器
    本文将带你深入了解JSON解析器的构建过程,通过实践掌握JSON解析的基本原理。适合所有对数据解析感兴趣的开发者。 ... [详细]
  • 本文将详细介绍如何使用ViewPager实现多页面滑动切换,并探讨如何去掉其默认的左右切换动画效果。ViewPager是Android开发中常用的组件之一,用于实现屏幕间的内容切换。 ... [详细]
  • 本文探讨了如何利用自定义URI方案和注册表编辑,在Windows操作系统中实现从Web浏览器启动本地应用程序的方法,同时强调了这一过程中的安全考虑。 ... [详细]
  • 本文详细介绍了RocketMQ中的消息并发消费机制,包括消息拉取后的处理流程、消费服务的调用以及消费任务的具体执行过程。 ... [详细]
  • DP:InitiallyIthinkof1DDP,dp[i]standsfortheshorteststringoffirsticharacters,then:dp[i]minLe ... [详细]
  • 题目描述:孩子们围坐在一起,分享水果,场面温馨。然而,由于孩子们身高不同,排队时显得高低不齐。给定孩子们的身高序列,通过交换某些孩子的顺序,计算每次交换后的序列混乱度。 ... [详细]
  • 大数据核心技术解析
    本文深入探讨了大数据技术的关键领域,包括数据的收集、预处理、存储管理、以及分析挖掘等方面,旨在提供一个全面的技术框架理解。 ... [详细]
  • 本文介绍了一个基于 div 标签设计的宿舍管理系统登录页面,包括用户身份选择、记住我功能以及错误信息提示。 ... [详细]
  • 在软件开发中,对象的状态频繁变化是常见现象。如何高效地管理这些状态的变化,并确保系统的高层模块保持稳定?本文探讨了状态模式作为一种有效的解决方案,介绍了其原理和实现方法。 ... [详细]
  • 本文详细介绍了Oracle数据库的基本架构,包括数据文件和内存结构的概念。文章重点解释了Oracle实例的组成部分,如系统全局内存区域(SGA)和后台进程,以及客户端进程与服务器进程的交互方式。此外,还探讨了SGA中的共享池、库高速缓存、锁存器及SGA缓冲区缓存等关键组件的功能和运作机制。 ... [详细]
  • Java类加载详解(类的生命周期)
    https:www.cnblogs.comjhxxbp10900405.html类从被加载到虚拟机内存开始,到卸载出内存为止。解析阶段在某些情况下可以在初始化后再 ... [详细]
author-avatar
高玉成
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有