技术标签: 杭电计算机组成原理课程设计
选以下4种系统结构之一,设计一个MIPS单周期R-CPU
(1)不带状态寄存器,8条指令
(2)带状态寄存器,8条指令
(3)不带状态寄存器,9条指令(多了sll)
(4)带状态寄存器,9条指令(多了sll)
本文选取第4种结构进行设计
具体步骤
实验流程图
R型指令的控制信号
地址 | 机器代码 | 汇编指令 | 执行结果 |
---|---|---|---|
[0x00400000] | 0x00004827 | nor $9, $0, $0 | R9 (t1) = ffffffff |
[0x00400004] | 0x0009502b | sltu $10, $0, $9 | R10 (t2) = 00000001 |
[0x00400008] | 0x012a5822 | sub $11, $9, $10 | R11 (t3) = fffffffe |
[0x0040000c] | 0x012b6022 | sub $12, $9, $11 | R12 (t4) = 00000001 |
[0x00400010] | 0x014c6820 | add $13, $10, $12 | R13 (t5) = 00000002 |
[0x00400014] | 0x01a97004 | sllv $14, $9, $13 | R14 (t6) = fffffffc |
[0x00400018] | 0x01ad7804 | sllv $15, $13, $13 | R15 (t7) = 00000008 |
[0x0040001c] | 0x01eac020 | add $24, $15, $10 | R24 (t8) = 00000009 |
[0x00400020] | 0x030bc825 | or $25, $24, $11 | R25 (t9) = ffffffff |
[0x00400024] | 0x01798826 | xor $17, $11, $25 | R17 (s1) = 00000001 |
[0x00400028] | 0x01d89024 | and $18, $14, $24 | R18 (s2) = 00000008 |
[0x0040002c] | 0x02299820 | add $19, $17, $9 | R19 (s3) = 00000000 |
[0x00400030] | 0x0253a025 | or $20, $18, $19 | R20 (s4) = 00000008 |
[0x00400034] | 0x01b1a804 | sllv $21, $17, $13 | R21 (s5) = 00000004 |
[0x00400038] | 0x02b1b004 | sllv $22, $17, $21 | R22 (s6) = 00000010 |
[0x0040003c] | 0x016eb820 | add $23, $11, $14 | R23 (s7) = fffffffa |
[0x00400040] | 0x0009f880 | sll $31, $9, 2 | R31 (ra) = fffffffc |
.coe文件内容
memory_initialization_radix=16;
memory_initialization_vector=00004827,0009502b,012a5822,012b6022,014c6820,01a97004,01ad7804,01eac020,030bc825,01798826,01d89024,02299820,0253a025,01b1a804,02b1b004,016eb820,0009f880,00000820,00010fff,20006789,ffff0000,0000ffff,88888888,99999999,aaaaaaaa,bbbbbbbb,12345678,23456789,3456789a,456789ab,56789abc,6789abcd,00000820,00632020,00010fff,20006789,ffff0000,0000ffff,88888888,99999999,aaaaaaaa,bbbbbbbb,12345678,23456789,3456789a,456789ab,56789abc,6789abcd,00000820,00632020,00010fff,20006789,ffff0000,0000ffff,88888888,99999999,aaaaaaaa,bbbbbbbb,12345678,23456789,3456789a,456789ab,56789abc,6789abcd;
.coe文件内容由汇编语言翻译而来,详情见 MIPS汇编器与模拟器实验
根据.coe文件创建IP核,IP核的创建详情见 ISE IP核创建教程
module R_CPU(
clk,rst,
Inst_code,PC,
opcode,rs,rt,rd,shamt,func,
ALU_F,FR_ZF,FR_OF,ALU_OP,
rs_shamt,ALU_A
);
input clk;//时钟
input rst;//清零
output reg [31:0]PC;//PC地址
output [31:0]Inst_code;//取出的指令
output [5:0]opcode,func;//指令分段
output [4:0]rs,rt,rd,shamt;//指令分段
output [31:0] ALU_F;//ALU结果
output reg [2:0] ALU_OP;//ALU运算的OP
output reg FR_ZF; //ZF储存结果
output reg FR_OF;//OF储存结果
output [31:0]ALU_A; //ALU运算时A的数据
output reg rs_shamt; //控制ALU的A输入数据的信号
module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk);
input clk;//写入时钟信号
input rst;//清零信号
input Write_Reg;//写控制信号
input [4:0]R_Addr_A;//A端口读寄存器地址
input [4:0]R_Addr_B;//B端口读寄存器地址
input [4:0]W_Addr;//写寄存器地址
input [31:0]W_Data;//写入数据
output [31:0]R_Data_A;//A端口读出数据
output [31:0]R_Data_B;//B端口读出数据
module ALU(ALU_OP,A,B,F,ZF,OF);
input [2:0] ALU_OP;//控制ALU运算类型的OP
input [31:0] A; //ALU运算数据A
input [31:0] B; //ALU运算数据B
output [31:0] F; //ALU运算结果F
output ZF; //零标志位
output OF; //溢出标志位
Inst_code表示当前OP地址中的指令
PC表示当前OP地址
Opcode,rs,rt,rd,shamt,func皆为指令分段
ALU_F为ALU运算结果
FR_ZF,FR_OF储存ALU运算得出的ZF,OF
ALU_OP为当前ALU运算的操作码
Rs_shamt控制当前是否使用shamt进行移位
ALU_A为当前ALU的A口输入数据
Clk为时钟信号,rst为复位信号
module R_CPU(
clk,rst,
Inst_code,PC,
opcode,rs,rt,rd,shamt,func,
ALU_F,FR_ZF,FR_OF,ALU_OP,
rs_shamt,ALU_A
);
input clk;//时钟
input rst;//清零
output reg [31:0]PC;//地址
wire [31:0]PC_new;
output [31:0]Inst_code;//取出的指令
output [5:0]opcode,func;//指令分段
output [4:0]rs,rt,rd,shamt;//指令分段
wire [15:0]imm,offset;//指令分段
wire [25:0]address;//指令分段
output [31:0] ALU_F;//ALU结果
output reg [2:0] ALU_OP;//ALU结果
output reg FR_ZF;
output reg FR_OF;
wire ZF,OF;
output [31:0]ALU_A;
reg Write_Reg;
wire [31:0]R_Data_A;
wire [31:0]R_Data_B;
reg Set_ZF;
reg Set_OF;
wire [31:0]shamt_kz;
output reg rs_shamt;
assign shamt_kz={
{
16{
1'b0}},shamt};
initial PC = 32'h00000000;
assign PC_new = PC + 4;
Inst_Rom ROM2 (
.clka(clk), // input clka
.addra(PC[7:2]), // input [5 : 0] addra
.douta(Inst_code) // output [31 : 0] douta
);
always @(negedge clk or posedge rst)
begin
if (rst)
PC = 32'h00000000; //PC复位;
else
PC = PC_new; //PC更新为PC+4;
end;
assign opcode = Inst_code[31:26];
assign rs = Inst_code[25:21];
assign rt = Inst_code[20:16];
assign rd= Inst_code[15:11];
assign shamt = Inst_code[10:6];
assign func = Inst_code[5:0];
always @(*)
begin
ALU_OP = 3'b000;
Write_Reg = 1'b0;
rs_shamt=1'b0;
if (opcode==6'b000000) //R指令
begin
Write_Reg = 1'b1; //结果送寄存器
case (func)
6'b100000:begin ALU_OP=3'b100;Set_ZF=1;Set_OF=1; end
6'b100010:begin ALU_OP=3'b101;Set_ZF=1;Set_OF=1; end
6'b100100:begin ALU_OP=3'b000;Set_ZF=1;Set_OF=0; end
6'b100101:begin ALU_OP=3'b001;Set_ZF=1;Set_OF=0; end
6'b100110:begin ALU_OP=3'b010;Set_ZF=1;Set_OF=0; end
6'b100111:begin ALU_OP=3'b011;Set_ZF=1;Set_OF=0; end
6'b101011:begin ALU_OP=3'b110;Set_ZF=1;Set_OF=0; end
6'b000100:begin ALU_OP=3'b111;Set_ZF=1;Set_OF=0; end
6'b000000:begin ALU_OP=3'b111;Set_ZF=1;Set_OF=0;rs_shamt=1'b1; end
endcase
end
end;
REGS REGS_1(R_Data_A,R_Data_B,ALU_F,rs,rt,rd,Write_Reg,rst,~clk);
assign ALU_A = (rs_shamt)?shamt_kz:R_Data_A;
ALU ALU_1(ALU_OP,ALU_A,R_Data_B,ALU_F,ZF,OF);
always @(negedge clk or posedge rst)
if (rst)
begin
FR_OF <= 1'b0;
FR_ZF <= 1'b0;
end
else
begin
if (Set_ZF)
FR_ZF <= ZF;
if (Set_OF)
FR_OF <= OF;
end
endmodule
module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk);
input clk;//写入时钟信号
input rst;//清零信号
input Write_Reg;//写控制信号
input [4:0]R_Addr_A;//A端口读寄存器地址
input [4:0]R_Addr_B;//B端口读寄存器地址
input [4:0]W_Addr;//写寄存器地址
input [31:0]W_Data;//写入数据
output [31:0]R_Data_A;//A端口读出数据
output [31:0]R_Data_B;//B端口读出数据
integer i;
reg [31:0] REG_Files[0:31];
initial
for(i=0;i<32;i=i+1) REG_Files[i]<=0;
[email protected](posedge clk or posedge rst)
begin
if(rst)
for(i=0;i<32;i=i+1) REG_Files[i]<=0;
else
if(Write_Reg&&W_Addr!=32'd0) REG_Files[W_Addr]<=W_Data;
end
assign R_Data_A=REG_Files[R_Addr_A];
assign R_Data_B=REG_Files[R_Addr_B];
endmodule
module ALU(ALU_OP,A,B,F,ZF,OF);
input [2:0] ALU_OP;
input [31:0] A;
input [31:0] B;
output [31:0] F;
output ZF;
output OF;
reg [31:0] F;
reg C,ZF;
[email protected](*)
begin
C=0;
case(ALU_OP)
3'b000:begin F=A&B; end
3'b001:begin F=A|B; end
3'b010:begin F=A^B; end
3'b011:begin F=~(A|B); end
3'b100:begin {
C,F}=A+B; end
3'b101:begin {
C,F}=A-B; end
3'b110:begin F=A<B; end
3'b111:begin F=B<<A; end
endcase
ZF = F==0;
end
assign OF = ((ALU_OP==3'b100)||(ALU_OP==3'b101))&&(A[31] ^ B[31] ^ F[31] ^ C);
endmodule
always #50 clk=~clk;
initial begin
// Initialize Inputs
clk=0;
rst=1;
#5;
rst = 0;
end
endmodule
sll rd, rt, shamt 指令将 rt 寄存器的数据进行逻辑左移,左移的位数则是由字段shamt 指定。试着实现该指令,谈谈你的实现方法。
答:加入rs_shamt信号,控制位移量是rs地址数据还是shamt。
assign ALU_A = (rs_shamt)?shamt_kz:R_Data_A;
ALU ALU_1(ALU_OP,ALU_A,R_Data_B,ALU_F,ZF,OF);
在case(func)中加入:
6’b000000:begin ALU_OP=3’b111;Set_ZF=1;Set_OF=0;rs_shamt=1’b1; end
本实验实现的 sltu 指令是对无符号数的比较置位指令,如果需要实现有符号数的比较置位指令——slt 指令,请问应该如何实现?
答:若想实现有符号数的比较置位指令,可以先根据有符号数的最高位进行分类:
若两正,则和无符号数比较置位无异,若一正一负,则可轻易得出结论。若两负,则将余下位数进行比较置位,再将结果取反即可。
srav 是对(有符号)数据的算术右移指令,考虑如何实现它?
答:读取数据符号位,设右移位数为n,从数据最右边开始,将其每一位覆盖为其左边n位的数的数值,当其左边n位数不存在时,改为复制符号位即可。
在所设计的CPU基础上,添加一个输入设备(逻辑开关)和一个输出设备(LED 灯),假如直接用指令来实现输入输出功能,输入指令 in 和输出指令 out 的格式也是 R 型指令,
请画出修改后的系统结构图,并写出这两条指令对应令对应的控制信号。
设IN和OUT的func分别为110000,110001
输入输出对应的设备号由rs的低2位控制
IO_R=1时,执行输入指令
IO_W=1时,执行输出指令
增加信号alu_IO_s,控制寄存器W_Data的写入数据。
alu_IO_s=1时,数据由输入设备输入,为0时,数据由ALU运算结果输入。
之前做了个时间日历比较简单的把,如果要加价格什么的也可以稍微看着加加,之前写过这样的一个博客,只不过那个照片太丑然后又有点变化,就重新写过了。如图那个时间点是入口。这个呢是未选中的样子。这个是选了连续的样式,这个是选了好多个时间的样式。其实还有些中间不可选的样式,只不过是调接口获取的,不过接口已经挂了所以就没办法显示出来了,大概就是有些已经满课的然后选的时间范围内有满课的就提示这个时间段不能选,接下来就是展示代码的时刻了。首先还是看view<view class="page"..
自iOS8以来新出的WKWebView,大大优化了UIWebView的内存飙升问题,使得开发者迫不及待的用它来替换掉UIWebView,iOS8刚出,作者我就赶紧把项目里的webView都替换成WKWebView了,然而....当我替换完后发现...我去!WKWebView并没有清除缓存的功能,即使使用了以下代码:NSHTTPCookie *cookie;NSHTTPCookieStorag
DOM解析是把文档所有内容都加载进内存,解析成DOM树,有根节点(Element)、子孙节点,文本节点(Text),属性节点(Attr)。SAX解析是从上往下读一行解析一行,不能往回读。优缺点:DOM占用内存比较多,适合做CRUD(create,read,update,delete);SAX速度快,对内存几乎没压力,只适合做读操作。
常用的java 发送http请求的方式有两种1、通过HttpsURLConnection 自己去发送请求2、 用spring框架提供的RestTemplate (import org.springframework.web.client.RestTemplate;) 对象发送请求第一种方式配置代理服务器关键代码: int PROXY_PORT = 80;// 改成你自己的代理服务器端口 String PROXY_HOST = "127.0.0.1";// 改成你自己的代理...
第一看: 看子孙睡到几点,假如睡到太阳都已经升得很高的时候才起来,那代表这个家族会慢慢懈怠下来; 第二看: 看子孙有没有做家务,因为勤劳、劳动的习惯影响一个人一辈子; 第三看: 看后代子孙有没有在读圣贤的经典,"人不学,不知义,不知道"。 畅游史海,可以看到"盛不过三代"是大多数官宦之家很难逾越的魔咒。而曾氏家族却代有英才层出不穷,出现了
为什么80%的码农都做不了架构师?>>> ...
今天下载了一个软件,解压后即可直接使用,可是每次都要到软件所在目录下执行,比较麻烦。于是看了看,发现可以在桌面增加启动器,这样就可以双击桌面的图标运行程序;但是如果能增加到应用程序菜单中,那就更方便了。研究了一下已有的desktop文件,找到了方法,以我下载的psq软件为例,我将下载的psq软件解压到/usr/share文件夹内。1、首先建立可执行(脚本)程序的连接到/usr/bin文件夹sudo
linux 行长度I have a text file with many lines of text. 我有一个包含多行文本的文本文件。 In Linux, how to sort the lines by their length? 在Linux中 ,如何按行长排序? You can make use of awk together with the sort program like 您...
JVM运行时的内存块pc寄存器:(线程独有)保存线程运行的java方法地址Java 虚拟接栈(线程独有):用于存储线程的栈帧Java堆(全局共享):随着Java虚拟机的启动 创建 存储着所有对象的实例以及数组对象,而且内置gc(垃圾回收机制)方法区:运行常量池本地方法栈:线程独有。在jvm中gc(垃圾回收机制)是Java立足点之一。垃圾自动回收可以让Java程...
1.首先我们打开VBA编程的界面,在工程资源管理器中右键添加类模块,并且命名为person,这样我们就创建了一个类2.接下来,我们要在类里面填加字段来保存内容,最好使用的是private,如果使用public所保存的内容就没有约束性Private sname As String '姓名Private sgender As String '性别Private sage As String '年龄3....
【最初做法】1. 跟平时一样写Spring Boot的Controller2. X5页面使用Ajax调用3. 处理跨域请求问题【初步结果】第一个调用的是登录接口,没有问题第二个是查询列表,可是浏览器控制台打印的结果是EasyWeb中的登录页代码(也就是需要重新登录)【问题分析】打开Network查看请求信息可以看到的是后面的请求并没有带上cookie...
文章目录intro构建工具:解放程序员的双手构建一个软件项目通常包含下面的一步或多步。Maven 的好处Maven 能够提供的信息如下。Maven的命根子pom.xml文件Maven 如何使用 POM 文件?POM 文件构建生命周期、构建阶段、构建目标依赖和仓库构建插件构建配置文件pom.xml文件案例Maven的目录结构Maven 的生命周期构建生命周期构建阶段构建目标Maven 项目快速创建使用「原型(Archetype)」快速 创建 Maven 项目运行 maven 项目Maven pom快速配置Ma