高密做网站哪家好代理,html编辑器dw,招聘网页模板,怎么制作网站的网页设计0 回顾
之前#xff0c;我们完成了17条R型指令的设计#xff0c;接下来#xff0c;我们逐步完成I型指令的设计。
1 核心思想#xff1a;增量思维 复用思维 学会选择 分治思想
增量思维
我们从无到有#xff0c;构建了支持R型指令的CPU#xff0c;接…0 回顾
之前我们完成了17条R型指令的设计接下来我们逐步完成I型指令的设计。
1 核心思想增量思维 复用思维 学会选择 分治思想
增量思维
我们从无到有构建了支持R型指令的CPU接下来还会完成I型指令J型指令这样单周期CPU就完成了之后我们会将其改进为多周期CPU也会改进为五级流水线CPU之后可能需要提升性能增加串口将内存移出去增加内存控制器增加指令Cache和数据Cache……让我们慢慢启程吧
复用思维 学会选择
人生皆选择CPU也一样同样的一个功能复用同一个器件输入却可能不同而控制器就帮其做出选择配合多路选择器完成这个选择
分治思想
我们每一次都是完成一类指令我们将一类具备共同特征的指令抽出来一起来完成它提高效率
2 第一类I型指令
这些指令是R型指令的立即数操作。
I-类型oprsrtimmediateaddi001000rsrtimmediateaddiu001001rsrtimmediateandi001100rsrtimmediateori001101rsrtimmediatexori001110rsrtimmediatelui00111100000rtimmediateslti001010rsrtimmediatesltiu001011rsrtimmediate
它们共同的操作都是 rt - rs op imm
特别的lui比较特殊直接将imm移动到32位高16位低16位补0.
另外16位的imm需要扩展可能是0扩展也可能是符号扩展根据不同的指令进行不同判断即可。
然后我们看看这些操作需要增加的器件和控制信号再进行设计即可这个过程已经做了好多遍了这里可以直接加速完成不再细说了。 这里还需要一个额外的控制信号表明是0扩展还是符号扩展我们使用Zero_sign_ex
00扩展1符号扩展
还有Lui信号表明是lui指令输入到ALU。 这是新的数据通路我们在设计的时候
将immALUSrcZero_sign_ex集成到ALU中将RegDst集成到Reg Files中
3 设计
3.1 控制器
特别注意RegDst 信号
0rt I类指令1rd R类指令
instructionopALUopRegWriteSftmdJrnLuiRegDstALUSrcZero_sign_exaddi00100000001000011addiu00100100011000011andi00110001001000010ori00110101011000010xori00111001101000010lui00111111011001010slti00101010001000011sltiu00101110011000010
timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/14 22:30:48
// Design Name:
// Module Name: control_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module control_1(input [5:0] op,input [5:0] func,output reg RegWrite,output reg Sftmd, // indicate the instruction is sll/srl/sraoutput reg [3:0] ALUop,output reg Jrn, // jr instructionoutput reg Lui, // lui instructionoutput reg RegDst,output reg ALUSrc,output reg Zero_sign_ex);always (*)
begincase(op)6b000000: R-type begincase (func)6b100000: // addbeginRegWrite 1;Sftmd 0;ALUop 4b0000;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b100001: // addubeginRegWrite 1;Sftmd 0;ALUop 4b0001;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b100010: // subbeginRegWrite 1;Sftmd 0;ALUop 4b0010;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b100011: // sububeginRegWrite 1;Sftmd 0;ALUop 4b0011;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b100100: // andbeginRegWrite 1;Sftmd 0;ALUop 4b0100;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b100101: // orbeginRegWrite 1;Sftmd 0;ALUop 4b0101;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b100110: // xorbeginRegWrite 1;Sftmd 0;ALUop 4b0110;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b100111: // norbeginRegWrite 1;Sftmd 0;ALUop 4b0111;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b101010: // sltbeginRegWrite 1;Sftmd 0;ALUop 4b1000;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b101011: // sltubeginRegWrite 1;Sftmd 0;ALUop 4b1001;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b000100: // sllvbeginRegWrite 1;Sftmd 0;ALUop 4b1010;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b000110: // srlvbeginRegWrite 1;Sftmd 0;ALUop 4b1011;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b000111: // sravbeginRegWrite 1;Sftmd 0;ALUop 4b1100;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b000000: // sllbeginRegWrite 1;Sftmd 1;ALUop 4b1010;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b000010: // srlbeginRegWrite 1;Sftmd 1;ALUop 4b1011;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b000011: // srabeginRegWrite 1;Sftmd 1;ALUop 4b1100;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;end6b001000: // jrbeginRegWrite 0;Sftmd 0;ALUop 4b1111;Jrn 1;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;enddefault:beginRegWrite 0;Sftmd 0;ALUop 4b1111;Jrn 0;Lui 0;RegDst 1;ALUSrc 0;Zero_sign_ex 0;endendcaseend/*************** I-type ***************/6b001000: // addibeginALUop 4b0000;RegWrite 1;Sftmd 0;Jrn 0;Lui 0;RegDst 0;ALUSrc 1;Zero_sign_ex 1;end6b001001: // addiubeginALUop 4b0001;RegWrite 1;Sftmd 0;Jrn 0;Lui 0;RegDst 0;ALUSrc 1;Zero_sign_ex 1;end6b001100: // andibeginALUop 4b0100;RegWrite 1;Sftmd 0;Jrn 0;Lui 0;RegDst 0;ALUSrc 1;Zero_sign_ex 0;end6b001101: // oribeginALUop 4b0101;RegWrite 1;Sftmd 0;Jrn 0;Lui 0;RegDst 0;ALUSrc 1;Zero_sign_ex 0;end6b001110: // xoribeginALUop 4b0110;RegWrite 1;Sftmd 0;Jrn 0;Lui 0;RegDst 0;ALUSrc 1;Zero_sign_ex 0;end6b001111: // lui note beginALUop 4b1101;RegWrite 1;Sftmd 0;Jrn 0;Lui 1;RegDst 0;ALUSrc 1;Zero_sign_ex 0;end6b001010: // sltibeginALUop 4b1000;RegWrite 1;Sftmd 0;Jrn 0;Lui 0;RegDst 0;ALUSrc 1;Zero_sign_ex 1;end6b001011: // sltiubeginALUop 4b1001;RegWrite 1;Sftmd 0;Jrn 0;Lui 0;RegDst 0;ALUSrc 1;Zero_sign_ex 0;enddefault:beginRegWrite 0;Sftmd 0;ALUop 4b1111;Jrn 0;Lui 0;RegDst 0;ALUSrc 0;Zero_sign_ex 0;endendcase
endendmodule
3.2 ALU
timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/14 22:30:23
// Design Name:
// Module Name: ALU_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module ALU_1(// datainput [31:0] A,input [31:0] B,input [4:0] shamt,// controlinput [3:0] ALUop,input Sftmd, // shift instruction control/*** I-type ***/input [15:0] imm, // data// controlinput Lui, // 1:lui instructioninput ALUSrc, // 1:imm calculateinput Zero_sign_ex, // 0:zero extension; 1:sign extensionoutput reg [31:0] ALUresult);// convert A and B to signed numbers
wire signed [31:0] A_signed A;
wire signed [31:0] B_signed;
wire signed [31:0] B_signed_origin B; // for sra instruction// for shift instructions
// select data: if (Sftmd 1) input shamt else input rs
wire [31:0] A_or_Shift (Sftmd 0) ? A : {27b0,shamt};/*** I-type: data select ***/// immediate data extension and select
wire [31:0] zero_imm_ex {16b0,imm};
wire [31:0] sign_imm_ex (imm[15] 1)? {16hffff,imm}: {16b0,imm}; // NOTE: 16b1 is incorrect
wire [31:0] imm_input (Zero_sign_ex 0)? zero_imm_ex: sign_imm_ex;// R[rt] or imm extension
wire [31:0] B_select (ALUSrc 0)? B: imm_input;
assign B_signed B_select;/* calculate */
always (*)
begincase (ALUop)4b0000: // add addibeginALUresult A B_select;end4b0001: // addu addiubeginALUresult A B_select;end4b0010: // subbeginALUresult A - B;end4b0011: // sububeginALUresult A - B;end4b0100: // and andibeginALUresult A B_select;end4b0101: // or oribeginALUresult A | B_select;end4b0110: // xor xoribeginALUresult A ^ B_select;end4b0111: // nor noribeginALUresult ~(A | B_select);end4b1000: // slt slti // note:********signed********//beginif(A_signed B_signed)ALUresult 1;elseALUresult 0;end4b1001: // sltu sltiubeginif(A B_select)ALUresult 1;elseALUresult 0;end4b1010: // sllv 10 /*** note: not B_select ***/beginALUresult B A_or_Shift; // NOTE: not A B!end4b1011: // srlvbeginALUresult B A_or_Shift; // NOTE: not A B!end4b1100: // srav // note: ******signed*******//beginALUresult B_signed_origin A_or_Shift; // NOTE: not A_signed B!end4b1101: // luibeginALUresult (Lui 1)? {imm,16b0}: 0;enddefault:beginALUresult 0;endendcase
endendmodule
3.3 Reg Files
timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/14 22:31:09
// Design Name:
// Module Name: reg_files_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module reg_files_1(input clk,input rst_n,/*** read port 1 ***/input [4:0] rA, // rs fieldoutput reg [31:0] A,/*** read port 2 ***/input [4:0] rB, // rtoutput reg [31:0] B,/*** write port ***/input [4:0] rW, // rdinput [31:0] writeData, // datainput RegWrite, // if RegWrite 1,you can write data to reg files/*** I-type input control ***/input RegDst // 1: R-type destination is rd; 0: I-type dst is rt);// reg files
reg [31:0] register [0:31];
integer i;
initial
beginfor (i 0;i 32;i i 1)begin// 为了方便初步测试 ///register[i] i;// register[i] 0;end
end/******* write operation *******/
wire [4:0] rW_select;
assign rW_select (RegDst 1)? rW: rB;always (posedge clk) // sequential logic
beginif(rst_n 0) // reset is invalidbeginif((RegWrite 1b1) (rW_select ! 5b0)) // write is valid and address is not equal zerobeginregister[rW_select] writeData;endelse;endelse;
end/******* rA read operation *******/
always (*) // combinational logic
beginif(rst_n 1)beginA 32b0;endelse if(rA 5b0)beginA 32b0;endelsebeginA register[rA];end
end/******* rB read operation *******/
always (*) // combinational logic
beginif(rst_n 1)beginB 32b0;endelse if(rB 5b0) // $zerobeginB 32b0;endelsebeginB register[rB];end
endendmodule
注意事项需要16位1的写法是16h_FFFF不是16b1缺少的项会被自动补0如果需要16位0只需要16b0即可。
3.4 datapath
timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/27 11:41:34
// Design Name:
// Module Name: datapath_1
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 仅仅实现了几个简单的R类指令的最简单的数据通路不与外界交互
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module datapath_1(input clk,input rst_n,output [31:0] result // 测试syntheses没有输出的模块是恐怖的);/******** PC ********/// pc_1 Inputs
wire Jrn;
wire [31:0] JrPC;// pc_1 Outputs
wire [31:0] pcOld;pc_1 u_pc_1 (.clk ( clk ),.rst_n ( rst_n ),.pcOrigin ( pcOld ),.JrPC ( JrPC ),.Jrn ( Jrn ),.pcOld ( pcOld ));///
/******** Instruction ROM ********/
///// blk_mem_gen_0 Inputs
// wire [13:0] addra pcOld[15:2];// blk_mem_gen_0 Outputs // instructions
wire [31:0] instruction;blk_mem_gen_0 u_blk_mem_gen_0 (.clka ( clk ),.addra ( pcOld[15:2] ),.douta ( instruction ));/
/******** Reg Files ********/
/// reg_files_1 Inputs
wire [31:0] ALUresult;/// wire [4:0] rA instruction[25:21];
/// wire [4:0] rB instruction[20:16];
/// wire [4:0] rW instruction[15:11];
/// wire [31:0] writeData ALUresult;
wire RegWrite;
wire RegDst_in;// reg_files_1 Outputs
wire [31:0] A; // rs
wire [31:0] B; // rt
assign JrPC A;reg_files_1 u_reg_files_1 (.clk ( clk ),.rst_n ( rst_n ),.rA ( instruction[25:21] ),.rB ( instruction[20:16] ),.rW ( instruction[15:11] ),.writeData ( ALUresult ),.RegWrite ( RegWrite ),.RegDst ( RegDst_in ),.A ( A ),.B ( B ));///
/******** ALU ********/
///// ALU_1 Inputs
// wire [31:0] A;
// wire [31:0] B;
wire [3:0] ALUop;
wire Sftmd;wire [15:0] imm instruction[15:0];
wire Lui_in;
wire ALUSrc_in;
wire Zero_sign_ex_in;// ALU_1 Outputs
// wire [31:0] ALUresult writeData; // NoteErrorALU_1 u_ALU_1 (.A ( A ),.B ( B ),.shamt ( instruction[10:6]),.ALUop ( ALUop ),.Sftmd ( Sftmd ),/** I-type **/.imm ( imm ),.Lui ( Lui_in ),.ALUSrc ( ALUSrc_in ),.Zero_sign_ex ( Zero_sign_ex_in ),.ALUresult ( ALUresult ));/
/******** controler ********/
/// control_1 Inputs
// wire [5:0] op instruction[31:26];
// wire [5:0] func instruction[5:0];// control_1 Outputs
// wire RegWrite
// wire [3:0] ALUop;
wire Lui;
wire RegDst;
wire ALUSrc;
wire Zero_sign_ex;assign RegDst_in RegDst; // Send to Reg Files
// send to ALU
assign Lui_in Lui;
assign ALUSrc_in ALUSrc;
assign Zero_sign_ex_in Zero_sign_ex;control_1 u_control_1 (.op ( instruction[31:26] ),.func ( instruction[5:0] ),.RegWrite ( RegWrite ),.Sftmd ( Sftmd ),.ALUop ( ALUop ),.Jrn ( Jrn ),// I type.Lui ( Lui ),.RegDst ( RegDst ),.ALUSrc ( ALUSrc ),.Zero_sign_ex ( Zero_sign_ex ));assign result ALUresult;endmodule4 测试
注意以前完成的指令依然要测试因为你不知道你改完之后是不是把以前对的改错了。
nop
add $1,$2,$3 # $1 2 3 5
addu $2,$4,$1 # $2 4 5 9
sub $4,$2,$1 # $4 9 - 5 4
subu $5,$4,$3 # $5 4 - 3 1and $6,$7,$8 # $6 0111 and 1000 0
or $7,$6,$8 # $7 0 or 1000 8
xor $7,$6,$8 # $7 0000 xor 1000 1000 8
nor $8,$7,$6 # $8 not (1000 or 0) 11111111111110111slt $10,$11,$12 # $10 11 12 1 # 应该用负数验证以后再说
sltu $10,$12,$11 # $10 12 11 0# sllv $12,$5,$13 # $12 1101 1 1101_0 1A 【注意此处的倒置问题 sllv rd,rt,rs】
# srlv $12,$5,$13 # $12 1101 1 110 6
# srav $14,$5,$15 # $14 1111 1 111 7 应该用负数验证以后再说# 上面3条是错误的我们应该改的不是使用而是内部运算逻辑
# 对于使用者来说逻辑就是 $13 $5
# 而实际的编码是 rt $13rs $5这与一般的指令不一样
# 因此我们在ALU运算中 rt--Brs--A应该是 【B A】而不是 A B。
sllv $12,$13,$5 # $12 1101 1 1101_0 1A
srlv $12,$13,$5 # $12 1101 1 110 6
srav $14,$15,$5 # $14 1111 1 111 7 应该用负数验证以后再说sll $16,$17,2 # $16 1_0001 2 100_0100 44
srl $16,$18,2 # $16 1_0010 2 0100 4
sra $16,$19,2 # 应该用负数验证以后再说 $16 4################ I type test #################
addi $17,$7,-1 # $17 8 - 1 7 测试符号扩展
addiu $17,$7,-2 # $17 8 - 2 6
andi $17,$8,1 # $17 1 测试zero extension
ori $17,$8,0 # $17 ffff_fff7 ffff_fff7
xori $17,$8,15 # $17 ffff_fff7 xor 0000_000f ffff_fff8 lui $17,100 # $17 前16位是64_后16位是0jr $16 # PC 4编码
memory_initialization_radix 16;
memory_initialization_vector
00000000,
00430820,
00811021,
00412022,
00832823,
00e83024,
00c83825,
00c83826,
00e64027,
016c502a,
018b502b,
00ad6004,
00ad6006,
00af7007,
00118080,
00128082,
00138083,
20f1ffff,
24f1fffe,
31110001,
35110000,
3911000f,
3c110064,
02000008;行为仿真测试成功。