From 613763566908ed727dc36fa271c59eb2a8d226ee Mon Sep 17 00:00:00 2001 From: unknown <1975697725@qq.com> Date: Mon, 22 Nov 2021 21:44:07 +0800 Subject: [PATCH] * --- code/Imm_gen.py | 26 ++--- code/alu.py | 184 +++++++++++++++++---------------- code/alu_controller.py | 2 +- code/binandint.py | 9 +- code/branch_unit.py | 2 +- code/data_mem.py | 44 +++++--- code/datapath.py | 62 +++++++++++ code/hazard_detector.py | 4 +- code/insn_mem.py | 13 ++- code/proc_controller.py | 2 +- code/reg_file.py | 14 +++ code/top(wating_to_filling).py | 1 + 12 files changed, 230 insertions(+), 133 deletions(-) create mode 100644 code/datapath.py create mode 100644 code/reg_file.py create mode 100644 code/top(wating_to_filling).py diff --git a/code/Imm_gen.py b/code/Imm_gen.py index e211483..7448125 100644 --- a/code/Imm_gen.py +++ b/code/Imm_gen.py @@ -1,23 +1,17 @@ def Imm_gen(inst_code): - test=inst_code[25:32] - if test=='0010011': - imm_out=20*inst_code[0]+inst_code[0:12] - elif test=='0000011': + test = inst_code[25:32] + if test == '0010011': + imm_out = 20*inst_code[0]+inst_code[0:12] + elif test == '0000011': pass - elif test=='0100011': + elif test == '0100011': pass - elif test=='1100011': + elif test == '1100011': pass - elif test=='1101111': + elif test == '1101111': pass - elif test=='1100111': + elif test == '1100111': pass - elif test=='0110111': + elif test == '0110111': pass -def imm_gen(inst_code,imm_out): - test=inst_code[25:32] - if test=="0010011": - imm_out=inst_code[0]*20+inst_code[0:12] - else: - imm_out='0'*32 - return imm_out \ No newline at end of file + return imm_out diff --git a/code/alu.py b/code/alu.py index 10606ca..864c5f2 100644 --- a/code/alu.py +++ b/code/alu.py @@ -1,92 +1,94 @@ from binandint import * -def alu(a,b,alu_ctrl): #a,b为两个运算数,alu_ctrl为控制信号,返回运算结果result与是否为0 zero - signed = a-b - if alu_ctrl=='00000': #add,jalr - alu_result = a+b - elif alu_ctrl=='00001': #sub - alu_result = a-b - elif alu_ctrl=='00010': #or - alu_result = a|b - elif alu_ctrl=='00011': #and - alu_result = a&b - elif alu_ctrl=='00100': #slt - if(signed >= 0): - alu_result = 0 - else: - alu_result = 1 - elif alu_ctrl=='00101': #beq - if a == b: - alu_result = 1 - else: - alu_result = 0 - elif alu_ctrl=='00110': #bne - if a != b: - alu_result = 1 - else: - alu_result = 0 - elif alu_ctrl=='00111': #blt - if a=b: - alu_result = 1 - else: - alu_result = 0 - elif alu_ctrl=='01001': - if a<0: - ua = a+2**32 - else: - ua=a - if b<0: - ub = b+2**32 - else: - ub=b - if ua < ub: - alu_result = 1 - else: - alu_result = 0 - elif alu_ctrl=='01010': - if a<0: - ua = a+2**32 - else: - ua=a - if b<0: - ub = b+2**32 - else: - ub=b - if ua >= ub: - alu_result = 1 - else: - alu_result = 0 - elif alu_ctrl=='01011': - alu_result = 1 - elif alu_ctrl=='01100': - alu_result = a^b - elif alu_ctrl=='01101': - alu_result=a<>b - elif alu_ctrl=='10000': - alu_result=a>>b - else: - alu_result = 0 - return alu_result \ No newline at end of file + + +def alu(a, b, alu_ctrl): # a,b为两个运算数,alu_ctrl为控制信号,返回运算结果result与是否为0 zero + signed = a-b + if alu_ctrl == '00000': # add,jalr + alu_result = a+b + elif alu_ctrl == '00001': # sub + alu_result = a-b + elif alu_ctrl == '00010': # or + alu_result = a | b + elif alu_ctrl == '00011': # and + alu_result = a & b + elif alu_ctrl == '00100': # slt + if(signed >= 0): + alu_result = 0 + else: + alu_result = 1 + elif alu_ctrl == '00101': # beq + if a == b: + alu_result = 1 + else: + alu_result = 0 + elif alu_ctrl == '00110': # bne + if a != b: + alu_result = 1 + else: + alu_result = 0 + elif alu_ctrl == '00111': # blt + if a < b: + alu_result = 1 + else: + alu_result = 0 + elif alu_ctrl == '01000': # bge + if a >= b: + alu_result = 1 + else: + alu_result = 0 + elif alu_ctrl == '01001': + if a < 0: + ua = a+2**32 + else: + ua = a + if b < 0: + ub = b+2**32 + else: + ub = b + if ua < ub: + alu_result = 1 + else: + alu_result = 0 + elif alu_ctrl == '01010': + if a < 0: + ua = a+2**32 + else: + ua = a + if b < 0: + ub = b+2**32 + else: + ub = b + if ua >= ub: + alu_result = 1 + else: + alu_result = 0 + elif alu_ctrl == '01011': + alu_result = 1 + elif alu_ctrl == '01100': + alu_result = a ^ b + elif alu_ctrl == '01101': + alu_result = a << b + elif alu_ctrl == '01110': + if a < 0: + ua = a+2**32 + else: + ua = a + if b < 0: + ub = b+2**32 + else: + ub = b + if ua <= ub: + alu_result = 1 + else: + alu_result = 0 + elif alu_ctrl == '01111': + if a < 0: + ua = a+2**32 + else: + ua = a + alu_result = a >> b + elif alu_ctrl == '10000': + alu_result = a >> b + else: + alu_result = 0 + return alu_result diff --git a/code/alu_controller.py b/code/alu_controller.py index a36bc80..63c9520 100644 --- a/code/alu_controller.py +++ b/code/alu_controller.py @@ -33,7 +33,7 @@ def alu_controller(alu_op,funct7,funct3): #alu_op来自主控制 elif funct3=='001': opreation='01101' #sll,slli 未存在 elif funct3=='011': - opreation='01110' #sliu,sltiu 未存在 + opreation='01110' #slti,sltiu 未存在 elif funct3=='101': if funct7=='0100000': #sra,srai opreation='01111' diff --git a/code/binandint.py b/code/binandint.py index 389cce0..1164a93 100644 --- a/code/binandint.py +++ b/code/binandint.py @@ -16,4 +16,11 @@ def UInttoBin(x, n): def InttoBin(x, n): if x < 0: x += 2**n - return UInttoBin(x, n) \ No newline at end of file + return UInttoBin(x, n) + +def unsigned_ext(x, n): + return '0' * (n - len(x)) + x + + +def signed_ext(x, n): + return x[0] * (n - len(x)) + x \ No newline at end of file diff --git a/code/branch_unit.py b/code/branch_unit.py index baf20fb..b26e99e 100644 --- a/code/branch_unit.py +++ b/code/branch_unit.py @@ -2,7 +2,7 @@ def branch_unit(cur_pc,imm,jalr_sel,branch_taken,alu_result): #输入 pc_plus_4=cur_pc+4 #输出为pc_plus_imm,pc_plus_4,branch_target,pc_sel(忘了这是啥了,需要回头再看) pc_plus_imm=cur_pc+imm pc_sel = jalr_sel | (branch_taken & (alu_result%2)) - if jalr_sel==1: + if jalr_sel=='1': branch_target=alu_result&(2**32-2) else: branch_target=cur_pc+imm*2 diff --git a/code/data_mem.py b/code/data_mem.py index 2846be7..9c9da04 100644 --- a/code/data_mem.py +++ b/code/data_mem.py @@ -1,26 +1,38 @@ +from binandint import * class data_mem: memory=[8*'0']*4*1024*16 + + def __init__(self) -> None: + pass + def mem(self,write_en,read_en,address,data_in,funct3): #写使能,读使能,(使能为int的0或1)地址,输入数据,func3 #输出为data_out if write_en: - if funct3=='000': - pass - elif funct3=='001': - pass - elif funct3=='010': - pass + if funct3=='000': #sb + self.memory[address]=InttoBin(data_in%2**8, 8) + elif funct3=='001': #sh + temp=InttoBin(data_in%2**16, 16) + self.memory[address+1]=temp[0:8] + self.memory[address]=temp[8:16] + elif funct3=='010': #sw + temp=InttoBin(data_in, 32) + self.memory[address+3]=temp[0:8] + self.memory[address+2]=temp[8:16] + self.memory[address+1]=temp[16:24] + self.memory[address]=temp[24:32] else: pass if read_en: - if funct3=='000': - pass - elif funct3=='001': - pass - elif funct3=='010': - pass - elif funct3=='100': - pass - elif funct3=='101': - pass + if funct3=='000': #lb + data_out=BintoInt(self.memory[address]) + elif funct3=='001': #lh + data_out=BintoInt(self.memory[address+1]+self.memory[address]) + elif funct3=='010': #lw + data_out=BintoInt(self.memory[address+3]+self.memory[address+2]+self.memory[address+1]+self.memory[address]) + elif funct3=='100': #lbu + data_out=BintoUInt(self.memory[address+1]+self.memory[address]) + elif funct3=='101': #lhu + data_out=BintoUInt(self.memory[address+3]+self.memory[address+2]+self.memory[address+1]+self.memory[address]) else: pass + return data_out diff --git a/code/datapath.py b/code/datapath.py new file mode 100644 index 0000000..fb26d51 --- /dev/null +++ b/code/datapath.py @@ -0,0 +1,62 @@ +from adder import * +from alu_controller import * +from alu import * +from binandint import * +from branch_unit import * +from data_mem import * +from forwarding_unit import * +from hazard_detector import * +from Imm_gen import * +from insn_mem import * +from mux import * +from mux4 import * +from proc_controller import * +from reg_file import reg_file + +IM=insn_mem() +PC=0 +def IF(BrPC,Brflush,stall,PC,IM): + PCplus4=adder(PC,4) + if Brflush=='1': + nPC=BrPC + else: + nPC=PC+4 + insn=IM.fetch(nPC) + return nPC,insn + +REG=reg_file() + +def ID(PC,insn,RegWrite,Brflush,stall,REG,WB_data): + funct7=insn[0:7] + rs2=BintoUInt(insn[7:12]) + rs1=BintoUInt(insn[12:17]) + funct3=insn[17:20] + rd=BintoUInt(insn[20:25]) + opcode=insn[25:32] + ALUSrc, MemtoReg, RegWritex, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel=proc_controller(opcode) + ImmG=Imm_gen(insn) + REG.write(RegWrite,rd,WB_data) + RD1,RD2=REG.read(rs1,rs2) + return ALUSrc, MemtoReg, RegWritex, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel,PC,RD1,RD2,ImmG,rs1,rs2,rd,funct3,funct7 + +def EX(ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel,PC,RD1,RD2,ImmG,rs1,rs2,rd,funct3,funct7,lastrs1,lastrs2,forwardA,forwardB,WB_data,alu_out): + stall=hazard_detector(lastrs1,lastrs2,rd,MemRead) + tempA=mux4(RD1,alu_out,WB_data,0,forwardA) + tempB=mux4(RD2,alu_out,WB_data,0,forwardB) + tempB2=mux(tempB,ImmG,ALUSrc) + alu_ctrl=alu_controller(ALUOp,funct7,funct3) + ALU_result=alu(tempA, tempB2, alu_ctrl) + pc_plus_imm,pc_plus_4,branch_target,pc_sel=branch_unit(PC,ImmG,JalrSel,Branch,ALU_result) + return MemtoReg, RegWrite,MemWrite,RWSel,MemRead,pc_plus_imm,pc_plus_4,branch_target,pc_sel,ALU_result,rs1,rs2,rd,tempA,tempB,funct3,funct7 + +MEMORY=data_mem() + +def MEM(MEMORY,MemtoReg, RegWrite,MemWrite,RWSel,MemRead,pc_plus_imm,pc_plus_4,ALU_result,rs1,rs2,rd,tempA,tempB,funct3,funct7): + data_out=MEMORY(MemWrite,MemRead,ALU_result,tempB,funct3) + return MemtoReg, RegWrite,RWSel,pc_plus_imm,pc_plus_4,data_out,tempB,rd + +def WB(MemtoReg, RegWrite,RWSel,pc_plus_imm,pc_plus_4,data_out,tempB,ex_mem_rd,mem_wb_rd,ex_mem_rs1,ex_mem_rs2,ex_mem_regwrite,mem_wb_regwrite): + mem_out=mux(data_out,tempB,MemtoReg) + WB_data=mux4(mem_out,pc_plus_4,pc_plus_imm,0,RWSel) + forward_a,forward_b= fowardingunit(ex_mem_rs1,ex_mem_rs2,ex_mem_rd,mem_wb_rd,ex_mem_regwrite,mem_wb_regwrite) + return WB_data,RegWrite,forward_a,forward_b \ No newline at end of file diff --git a/code/hazard_detector.py b/code/hazard_detector.py index 167110c..d4b9d90 100644 --- a/code/hazard_detector.py +++ b/code/hazard_detector.py @@ -1,6 +1,6 @@ def hazard_detector(if_id_rs1,if_id_rs2,id_ex_rd,id_ex_memread): if id_ex_memread and (id_ex_rd==if_id_rs1 or id_ex_rd==if_id_rs2): - stall=1 + stall='1' else: - stall=0 + stall='0' return stall \ No newline at end of file diff --git a/code/insn_mem.py b/code/insn_mem.py index 5f17c02..aa5ec26 100644 --- a/code/insn_mem.py +++ b/code/insn_mem.py @@ -1,5 +1,10 @@ class insn_mem: - memory=[8*'0']*4*1024*16 - def fetch(self,address): - insn=self.memory[address] - return insn \ No newline at end of file + memory = [8*'0']*4*1024*16 + + def __init__(self) -> None: + pass + + def fetch(self, address): + insn = self.memory[address+3]+self.memory[address+2] + \ + self.memory[address+1]+self.memory[address] + return insn diff --git a/code/proc_controller.py b/code/proc_controller.py index 832426b..b81151c 100644 --- a/code/proc_controller.py +++ b/code/proc_controller.py @@ -19,7 +19,7 @@ def proc_controller(opcode): ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel='1','0','1','0','0','11','1','0','01' ################################# elif opcode=='0010111': #(auipc)20位立即数 - ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel='1','0','1','0','0','00','1','0','11' + ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel='1','0','1','0','0','00','1','0','10' else: ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel='0','0','0','0','0','00','0','0','00' return ALUSrc, MemtoReg, RegWrite, MemRead, MemWrite, ALUOp, Branch, JalrSel, RWSel \ No newline at end of file diff --git a/code/reg_file.py b/code/reg_file.py new file mode 100644 index 0000000..88ddedf --- /dev/null +++ b/code/reg_file.py @@ -0,0 +1,14 @@ +class reg_file: + regs = [0]*32 + + def __init__(self) -> None: + pass + + def write(self, write_en, write_addr, data_in): + if write_en == '1' and write_addr != 0: + self.regs[write_addr] = data_in + + def read(self, read_addr1, read_addr2): + data_out1 = self.regs[read_addr1] + data_out2 = self.regs[read_addr2] + return data_out1, data_out2 diff --git a/code/top(wating_to_filling).py b/code/top(wating_to_filling).py new file mode 100644 index 0000000..641e6f9 --- /dev/null +++ b/code/top(wating_to_filling).py @@ -0,0 +1 @@ +from datapath import * \ No newline at end of file