X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fexperiment%2Fscore6600.py;h=ed953e8b71a3b80ff82fde4c93a115d8fcd39303;hb=9160489ce48a008af3e07fdc81d458a0b366f997;hp=602be44ed86e316b5654ce55596c64d08081088b;hpb=1f92c6f569be4ff53323c6b255191aad89e58a35;p=soc.git diff --git a/src/experiment/score6600.py b/src/experiment/score6600.py index 602be44e..ed953e8b 100644 --- a/src/experiment/score6600.py +++ b/src/experiment/score6600.py @@ -1,6 +1,6 @@ from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil -from nmigen import Module, Const, Signal, Array, Cat, Elaboratable +from nmigen import Module, Const, Signal, Array, Cat, Elaboratable, Memory from regfile.regfile import RegFileArray, treereduce from scoreboard.fu_fu_matrix import FUFUDepMatrix @@ -10,8 +10,10 @@ from scoreboard.group_picker import GroupPicker from scoreboard.issue_unit import IssueUnitGroup, IssueUnitArray, RegDecode from scoreboard.shadow import ShadowMatrix, BranchSpeculationRecord from scoreboard.instruction_q import Instruction, InstructionQ +from scoreboard.memfu import MemFunctionUnits from compalu import ComputationUnitNoDelay +from compldst import LDSTCompUnit from alu_hier import ALU, BranchALU from nmutil.latch import SRLatch @@ -22,10 +24,10 @@ from copy import deepcopy from math import log -class Memory(Elaboratable): +class TestMemory(Elaboratable): def __init__(self, regwid, addrw): - self.ddepth = regwid/8 - depth = (1< Mem FUs + comb += memfus.addr_we_i.eq(cul.adr_rel_o) # Match enable on adr rel + + comb += memfus.addrs_i[0].eq(cul.units[0].data_o) + comb += memfus.addrs_i[1].eq(cul.units[1].data_o) + + #comb += cu.go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus]) + #comb += cu.go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus]) + #comb += cu.issue_i[0:n_intfus].eq(fn_issue_o[0:n_intfus]) + #--------- # merge shadow matrices outputs #--------- @@ -538,9 +637,9 @@ class Scoreboard(Elaboratable): with m.If(br1.issue_i): sync += bspec.active_i.eq(1) with m.If(self.branch_succ_i): - comb += bspec.good_i.eq(fn_issue_o & 0x1f) + comb += bspec.good_i.eq(fn_issue_o & 0x1f) # XXX MAGIC CONSTANT with m.If(self.branch_fail_i): - comb += bspec.fail_i.eq(fn_issue_o & 0x1f) + comb += bspec.fail_i.eq(fn_issue_o & 0x1f) # XXX MAGIC CONSTANT # branch is active (TODO: a better signal: this is over-using the # go_write signal - actually the branch should not be "writing") @@ -615,8 +714,10 @@ class IssueToScoreboard(Elaboratable): iq = InstructionQ(self.rwid, self.opw, self.qlen, self.n_in, self.n_out) sc = Scoreboard(self.rwid, self.n_regs) + mem = TestMemory(self.rwid, 8) # not too big, takes too long m.submodules.iq = iq m.submodules.sc = sc + m.submodules.mem = mem # get at the regfile for testing self.intregs = sc.intregs @@ -638,9 +739,13 @@ class IssueToScoreboard(Elaboratable): # in "waiting" state wait_issue_br = Signal() wait_issue_alu = Signal() + wait_issue_ls = Signal() - with m.If(wait_issue_br | wait_issue_alu): + with m.If(wait_issue_br | wait_issue_alu | wait_issue_ls): # set instruction pop length to 1 if the unit accepted + with m.If(wait_issue_ls & (sc.lsissue.fn_issue_o != 0)): + with m.If(iq.qlen_o != 0): + comb += iq.n_sub_i.eq(1) with m.If(wait_issue_br & (sc.brissue.fn_issue_o != 0)): with m.If(iq.qlen_o != 0): comb += iq.n_sub_i.eq(1) @@ -654,10 +759,12 @@ class IssueToScoreboard(Elaboratable): # "resetting" done above (insn_i=0) could be re-ASSERTed. with m.If(iq.qlen_o != 0): # get the operands and operation + imm = iq.data_o[0].imm_i dest = iq.data_o[0].dest_i src1 = iq.data_o[0].src1_i src2 = iq.data_o[0].src2_i op = iq.data_o[0].oper_i + opi = iq.data_o[0].opim_i # immediate set # set the src/dest regs comb += sc.int_dest_i.eq(dest) @@ -667,12 +774,24 @@ class IssueToScoreboard(Elaboratable): # choose a Function-Unit-Group with m.If((op & (0x3<<2)) != 0): # branch + comb += sc.br_oper_i.eq(Cat(op[0:2], opi)) + comb += sc.br_imm_i.eq(imm) comb += sc.brissue.insn_i.eq(1) - comb += sc.br_oper_i.eq(op & 0x3) comb += wait_issue_br.eq(1) - with m.Else(): # alu + with m.Elif((op & (0x3<<4)) != 0): # ld/st + # see compldst.py + # bit 0: ADD/SUB + # bit 1: immed + # bit 4: LD + # bit 5: ST + comb += sc.ls_oper_i.eq(Cat(op[0], opi[0], op[4:6])) + comb += sc.ls_imm_i.eq(imm) + comb += sc.lsissue.insn_i.eq(1) + comb += wait_issue_ls.eq(1) + with m.Else(): # alu + comb += sc.alu_oper_i.eq(Cat(op[0:2], opi)) + comb += sc.alu_imm_i.eq(imm) comb += sc.aluissue.insn_i.eq(1) - comb += sc.alu_oper_i.eq(op & 0x3) comb += wait_issue_alu.eq(1) # XXX TODO @@ -703,15 +822,18 @@ IBLT = 5 IBEQ = 6 IBNE = 7 + class RegSim: def __init__(self, rwidth, nregs): self.rwidth = rwidth self.regs = [0] * nregs - def op(self, op, op_imm, src1, src2, dest): + def op(self, op, op_imm, imm, src1, src2, dest): maxbits = (1 << self.rwidth) - 1 src1 = self.regs[src1] & maxbits - if not op_imm: # put op in src2 + if op_imm: + src2 = imm + else: src2 = self.regs[src2] & maxbits if op == IADD: val = src1 + src2 @@ -729,6 +851,8 @@ class RegSim: val = int(src1 == src2) elif op == IBNE: val = int(src1 != src2) + else: + return 0 # LD/ST TODO val &= maxbits self.setval(dest, val) return val @@ -751,8 +875,9 @@ class RegSim: yield from self.dump(dut) assert False -def instr_q(dut, op, op_imm, src1, src2, dest, branch_success, branch_fail): - instrs = [{'oper_i': op, 'dest_i': dest, 'opim_i': op_imm, +def instr_q(dut, op, op_imm, imm, src1, src2, dest, + branch_success, branch_fail): + instrs = [{'oper_i': op, 'dest_i': dest, 'imm_i': imm, 'opim_i': op_imm, 'src1_i': src1, 'src2_i': src2}] sendlen = 1 @@ -770,7 +895,7 @@ def instr_q(dut, op, op_imm, src1, src2, dest, branch_success, branch_fail): yield dut.p_add_i.eq(0) -def int_instr(dut, op, src1, src2, dest, branch_success, branch_fail): +def int_instr(dut, op, imm, src1, src2, dest, branch_success, branch_fail): yield from disable_issue(dut) yield dut.int_dest_i.eq(dest) yield dut.int_src1_i.eq(src1) @@ -778,10 +903,12 @@ def int_instr(dut, op, src1, src2, dest, branch_success, branch_fail): if (op & (0x3<<2)) != 0: # branch yield dut.brissue.insn_i.eq(1) yield dut.br_oper_i.eq(Const(op & 0x3, 2)) + yield dut.br_imm_i.eq(imm) dut_issue = dut.brissue else: yield dut.aluissue.insn_i.eq(1) yield dut.alu_oper_i.eq(Const(op & 0x3, 2)) + yield dut.alu_imm_i.eq(imm) dut_issue = dut.aluissue yield dut.reg_enable_i.eq(1) @@ -808,14 +935,15 @@ def create_random_ops(dut, n_ops, shadowing=False, max_opnums=3): for i in range(n_ops): src1 = randint(1, dut.n_regs-1) src2 = randint(1, dut.n_regs-1) + imm = randint(1, (1<