From: Luke Kenneth Casson Leighton Date: Fri, 23 Nov 2018 23:44:51 +0000 (+0000) Subject: more cpu decode conversion X-Git-Url: https://git.libre-soc.org/?p=rv32.git;a=commitdiff_plain;h=4c82b31e3ed6215777984396e4ab0e65b8ea73f6 more cpu decode conversion --- diff --git a/cpu_decoder.py b/cpu_decoder.py index d2eff7d..93dbe63 100644 --- a/cpu_decoder.py +++ b/cpu_decoder.py @@ -29,66 +29,6 @@ from migen.fhdl import verilog from riscvdefs import * from cpudefs import * -def calculate_immediate(instruction, immediate): - """ calculate immediate - """ - ci = {} - no_imm = 0x0 - - # R-type: no immediate - for op in [opcode_amo, opcode_op, opcode_op_32, opcode_op_fp]: - ci[op] = immediate.eq(no_imm) - - # I-type - im = Cat(instruction[20:], Replicate(instruction[31], 20)) - for op in [opcode_load, opcode_load_fp, opcode_misc_mem, - opcode_op_imm, opcode_op_imm_32, opcode_jalr, - opcode_system]: - ci[op] = immediate.eq(im) - - # S-type - im = Cat(instruction[7:12], instruction[25:31], - Replicate(instruction[31], 21)) - for op in [opcode_store, opcode_store_fp]: - ci[op] = immediate.eq(im) - - # B-type - im = Cat(Constant(0, 1), - instruction[8:12], instruction[25:31], - instruction[7], Replicate(instruction[31], 20)) - for op in [opcode_branch, ]: - ci[op] = immediate.eq(im) - - # U-type - im = Cat(Constant(0, 1), instruction[12:], ) - for op in [opcode_auipc, opcode_lui]: - ci[op] = immediate.eq(im) - - # J-type - im = Cat(Constant(0, 1), - instruction[21:25], instruction[25:31], - instruction[20], instruction[12:20], - Replicate(instruction[31], 12)) - for op in [opcode_jal, ]: - ci[op] = immediate.eq(im) - - # R4-type: no immediate - for op in [opcode_madd, opcode_msub, opcode_nmsub, opcode_nmadd]: - ci[op] = immediate.eq(no_imm) - - # unknown - for op in [ opcode_custom_0, opcode_48b_escape_0, opcode_custom_1, - opcode_64b_escape, opcode_reserved_10101, opcode_rv128_0, - opcode_48b_escape_1, opcode_reserved_11010, - opcode_reserved_11101, opcode_rv128_1, opcode_80b_escape]: - ci[op] = immediate.eq(no_imm) - - # default - for op in [ "default", ]: - ci[op] = immediate.eq(no_imm) - - return ci - class CPUDecoder(Module): def __init__(self): @@ -102,44 +42,116 @@ class CPUDecoder(Module): self.opcode = Signal(7) self.decode_action = Signal(decode_action) + # decode bits of instruction self.comb += self.funct7.eq(self.instruction[25:32]) self.comb += self.funct3.eq(self.instruction[12:15]) - self.comb += self.rd.eq(self.instruction[7:12]) - self.comb += self.rs1.eq(self.instruction[15:20]) - self.comb += self.rs2.eq(self.instruction[20:25]) + self.comb += self.rd.eq (self.instruction[7:12]) + self.comb += self.rs1.eq (self.instruction[15:20]) + self.comb += self.rs2.eq (self.instruction[20:25]) self.comb += self.opcode.eq(self.instruction[0:7]) - # add combinatorial decode opcode case statement - ci = calculate_immediate(self.instruction, self.immediate) - self.comb += Case(self.opcode, ci) - + # add combinatorial decode opcode case statements for immed and action + self.comb += self.calculate_immediate() self.comb += self.calculate_action() - def calculate_store_action(self): - """ decode store action + def calculate_immediate(self): + """ calculate immediate + """ + ci = {} + no_imm = 0x0 + + # R-type: no immediate + for op in [opcode_amo, opcode_op, opcode_op_32, opcode_op_fp]: + ci[op] = self.immediate.eq(no_imm) + + # I-type + im = Cat(self.instruction[20:], Replicate(self.instruction[31], 20)) + for op in [opcode_load, opcode_load_fp, opcode_misc_mem, + opcode_op_imm, opcode_op_imm_32, opcode_jalr, + opcode_system]: + ci[op] = self.immediate.eq(im) + + # S-type + im = Cat(self.instruction[7:12], self.instruction[25:31], + Replicate(self.instruction[31], 21)) + for op in [opcode_store, opcode_store_fp]: + ci[op] = self.immediate.eq(im) + + # B-type + im = Cat(Constant(0, 1), + self.instruction[8:12], self.instruction[25:31], + self.instruction[7], Replicate(self.instruction[31], 20)) + for op in [opcode_branch, ]: + ci[op] = self.immediate.eq(im) + + # U-type + im = Cat(Constant(0, 1), self.instruction[12:], ) + for op in [opcode_auipc, opcode_lui]: + ci[op] = self.immediate.eq(im) + + # J-type + im = Cat(Constant(0, 1), + self.instruction[21:25], self.instruction[25:31], + self.instruction[20], self.instruction[12:20], + Replicate(self.instruction[31], 12)) + for op in [opcode_jal, ]: + ci[op] = self.immediate.eq(im) + + # R4-type: no immediate + for op in [opcode_madd, opcode_msub, opcode_nmsub, opcode_nmadd]: + ci[op] = self.immediate.eq(no_imm) + + # unknown + for op in [ opcode_custom_0, opcode_48b_escape_0, opcode_custom_1, + opcode_64b_escape, opcode_reserved_10101, opcode_rv128_0, + opcode_48b_escape_1, opcode_reserved_11010, + opcode_reserved_11101, opcode_rv128_1, opcode_80b_escape]: + ci[op] = self.immediate.eq(no_imm) + + # default + for op in [ "default", ]: + ci[op] = self.immediate.eq(no_imm) + + return Case(self.opcode, ci) + + def _decode_funct3(self, options, action): + """ decode by list of cases """ c = {} # load opcode - for op in [ funct3_sb, funct3_sh, funct3_sw, ]: - c[op] = self.decode_action.eq(decode_action_store) + for op in options: + c[op] = self.decode_action.eq(action) # default c["default"] = \ self.decode_action.eq(decode_action_trap_illegal_instruction) return Case(self.funct3, c) + def calculate_store_action(self): + """ decode store action + """ + return self._decode_funct3([ funct3_sb, funct3_sh, funct3_sw, ], + decode_action_store) + def calculate_load_action(self): """ decode load action """ - c = {} - # load opcode - for op in [ funct3_lb, funct3_lbu, funct3_lh, funct3_lhu, funct3_lw, ]: - c[op] = self.decode_action.eq(decode_action_load) - # default - c["default"] = \ - self.decode_action.eq(decode_action_trap_illegal_instruction) + return self._decode_funct3([ funct3_lb, funct3_lbu, funct3_lh, + funct3_lhu, funct3_lw, ], + decode_action_load) - return Case(self.funct3, c) + def calculate_branch_action(self): + """ decode branch action + """ + return self._decode_funct3([ funct3_beq, funct3_bne, funct3_blt, + funct3_bge, funct3_bltu, funct3_bgeu ], + decode_action_branch) + + def calculate_jalr_action(self): + """ decode jalr action + """ + return self._decode_funct3([ funct3_jalr, ], + decode_action_jalr) def calculate_op_action(self): """ decode op action @@ -204,11 +216,14 @@ class CPUDecoder(Module): c[opcode_lui] = self.decode_action.eq(decode_action_lui_auipc) c[opcode_auipc] = self.decode_action.eq(decode_action_lui_auipc) c[opcode_store] = self.calculate_store_action() + c[opcode_branch] = self.calculate_branch_action() + c[opcode_jalr] = self.calculate_jalr_action() + c[opcode_jal] = self.decode_action.eq(decode_action_jal) return Case(self.opcode, c) """ - + function `decode_action calculate_action( input [6:0] funct7, input [2:0] funct3, @@ -219,28 +234,6 @@ class CPUDecoder(Module): input [6:0] opcode); begin case(opcode) - `opcode_branch: begin - case(funct3) - `funct3_beq, - `funct3_bne, - `funct3_blt, - `funct3_bge, - `funct3_bltu, - `funct3_bgeu: - calculate_action = `decode_action_branch; - default: - calculate_action = `decode_action_trap_illegal_instruction; - endcase - end - `opcode_jalr: begin - if(funct3 == `funct3_jalr) - calculate_action = `decode_action_jalr; - else - calculate_action = `decode_action_trap_illegal_instruction; - end - `opcode_jal: begin - calculate_action = `decode_action_jal; - end `opcode_system: begin case(funct3) `funct3_ecall_ebreak: @@ -287,7 +280,7 @@ class CPUDecoder(Module): endcase end endfunction - + assign decode_action = calculate_action(funct7, funct3, rd, @@ -295,7 +288,7 @@ class CPUDecoder(Module): rs2, immediate, opcode); - + endmodule """ @@ -303,7 +296,7 @@ class CPUDecoder(Module): if __name__ == "__main__": example = CPUDecoder() print(verilog.convert(example, - { + { example.instruction, example.funct7, example.funct3, diff --git a/riscvdefs.py b/riscvdefs.py index e7a2ab3..14267c5 100644 --- a/riscvdefs.py +++ b/riscvdefs.py @@ -1,4 +1,3 @@ - """ /* * Copyright 2018 Jacob Lifshay @@ -84,14 +83,17 @@ funct3_blt = Constant(0x4, 3) funct3_bge = Constant(0x5, 3) funct3_bltu = Constant(0x6, 3) funct3_bgeu = Constant(0x7, 3) + funct3_lb = Constant(0x0, 3) funct3_lh = Constant(0x1, 3) funct3_lw = Constant(0x2, 3) funct3_lbu = Constant(0x4, 3) funct3_lhu = Constant(0x5, 3) + funct3_sb = Constant(0x0, 3) funct3_sh = Constant(0x1, 3) funct3_sw = Constant(0x2, 3) + funct3_addi = Constant(0x0, 3) funct3_slli = Constant(0x1, 3) funct3_slti = Constant(0x2, 3) @@ -100,6 +102,7 @@ funct3_xori = Constant(0x4, 3) funct3_srli_srai = Constant(0x5, 3) funct3_ori = Constant(0x6, 3) funct3_andi = Constant(0x7, 3) + funct3_add_sub = Constant(0x0, 3) funct3_sll = Constant(0x1, 3) funct3_slt = Constant(0x2, 3) @@ -108,8 +111,10 @@ funct3_xor = Constant(0x4, 3) funct3_srl_sra = Constant(0x5, 3) funct3_or = Constant(0x6, 3) funct3_and = Constant(0x7, 3) + funct3_fence = Constant(0x0, 3) funct3_fence_i = Constant(0x1, 3) + funct3_ecall_ebreak = Constant(0x0, 3) funct3_csrrw = Constant(0x1, 3) funct3_csrrs = Constant(0x2, 3)